From 04963009eedfbc1e0ea2e1378ae69e7cebda6fd6 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Mon, 26 Nov 2018 23:22:11 +0100 Subject: [PATCH] Update IDF to a0468b2 (#2108) * Update IDF to a0468b2 * add missing ld file * Fix PIO builds and change coex policy --- platform.txt | 4 +- tools/esptool.py | 40 +- tools/gen_esp32part.py | 4 +- tools/platformio-build.py | 79 +- tools/sdk/bin/bootloader_dio_40m.bin | Bin 15680 -> 15216 bytes tools/sdk/bin/bootloader_dio_80m.bin | Bin 15664 -> 15216 bytes tools/sdk/bin/bootloader_dout_40m.bin | Bin 15680 -> 15216 bytes tools/sdk/bin/bootloader_dout_80m.bin | Bin 15664 -> 15216 bytes tools/sdk/bin/bootloader_qio_40m.bin | Bin 17184 -> 16736 bytes tools/sdk/bin/bootloader_qio_80m.bin | Bin 17168 -> 16720 bytes tools/sdk/bin/bootloader_qout_40m.bin | Bin 17184 -> 16736 bytes tools/sdk/bin/bootloader_qout_80m.bin | Bin 17168 -> 16720 bytes tools/sdk/include/app_trace/esp_app_trace.h | 265 + .../include/app_trace/esp_app_trace_util.h | 167 + tools/sdk/include/app_trace/esp_ota_ops.h | 177 - tools/sdk/include/asio/asio.hpp | 156 + .../asio/asio/associated_allocator.hpp | 131 + .../include/asio/asio/associated_executor.hpp | 149 + tools/sdk/include/asio/asio/async_result.hpp | 221 + .../asio/asio/basic_datagram_socket.hpp | 1040 +++ .../asio/asio/basic_deadline_timer.hpp | 628 ++ .../sdk/include/asio/asio/basic_io_object.hpp | 290 + .../include/asio/asio/basic_raw_socket.hpp | 1030 +++ .../asio/asio/basic_seq_packet_socket.hpp | 618 ++ .../include/asio/asio/basic_serial_port.hpp | 688 ++ .../include/asio/asio/basic_signal_set.hpp | 391 + tools/sdk/include/asio/asio/basic_socket.hpp | 1757 ++++ .../asio/asio/basic_socket_acceptor.hpp | 1986 +++++ .../asio/asio/basic_socket_iostream.hpp | 430 + .../asio/asio/basic_socket_streambuf.hpp | 707 ++ .../include/asio/asio/basic_stream_socket.hpp | 921 +++ .../sdk/include/asio/asio/basic_streambuf.hpp | 452 ++ .../include/asio/asio/basic_streambuf_fwd.hpp | 36 + .../asio/asio/basic_waitable_timer.hpp | 705 ++ tools/sdk/include/asio/asio/bind_executor.hpp | 611 ++ tools/sdk/include/asio/asio/buffer.hpp | 2162 +++++ .../asio/asio/buffered_read_stream.hpp | 257 + .../asio/asio/buffered_read_stream_fwd.hpp | 25 + .../sdk/include/asio/asio/buffered_stream.hpp | 278 + .../include/asio/asio/buffered_stream_fwd.hpp | 25 + .../asio/asio/buffered_write_stream.hpp | 249 + .../asio/asio/buffered_write_stream_fwd.hpp | 25 + .../include/asio/asio/buffers_iterator.hpp | 521 ++ .../asio/asio/completion_condition.hpp | 218 + tools/sdk/include/asio/asio/connect.hpp | 1059 +++ tools/sdk/include/asio/asio/coroutine.hpp | 328 + .../asio/asio/datagram_socket_service.hpp | 466 ++ .../sdk/include/asio/asio/deadline_timer.hpp | 38 + .../asio/asio/deadline_timer_service.hpp | 173 + tools/sdk/include/asio/asio/defer.hpp | 107 + tools/sdk/include/asio/asio/detail/array.hpp | 38 + .../include/asio/asio/detail/array_fwd.hpp | 34 + tools/sdk/include/asio/asio/detail/assert.hpp | 32 + .../include/asio/asio/detail/atomic_count.hpp | 45 + .../asio/detail/base_from_completion_cond.hpp | 68 + .../include/asio/asio/detail/bind_handler.hpp | 816 ++ .../asio/asio/detail/buffer_resize_guard.hpp | 66 + .../asio/detail/buffer_sequence_adapter.hpp | 544 ++ .../asio/detail/buffered_stream_storage.hpp | 126 + .../include/asio/asio/detail/call_stack.hpp | 125 + tools/sdk/include/asio/asio/detail/chrono.hpp | 66 + .../asio/asio/detail/chrono_time_traits.hpp | 190 + .../asio/asio/detail/completion_handler.hpp | 83 + .../asio/asio/detail/concurrency_hint.hpp | 94 + .../detail/conditionally_enabled_event.hpp | 112 + .../detail/conditionally_enabled_mutex.hpp | 149 + tools/sdk/include/asio/asio/detail/config.hpp | 1441 ++++ .../asio/asio/detail/consuming_buffers.hpp | 414 + .../sdk/include/asio/asio/detail/cstddef.hpp | 31 + .../sdk/include/asio/asio/detail/cstdint.hpp | 60 + .../asio/asio/detail/date_time_fwd.hpp | 34 + .../asio/detail/deadline_timer_service.hpp | 278 + .../asio/asio/detail/dependent_type.hpp | 36 + .../asio/asio/detail/descriptor_ops.hpp | 121 + .../asio/asio/detail/descriptor_read_op.hpp | 128 + .../asio/asio/detail/descriptor_write_op.hpp | 128 + .../asio/asio/detail/dev_poll_reactor.hpp | 218 + .../asio/asio/detail/epoll_reactor.hpp | 266 + tools/sdk/include/asio/asio/detail/event.hpp | 48 + .../detail/eventfd_select_interrupter.hpp | 83 + .../include/asio/asio/detail/executor_op.hpp | 84 + .../asio/asio/detail/fd_set_adapter.hpp | 39 + .../include/asio/asio/detail/fenced_block.hpp | 80 + .../include/asio/asio/detail/functional.hpp | 38 + .../asio/asio/detail/gcc_arm_fenced_block.hpp | 91 + .../asio/detail/gcc_hppa_fenced_block.hpp | 68 + .../asio/detail/gcc_sync_fenced_block.hpp | 65 + .../asio/asio/detail/gcc_x86_fenced_block.hpp | 99 + tools/sdk/include/asio/asio/detail/global.hpp | 52 + .../asio/detail/handler_alloc_helpers.hpp | 235 + .../asio/asio/detail/handler_cont_helpers.hpp | 45 + .../asio/detail/handler_invoke_helpers.hpp | 57 + .../asio/asio/detail/handler_tracking.hpp | 238 + .../asio/detail/handler_type_requirements.hpp | 556 ++ .../include/asio/asio/detail/handler_work.hpp | 95 + .../sdk/include/asio/asio/detail/hash_map.hpp | 331 + .../asio/detail/impl/dev_poll_reactor.hpp | 91 + .../asio/asio/detail/impl/epoll_reactor.hpp | 89 + .../asio/asio/detail/impl/kqueue_reactor.hpp | 93 + .../asio/asio/detail/impl/select_reactor.hpp | 100 + .../asio/detail/impl/service_registry.hpp | 94 + .../detail/impl/strand_executor_service.hpp | 179 + .../asio/asio/detail/impl/strand_service.hpp | 118 + .../asio/detail/impl/win_iocp_io_context.hpp | 103 + .../detail/impl/winrt_timer_scheduler.hpp | 92 + .../include/asio/asio/detail/io_control.hpp | 84 + .../asio/asio/detail/is_buffer_sequence.hpp | 239 + .../include/asio/asio/detail/is_executor.hpp | 126 + .../asio/asio/detail/keyword_tss_ptr.hpp | 70 + .../asio/asio/detail/kqueue_reactor.hpp | 242 + tools/sdk/include/asio/asio/detail/limits.hpp | 26 + .../asio/detail/local_free_on_block_exit.hpp | 59 + .../asio/asio/detail/macos_fenced_block.hpp | 62 + tools/sdk/include/asio/asio/detail/memory.hpp | 70 + tools/sdk/include/asio/asio/detail/mutex.hpp | 48 + .../include/asio/asio/detail/noncopyable.hpp | 43 + .../include/asio/asio/detail/null_event.hpp | 100 + .../asio/asio/detail/null_fenced_block.hpp | 47 + .../include/asio/asio/detail/null_global.hpp | 59 + .../include/asio/asio/detail/null_mutex.hpp | 64 + .../include/asio/asio/detail/null_reactor.hpp | 68 + .../asio/asio/detail/null_signal_blocker.hpp | 69 + .../asio/asio/detail/null_socket_service.hpp | 508 ++ .../asio/asio/detail/null_static_mutex.hpp | 60 + .../include/asio/asio/detail/null_thread.hpp | 67 + .../include/asio/asio/detail/null_tss_ptr.hpp | 68 + .../include/asio/asio/detail/object_pool.hpp | 171 + .../asio/asio/detail/old_win_sdk_compat.hpp | 214 + .../sdk/include/asio/asio/detail/op_queue.hpp | 162 + .../include/asio/asio/detail/operation.hpp | 38 + .../asio/detail/pipe_select_interrupter.hpp | 89 + .../include/asio/asio/detail/pop_options.hpp | 135 + .../include/asio/asio/detail/posix_event.hpp | 162 + .../asio/asio/detail/posix_fd_set_adapter.hpp | 118 + .../include/asio/asio/detail/posix_global.hpp | 80 + .../include/asio/asio/detail/posix_mutex.hpp | 76 + .../asio/asio/detail/posix_signal_blocker.hpp | 85 + .../asio/asio/detail/posix_static_mutex.hpp | 64 + .../include/asio/asio/detail/posix_thread.hpp | 109 + .../asio/asio/detail/posix_tss_ptr.hpp | 79 + .../include/asio/asio/detail/push_options.hpp | 175 + .../detail/reactive_descriptor_service.hpp | 388 + .../asio/detail/reactive_null_buffers_op.hpp | 90 + .../detail/reactive_serial_port_service.hpp | 236 + .../asio/detail/reactive_socket_accept_op.hpp | 217 + .../detail/reactive_socket_connect_op.hpp | 113 + .../asio/detail/reactive_socket_recv_op.hpp | 135 + .../detail/reactive_socket_recvfrom_op.hpp | 138 + .../detail/reactive_socket_recvmsg_op.hpp | 132 + .../asio/detail/reactive_socket_send_op.hpp | 134 + .../asio/detail/reactive_socket_sendto_op.hpp | 130 + .../asio/detail/reactive_socket_service.hpp | 526 ++ .../detail/reactive_socket_service_base.hpp | 511 ++ .../asio/asio/detail/reactive_wait_op.hpp | 90 + .../sdk/include/asio/asio/detail/reactor.hpp | 32 + .../include/asio/asio/detail/reactor_fwd.hpp | 40 + .../include/asio/asio/detail/reactor_op.hpp | 65 + .../asio/asio/detail/reactor_op_queue.hpp | 168 + .../asio/asio/detail/recycling_allocator.hpp | 104 + .../include/asio/asio/detail/regex_fwd.hpp | 35 + .../asio/asio/detail/resolve_endpoint_op.hpp | 122 + .../include/asio/asio/detail/resolve_op.hpp | 45 + .../asio/asio/detail/resolve_query_op.hpp | 134 + .../asio/asio/detail/resolver_service.hpp | 145 + .../asio/detail/resolver_service_base.hpp | 140 + .../include/asio/asio/detail/scheduler.hpp | 213 + .../asio/asio/detail/scheduler_operation.hpp | 78 + .../asio/detail/scheduler_thread_info.hpp | 40 + .../include/asio/asio/detail/scoped_lock.hpp | 101 + .../include/asio/asio/detail/scoped_ptr.hpp | 87 + .../asio/asio/detail/select_interrupter.hpp | 46 + .../asio/asio/detail/select_reactor.hpp | 238 + .../asio/asio/detail/service_registry.hpp | 164 + .../asio/asio/detail/signal_blocker.hpp | 44 + .../asio/asio/detail/signal_handler.hpp | 86 + .../include/asio/asio/detail/signal_init.hpp | 47 + .../include/asio/asio/detail/signal_op.hpp | 49 + .../asio/asio/detail/signal_set_service.hpp | 217 + .../asio/asio/detail/socket_holder.hpp | 98 + .../include/asio/asio/detail/socket_ops.hpp | 337 + .../asio/asio/detail/socket_option.hpp | 316 + .../asio/detail/socket_select_interrupter.hpp | 92 + .../include/asio/asio/detail/socket_types.hpp | 419 + .../asio/asio/detail/solaris_fenced_block.hpp | 62 + .../include/asio/asio/detail/static_mutex.hpp | 52 + .../include/asio/asio/detail/std_event.hpp | 176 + .../asio/asio/detail/std_fenced_block.hpp | 62 + .../include/asio/asio/detail/std_global.hpp | 70 + .../include/asio/asio/detail/std_mutex.hpp | 73 + .../asio/asio/detail/std_static_mutex.hpp | 81 + .../include/asio/asio/detail/std_thread.hpp | 71 + .../asio/detail/strand_executor_service.hpp | 142 + .../asio/asio/detail/strand_service.hpp | 142 + .../include/asio/asio/detail/string_view.hpp | 47 + tools/sdk/include/asio/asio/detail/thread.hpp | 60 + .../asio/asio/detail/thread_context.hpp | 42 + .../include/asio/asio/detail/thread_group.hpp | 89 + .../asio/asio/detail/thread_info_base.hpp | 121 + .../include/asio/asio/detail/throw_error.hpp | 53 + .../asio/asio/detail/throw_exception.hpp | 51 + .../include/asio/asio/detail/timer_queue.hpp | 358 + .../asio/asio/detail/timer_queue_base.hpp | 68 + .../asio/asio/detail/timer_queue_ptime.hpp | 99 + .../asio/asio/detail/timer_queue_set.hpp | 66 + .../asio/asio/detail/timer_scheduler.hpp | 35 + .../asio/asio/detail/timer_scheduler_fwd.hpp | 40 + .../sdk/include/asio/asio/detail/tss_ptr.hpp | 69 + .../include/asio/asio/detail/type_traits.hpp | 86 + .../asio/asio/detail/variadic_templates.hpp | 119 + .../include/asio/asio/detail/wait_handler.hpp | 85 + .../sdk/include/asio/asio/detail/wait_op.hpp | 45 + .../include/asio/asio/detail/win_event.hpp | 151 + .../asio/asio/detail/win_fd_set_adapter.hpp | 149 + .../asio/asio/detail/win_fenced_block.hpp | 90 + .../include/asio/asio/detail/win_global.hpp | 73 + .../asio/detail/win_iocp_handle_read_op.hpp | 111 + .../asio/detail/win_iocp_handle_service.hpp | 323 + .../asio/detail/win_iocp_handle_write_op.hpp | 103 + .../asio/asio/detail/win_iocp_io_context.hpp | 328 + .../asio/detail/win_iocp_null_buffers_op.hpp | 121 + .../asio/asio/detail/win_iocp_operation.hpp | 96 + .../asio/detail/win_iocp_overlapped_op.hpp | 90 + .../asio/detail/win_iocp_overlapped_ptr.hpp | 143 + .../detail/win_iocp_serial_port_service.hpp | 230 + .../asio/detail/win_iocp_socket_accept_op.hpp | 297 + .../detail/win_iocp_socket_connect_op.hpp | 127 + .../asio/detail/win_iocp_socket_recv_op.hpp | 117 + .../detail/win_iocp_socket_recvfrom_op.hpp | 125 + .../detail/win_iocp_socket_recvmsg_op.hpp | 118 + .../asio/detail/win_iocp_socket_send_op.hpp | 111 + .../asio/detail/win_iocp_socket_service.hpp | 599 ++ .../detail/win_iocp_socket_service_base.hpp | 591 ++ .../asio/asio/detail/win_iocp_thread_info.hpp | 34 + .../asio/asio/detail/win_iocp_wait_op.hpp | 121 + .../include/asio/asio/detail/win_mutex.hpp | 78 + .../asio/detail/win_object_handle_service.hpp | 184 + .../asio/asio/detail/win_static_mutex.hpp | 74 + .../include/asio/asio/detail/win_thread.hpp | 147 + .../include/asio/asio/detail/win_tss_ptr.hpp | 79 + .../asio/asio/detail/winapp_thread.hpp | 124 + .../include/asio/asio/detail/wince_thread.hpp | 124 + .../asio/asio/detail/winrt_async_manager.hpp | 294 + .../asio/asio/detail/winrt_async_op.hpp | 65 + .../asio/asio/detail/winrt_resolve_op.hpp | 118 + .../asio/detail/winrt_resolver_service.hpp | 198 + .../asio/detail/winrt_socket_connect_op.hpp | 92 + .../asio/asio/detail/winrt_socket_recv_op.hpp | 112 + .../asio/asio/detail/winrt_socket_send_op.hpp | 103 + .../asio/detail/winrt_ssocket_service.hpp | 241 + .../detail/winrt_ssocket_service_base.hpp | 359 + .../asio/detail/winrt_timer_scheduler.hpp | 137 + .../include/asio/asio/detail/winrt_utils.hpp | 106 + .../include/asio/asio/detail/winsock_init.hpp | 128 + .../asio/asio/detail/work_dispatcher.hpp | 72 + .../asio/asio/detail/wrapped_handler.hpp | 291 + tools/sdk/include/asio/asio/dispatch.hpp | 108 + tools/sdk/include/asio/asio/error.hpp | 356 + tools/sdk/include/asio/asio/error_code.hpp | 206 + .../include/asio/asio/execution_context.hpp | 411 + tools/sdk/include/asio/asio/executor.hpp | 341 + .../include/asio/asio/executor_work_guard.hpp | 170 + tools/sdk/include/asio/asio/experimental.hpp | 22 + .../asio/asio/experimental/co_spawn.hpp | 226 + .../asio/asio/experimental/detached.hpp | 65 + .../asio/asio/experimental/impl/co_spawn.hpp | 876 ++ .../asio/asio/experimental/impl/detached.hpp | 91 + .../asio/experimental/impl/redirect_error.hpp | 294 + .../asio/asio/experimental/redirect_error.hpp | 67 + .../asio/asio/generic/basic_endpoint.hpp | 193 + .../asio/asio/generic/datagram_protocol.hpp | 123 + .../asio/asio/generic/detail/endpoint.hpp | 133 + .../asio/asio/generic/raw_protocol.hpp | 121 + .../asio/asio/generic/seq_packet_protocol.hpp | 122 + .../asio/asio/generic/stream_protocol.hpp | 127 + .../include/asio/asio/handler_alloc_hook.hpp | 81 + .../asio/asio/handler_continuation_hook.hpp | 54 + .../include/asio/asio/handler_invoke_hook.hpp | 85 + tools/sdk/include/asio/asio/handler_type.hpp | 50 + .../asio/asio/high_resolution_timer.hpp | 44 + .../asio/asio/impl/buffered_read_stream.hpp | 429 + .../asio/asio/impl/buffered_write_stream.hpp | 411 + tools/sdk/include/asio/asio/impl/connect.hpp | 860 ++ tools/sdk/include/asio/asio/impl/defer.hpp | 77 + tools/sdk/include/asio/asio/impl/dispatch.hpp | 78 + .../asio/asio/impl/execution_context.hpp | 107 + tools/sdk/include/asio/asio/impl/executor.hpp | 386 + .../sdk/include/asio/asio/impl/io_context.hpp | 343 + tools/sdk/include/asio/asio/impl/post.hpp | 77 + tools/sdk/include/asio/asio/impl/read.hpp | 715 ++ tools/sdk/include/asio/asio/impl/read_at.hpp | 640 ++ .../sdk/include/asio/asio/impl/read_until.hpp | 1500 ++++ .../asio/asio/impl/serial_port_base.hpp | 59 + tools/sdk/include/asio/asio/impl/spawn.hpp | 535 ++ tools/sdk/include/asio/asio/impl/src.hpp | 82 + .../include/asio/asio/impl/system_context.hpp | 34 + .../asio/asio/impl/system_executor.hpp | 85 + .../include/asio/asio/impl/thread_pool.hpp | 127 + .../sdk/include/asio/asio/impl/use_future.hpp | 938 +++ tools/sdk/include/asio/asio/impl/write.hpp | 674 ++ tools/sdk/include/asio/asio/impl/write_at.hpp | 572 ++ tools/sdk/include/asio/asio/io_context.hpp | 876 ++ .../include/asio/asio/io_context_strand.hpp | 384 + tools/sdk/include/asio/asio/io_service.hpp | 33 + .../include/asio/asio/io_service_strand.hpp | 20 + tools/sdk/include/asio/asio/ip/address.hpp | 260 + tools/sdk/include/asio/asio/ip/address_v4.hpp | 329 + .../asio/asio/ip/address_v4_iterator.hpp | 162 + .../include/asio/asio/ip/address_v4_range.hpp | 134 + tools/sdk/include/asio/asio/ip/address_v6.hpp | 336 + .../asio/asio/ip/address_v6_iterator.hpp | 183 + .../include/asio/asio/ip/address_v6_range.hpp | 129 + .../include/asio/asio/ip/bad_address_cast.hpp | 48 + .../include/asio/asio/ip/basic_endpoint.hpp | 263 + .../include/asio/asio/ip/basic_resolver.hpp | 1018 +++ .../asio/asio/ip/basic_resolver_entry.hpp | 113 + .../asio/asio/ip/basic_resolver_iterator.hpp | 192 + .../asio/asio/ip/basic_resolver_query.hpp | 244 + .../asio/asio/ip/basic_resolver_results.hpp | 311 + .../include/asio/asio/ip/detail/endpoint.hpp | 139 + .../asio/asio/ip/detail/socket_option.hpp | 566 ++ tools/sdk/include/asio/asio/ip/host_name.hpp | 42 + tools/sdk/include/asio/asio/ip/icmp.hpp | 115 + .../sdk/include/asio/asio/ip/impl/address.hpp | 67 + .../include/asio/asio/ip/impl/address_v4.hpp | 67 + .../include/asio/asio/ip/impl/address_v6.hpp | 67 + .../asio/asio/ip/impl/basic_endpoint.hpp | 43 + .../include/asio/asio/ip/impl/network_v4.hpp | 54 + .../include/asio/asio/ip/impl/network_v6.hpp | 53 + tools/sdk/include/asio/asio/ip/multicast.hpp | 191 + tools/sdk/include/asio/asio/ip/network_v4.hpp | 261 + tools/sdk/include/asio/asio/ip/network_v6.hpp | 235 + .../include/asio/asio/ip/resolver_base.hpp | 129 + .../asio/asio/ip/resolver_query_base.hpp | 43 + .../include/asio/asio/ip/resolver_service.hpp | 200 + tools/sdk/include/asio/asio/ip/tcp.hpp | 155 + tools/sdk/include/asio/asio/ip/udp.hpp | 111 + tools/sdk/include/asio/asio/ip/unicast.hpp | 70 + tools/sdk/include/asio/asio/ip/v6_only.hpp | 69 + tools/sdk/include/asio/asio/is_executor.hpp | 46 + .../include/asio/asio/is_read_buffered.hpp | 59 + .../include/asio/asio/is_write_buffered.hpp | 59 + .../asio/asio/local/basic_endpoint.hpp | 239 + .../include/asio/asio/local/connect_pair.hpp | 106 + .../asio/asio/local/datagram_protocol.hpp | 80 + .../asio/asio/local/detail/endpoint.hpp | 133 + .../asio/asio/local/stream_protocol.hpp | 90 + tools/sdk/include/asio/asio/packaged_task.hpp | 126 + tools/sdk/include/asio/asio/placeholders.hpp | 151 + .../asio/asio/posix/basic_descriptor.hpp | 582 ++ .../asio/posix/basic_stream_descriptor.hpp | 362 + .../include/asio/asio/posix/descriptor.hpp | 644 ++ .../asio/asio/posix/descriptor_base.hpp | 90 + .../asio/asio/posix/stream_descriptor.hpp | 360 + .../asio/posix/stream_descriptor_service.hpp | 279 + tools/sdk/include/asio/asio/post.hpp | 107 + .../include/asio/asio/raw_socket_service.hpp | 466 ++ tools/sdk/include/asio/asio/read.hpp | 947 +++ tools/sdk/include/asio/asio/read_at.hpp | 671 ++ tools/sdk/include/asio/asio/read_until.hpp | 1824 +++++ .../asio/asio/seq_packet_socket_service.hpp | 416 + tools/sdk/include/asio/asio/serial_port.hpp | 769 ++ .../include/asio/asio/serial_port_base.hpp | 167 + .../include/asio/asio/serial_port_service.hpp | 249 + tools/sdk/include/asio/asio/signal_set.hpp | 447 + .../include/asio/asio/signal_set_service.hpp | 142 + .../asio/asio/socket_acceptor_service.hpp | 372 + tools/sdk/include/asio/asio/socket_base.hpp | 559 ++ tools/sdk/include/asio/asio/spawn.hpp | 336 + tools/sdk/include/asio/asio/ssl.hpp | 27 + tools/sdk/include/asio/asio/ssl/context.hpp | 758 ++ .../include/asio/asio/ssl/context_base.hpp | 192 + .../asio/ssl/detail/buffered_handshake_op.hpp | 114 + .../include/asio/asio/ssl/detail/engine.hpp | 160 + .../asio/asio/ssl/detail/handshake_op.hpp | 62 + tools/sdk/include/asio/asio/ssl/detail/io.hpp | 372 + .../asio/asio/ssl/detail/openssl_init.hpp | 101 + .../asio/asio/ssl/detail/openssl_types.hpp | 30 + .../asio/ssl/detail/password_callback.hpp | 66 + .../include/asio/asio/ssl/detail/read_op.hpp | 67 + .../asio/asio/ssl/detail/shutdown_op.hpp | 54 + .../asio/asio/ssl/detail/stream_core.hpp | 134 + .../asio/asio/ssl/detail/verify_callback.hpp | 62 + .../include/asio/asio/ssl/detail/write_op.hpp | 67 + tools/sdk/include/asio/asio/ssl/error.hpp | 111 + .../include/asio/asio/ssl/impl/context.hpp | 67 + tools/sdk/include/asio/asio/ssl/impl/src.hpp | 28 + .../asio/asio/ssl/rfc2818_verification.hpp | 94 + tools/sdk/include/asio/asio/ssl/stream.hpp | 761 ++ .../sdk/include/asio/asio/ssl/stream_base.hpp | 52 + .../include/asio/asio/ssl/verify_context.hpp | 67 + .../sdk/include/asio/asio/ssl/verify_mode.hpp | 63 + tools/sdk/include/asio/asio/steady_timer.hpp | 42 + tools/sdk/include/asio/asio/strand.hpp | 286 + .../asio/asio/stream_socket_service.hpp | 412 + tools/sdk/include/asio/asio/streambuf.hpp | 33 + .../sdk/include/asio/asio/system_context.hpp | 78 + tools/sdk/include/asio/asio/system_error.hpp | 131 + .../sdk/include/asio/asio/system_executor.hpp | 129 + tools/sdk/include/asio/asio/system_timer.hpp | 42 + tools/sdk/include/asio/asio/thread.hpp | 92 + tools/sdk/include/asio/asio/thread_pool.hpp | 232 + tools/sdk/include/asio/asio/time_traits.hpp | 86 + tools/sdk/include/asio/asio/ts/buffer.hpp | 24 + tools/sdk/include/asio/asio/ts/executor.hpp | 35 + tools/sdk/include/asio/asio/ts/internet.hpp | 40 + tools/sdk/include/asio/asio/ts/io_context.hpp | 20 + tools/sdk/include/asio/asio/ts/net.hpp | 26 + tools/sdk/include/asio/asio/ts/netfwd.hpp | 197 + tools/sdk/include/asio/asio/ts/socket.hpp | 27 + tools/sdk/include/asio/asio/ts/timer.hpp | 26 + tools/sdk/include/asio/asio/unyield.hpp | 21 + tools/sdk/include/asio/asio/use_future.hpp | 159 + tools/sdk/include/asio/asio/uses_executor.hpp | 71 + tools/sdk/include/asio/asio/version.hpp | 23 + tools/sdk/include/asio/asio/wait_traits.hpp | 56 + .../asio/asio/waitable_timer_service.hpp | 210 + .../asio/asio/windows/basic_handle.hpp | 273 + .../asio/asio/windows/basic_object_handle.hpp | 182 + .../windows/basic_random_access_handle.hpp | 376 + .../asio/asio/windows/basic_stream_handle.hpp | 359 + .../asio/asio/windows/object_handle.hpp | 381 + .../asio/windows/object_handle_service.hpp | 183 + .../asio/asio/windows/overlapped_handle.hpp | 331 + .../asio/asio/windows/overlapped_ptr.hpp | 116 + .../asio/windows/random_access_handle.hpp | 378 + .../windows/random_access_handle_service.hpp | 214 + .../asio/asio/windows/stream_handle.hpp | 362 + .../asio/windows/stream_handle_service.hpp | 210 + tools/sdk/include/asio/asio/write.hpp | 927 +++ tools/sdk/include/asio/asio/write_at.hpp | 677 ++ tools/sdk/include/asio/asio/yield.hpp | 23 + tools/sdk/include/asio/esp_asio_config.h | 45 + tools/sdk/include/asio/esp_exception.h | 39 + tools/sdk/include/bluedroid/a2d_int.h | 81 - tools/sdk/include/bluedroid/aes.h | 162 - tools/sdk/include/bluedroid/avct_defs.h | 62 - tools/sdk/include/bluedroid/avct_int.h | 237 - tools/sdk/include/bluedroid/avdt_defs.h | 208 - tools/sdk/include/bluedroid/avdt_int.h | 748 -- tools/sdk/include/bluedroid/avrc_int.h | 158 - tools/sdk/include/bluedroid/blufi_int.h | 185 - tools/sdk/include/bluedroid/bt.h | 3 - tools/sdk/include/bluedroid/bt_sdp.h | 111 - tools/sdk/include/bluedroid/bta/bta_api.h | 2543 ------ tools/sdk/include/bluedroid/bta/bta_ar_api.h | 144 - tools/sdk/include/bluedroid/bta/bta_av_api.h | 813 -- tools/sdk/include/bluedroid/bta/bta_av_ci.h | 77 - tools/sdk/include/bluedroid/bta/bta_av_co.h | 393 - tools/sdk/include/bluedroid/bta/bta_av_sbc.h | 223 - tools/sdk/include/bluedroid/bta/bta_dm_ci.h | 68 - tools/sdk/include/bluedroid/bta/bta_dm_co.h | 207 - .../sdk/include/bluedroid/bta/bta_gatt_api.h | 1482 ---- .../include/bluedroid/bta/bta_gatt_common.h | 36 - .../sdk/include/bluedroid/bta/bta_gattc_ci.h | 117 - .../sdk/include/bluedroid/bta/bta_gattc_co.h | 140 - .../sdk/include/bluedroid/bta/bta_gatts_co.h | 81 - .../include/bluedroid/bta/bta_hf_client_api.h | 378 - .../include/bluedroid/bta/bta_hf_client_co.h | 115 - .../sdk/include/bluedroid/bta/bta_hfp_defs.h | 47 - tools/sdk/include/bluedroid/bta/bta_hh_api.h | 545 -- tools/sdk/include/bluedroid/bta/bta_hh_co.h | 132 - tools/sdk/include/bluedroid/bta/bta_jv_api.h | 884 -- tools/sdk/include/bluedroid/bta/bta_jv_co.h | 55 - tools/sdk/include/bluedroid/bta/bta_sdp_api.h | 147 - tools/sdk/include/bluedroid/bta/bta_sys.h | 283 - tools/sdk/include/bluedroid/bta/utl.h | 184 - tools/sdk/include/bluedroid/bta_sys_int.h | 101 - .../include/bluedroid/btc/btc_ble_storage.h | 86 - tools/sdk/include/bluedroid/btc/btc_common.h | 35 - tools/sdk/include/bluedroid/btc/btc_config.h | 58 - tools/sdk/include/bluedroid/btc/btc_dm.h | 86 - tools/sdk/include/bluedroid/btc/btc_main.h | 64 - .../include/bluedroid/btc/btc_profile_queue.h | 55 - tools/sdk/include/bluedroid/btc/btc_sm.h | 115 - tools/sdk/include/bluedroid/btc/btc_storage.h | 92 - tools/sdk/include/bluedroid/btc/btc_task.h | 82 - tools/sdk/include/bluedroid/btc/btc_util.h | 50 - tools/sdk/include/bluedroid/btc_a2dp.h | 108 - .../sdk/include/bluedroid/btc_a2dp_control.h | 110 - tools/sdk/include/bluedroid/btc_a2dp_sink.h | 139 - tools/sdk/include/bluedroid/btc_a2dp_source.h | 244 - tools/sdk/include/bluedroid/btc_av.h | 220 - tools/sdk/include/bluedroid/btc_av_api.h | 201 - tools/sdk/include/bluedroid/btc_av_co.h | 172 - tools/sdk/include/bluedroid/btc_avrc.h | 88 - tools/sdk/include/bluedroid/btc_blufi_prf.h | 70 - tools/sdk/include/bluedroid/btc_gap_ble.h | 172 - tools/sdk/include/bluedroid/btc_gap_bt.h | 136 - tools/sdk/include/bluedroid/btc_gatt_common.h | 37 - tools/sdk/include/bluedroid/btc_gatt_util.h | 40 - tools/sdk/include/bluedroid/btc_gattc.h | 240 - tools/sdk/include/bluedroid/btc_gatts.h | 153 - tools/sdk/include/bluedroid/btc_hf_client.h | 128 - tools/sdk/include/bluedroid/btc_spp.h | 92 - tools/sdk/include/bluedroid/button_pro.h | 120 - .../bluedroid/common/bt_common_types.h | 43 - tools/sdk/include/bluedroid/common/bt_defs.h | 155 - .../sdk/include/bluedroid/common/bt_target.h | 1967 ----- tools/sdk/include/bluedroid/common/bt_trace.h | 748 -- .../include/bluedroid/common/bt_vendor_lib.h | 362 - tools/sdk/include/bluedroid/common/bte.h | 116 - tools/sdk/include/bluedroid/common/bte_appl.h | 49 - tools/sdk/include/bluedroid/device/bdaddr.h | 63 - .../sdk/include/bluedroid/device/controller.h | 91 - .../bluedroid/device/device_features.h | 29 - .../sdk/include/bluedroid/device/event_mask.h | 30 - tools/sdk/include/bluedroid/device/interop.h | 45 - .../bluedroid/device/interop_database.h | 50 - tools/sdk/include/bluedroid/device/version.h | 31 - tools/sdk/include/bluedroid/dis_api.h | 338 - tools/sdk/include/bluedroid/esp_bt.h | 472 -- tools/sdk/include/bluedroid/esp_sec_api.h | 79 - tools/sdk/include/bluedroid/gap_int.h | 154 - tools/sdk/include/bluedroid/gatt_int.h | 753 -- .../sdk/include/bluedroid/hci/bt_vendor_lib.h | 362 - tools/sdk/include/bluedroid/hci/hci_audio.h | 42 - tools/sdk/include/bluedroid/hci/hci_hal.h | 85 - .../sdk/include/bluedroid/hci/hci_internals.h | 31 - tools/sdk/include/bluedroid/hci/hci_layer.h | 99 - .../bluedroid/hci/hci_packet_factory.h | 52 - .../include/bluedroid/hci/hci_packet_parser.h | 102 - .../include/bluedroid/hci/packet_fragmenter.h | 62 - tools/sdk/include/bluedroid/hid_conn.h | 69 - tools/sdk/include/bluedroid/hidh_int.h | 95 - tools/sdk/include/bluedroid/l2c_int.h | 819 -- tools/sdk/include/bluedroid/oi_assert.h | 86 - tools/sdk/include/bluedroid/oi_bitstream.h | 123 - tools/sdk/include/bluedroid/oi_bt_spec.h | 229 - tools/sdk/include/bluedroid/oi_codec_sbc.h | 484 -- .../include/bluedroid/oi_codec_sbc_private.h | 229 - tools/sdk/include/bluedroid/oi_common.h | 43 - tools/sdk/include/bluedroid/oi_cpu_dep.h | 505 -- tools/sdk/include/bluedroid/oi_modules.h | 171 - tools/sdk/include/bluedroid/oi_osinterface.h | 197 - tools/sdk/include/bluedroid/oi_status.h | 579 -- tools/sdk/include/bluedroid/oi_stddefs.h | 232 - tools/sdk/include/bluedroid/oi_string.h | 208 - tools/sdk/include/bluedroid/oi_time.h | 200 - tools/sdk/include/bluedroid/oi_utils.h | 377 - tools/sdk/include/bluedroid/osi/alarm.h | 80 - tools/sdk/include/bluedroid/osi/allocator.h | 141 - tools/sdk/include/bluedroid/osi/buffer.h | 59 - tools/sdk/include/bluedroid/osi/config.h | 148 - tools/sdk/include/bluedroid/osi/fixed_queue.h | 135 - tools/sdk/include/bluedroid/osi/future.h | 53 - .../include/bluedroid/osi/hash_functions.h | 37 - tools/sdk/include/bluedroid/osi/hash_map.h | 110 - tools/sdk/include/bluedroid/osi/list.h | 110 - tools/sdk/include/bluedroid/osi/mutex.h | 53 - tools/sdk/include/bluedroid/osi/osi.h | 16 - tools/sdk/include/bluedroid/osi/semaphore.h | 43 - tools/sdk/include/bluedroid/osi/thread.h | 115 - tools/sdk/include/bluedroid/p_256_ecc_pp.h | 67 - .../include/bluedroid/p_256_multprecision.h | 62 - tools/sdk/include/bluedroid/port_int.h | 247 - tools/sdk/include/bluedroid/rfc_int.h | 378 - tools/sdk/include/bluedroid/sbc_dct.h | 91 - .../include/bluedroid/sbc_enc_func_declare.h | 57 - tools/sdk/include/bluedroid/sbc_encoder.h | 201 - tools/sdk/include/bluedroid/sbc_if.h | 47 - tools/sdk/include/bluedroid/sbc_types.h | 59 - tools/sdk/include/bluedroid/sdpint.h | 316 - tools/sdk/include/bluedroid/smp_int.h | 539 -- tools/sdk/include/bluedroid/srvc_api.h | 210 - .../sdk/include/bluedroid/srvc_battery_int.h | 79 - tools/sdk/include/bluedroid/srvc_dis_int.h | 82 - tools/sdk/include/bluedroid/stack/a2d_api.h | 256 - tools/sdk/include/bluedroid/stack/a2d_sbc.h | 213 - tools/sdk/include/bluedroid/stack/avct_api.h | 279 - tools/sdk/include/bluedroid/stack/avdt_api.h | 988 --- tools/sdk/include/bluedroid/stack/avdtc_api.h | 230 - tools/sdk/include/bluedroid/stack/avrc_api.h | 653 -- tools/sdk/include/bluedroid/stack/avrc_defs.h | 1362 ---- tools/sdk/include/bluedroid/stack/bt_types.h | 793 -- tools/sdk/include/bluedroid/stack/btm_api.h | 4100 ---------- .../sdk/include/bluedroid/stack/btm_ble_api.h | 2059 ----- tools/sdk/include/bluedroid/stack/btu.h | 285 - tools/sdk/include/bluedroid/stack/dyn_mem.h | 217 - tools/sdk/include/bluedroid/stack/gap_api.h | 391 - tools/sdk/include/bluedroid/stack/gatt_api.h | 1218 --- tools/sdk/include/bluedroid/stack/gattdefs.h | 124 - tools/sdk/include/bluedroid/stack/hcidefs.h | 2609 ------ tools/sdk/include/bluedroid/stack/hcimsgs.h | 811 -- tools/sdk/include/bluedroid/stack/hiddefs.h | 163 - tools/sdk/include/bluedroid/stack/hidh_api.h | 238 - tools/sdk/include/bluedroid/stack/l2c_api.h | 1237 --- .../include/bluedroid/stack/l2cap_client.h | 80 - tools/sdk/include/bluedroid/stack/l2cdefs.h | 329 - tools/sdk/include/bluedroid/stack/port_api.h | 657 -- tools/sdk/include/bluedroid/stack/port_ext.h | 31 - .../include/bluedroid/stack/profiles_api.h | 70 - tools/sdk/include/bluedroid/stack/rfcdefs.h | 248 - tools/sdk/include/bluedroid/stack/sdp_api.h | 726 -- tools/sdk/include/bluedroid/stack/sdpdefs.h | 327 - tools/sdk/include/bluedroid/stack/smp_api.h | 511 -- tools/sdk/include/bluedroid/wx_airsync_prf.h | 110 - .../bootloader_support/bootloader_util.h | 34 + .../include/bootloader_support/esp_efuse.h | 33 + .../bootloader_support/esp_image_format.h | 12 + .../{bluedroid/api => bt}/esp_a2dp_api.h | 0 .../{bluedroid/api => bt}/esp_avrc_api.h | 0 .../{bluedroid/api => bt}/esp_blufi_api.h | 0 .../{bluedroid/api => bt}/esp_bt_defs.h | 0 .../{bluedroid/api => bt}/esp_bt_device.h | 0 .../{bluedroid/api => bt}/esp_bt_main.h | 0 .../{bluedroid/api => bt}/esp_gap_ble_api.h | 133 +- .../{bluedroid/api => bt}/esp_gap_bt_api.h | 0 .../api => bt}/esp_gatt_common_api.h | 0 .../{bluedroid/api => bt}/esp_gatt_defs.h | 5 + .../{bluedroid/api => bt}/esp_gattc_api.h | 10 +- .../{bluedroid/api => bt}/esp_gatts_api.h | 73 +- .../{bluedroid/api => bt}/esp_hf_client_api.h | 18 +- .../{bluedroid/api => bt}/esp_hf_defs.h | 0 .../{bluedroid/api => bt}/esp_spp_api.h | 3 +- tools/sdk/include/coap/address.h | 152 + tools/sdk/include/coap/async.h | 146 + tools/sdk/include/coap/bits.h | 78 + tools/sdk/include/coap/block.h | 137 + .../include/coap/{coap/coap.h.in => coap.h} | 23 +- tools/sdk/include/coap/coap_io.h | 167 + tools/sdk/include/coap/coap_time.h | 142 + tools/sdk/include/coap/debug.h | 85 + tools/sdk/include/coap/encode.h | 52 + tools/sdk/include/coap/hashkey.h | 57 + tools/sdk/include/coap/libcoap.h | 26 + tools/sdk/include/coap/lwippools.h | 57 + tools/sdk/include/coap/mem.h | 111 + tools/sdk/include/coap/net.h | 521 ++ tools/sdk/include/coap/option.h | 410 + tools/sdk/include/coap/pdu.h | 388 + tools/sdk/include/coap/prng.h | 106 + tools/sdk/include/coap/resource.h | 408 + tools/sdk/include/coap/str.h | 33 + tools/sdk/include/coap/subscribe.h | 72 + tools/sdk/include/coap/uri.h | 121 + tools/sdk/include/coap/uthash.h | 963 +++ tools/sdk/include/coap/utlist.h | 757 ++ tools/sdk/include/config/sdkconfig.h | 37 +- tools/sdk/include/driver/driver/i2c.h | 29 + tools/sdk/include/driver/driver/mcpwm.h | 45 +- tools/sdk/include/driver/driver/spi_common.h | 39 +- tools/sdk/include/driver/driver/spi_master.h | 135 +- tools/sdk/include/driver/driver/spi_slave.h | 48 +- tools/sdk/include/esp-tls/esp_tls.h | 142 +- tools/sdk/include/esp32/esp_attr.h | 18 +- tools/sdk/include/esp32/esp_clk.h | 1 + tools/sdk/include/esp32/esp_core_dump.h | 55 +- tools/sdk/include/esp32/esp_err.h | 31 + .../esp32/{esp_event.h => esp_event_legacy.h} | 0 .../sdk/include/esp32/esp_flash_data_types.h | 1 + tools/sdk/include/esp32/esp_himem.h | 152 + tools/sdk/include/esp32/esp_intr_alloc.h | 11 +- tools/sdk/include/esp32/esp_ipc.h | 15 - tools/sdk/include/esp32/esp_mesh.h | 148 +- tools/sdk/include/esp32/esp_mesh_internal.h | 2 +- tools/sdk/include/esp32/esp_spiram.h | 26 +- tools/sdk/include/esp32/esp_task.h | 1 + tools/sdk/include/esp32/esp_wifi.h | 8 + tools/sdk/include/esp32/esp_wifi_internal.h | 9 + tools/sdk/include/esp32/hwcrypto/aes.h | 66 + tools/sdk/include/esp32/rom/cache.h | 16 +- tools/sdk/include/esp32/rom/uart.h | 14 +- tools/sdk/include/esp32/xtensa/config/core.h | 11 + tools/sdk/include/esp_event/esp_event.h | 336 + tools/sdk/include/esp_event/esp_event_base.h | 43 + .../include/esp_http_client/esp_http_client.h | 8 +- .../esp_http_server.h} | 342 +- .../sdk/include/esp_http_server/http_server.h | 2 + .../esp_https_server/esp_https_server.h | 117 + .../freertos/ringbuf.h | 0 tools/sdk/include/ethernet/esp_eth.h | 75 +- .../include/ethernet/eth_phy/phy_lan8720.h | 2 +- tools/sdk/include/ethernet/eth_phy/phy_reg.h | 42 +- .../sdk/include/ethernet/eth_phy/phy_tlk110.h | 2 +- tools/sdk/include/expat/.gitignore | 18 - tools/sdk/include/expat/Makefile.am | 77 - tools/sdk/include/expat/expat.vcxproj | 179 - tools/sdk/include/expat/expat.vcxproj.filters | 83 - tools/sdk/include/expat/expat_static.vcxproj | 149 - .../expat/expat_static.vcxproj.filters | 74 - tools/sdk/include/expat/expatw.vcxproj | 179 - .../sdk/include/expat/expatw.vcxproj.filters | 83 - tools/sdk/include/expat/expatw_static.vcxproj | 149 - .../expat/expatw_static.vcxproj.filters | 74 - tools/sdk/include/expat/libexpat.def | 78 - tools/sdk/include/expat/libexpatw.def | 78 - tools/sdk/include/expat/loadlibrary.c | 143 - tools/sdk/include/expat/xmlparse.c | 7195 ----------------- tools/sdk/include/expat/xmlrole.c | 1386 ---- tools/sdk/include/expat/xmltok.c | 1806 ----- tools/sdk/include/expat/xmltok_impl.c | 1760 ---- tools/sdk/include/expat/xmltok_ns.c | 142 - tools/sdk/include/fatfs/ffconf.h | 2 +- tools/sdk/include/freemodbus/mb.h | 417 + tools/sdk/include/freemodbus/mbconfig.h | 132 + tools/sdk/include/freemodbus/mbcontroller.h | 186 + tools/sdk/include/freemodbus/mbframe.h | 87 + tools/sdk/include/freemodbus/mbfunc.h | 80 + tools/sdk/include/freemodbus/mbport.h | 130 + tools/sdk/include/freemodbus/mbproto.h | 83 + tools/sdk/include/freemodbus/mbutils.h | 108 + .../freertos/freertos/FreeRTOSConfig.h | 7 +- tools/sdk/include/freertos/freertos/task.h | 36 +- tools/sdk/include/idf_test/idf_performance.h | 24 + tools/sdk/include/json/tests/common.h | 122 + .../examples/example_1/src/ProductionCode.h | 3 + .../examples/example_1/src/ProductionCode2.h | 2 + .../examples/example_2/src/ProductionCode.h | 3 + .../examples/example_2/src/ProductionCode2.h | 2 + .../examples/example_3/helper/UnityHelper.h | 12 + .../examples/example_3/src/ProductionCode.h | 3 + .../examples/example_3/src/ProductionCode2.h | 2 + .../json/tests/unity/examples/unity_config.h | 239 + .../unity/extras/fixture/src/unity_fixture.h | 83 + .../fixture/src/unity_fixture_internals.h | 51 + .../src/unity_fixture_malloc_overrides.h | 47 + .../extras/fixture/test/unity_output_Spy.h | 17 + .../sdk/include/json/tests/unity/src/unity.h | 503 ++ .../json/tests/unity/src/unity_internals.h | 870 ++ .../unity/test/expectdata/testsample_head1.h | 15 + .../test/expectdata/testsample_mock_head1.h | 13 + .../tests/unity/test/testdata/CException.h | 11 + .../json/tests/unity/test/testdata/Defs.h | 8 + .../json/tests/unity/test/testdata/cmock.h | 14 + .../json/tests/unity/test/testdata/mockMock.h | 13 + tools/sdk/include/libsodium/sodium.h | 68 + tools/sdk/include/libsodium/sodium/core.h | 19 + .../libsodium/sodium/crypto_aead_aes256gcm.h | 145 + .../sodium/crypto_aead_chacha20poly1305.h | 162 + .../sodium/crypto_aead_xchacha20poly1305.h | 91 + .../include/libsodium/sodium/crypto_auth.h | 44 + .../libsodium/sodium/crypto_auth_hmacsha256.h | 68 + .../libsodium/sodium/crypto_auth_hmacsha512.h | 67 + .../sodium/crypto_auth_hmacsha512256.h | 62 + .../sdk/include/libsodium/sodium/crypto_box.h | 169 + .../crypto_box_curve25519xchacha20poly1305.h | 130 + .../crypto_box_curve25519xsalsa20poly1305.h | 100 + .../libsodium/sodium/crypto_core_hchacha20.h | 35 + .../libsodium/sodium/crypto_core_hsalsa20.h | 35 + .../libsodium/sodium/crypto_core_salsa20.h | 35 + .../libsodium/sodium/crypto_core_salsa2012.h | 35 + .../libsodium/sodium/crypto_core_salsa208.h | 35 + .../libsodium/sodium/crypto_generichash.h | 75 + .../sodium/crypto_generichash_blake2b.h | 121 + .../include/libsodium/sodium/crypto_hash.h | 40 + .../libsodium/sodium/crypto_hash_sha256.h | 57 + .../libsodium/sodium/crypto_hash_sha512.h | 57 + .../sdk/include/libsodium/sodium/crypto_kdf.h | 51 + .../libsodium/sodium/crypto_kdf_blake2b.h | 42 + .../sdk/include/libsodium/sodium/crypto_kx.h | 64 + .../libsodium/sodium/crypto_onetimeauth.h | 62 + .../sodium/crypto_onetimeauth_poly1305.h | 71 + .../include/libsodium/sodium/crypto_pwhash.h | 121 + .../libsodium/sodium/crypto_pwhash_argon2i.h | 120 + .../crypto_pwhash_scryptsalsa208sha256.h | 112 + .../libsodium/sodium/crypto_scalarmult.h | 37 + .../sodium/crypto_scalarmult_curve25519.h | 36 + .../libsodium/sodium/crypto_secretbox.h | 87 + .../crypto_secretbox_xchacha20poly1305.h | 62 + .../crypto_secretbox_xsalsa20poly1305.h | 58 + .../libsodium/sodium/crypto_shorthash.h | 39 + .../sodium/crypto_shorthash_siphash24.h | 48 + .../include/libsodium/sodium/crypto_sign.h | 99 + .../libsodium/sodium/crypto_sign_ed25519.h | 110 + .../crypto_sign_edwards25519sha512batch.h | 54 + .../include/libsodium/sodium/crypto_stream.h | 52 + .../sodium/crypto_stream_aes128ctr.h | 65 + .../libsodium/sodium/crypto_stream_chacha20.h | 92 + .../libsodium/sodium/crypto_stream_salsa20.h | 57 + .../sodium/crypto_stream_salsa2012.h | 46 + .../libsodium/sodium/crypto_stream_salsa208.h | 46 + .../sodium/crypto_stream_xchacha20.h | 53 + .../libsodium/sodium/crypto_stream_xsalsa20.h | 53 + .../libsodium/sodium/crypto_verify_16.h | 23 + .../libsodium/sodium/crypto_verify_32.h | 23 + .../libsodium/sodium/crypto_verify_64.h | 23 + tools/sdk/include/libsodium/sodium/export.h | 44 + .../include/libsodium/sodium/private/common.h | 217 + .../sodium/private/curve25519_ref10.h | 160 + .../include/libsodium/sodium/private/mutex.h | 7 + .../libsodium/sodium/private/sse2_64_32.h | 50 + .../include/libsodium/sodium/randombytes.h | 66 + .../sodium/randombytes_nativeclient.h | 23 + .../sodium/randombytes_salsa20_random.h | 19 + .../libsodium/sodium/randombytes_sysrandom.h | 19 + tools/sdk/include/libsodium/sodium/runtime.h | 46 + tools/sdk/include/libsodium/sodium/utils.h | 131 + tools/sdk/include/libsodium/sodium/version.h | 35 + tools/sdk/include/lwip/apps/sntp/sntp.h | 3 + tools/sdk/include/lwip/arch/sys_arch.h | 3 +- tools/sdk/include/lwip/{ping => }/esp_ping.h | 7 +- tools/sdk/include/lwip/lwip/api.h | 9 + tools/sdk/include/lwip/lwip/apps/FILES | 2 - tools/sdk/include/lwip/lwip/autoip.h | 20 - tools/sdk/include/lwip/lwip/sys.h | 11 + tools/sdk/include/lwip/sys_arch.h | 3 +- tools/sdk/include/mbedtls/.gitignore | 4 - tools/sdk/include/mbedtls/CMakeLists.txt | 16 - .../{mbedtls_port => mbedtls}/aes_alt.h | 8 + .../btc/btc_alarm.h => mbedtls/esp_mem.h} | 22 +- tools/sdk/include/mbedtls/mbedtls/aes.h | 4 +- tools/sdk/include/mbedtls/mbedtls/arc4.h | 2 +- tools/sdk/include/mbedtls/mbedtls/aria.h | 2 +- tools/sdk/include/mbedtls/mbedtls/bignum.h | 2 +- tools/sdk/include/mbedtls/mbedtls/blowfish.h | 2 +- tools/sdk/include/mbedtls/mbedtls/camellia.h | 2 +- tools/sdk/include/mbedtls/mbedtls/ccm.h | 3 +- tools/sdk/include/mbedtls/mbedtls/chacha20.h | 2 +- .../sdk/include/mbedtls/mbedtls/chachapoly.h | 2 +- tools/sdk/include/mbedtls/mbedtls/cipher.h | 9 +- tools/sdk/include/mbedtls/mbedtls/config.h | 47 +- tools/sdk/include/mbedtls/mbedtls/ctr_drbg.h | 2 +- tools/sdk/include/mbedtls/mbedtls/des.h | 4 +- tools/sdk/include/mbedtls/mbedtls/dhm.h | 2 +- tools/sdk/include/mbedtls/mbedtls/ecdh.h | 2 +- tools/sdk/include/mbedtls/mbedtls/ecjpake.h | 2 +- tools/sdk/include/mbedtls/mbedtls/ecp.h | 8 +- tools/sdk/include/mbedtls/mbedtls/entropy.h | 4 +- .../mbedtls/esp_config.h | 52 +- .../mbedtls/esp_debug.h | 0 tools/sdk/include/mbedtls/mbedtls/gcm.h | 3 +- tools/sdk/include/mbedtls/mbedtls/havege.h | 2 +- tools/sdk/include/mbedtls/mbedtls/hkdf.h | 14 +- tools/sdk/include/mbedtls/mbedtls/hmac_drbg.h | 2 +- tools/sdk/include/mbedtls/mbedtls/md.h | 3 +- tools/sdk/include/mbedtls/mbedtls/md2.h | 2 +- tools/sdk/include/mbedtls/mbedtls/md4.h | 2 +- tools/sdk/include/mbedtls/mbedtls/md5.h | 2 +- .../sdk/include/mbedtls/mbedtls/net_sockets.h | 2 +- tools/sdk/include/mbedtls/mbedtls/oid.h | 3 +- tools/sdk/include/mbedtls/mbedtls/pem.h | 2 +- tools/sdk/include/mbedtls/mbedtls/pk.h | 6 +- tools/sdk/include/mbedtls/mbedtls/pkcs11.h | 3 +- tools/sdk/include/mbedtls/mbedtls/platform.h | 3 +- .../include/mbedtls/mbedtls/platform_util.h | 41 + tools/sdk/include/mbedtls/mbedtls/poly1305.h | 2 +- tools/sdk/include/mbedtls/mbedtls/ripemd160.h | 2 +- tools/sdk/include/mbedtls/mbedtls/rsa.h | 2 +- tools/sdk/include/mbedtls/mbedtls/sha1.h | 2 +- tools/sdk/include/mbedtls/mbedtls/sha256.h | 2 +- tools/sdk/include/mbedtls/mbedtls/sha512.h | 2 +- tools/sdk/include/mbedtls/mbedtls/ssl.h | 169 +- .../sdk/include/mbedtls/mbedtls/ssl_cookie.h | 2 +- .../include/mbedtls/mbedtls/ssl_internal.h | 53 +- .../sdk/include/mbedtls/mbedtls/ssl_ticket.h | 4 +- tools/sdk/include/mbedtls/mbedtls/threading.h | 13 +- tools/sdk/include/mbedtls/mbedtls/timing.h | 2 +- tools/sdk/include/mbedtls/mbedtls/version.h | 10 +- tools/sdk/include/mbedtls/mbedtls/x509_crt.h | 2 +- tools/sdk/include/mbedtls/mbedtls/xtea.h | 2 +- .../{mbedtls_port => mbedtls}/sha1_alt.h | 0 .../{mbedtls_port => mbedtls}/sha256_alt.h | 0 .../{mbedtls_port => mbedtls}/sha512_alt.h | 0 .../sdk/include/mbedtls_port/mbedtls/bignum.h | 78 - .../sdk/include/mbedtls_port/mbedtls/config.h | 9 - tools/sdk/include/micro-ecc/types.h | 108 + tools/sdk/include/micro-ecc/uECC.h | 365 + tools/sdk/include/micro-ecc/uECC_vli.h | 172 + .../include/{esp-mqtt => mqtt}/mqtt_client.h | 34 +- .../include/{esp-mqtt => mqtt}/mqtt_config.h | 0 tools/sdk/include/newlib/assert.h | 72 +- tools/sdk/include/newlib/errno.h | 42 +- tools/sdk/include/newlib/pthread.h | 440 +- tools/sdk/include/newlib/sys/unistd.h | 523 +- tools/sdk/include/newlib/time.h | 296 +- .../nghttp/{http_parser => }/http_parser.h | 0 tools/sdk/include/nvs_flash/nvs.h | 43 +- tools/sdk/include/nvs_flash/nvs_flash.h | 87 + .../protobuf-c/protobuf-c/protobuf-c.h | 1106 +++ .../protobuf-c/protoc-c/c_bytes_field.h | 100 + .../sdk/include/protobuf-c/protoc-c/c_enum.h | 118 + .../protobuf-c/protoc-c/c_enum_field.h | 98 + .../include/protobuf-c/protoc-c/c_extension.h | 110 + .../sdk/include/protobuf-c/protoc-c/c_field.h | 132 + .../sdk/include/protobuf-c/protoc-c/c_file.h | 117 + .../include/protobuf-c/protoc-c/c_generator.h | 100 + .../include/protobuf-c/protoc-c/c_helpers.h | 197 + .../include/protobuf-c/protoc-c/c_message.h | 141 + .../protobuf-c/protoc-c/c_message_field.h | 97 + .../protobuf-c/protoc-c/c_primitive_field.h | 96 + .../include/protobuf-c/protoc-c/c_service.h | 112 + .../protobuf-c/protoc-c/c_string_field.h | 100 + .../t/generated-code2/common-test-arrays.h | 62 + tools/sdk/include/protocomm/protocomm.h | 226 + tools/sdk/include/protocomm/protocomm_ble.h | 92 + .../sdk/include/protocomm/protocomm_console.h | 59 + tools/sdk/include/protocomm/protocomm_httpd.h | 73 + .../include/protocomm/protocomm_security.h | 93 + .../protocomm_security0.h} | 25 +- .../protocomm_security1.h} | 35 +- tools/sdk/include/pthread/esp_pthread.h | 73 + tools/sdk/include/soc/soc/cpu.h | 9 + tools/sdk/include/soc/soc/efuse_reg.h | 3 + tools/sdk/include/soc/soc/periph_defs.h | 3 + tools/sdk/include/soc/soc/soc.h | 30 +- tools/sdk/include/soc/soc/soc_memory_layout.h | 16 + tools/sdk/include/spi_flash/esp_partition.h | 1 + tools/sdk/include/spi_flash/esp_spi_flash.h | 31 +- .../{transport.h => esp_transport.h} | 111 +- .../include/tcp_transport/esp_transport_ssl.h | 69 + .../{transport_tcp.h => esp_transport_tcp.h} | 14 +- ...ransport_utils.h => esp_transport_utils.h} | 10 +- .../include/tcp_transport/esp_transport_ws.h | 34 + .../sdk/include/tcp_transport/transport_ssl.h | 48 - .../sdk/include/tcpip_adapter/tcpip_adapter.h | 10 + tools/sdk/include/unity/unity.h | 503 ++ tools/sdk/include/unity/unity_config.h | 53 + tools/sdk/include/unity/unity_internals.h | 928 +++ tools/sdk/include/unity/unity_test_runner.h | 174 + tools/sdk/include/vfs/esp_vfs.h | 6 + .../wifi_provisioning/wifi_config.h | 120 + .../include/wpa_supplicant/crypto/crypto.h | 359 + tools/sdk/include/wpa_supplicant/endian.h | 1 + tools/sdk/include/wpa_supplicant/os.h | 2 +- tools/sdk/ld/esp32.common.ld | 180 +- tools/sdk/ld/esp32.extram.bss.ld | 17 + tools/sdk/ld/esp32.ld | 18 + tools/sdk/ld/esp32.rom.ld | 56 +- tools/sdk/ld/esp32.rom.redefined.ld | 60 + .../ld/esp32.rom.spiram_incompatible_fns.ld | 4 - tools/sdk/ld/esp32_out.ld | 10 + tools/sdk/lib/libapp_trace.a | Bin 23000 -> 23000 bytes tools/sdk/lib/libapp_update.a | Bin 52882 -> 53002 bytes tools/sdk/lib/libasio.a | Bin 2004904 -> 2004332 bytes tools/sdk/lib/libbootloader_support.a | Bin 336386 -> 295512 bytes tools/sdk/lib/libbt.a | Bin 12967336 -> 13111280 bytes tools/sdk/lib/libbtdm_app.a | Bin 317842 -> 341708 bytes tools/sdk/lib/libcoap.a | Bin 458066 -> 458066 bytes tools/sdk/lib/libcoexist.a | Bin 51776 -> 55692 bytes tools/sdk/lib/libconsole.a | Bin 401084 -> 401084 bytes tools/sdk/lib/libcore.a | Bin 11638 -> 11638 bytes tools/sdk/lib/libcxx.a | Bin 63624 -> 63624 bytes tools/sdk/lib/libdriver.a | Bin 2420766 -> 2463996 bytes tools/sdk/lib/libesp-tls.a | Bin 58596 -> 80048 bytes tools/sdk/lib/libesp32.a | Bin 1212224 -> 1291416 bytes tools/sdk/lib/libesp_adc_cal.a | Bin 39920 -> 39920 bytes tools/sdk/lib/libesp_event.a | Bin 0 -> 88654 bytes tools/sdk/lib/libesp_http_client.a | Bin 168794 -> 181314 bytes tools/sdk/lib/libesp_http_server.a | Bin 0 -> 255858 bytes tools/sdk/lib/libesp_https_ota.a | Bin 20430 -> 20518 bytes tools/sdk/lib/libesp_https_server.a | Bin 0 -> 32984 bytes tools/sdk/lib/libesp_ringbuf.a | Bin 118268 -> 118268 bytes tools/sdk/lib/libespnow.a | Bin 46530 -> 46530 bytes tools/sdk/lib/libethernet.a | Bin 159166 -> 163724 bytes tools/sdk/lib/libexpat.a | Bin 1219082 -> 1219082 bytes tools/sdk/lib/libfatfs.a | Bin 454872 -> 463404 bytes tools/sdk/lib/libfreemodbus.a | Bin 0 -> 248968 bytes tools/sdk/lib/libfreertos.a | Bin 536940 -> 535980 bytes tools/sdk/lib/libheap.a | Bin 228102 -> 228102 bytes tools/sdk/lib/libhttp_server.a | Bin 236646 -> 0 bytes tools/sdk/lib/libjsmn.a | Bin 21694 -> 21694 bytes tools/sdk/lib/libjson.a | Bin 300090 -> 300090 bytes tools/sdk/lib/liblibsodium.a | Bin 0 -> 1814296 bytes tools/sdk/lib/liblog.a | Bin 40640 -> 40640 bytes tools/sdk/lib/liblwip.a | Bin 3292790 -> 3295892 bytes tools/sdk/lib/libmbedtls.a | Bin 3364080 -> 3412002 bytes tools/sdk/lib/libmdns.a | Bin 655816 -> 656292 bytes tools/sdk/lib/libmesh.a | Bin 644822 -> 856100 bytes tools/sdk/lib/libmicro-ecc.a | Bin 155340 -> 155340 bytes tools/sdk/lib/libmqtt.a | Bin 213182 -> 177780 bytes tools/sdk/lib/libnet80211.a | Bin 1037758 -> 945290 bytes tools/sdk/lib/libnewlib.a | Bin 124830 -> 129354 bytes tools/sdk/lib/libnghttp.a | Bin 1560590 -> 1560590 bytes tools/sdk/lib/libnvs_flash.a | Bin 776884 -> 840512 bytes tools/sdk/lib/libopenssl.a | Bin 288284 -> 288436 bytes tools/sdk/lib/libpp.a | Bin 476726 -> 477354 bytes tools/sdk/lib/libprotobuf-c.a | Bin 0 -> 329210 bytes tools/sdk/lib/libprotocomm.a | Bin 0 -> 424886 bytes tools/sdk/lib/libpthread.a | Bin 106278 -> 117942 bytes tools/sdk/lib/libsdmmc.a | Bin 255524 -> 255528 bytes tools/sdk/lib/libsmartconfig.a | Bin 103336 -> 104474 bytes tools/sdk/lib/libsmartconfig_ack.a | Bin 22294 -> 22294 bytes tools/sdk/lib/libsoc.a | Bin 230944 -> 231232 bytes tools/sdk/lib/libspi_flash.a | Bin 211280 -> 213156 bytes tools/sdk/lib/libspiffs.a | Bin 585754 -> 590322 bytes tools/sdk/lib/libtcp_transport.a | Bin 98078 -> 145704 bytes tools/sdk/lib/libtcpip_adapter.a | Bin 133646 -> 134876 bytes tools/sdk/lib/libulp.a | Bin 37442 -> 37442 bytes tools/sdk/lib/libunity.a | Bin 0 -> 172882 bytes tools/sdk/lib/libvfs.a | Bin 236660 -> 242366 bytes tools/sdk/lib/libwear_levelling.a | Bin 235776 -> 235920 bytes tools/sdk/lib/libwifi_provisioning.a | Bin 0 -> 147522 bytes tools/sdk/lib/libwpa.a | Bin 158180 -> 158180 bytes tools/sdk/lib/libwpa2.a | Bin 24878 -> 25158 bytes tools/sdk/lib/libwpa_supplicant.a | Bin 3035404 -> 3099006 bytes tools/sdk/lib/libwps.a | Bin 52004 -> 53020 bytes tools/sdk/lib/libxtensa-debug-module.a | Bin 12130 -> 12130 bytes tools/sdk/sdkconfig | 87 +- 988 files changed, 114643 insertions(+), 65141 deletions(-) create mode 100644 tools/sdk/include/app_trace/esp_app_trace.h create mode 100644 tools/sdk/include/app_trace/esp_app_trace_util.h delete mode 100644 tools/sdk/include/app_trace/esp_ota_ops.h create mode 100644 tools/sdk/include/asio/asio.hpp create mode 100644 tools/sdk/include/asio/asio/associated_allocator.hpp create mode 100644 tools/sdk/include/asio/asio/associated_executor.hpp create mode 100644 tools/sdk/include/asio/asio/async_result.hpp create mode 100644 tools/sdk/include/asio/asio/basic_datagram_socket.hpp create mode 100644 tools/sdk/include/asio/asio/basic_deadline_timer.hpp create mode 100644 tools/sdk/include/asio/asio/basic_io_object.hpp create mode 100644 tools/sdk/include/asio/asio/basic_raw_socket.hpp create mode 100644 tools/sdk/include/asio/asio/basic_seq_packet_socket.hpp create mode 100644 tools/sdk/include/asio/asio/basic_serial_port.hpp create mode 100644 tools/sdk/include/asio/asio/basic_signal_set.hpp create mode 100644 tools/sdk/include/asio/asio/basic_socket.hpp create mode 100644 tools/sdk/include/asio/asio/basic_socket_acceptor.hpp create mode 100644 tools/sdk/include/asio/asio/basic_socket_iostream.hpp create mode 100644 tools/sdk/include/asio/asio/basic_socket_streambuf.hpp create mode 100644 tools/sdk/include/asio/asio/basic_stream_socket.hpp create mode 100644 tools/sdk/include/asio/asio/basic_streambuf.hpp create mode 100644 tools/sdk/include/asio/asio/basic_streambuf_fwd.hpp create mode 100644 tools/sdk/include/asio/asio/basic_waitable_timer.hpp create mode 100644 tools/sdk/include/asio/asio/bind_executor.hpp create mode 100644 tools/sdk/include/asio/asio/buffer.hpp create mode 100644 tools/sdk/include/asio/asio/buffered_read_stream.hpp create mode 100644 tools/sdk/include/asio/asio/buffered_read_stream_fwd.hpp create mode 100644 tools/sdk/include/asio/asio/buffered_stream.hpp create mode 100644 tools/sdk/include/asio/asio/buffered_stream_fwd.hpp create mode 100644 tools/sdk/include/asio/asio/buffered_write_stream.hpp create mode 100644 tools/sdk/include/asio/asio/buffered_write_stream_fwd.hpp create mode 100644 tools/sdk/include/asio/asio/buffers_iterator.hpp create mode 100644 tools/sdk/include/asio/asio/completion_condition.hpp create mode 100644 tools/sdk/include/asio/asio/connect.hpp create mode 100644 tools/sdk/include/asio/asio/coroutine.hpp create mode 100644 tools/sdk/include/asio/asio/datagram_socket_service.hpp create mode 100644 tools/sdk/include/asio/asio/deadline_timer.hpp create mode 100644 tools/sdk/include/asio/asio/deadline_timer_service.hpp create mode 100644 tools/sdk/include/asio/asio/defer.hpp create mode 100644 tools/sdk/include/asio/asio/detail/array.hpp create mode 100644 tools/sdk/include/asio/asio/detail/array_fwd.hpp create mode 100644 tools/sdk/include/asio/asio/detail/assert.hpp create mode 100644 tools/sdk/include/asio/asio/detail/atomic_count.hpp create mode 100644 tools/sdk/include/asio/asio/detail/base_from_completion_cond.hpp create mode 100644 tools/sdk/include/asio/asio/detail/bind_handler.hpp create mode 100644 tools/sdk/include/asio/asio/detail/buffer_resize_guard.hpp create mode 100644 tools/sdk/include/asio/asio/detail/buffer_sequence_adapter.hpp create mode 100644 tools/sdk/include/asio/asio/detail/buffered_stream_storage.hpp create mode 100644 tools/sdk/include/asio/asio/detail/call_stack.hpp create mode 100644 tools/sdk/include/asio/asio/detail/chrono.hpp create mode 100644 tools/sdk/include/asio/asio/detail/chrono_time_traits.hpp create mode 100644 tools/sdk/include/asio/asio/detail/completion_handler.hpp create mode 100644 tools/sdk/include/asio/asio/detail/concurrency_hint.hpp create mode 100644 tools/sdk/include/asio/asio/detail/conditionally_enabled_event.hpp create mode 100644 tools/sdk/include/asio/asio/detail/conditionally_enabled_mutex.hpp create mode 100644 tools/sdk/include/asio/asio/detail/config.hpp create mode 100644 tools/sdk/include/asio/asio/detail/consuming_buffers.hpp create mode 100644 tools/sdk/include/asio/asio/detail/cstddef.hpp create mode 100644 tools/sdk/include/asio/asio/detail/cstdint.hpp create mode 100644 tools/sdk/include/asio/asio/detail/date_time_fwd.hpp create mode 100644 tools/sdk/include/asio/asio/detail/deadline_timer_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/dependent_type.hpp create mode 100644 tools/sdk/include/asio/asio/detail/descriptor_ops.hpp create mode 100644 tools/sdk/include/asio/asio/detail/descriptor_read_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/descriptor_write_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/dev_poll_reactor.hpp create mode 100644 tools/sdk/include/asio/asio/detail/epoll_reactor.hpp create mode 100644 tools/sdk/include/asio/asio/detail/event.hpp create mode 100644 tools/sdk/include/asio/asio/detail/eventfd_select_interrupter.hpp create mode 100644 tools/sdk/include/asio/asio/detail/executor_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/fd_set_adapter.hpp create mode 100644 tools/sdk/include/asio/asio/detail/fenced_block.hpp create mode 100644 tools/sdk/include/asio/asio/detail/functional.hpp create mode 100644 tools/sdk/include/asio/asio/detail/gcc_arm_fenced_block.hpp create mode 100644 tools/sdk/include/asio/asio/detail/gcc_hppa_fenced_block.hpp create mode 100644 tools/sdk/include/asio/asio/detail/gcc_sync_fenced_block.hpp create mode 100644 tools/sdk/include/asio/asio/detail/gcc_x86_fenced_block.hpp create mode 100644 tools/sdk/include/asio/asio/detail/global.hpp create mode 100644 tools/sdk/include/asio/asio/detail/handler_alloc_helpers.hpp create mode 100644 tools/sdk/include/asio/asio/detail/handler_cont_helpers.hpp create mode 100644 tools/sdk/include/asio/asio/detail/handler_invoke_helpers.hpp create mode 100644 tools/sdk/include/asio/asio/detail/handler_tracking.hpp create mode 100644 tools/sdk/include/asio/asio/detail/handler_type_requirements.hpp create mode 100644 tools/sdk/include/asio/asio/detail/handler_work.hpp create mode 100644 tools/sdk/include/asio/asio/detail/hash_map.hpp create mode 100644 tools/sdk/include/asio/asio/detail/impl/dev_poll_reactor.hpp create mode 100644 tools/sdk/include/asio/asio/detail/impl/epoll_reactor.hpp create mode 100644 tools/sdk/include/asio/asio/detail/impl/kqueue_reactor.hpp create mode 100644 tools/sdk/include/asio/asio/detail/impl/select_reactor.hpp create mode 100644 tools/sdk/include/asio/asio/detail/impl/service_registry.hpp create mode 100644 tools/sdk/include/asio/asio/detail/impl/strand_executor_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/impl/strand_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/impl/win_iocp_io_context.hpp create mode 100644 tools/sdk/include/asio/asio/detail/impl/winrt_timer_scheduler.hpp create mode 100644 tools/sdk/include/asio/asio/detail/io_control.hpp create mode 100644 tools/sdk/include/asio/asio/detail/is_buffer_sequence.hpp create mode 100644 tools/sdk/include/asio/asio/detail/is_executor.hpp create mode 100644 tools/sdk/include/asio/asio/detail/keyword_tss_ptr.hpp create mode 100644 tools/sdk/include/asio/asio/detail/kqueue_reactor.hpp create mode 100644 tools/sdk/include/asio/asio/detail/limits.hpp create mode 100644 tools/sdk/include/asio/asio/detail/local_free_on_block_exit.hpp create mode 100644 tools/sdk/include/asio/asio/detail/macos_fenced_block.hpp create mode 100644 tools/sdk/include/asio/asio/detail/memory.hpp create mode 100644 tools/sdk/include/asio/asio/detail/mutex.hpp create mode 100644 tools/sdk/include/asio/asio/detail/noncopyable.hpp create mode 100644 tools/sdk/include/asio/asio/detail/null_event.hpp create mode 100644 tools/sdk/include/asio/asio/detail/null_fenced_block.hpp create mode 100644 tools/sdk/include/asio/asio/detail/null_global.hpp create mode 100644 tools/sdk/include/asio/asio/detail/null_mutex.hpp create mode 100644 tools/sdk/include/asio/asio/detail/null_reactor.hpp create mode 100644 tools/sdk/include/asio/asio/detail/null_signal_blocker.hpp create mode 100644 tools/sdk/include/asio/asio/detail/null_socket_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/null_static_mutex.hpp create mode 100644 tools/sdk/include/asio/asio/detail/null_thread.hpp create mode 100644 tools/sdk/include/asio/asio/detail/null_tss_ptr.hpp create mode 100644 tools/sdk/include/asio/asio/detail/object_pool.hpp create mode 100644 tools/sdk/include/asio/asio/detail/old_win_sdk_compat.hpp create mode 100644 tools/sdk/include/asio/asio/detail/op_queue.hpp create mode 100644 tools/sdk/include/asio/asio/detail/operation.hpp create mode 100644 tools/sdk/include/asio/asio/detail/pipe_select_interrupter.hpp create mode 100644 tools/sdk/include/asio/asio/detail/pop_options.hpp create mode 100644 tools/sdk/include/asio/asio/detail/posix_event.hpp create mode 100644 tools/sdk/include/asio/asio/detail/posix_fd_set_adapter.hpp create mode 100644 tools/sdk/include/asio/asio/detail/posix_global.hpp create mode 100644 tools/sdk/include/asio/asio/detail/posix_mutex.hpp create mode 100644 tools/sdk/include/asio/asio/detail/posix_signal_blocker.hpp create mode 100644 tools/sdk/include/asio/asio/detail/posix_static_mutex.hpp create mode 100644 tools/sdk/include/asio/asio/detail/posix_thread.hpp create mode 100644 tools/sdk/include/asio/asio/detail/posix_tss_ptr.hpp create mode 100644 tools/sdk/include/asio/asio/detail/push_options.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactive_descriptor_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactive_null_buffers_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactive_serial_port_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactive_socket_accept_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactive_socket_connect_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactive_socket_recv_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactive_socket_recvfrom_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactive_socket_recvmsg_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactive_socket_send_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactive_socket_sendto_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactive_socket_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactive_socket_service_base.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactive_wait_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactor.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactor_fwd.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactor_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/reactor_op_queue.hpp create mode 100644 tools/sdk/include/asio/asio/detail/recycling_allocator.hpp create mode 100644 tools/sdk/include/asio/asio/detail/regex_fwd.hpp create mode 100644 tools/sdk/include/asio/asio/detail/resolve_endpoint_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/resolve_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/resolve_query_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/resolver_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/resolver_service_base.hpp create mode 100644 tools/sdk/include/asio/asio/detail/scheduler.hpp create mode 100644 tools/sdk/include/asio/asio/detail/scheduler_operation.hpp create mode 100644 tools/sdk/include/asio/asio/detail/scheduler_thread_info.hpp create mode 100644 tools/sdk/include/asio/asio/detail/scoped_lock.hpp create mode 100644 tools/sdk/include/asio/asio/detail/scoped_ptr.hpp create mode 100644 tools/sdk/include/asio/asio/detail/select_interrupter.hpp create mode 100644 tools/sdk/include/asio/asio/detail/select_reactor.hpp create mode 100644 tools/sdk/include/asio/asio/detail/service_registry.hpp create mode 100644 tools/sdk/include/asio/asio/detail/signal_blocker.hpp create mode 100644 tools/sdk/include/asio/asio/detail/signal_handler.hpp create mode 100644 tools/sdk/include/asio/asio/detail/signal_init.hpp create mode 100644 tools/sdk/include/asio/asio/detail/signal_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/signal_set_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/socket_holder.hpp create mode 100644 tools/sdk/include/asio/asio/detail/socket_ops.hpp create mode 100644 tools/sdk/include/asio/asio/detail/socket_option.hpp create mode 100644 tools/sdk/include/asio/asio/detail/socket_select_interrupter.hpp create mode 100644 tools/sdk/include/asio/asio/detail/socket_types.hpp create mode 100644 tools/sdk/include/asio/asio/detail/solaris_fenced_block.hpp create mode 100644 tools/sdk/include/asio/asio/detail/static_mutex.hpp create mode 100644 tools/sdk/include/asio/asio/detail/std_event.hpp create mode 100644 tools/sdk/include/asio/asio/detail/std_fenced_block.hpp create mode 100644 tools/sdk/include/asio/asio/detail/std_global.hpp create mode 100644 tools/sdk/include/asio/asio/detail/std_mutex.hpp create mode 100644 tools/sdk/include/asio/asio/detail/std_static_mutex.hpp create mode 100644 tools/sdk/include/asio/asio/detail/std_thread.hpp create mode 100644 tools/sdk/include/asio/asio/detail/strand_executor_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/strand_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/string_view.hpp create mode 100644 tools/sdk/include/asio/asio/detail/thread.hpp create mode 100644 tools/sdk/include/asio/asio/detail/thread_context.hpp create mode 100644 tools/sdk/include/asio/asio/detail/thread_group.hpp create mode 100644 tools/sdk/include/asio/asio/detail/thread_info_base.hpp create mode 100644 tools/sdk/include/asio/asio/detail/throw_error.hpp create mode 100644 tools/sdk/include/asio/asio/detail/throw_exception.hpp create mode 100644 tools/sdk/include/asio/asio/detail/timer_queue.hpp create mode 100644 tools/sdk/include/asio/asio/detail/timer_queue_base.hpp create mode 100644 tools/sdk/include/asio/asio/detail/timer_queue_ptime.hpp create mode 100644 tools/sdk/include/asio/asio/detail/timer_queue_set.hpp create mode 100644 tools/sdk/include/asio/asio/detail/timer_scheduler.hpp create mode 100644 tools/sdk/include/asio/asio/detail/timer_scheduler_fwd.hpp create mode 100644 tools/sdk/include/asio/asio/detail/tss_ptr.hpp create mode 100644 tools/sdk/include/asio/asio/detail/type_traits.hpp create mode 100644 tools/sdk/include/asio/asio/detail/variadic_templates.hpp create mode 100644 tools/sdk/include/asio/asio/detail/wait_handler.hpp create mode 100644 tools/sdk/include/asio/asio/detail/wait_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_event.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_fd_set_adapter.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_fenced_block.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_global.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_handle_read_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_handle_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_handle_write_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_io_context.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_null_buffers_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_operation.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_overlapped_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_overlapped_ptr.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_serial_port_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_socket_accept_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_socket_connect_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_socket_recv_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_socket_recvfrom_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_socket_recvmsg_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_socket_send_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_socket_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_socket_service_base.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_thread_info.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_iocp_wait_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_mutex.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_object_handle_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_static_mutex.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_thread.hpp create mode 100644 tools/sdk/include/asio/asio/detail/win_tss_ptr.hpp create mode 100644 tools/sdk/include/asio/asio/detail/winapp_thread.hpp create mode 100644 tools/sdk/include/asio/asio/detail/wince_thread.hpp create mode 100644 tools/sdk/include/asio/asio/detail/winrt_async_manager.hpp create mode 100644 tools/sdk/include/asio/asio/detail/winrt_async_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/winrt_resolve_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/winrt_resolver_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/winrt_socket_connect_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/winrt_socket_recv_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/winrt_socket_send_op.hpp create mode 100644 tools/sdk/include/asio/asio/detail/winrt_ssocket_service.hpp create mode 100644 tools/sdk/include/asio/asio/detail/winrt_ssocket_service_base.hpp create mode 100644 tools/sdk/include/asio/asio/detail/winrt_timer_scheduler.hpp create mode 100644 tools/sdk/include/asio/asio/detail/winrt_utils.hpp create mode 100644 tools/sdk/include/asio/asio/detail/winsock_init.hpp create mode 100644 tools/sdk/include/asio/asio/detail/work_dispatcher.hpp create mode 100644 tools/sdk/include/asio/asio/detail/wrapped_handler.hpp create mode 100644 tools/sdk/include/asio/asio/dispatch.hpp create mode 100644 tools/sdk/include/asio/asio/error.hpp create mode 100644 tools/sdk/include/asio/asio/error_code.hpp create mode 100644 tools/sdk/include/asio/asio/execution_context.hpp create mode 100644 tools/sdk/include/asio/asio/executor.hpp create mode 100644 tools/sdk/include/asio/asio/executor_work_guard.hpp create mode 100644 tools/sdk/include/asio/asio/experimental.hpp create mode 100644 tools/sdk/include/asio/asio/experimental/co_spawn.hpp create mode 100644 tools/sdk/include/asio/asio/experimental/detached.hpp create mode 100644 tools/sdk/include/asio/asio/experimental/impl/co_spawn.hpp create mode 100644 tools/sdk/include/asio/asio/experimental/impl/detached.hpp create mode 100644 tools/sdk/include/asio/asio/experimental/impl/redirect_error.hpp create mode 100644 tools/sdk/include/asio/asio/experimental/redirect_error.hpp create mode 100644 tools/sdk/include/asio/asio/generic/basic_endpoint.hpp create mode 100644 tools/sdk/include/asio/asio/generic/datagram_protocol.hpp create mode 100644 tools/sdk/include/asio/asio/generic/detail/endpoint.hpp create mode 100644 tools/sdk/include/asio/asio/generic/raw_protocol.hpp create mode 100644 tools/sdk/include/asio/asio/generic/seq_packet_protocol.hpp create mode 100644 tools/sdk/include/asio/asio/generic/stream_protocol.hpp create mode 100644 tools/sdk/include/asio/asio/handler_alloc_hook.hpp create mode 100644 tools/sdk/include/asio/asio/handler_continuation_hook.hpp create mode 100644 tools/sdk/include/asio/asio/handler_invoke_hook.hpp create mode 100644 tools/sdk/include/asio/asio/handler_type.hpp create mode 100644 tools/sdk/include/asio/asio/high_resolution_timer.hpp create mode 100644 tools/sdk/include/asio/asio/impl/buffered_read_stream.hpp create mode 100644 tools/sdk/include/asio/asio/impl/buffered_write_stream.hpp create mode 100644 tools/sdk/include/asio/asio/impl/connect.hpp create mode 100644 tools/sdk/include/asio/asio/impl/defer.hpp create mode 100644 tools/sdk/include/asio/asio/impl/dispatch.hpp create mode 100644 tools/sdk/include/asio/asio/impl/execution_context.hpp create mode 100644 tools/sdk/include/asio/asio/impl/executor.hpp create mode 100644 tools/sdk/include/asio/asio/impl/io_context.hpp create mode 100644 tools/sdk/include/asio/asio/impl/post.hpp create mode 100644 tools/sdk/include/asio/asio/impl/read.hpp create mode 100644 tools/sdk/include/asio/asio/impl/read_at.hpp create mode 100644 tools/sdk/include/asio/asio/impl/read_until.hpp create mode 100644 tools/sdk/include/asio/asio/impl/serial_port_base.hpp create mode 100644 tools/sdk/include/asio/asio/impl/spawn.hpp create mode 100644 tools/sdk/include/asio/asio/impl/src.hpp create mode 100644 tools/sdk/include/asio/asio/impl/system_context.hpp create mode 100644 tools/sdk/include/asio/asio/impl/system_executor.hpp create mode 100644 tools/sdk/include/asio/asio/impl/thread_pool.hpp create mode 100644 tools/sdk/include/asio/asio/impl/use_future.hpp create mode 100644 tools/sdk/include/asio/asio/impl/write.hpp create mode 100644 tools/sdk/include/asio/asio/impl/write_at.hpp create mode 100644 tools/sdk/include/asio/asio/io_context.hpp create mode 100644 tools/sdk/include/asio/asio/io_context_strand.hpp create mode 100644 tools/sdk/include/asio/asio/io_service.hpp create mode 100644 tools/sdk/include/asio/asio/io_service_strand.hpp create mode 100644 tools/sdk/include/asio/asio/ip/address.hpp create mode 100644 tools/sdk/include/asio/asio/ip/address_v4.hpp create mode 100644 tools/sdk/include/asio/asio/ip/address_v4_iterator.hpp create mode 100644 tools/sdk/include/asio/asio/ip/address_v4_range.hpp create mode 100644 tools/sdk/include/asio/asio/ip/address_v6.hpp create mode 100644 tools/sdk/include/asio/asio/ip/address_v6_iterator.hpp create mode 100644 tools/sdk/include/asio/asio/ip/address_v6_range.hpp create mode 100644 tools/sdk/include/asio/asio/ip/bad_address_cast.hpp create mode 100644 tools/sdk/include/asio/asio/ip/basic_endpoint.hpp create mode 100644 tools/sdk/include/asio/asio/ip/basic_resolver.hpp create mode 100644 tools/sdk/include/asio/asio/ip/basic_resolver_entry.hpp create mode 100644 tools/sdk/include/asio/asio/ip/basic_resolver_iterator.hpp create mode 100644 tools/sdk/include/asio/asio/ip/basic_resolver_query.hpp create mode 100644 tools/sdk/include/asio/asio/ip/basic_resolver_results.hpp create mode 100644 tools/sdk/include/asio/asio/ip/detail/endpoint.hpp create mode 100644 tools/sdk/include/asio/asio/ip/detail/socket_option.hpp create mode 100644 tools/sdk/include/asio/asio/ip/host_name.hpp create mode 100644 tools/sdk/include/asio/asio/ip/icmp.hpp create mode 100644 tools/sdk/include/asio/asio/ip/impl/address.hpp create mode 100644 tools/sdk/include/asio/asio/ip/impl/address_v4.hpp create mode 100644 tools/sdk/include/asio/asio/ip/impl/address_v6.hpp create mode 100644 tools/sdk/include/asio/asio/ip/impl/basic_endpoint.hpp create mode 100644 tools/sdk/include/asio/asio/ip/impl/network_v4.hpp create mode 100644 tools/sdk/include/asio/asio/ip/impl/network_v6.hpp create mode 100644 tools/sdk/include/asio/asio/ip/multicast.hpp create mode 100644 tools/sdk/include/asio/asio/ip/network_v4.hpp create mode 100644 tools/sdk/include/asio/asio/ip/network_v6.hpp create mode 100644 tools/sdk/include/asio/asio/ip/resolver_base.hpp create mode 100644 tools/sdk/include/asio/asio/ip/resolver_query_base.hpp create mode 100644 tools/sdk/include/asio/asio/ip/resolver_service.hpp create mode 100644 tools/sdk/include/asio/asio/ip/tcp.hpp create mode 100644 tools/sdk/include/asio/asio/ip/udp.hpp create mode 100644 tools/sdk/include/asio/asio/ip/unicast.hpp create mode 100644 tools/sdk/include/asio/asio/ip/v6_only.hpp create mode 100644 tools/sdk/include/asio/asio/is_executor.hpp create mode 100644 tools/sdk/include/asio/asio/is_read_buffered.hpp create mode 100644 tools/sdk/include/asio/asio/is_write_buffered.hpp create mode 100644 tools/sdk/include/asio/asio/local/basic_endpoint.hpp create mode 100644 tools/sdk/include/asio/asio/local/connect_pair.hpp create mode 100644 tools/sdk/include/asio/asio/local/datagram_protocol.hpp create mode 100644 tools/sdk/include/asio/asio/local/detail/endpoint.hpp create mode 100644 tools/sdk/include/asio/asio/local/stream_protocol.hpp create mode 100644 tools/sdk/include/asio/asio/packaged_task.hpp create mode 100644 tools/sdk/include/asio/asio/placeholders.hpp create mode 100644 tools/sdk/include/asio/asio/posix/basic_descriptor.hpp create mode 100644 tools/sdk/include/asio/asio/posix/basic_stream_descriptor.hpp create mode 100644 tools/sdk/include/asio/asio/posix/descriptor.hpp create mode 100644 tools/sdk/include/asio/asio/posix/descriptor_base.hpp create mode 100644 tools/sdk/include/asio/asio/posix/stream_descriptor.hpp create mode 100644 tools/sdk/include/asio/asio/posix/stream_descriptor_service.hpp create mode 100644 tools/sdk/include/asio/asio/post.hpp create mode 100644 tools/sdk/include/asio/asio/raw_socket_service.hpp create mode 100644 tools/sdk/include/asio/asio/read.hpp create mode 100644 tools/sdk/include/asio/asio/read_at.hpp create mode 100644 tools/sdk/include/asio/asio/read_until.hpp create mode 100644 tools/sdk/include/asio/asio/seq_packet_socket_service.hpp create mode 100644 tools/sdk/include/asio/asio/serial_port.hpp create mode 100644 tools/sdk/include/asio/asio/serial_port_base.hpp create mode 100644 tools/sdk/include/asio/asio/serial_port_service.hpp create mode 100644 tools/sdk/include/asio/asio/signal_set.hpp create mode 100644 tools/sdk/include/asio/asio/signal_set_service.hpp create mode 100644 tools/sdk/include/asio/asio/socket_acceptor_service.hpp create mode 100644 tools/sdk/include/asio/asio/socket_base.hpp create mode 100644 tools/sdk/include/asio/asio/spawn.hpp create mode 100644 tools/sdk/include/asio/asio/ssl.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/context.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/context_base.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/detail/buffered_handshake_op.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/detail/engine.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/detail/handshake_op.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/detail/io.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/detail/openssl_init.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/detail/openssl_types.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/detail/password_callback.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/detail/read_op.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/detail/shutdown_op.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/detail/stream_core.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/detail/verify_callback.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/detail/write_op.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/error.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/impl/context.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/impl/src.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/rfc2818_verification.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/stream.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/stream_base.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/verify_context.hpp create mode 100644 tools/sdk/include/asio/asio/ssl/verify_mode.hpp create mode 100644 tools/sdk/include/asio/asio/steady_timer.hpp create mode 100644 tools/sdk/include/asio/asio/strand.hpp create mode 100644 tools/sdk/include/asio/asio/stream_socket_service.hpp create mode 100644 tools/sdk/include/asio/asio/streambuf.hpp create mode 100644 tools/sdk/include/asio/asio/system_context.hpp create mode 100644 tools/sdk/include/asio/asio/system_error.hpp create mode 100644 tools/sdk/include/asio/asio/system_executor.hpp create mode 100644 tools/sdk/include/asio/asio/system_timer.hpp create mode 100644 tools/sdk/include/asio/asio/thread.hpp create mode 100644 tools/sdk/include/asio/asio/thread_pool.hpp create mode 100644 tools/sdk/include/asio/asio/time_traits.hpp create mode 100644 tools/sdk/include/asio/asio/ts/buffer.hpp create mode 100644 tools/sdk/include/asio/asio/ts/executor.hpp create mode 100644 tools/sdk/include/asio/asio/ts/internet.hpp create mode 100644 tools/sdk/include/asio/asio/ts/io_context.hpp create mode 100644 tools/sdk/include/asio/asio/ts/net.hpp create mode 100644 tools/sdk/include/asio/asio/ts/netfwd.hpp create mode 100644 tools/sdk/include/asio/asio/ts/socket.hpp create mode 100644 tools/sdk/include/asio/asio/ts/timer.hpp create mode 100644 tools/sdk/include/asio/asio/unyield.hpp create mode 100644 tools/sdk/include/asio/asio/use_future.hpp create mode 100644 tools/sdk/include/asio/asio/uses_executor.hpp create mode 100644 tools/sdk/include/asio/asio/version.hpp create mode 100644 tools/sdk/include/asio/asio/wait_traits.hpp create mode 100644 tools/sdk/include/asio/asio/waitable_timer_service.hpp create mode 100644 tools/sdk/include/asio/asio/windows/basic_handle.hpp create mode 100644 tools/sdk/include/asio/asio/windows/basic_object_handle.hpp create mode 100644 tools/sdk/include/asio/asio/windows/basic_random_access_handle.hpp create mode 100644 tools/sdk/include/asio/asio/windows/basic_stream_handle.hpp create mode 100644 tools/sdk/include/asio/asio/windows/object_handle.hpp create mode 100644 tools/sdk/include/asio/asio/windows/object_handle_service.hpp create mode 100644 tools/sdk/include/asio/asio/windows/overlapped_handle.hpp create mode 100644 tools/sdk/include/asio/asio/windows/overlapped_ptr.hpp create mode 100644 tools/sdk/include/asio/asio/windows/random_access_handle.hpp create mode 100644 tools/sdk/include/asio/asio/windows/random_access_handle_service.hpp create mode 100644 tools/sdk/include/asio/asio/windows/stream_handle.hpp create mode 100644 tools/sdk/include/asio/asio/windows/stream_handle_service.hpp create mode 100644 tools/sdk/include/asio/asio/write.hpp create mode 100644 tools/sdk/include/asio/asio/write_at.hpp create mode 100644 tools/sdk/include/asio/asio/yield.hpp create mode 100644 tools/sdk/include/asio/esp_asio_config.h create mode 100644 tools/sdk/include/asio/esp_exception.h delete mode 100644 tools/sdk/include/bluedroid/a2d_int.h delete mode 100644 tools/sdk/include/bluedroid/aes.h delete mode 100644 tools/sdk/include/bluedroid/avct_defs.h delete mode 100644 tools/sdk/include/bluedroid/avct_int.h delete mode 100644 tools/sdk/include/bluedroid/avdt_defs.h delete mode 100644 tools/sdk/include/bluedroid/avdt_int.h delete mode 100644 tools/sdk/include/bluedroid/avrc_int.h delete mode 100644 tools/sdk/include/bluedroid/blufi_int.h delete mode 100644 tools/sdk/include/bluedroid/bt.h delete mode 100644 tools/sdk/include/bluedroid/bt_sdp.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_api.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_ar_api.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_av_api.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_av_ci.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_av_co.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_av_sbc.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_dm_ci.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_dm_co.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_gatt_api.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_gatt_common.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_gattc_ci.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_gattc_co.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_gatts_co.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_hf_client_api.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_hf_client_co.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_hfp_defs.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_hh_api.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_hh_co.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_jv_api.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_jv_co.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_sdp_api.h delete mode 100644 tools/sdk/include/bluedroid/bta/bta_sys.h delete mode 100644 tools/sdk/include/bluedroid/bta/utl.h delete mode 100644 tools/sdk/include/bluedroid/bta_sys_int.h delete mode 100644 tools/sdk/include/bluedroid/btc/btc_ble_storage.h delete mode 100644 tools/sdk/include/bluedroid/btc/btc_common.h delete mode 100644 tools/sdk/include/bluedroid/btc/btc_config.h delete mode 100644 tools/sdk/include/bluedroid/btc/btc_dm.h delete mode 100644 tools/sdk/include/bluedroid/btc/btc_main.h delete mode 100644 tools/sdk/include/bluedroid/btc/btc_profile_queue.h delete mode 100644 tools/sdk/include/bluedroid/btc/btc_sm.h delete mode 100644 tools/sdk/include/bluedroid/btc/btc_storage.h delete mode 100644 tools/sdk/include/bluedroid/btc/btc_task.h delete mode 100644 tools/sdk/include/bluedroid/btc/btc_util.h delete mode 100644 tools/sdk/include/bluedroid/btc_a2dp.h delete mode 100644 tools/sdk/include/bluedroid/btc_a2dp_control.h delete mode 100644 tools/sdk/include/bluedroid/btc_a2dp_sink.h delete mode 100644 tools/sdk/include/bluedroid/btc_a2dp_source.h delete mode 100644 tools/sdk/include/bluedroid/btc_av.h delete mode 100644 tools/sdk/include/bluedroid/btc_av_api.h delete mode 100644 tools/sdk/include/bluedroid/btc_av_co.h delete mode 100644 tools/sdk/include/bluedroid/btc_avrc.h delete mode 100644 tools/sdk/include/bluedroid/btc_blufi_prf.h delete mode 100644 tools/sdk/include/bluedroid/btc_gap_ble.h delete mode 100644 tools/sdk/include/bluedroid/btc_gap_bt.h delete mode 100644 tools/sdk/include/bluedroid/btc_gatt_common.h delete mode 100644 tools/sdk/include/bluedroid/btc_gatt_util.h delete mode 100644 tools/sdk/include/bluedroid/btc_gattc.h delete mode 100644 tools/sdk/include/bluedroid/btc_gatts.h delete mode 100644 tools/sdk/include/bluedroid/btc_hf_client.h delete mode 100644 tools/sdk/include/bluedroid/btc_spp.h delete mode 100644 tools/sdk/include/bluedroid/button_pro.h delete mode 100644 tools/sdk/include/bluedroid/common/bt_common_types.h delete mode 100644 tools/sdk/include/bluedroid/common/bt_defs.h delete mode 100644 tools/sdk/include/bluedroid/common/bt_target.h delete mode 100644 tools/sdk/include/bluedroid/common/bt_trace.h delete mode 100644 tools/sdk/include/bluedroid/common/bt_vendor_lib.h delete mode 100644 tools/sdk/include/bluedroid/common/bte.h delete mode 100644 tools/sdk/include/bluedroid/common/bte_appl.h delete mode 100644 tools/sdk/include/bluedroid/device/bdaddr.h delete mode 100644 tools/sdk/include/bluedroid/device/controller.h delete mode 100644 tools/sdk/include/bluedroid/device/device_features.h delete mode 100644 tools/sdk/include/bluedroid/device/event_mask.h delete mode 100644 tools/sdk/include/bluedroid/device/interop.h delete mode 100644 tools/sdk/include/bluedroid/device/interop_database.h delete mode 100644 tools/sdk/include/bluedroid/device/version.h delete mode 100644 tools/sdk/include/bluedroid/dis_api.h delete mode 100644 tools/sdk/include/bluedroid/esp_bt.h delete mode 100644 tools/sdk/include/bluedroid/esp_sec_api.h delete mode 100644 tools/sdk/include/bluedroid/gap_int.h delete mode 100644 tools/sdk/include/bluedroid/gatt_int.h delete mode 100644 tools/sdk/include/bluedroid/hci/bt_vendor_lib.h delete mode 100644 tools/sdk/include/bluedroid/hci/hci_audio.h delete mode 100644 tools/sdk/include/bluedroid/hci/hci_hal.h delete mode 100644 tools/sdk/include/bluedroid/hci/hci_internals.h delete mode 100644 tools/sdk/include/bluedroid/hci/hci_layer.h delete mode 100644 tools/sdk/include/bluedroid/hci/hci_packet_factory.h delete mode 100644 tools/sdk/include/bluedroid/hci/hci_packet_parser.h delete mode 100644 tools/sdk/include/bluedroid/hci/packet_fragmenter.h delete mode 100644 tools/sdk/include/bluedroid/hid_conn.h delete mode 100644 tools/sdk/include/bluedroid/hidh_int.h delete mode 100644 tools/sdk/include/bluedroid/l2c_int.h delete mode 100644 tools/sdk/include/bluedroid/oi_assert.h delete mode 100644 tools/sdk/include/bluedroid/oi_bitstream.h delete mode 100644 tools/sdk/include/bluedroid/oi_bt_spec.h delete mode 100644 tools/sdk/include/bluedroid/oi_codec_sbc.h delete mode 100644 tools/sdk/include/bluedroid/oi_codec_sbc_private.h delete mode 100644 tools/sdk/include/bluedroid/oi_common.h delete mode 100644 tools/sdk/include/bluedroid/oi_cpu_dep.h delete mode 100644 tools/sdk/include/bluedroid/oi_modules.h delete mode 100644 tools/sdk/include/bluedroid/oi_osinterface.h delete mode 100644 tools/sdk/include/bluedroid/oi_status.h delete mode 100644 tools/sdk/include/bluedroid/oi_stddefs.h delete mode 100644 tools/sdk/include/bluedroid/oi_string.h delete mode 100644 tools/sdk/include/bluedroid/oi_time.h delete mode 100644 tools/sdk/include/bluedroid/oi_utils.h delete mode 100644 tools/sdk/include/bluedroid/osi/alarm.h delete mode 100644 tools/sdk/include/bluedroid/osi/allocator.h delete mode 100644 tools/sdk/include/bluedroid/osi/buffer.h delete mode 100644 tools/sdk/include/bluedroid/osi/config.h delete mode 100644 tools/sdk/include/bluedroid/osi/fixed_queue.h delete mode 100644 tools/sdk/include/bluedroid/osi/future.h delete mode 100644 tools/sdk/include/bluedroid/osi/hash_functions.h delete mode 100644 tools/sdk/include/bluedroid/osi/hash_map.h delete mode 100644 tools/sdk/include/bluedroid/osi/list.h delete mode 100644 tools/sdk/include/bluedroid/osi/mutex.h delete mode 100644 tools/sdk/include/bluedroid/osi/osi.h delete mode 100644 tools/sdk/include/bluedroid/osi/semaphore.h delete mode 100644 tools/sdk/include/bluedroid/osi/thread.h delete mode 100644 tools/sdk/include/bluedroid/p_256_ecc_pp.h delete mode 100644 tools/sdk/include/bluedroid/p_256_multprecision.h delete mode 100644 tools/sdk/include/bluedroid/port_int.h delete mode 100644 tools/sdk/include/bluedroid/rfc_int.h delete mode 100644 tools/sdk/include/bluedroid/sbc_dct.h delete mode 100644 tools/sdk/include/bluedroid/sbc_enc_func_declare.h delete mode 100644 tools/sdk/include/bluedroid/sbc_encoder.h delete mode 100644 tools/sdk/include/bluedroid/sbc_if.h delete mode 100644 tools/sdk/include/bluedroid/sbc_types.h delete mode 100644 tools/sdk/include/bluedroid/sdpint.h delete mode 100644 tools/sdk/include/bluedroid/smp_int.h delete mode 100644 tools/sdk/include/bluedroid/srvc_api.h delete mode 100644 tools/sdk/include/bluedroid/srvc_battery_int.h delete mode 100644 tools/sdk/include/bluedroid/srvc_dis_int.h delete mode 100644 tools/sdk/include/bluedroid/stack/a2d_api.h delete mode 100644 tools/sdk/include/bluedroid/stack/a2d_sbc.h delete mode 100644 tools/sdk/include/bluedroid/stack/avct_api.h delete mode 100644 tools/sdk/include/bluedroid/stack/avdt_api.h delete mode 100644 tools/sdk/include/bluedroid/stack/avdtc_api.h delete mode 100644 tools/sdk/include/bluedroid/stack/avrc_api.h delete mode 100644 tools/sdk/include/bluedroid/stack/avrc_defs.h delete mode 100644 tools/sdk/include/bluedroid/stack/bt_types.h delete mode 100644 tools/sdk/include/bluedroid/stack/btm_api.h delete mode 100644 tools/sdk/include/bluedroid/stack/btm_ble_api.h delete mode 100644 tools/sdk/include/bluedroid/stack/btu.h delete mode 100644 tools/sdk/include/bluedroid/stack/dyn_mem.h delete mode 100644 tools/sdk/include/bluedroid/stack/gap_api.h delete mode 100644 tools/sdk/include/bluedroid/stack/gatt_api.h delete mode 100644 tools/sdk/include/bluedroid/stack/gattdefs.h delete mode 100644 tools/sdk/include/bluedroid/stack/hcidefs.h delete mode 100644 tools/sdk/include/bluedroid/stack/hcimsgs.h delete mode 100644 tools/sdk/include/bluedroid/stack/hiddefs.h delete mode 100644 tools/sdk/include/bluedroid/stack/hidh_api.h delete mode 100644 tools/sdk/include/bluedroid/stack/l2c_api.h delete mode 100644 tools/sdk/include/bluedroid/stack/l2cap_client.h delete mode 100644 tools/sdk/include/bluedroid/stack/l2cdefs.h delete mode 100644 tools/sdk/include/bluedroid/stack/port_api.h delete mode 100644 tools/sdk/include/bluedroid/stack/port_ext.h delete mode 100644 tools/sdk/include/bluedroid/stack/profiles_api.h delete mode 100644 tools/sdk/include/bluedroid/stack/rfcdefs.h delete mode 100644 tools/sdk/include/bluedroid/stack/sdp_api.h delete mode 100644 tools/sdk/include/bluedroid/stack/sdpdefs.h delete mode 100644 tools/sdk/include/bluedroid/stack/smp_api.h delete mode 100644 tools/sdk/include/bluedroid/wx_airsync_prf.h create mode 100644 tools/sdk/include/bootloader_support/bootloader_util.h rename tools/sdk/include/{bluedroid/api => bt}/esp_a2dp_api.h (100%) rename tools/sdk/include/{bluedroid/api => bt}/esp_avrc_api.h (100%) rename tools/sdk/include/{bluedroid/api => bt}/esp_blufi_api.h (100%) rename tools/sdk/include/{bluedroid/api => bt}/esp_bt_defs.h (100%) rename tools/sdk/include/{bluedroid/api => bt}/esp_bt_device.h (100%) rename tools/sdk/include/{bluedroid/api => bt}/esp_bt_main.h (100%) rename tools/sdk/include/{bluedroid/api => bt}/esp_gap_ble_api.h (90%) rename tools/sdk/include/{bluedroid/api => bt}/esp_gap_bt_api.h (100%) rename tools/sdk/include/{bluedroid/api => bt}/esp_gatt_common_api.h (100%) rename tools/sdk/include/{bluedroid/api => bt}/esp_gatt_defs.h (98%) rename tools/sdk/include/{bluedroid/api => bt}/esp_gattc_api.h (98%) rename tools/sdk/include/{bluedroid/api => bt}/esp_gatts_api.h (85%) rename tools/sdk/include/{bluedroid/api => bt}/esp_hf_client_api.h (98%) rename tools/sdk/include/{bluedroid/api => bt}/esp_hf_defs.h (100%) rename tools/sdk/include/{bluedroid/api => bt}/esp_spp_api.h (99%) create mode 100644 tools/sdk/include/coap/address.h create mode 100644 tools/sdk/include/coap/async.h create mode 100644 tools/sdk/include/coap/bits.h create mode 100644 tools/sdk/include/coap/block.h rename tools/sdk/include/coap/{coap/coap.h.in => coap.h} (61%) create mode 100644 tools/sdk/include/coap/coap_io.h create mode 100644 tools/sdk/include/coap/coap_time.h create mode 100644 tools/sdk/include/coap/debug.h create mode 100644 tools/sdk/include/coap/encode.h create mode 100644 tools/sdk/include/coap/hashkey.h create mode 100644 tools/sdk/include/coap/libcoap.h create mode 100644 tools/sdk/include/coap/lwippools.h create mode 100644 tools/sdk/include/coap/mem.h create mode 100644 tools/sdk/include/coap/net.h create mode 100644 tools/sdk/include/coap/option.h create mode 100644 tools/sdk/include/coap/pdu.h create mode 100644 tools/sdk/include/coap/prng.h create mode 100644 tools/sdk/include/coap/resource.h create mode 100644 tools/sdk/include/coap/str.h create mode 100644 tools/sdk/include/coap/subscribe.h create mode 100644 tools/sdk/include/coap/uri.h create mode 100644 tools/sdk/include/coap/uthash.h create mode 100644 tools/sdk/include/coap/utlist.h rename tools/sdk/include/esp32/{esp_event.h => esp_event_legacy.h} (100%) create mode 100644 tools/sdk/include/esp32/esp_himem.h create mode 100644 tools/sdk/include/esp_event/esp_event.h create mode 100644 tools/sdk/include/esp_event/esp_event_base.h rename tools/sdk/include/{http_server/http_server.h => esp_http_server/esp_http_server.h} (72%) create mode 100644 tools/sdk/include/esp_http_server/http_server.h create mode 100644 tools/sdk/include/esp_https_server/esp_https_server.h rename tools/sdk/include/{freertos => esp_ringbuf}/freertos/ringbuf.h (100%) delete mode 100644 tools/sdk/include/expat/.gitignore delete mode 100644 tools/sdk/include/expat/Makefile.am delete mode 100644 tools/sdk/include/expat/expat.vcxproj delete mode 100644 tools/sdk/include/expat/expat.vcxproj.filters delete mode 100644 tools/sdk/include/expat/expat_static.vcxproj delete mode 100644 tools/sdk/include/expat/expat_static.vcxproj.filters delete mode 100644 tools/sdk/include/expat/expatw.vcxproj delete mode 100644 tools/sdk/include/expat/expatw.vcxproj.filters delete mode 100644 tools/sdk/include/expat/expatw_static.vcxproj delete mode 100644 tools/sdk/include/expat/expatw_static.vcxproj.filters delete mode 100644 tools/sdk/include/expat/libexpat.def delete mode 100644 tools/sdk/include/expat/libexpatw.def delete mode 100644 tools/sdk/include/expat/loadlibrary.c delete mode 100644 tools/sdk/include/expat/xmlparse.c delete mode 100644 tools/sdk/include/expat/xmlrole.c delete mode 100644 tools/sdk/include/expat/xmltok.c delete mode 100644 tools/sdk/include/expat/xmltok_impl.c delete mode 100644 tools/sdk/include/expat/xmltok_ns.c create mode 100644 tools/sdk/include/freemodbus/mb.h create mode 100644 tools/sdk/include/freemodbus/mbconfig.h create mode 100644 tools/sdk/include/freemodbus/mbcontroller.h create mode 100644 tools/sdk/include/freemodbus/mbframe.h create mode 100644 tools/sdk/include/freemodbus/mbfunc.h create mode 100644 tools/sdk/include/freemodbus/mbport.h create mode 100644 tools/sdk/include/freemodbus/mbproto.h create mode 100644 tools/sdk/include/freemodbus/mbutils.h create mode 100644 tools/sdk/include/idf_test/idf_performance.h create mode 100644 tools/sdk/include/json/tests/common.h create mode 100644 tools/sdk/include/json/tests/unity/examples/example_1/src/ProductionCode.h create mode 100644 tools/sdk/include/json/tests/unity/examples/example_1/src/ProductionCode2.h create mode 100644 tools/sdk/include/json/tests/unity/examples/example_2/src/ProductionCode.h create mode 100644 tools/sdk/include/json/tests/unity/examples/example_2/src/ProductionCode2.h create mode 100644 tools/sdk/include/json/tests/unity/examples/example_3/helper/UnityHelper.h create mode 100644 tools/sdk/include/json/tests/unity/examples/example_3/src/ProductionCode.h create mode 100644 tools/sdk/include/json/tests/unity/examples/example_3/src/ProductionCode2.h create mode 100644 tools/sdk/include/json/tests/unity/examples/unity_config.h create mode 100644 tools/sdk/include/json/tests/unity/extras/fixture/src/unity_fixture.h create mode 100644 tools/sdk/include/json/tests/unity/extras/fixture/src/unity_fixture_internals.h create mode 100644 tools/sdk/include/json/tests/unity/extras/fixture/src/unity_fixture_malloc_overrides.h create mode 100644 tools/sdk/include/json/tests/unity/extras/fixture/test/unity_output_Spy.h create mode 100644 tools/sdk/include/json/tests/unity/src/unity.h create mode 100644 tools/sdk/include/json/tests/unity/src/unity_internals.h create mode 100644 tools/sdk/include/json/tests/unity/test/expectdata/testsample_head1.h create mode 100644 tools/sdk/include/json/tests/unity/test/expectdata/testsample_mock_head1.h create mode 100644 tools/sdk/include/json/tests/unity/test/testdata/CException.h create mode 100644 tools/sdk/include/json/tests/unity/test/testdata/Defs.h create mode 100644 tools/sdk/include/json/tests/unity/test/testdata/cmock.h create mode 100644 tools/sdk/include/json/tests/unity/test/testdata/mockMock.h create mode 100644 tools/sdk/include/libsodium/sodium.h create mode 100644 tools/sdk/include/libsodium/sodium/core.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_aead_aes256gcm.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_aead_chacha20poly1305.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_aead_xchacha20poly1305.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_auth.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_auth_hmacsha256.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_auth_hmacsha512.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_auth_hmacsha512256.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_box.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_box_curve25519xchacha20poly1305.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_box_curve25519xsalsa20poly1305.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_core_hchacha20.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_core_hsalsa20.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_core_salsa20.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_core_salsa2012.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_core_salsa208.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_generichash.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_generichash_blake2b.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_hash.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_hash_sha256.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_hash_sha512.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_kdf.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_kdf_blake2b.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_kx.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_onetimeauth.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_onetimeauth_poly1305.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_pwhash.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_pwhash_argon2i.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_pwhash_scryptsalsa208sha256.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_scalarmult.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_scalarmult_curve25519.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_secretbox.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_secretbox_xchacha20poly1305.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_secretbox_xsalsa20poly1305.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_shorthash.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_shorthash_siphash24.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_sign.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_sign_ed25519.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_sign_edwards25519sha512batch.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_stream.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_stream_aes128ctr.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_stream_chacha20.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_stream_salsa20.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_stream_salsa2012.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_stream_salsa208.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_stream_xchacha20.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_stream_xsalsa20.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_verify_16.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_verify_32.h create mode 100644 tools/sdk/include/libsodium/sodium/crypto_verify_64.h create mode 100644 tools/sdk/include/libsodium/sodium/export.h create mode 100644 tools/sdk/include/libsodium/sodium/private/common.h create mode 100644 tools/sdk/include/libsodium/sodium/private/curve25519_ref10.h create mode 100644 tools/sdk/include/libsodium/sodium/private/mutex.h create mode 100644 tools/sdk/include/libsodium/sodium/private/sse2_64_32.h create mode 100644 tools/sdk/include/libsodium/sodium/randombytes.h create mode 100644 tools/sdk/include/libsodium/sodium/randombytes_nativeclient.h create mode 100644 tools/sdk/include/libsodium/sodium/randombytes_salsa20_random.h create mode 100644 tools/sdk/include/libsodium/sodium/randombytes_sysrandom.h create mode 100644 tools/sdk/include/libsodium/sodium/runtime.h create mode 100644 tools/sdk/include/libsodium/sodium/utils.h create mode 100644 tools/sdk/include/libsodium/sodium/version.h create mode 100644 tools/sdk/include/lwip/apps/sntp/sntp.h rename tools/sdk/include/lwip/{ping => }/esp_ping.h (90%) delete mode 100644 tools/sdk/include/lwip/lwip/apps/FILES delete mode 100644 tools/sdk/include/mbedtls/.gitignore delete mode 100644 tools/sdk/include/mbedtls/CMakeLists.txt rename tools/sdk/include/{mbedtls_port => mbedtls}/aes_alt.h (81%) rename tools/sdk/include/{bluedroid/btc/btc_alarm.h => mbedtls/esp_mem.h} (62%) rename tools/sdk/include/{mbedtls_port => mbedtls}/mbedtls/esp_config.h (97%) rename tools/sdk/include/{mbedtls_port => mbedtls}/mbedtls/esp_debug.h (100%) rename tools/sdk/include/{mbedtls_port => mbedtls}/sha1_alt.h (100%) rename tools/sdk/include/{mbedtls_port => mbedtls}/sha256_alt.h (100%) rename tools/sdk/include/{mbedtls_port => mbedtls}/sha512_alt.h (100%) delete mode 100644 tools/sdk/include/mbedtls_port/mbedtls/bignum.h delete mode 100644 tools/sdk/include/mbedtls_port/mbedtls/config.h create mode 100644 tools/sdk/include/micro-ecc/types.h create mode 100644 tools/sdk/include/micro-ecc/uECC.h create mode 100644 tools/sdk/include/micro-ecc/uECC_vli.h rename tools/sdk/include/{esp-mqtt => mqtt}/mqtt_client.h (68%) rename tools/sdk/include/{esp-mqtt => mqtt}/mqtt_config.h (100%) rename tools/sdk/include/nghttp/{http_parser => }/http_parser.h (100%) create mode 100755 tools/sdk/include/protobuf-c/protobuf-c/protobuf-c.h create mode 100644 tools/sdk/include/protobuf-c/protoc-c/c_bytes_field.h create mode 100644 tools/sdk/include/protobuf-c/protoc-c/c_enum.h create mode 100644 tools/sdk/include/protobuf-c/protoc-c/c_enum_field.h create mode 100644 tools/sdk/include/protobuf-c/protoc-c/c_extension.h create mode 100644 tools/sdk/include/protobuf-c/protoc-c/c_field.h create mode 100644 tools/sdk/include/protobuf-c/protoc-c/c_file.h create mode 100644 tools/sdk/include/protobuf-c/protoc-c/c_generator.h create mode 100644 tools/sdk/include/protobuf-c/protoc-c/c_helpers.h create mode 100644 tools/sdk/include/protobuf-c/protoc-c/c_message.h create mode 100644 tools/sdk/include/protobuf-c/protoc-c/c_message_field.h create mode 100644 tools/sdk/include/protobuf-c/protoc-c/c_primitive_field.h create mode 100644 tools/sdk/include/protobuf-c/protoc-c/c_service.h create mode 100644 tools/sdk/include/protobuf-c/protoc-c/c_string_field.h create mode 100644 tools/sdk/include/protobuf-c/t/generated-code2/common-test-arrays.h create mode 100644 tools/sdk/include/protocomm/protocomm.h create mode 100644 tools/sdk/include/protocomm/protocomm_ble.h create mode 100644 tools/sdk/include/protocomm/protocomm_console.h create mode 100644 tools/sdk/include/protocomm/protocomm_httpd.h create mode 100644 tools/sdk/include/protocomm/protocomm_security.h rename tools/sdk/include/{bluedroid/btc/btc_manage.h => protocomm/protocomm_security0.h} (58%) rename tools/sdk/include/{bluedroid/btc/btc_dev.h => protocomm/protocomm_security1.h} (50%) create mode 100644 tools/sdk/include/pthread/esp_pthread.h rename tools/sdk/include/tcp_transport/{transport.h => esp_transport.h} (59%) create mode 100644 tools/sdk/include/tcp_transport/esp_transport_ssl.h rename tools/sdk/include/tcp_transport/{transport_tcp.h => esp_transport_tcp.h} (71%) rename tools/sdk/include/tcp_transport/{transport_utils.h => esp_transport_utils.h} (78%) create mode 100644 tools/sdk/include/tcp_transport/esp_transport_ws.h delete mode 100644 tools/sdk/include/tcp_transport/transport_ssl.h create mode 100644 tools/sdk/include/unity/unity.h create mode 100644 tools/sdk/include/unity/unity_config.h create mode 100644 tools/sdk/include/unity/unity_internals.h create mode 100644 tools/sdk/include/unity/unity_test_runner.h create mode 100644 tools/sdk/include/wifi_provisioning/wifi_provisioning/wifi_config.h create mode 100644 tools/sdk/ld/esp32.extram.bss.ld create mode 100644 tools/sdk/ld/esp32.rom.redefined.ld create mode 100644 tools/sdk/lib/libesp_event.a create mode 100644 tools/sdk/lib/libesp_http_server.a create mode 100644 tools/sdk/lib/libesp_https_server.a create mode 100644 tools/sdk/lib/libfreemodbus.a delete mode 100644 tools/sdk/lib/libhttp_server.a create mode 100644 tools/sdk/lib/liblibsodium.a create mode 100644 tools/sdk/lib/libprotobuf-c.a create mode 100644 tools/sdk/lib/libprotocomm.a create mode 100644 tools/sdk/lib/libunity.a create mode 100644 tools/sdk/lib/libwifi_provisioning.a diff --git a/platform.txt b/platform.txt index 5cb04a12..a7426fc4 100644 --- a/platform.txt +++ b/platform.txt @@ -22,7 +22,7 @@ compiler.warning_flags.all=-Wall -Werror=all -Wextra compiler.path={runtime.tools.xtensa-esp32-elf-gcc.path}/bin/ compiler.sdk.path={runtime.platform.path}/tools/sdk -compiler.cpreprocessor.flags=-DESP_PLATFORM -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h" -DHAVE_CONFIG_H "-I{compiler.sdk.path}/include/config" "-I{compiler.sdk.path}/include/bluedroid" "-I{compiler.sdk.path}/include/bluedroid/api" "-I{compiler.sdk.path}/include/app_trace" "-I{compiler.sdk.path}/include/app_update" "-I{compiler.sdk.path}/include/bootloader_support" "-I{compiler.sdk.path}/include/bt" "-I{compiler.sdk.path}/include/driver" "-I{compiler.sdk.path}/include/esp32" "-I{compiler.sdk.path}/include/esp_adc_cal" "-I{compiler.sdk.path}/include/esp_http_client" "-I{compiler.sdk.path}/include/esp_https_ota" "-I{compiler.sdk.path}/include/esp-mqtt" "-I{compiler.sdk.path}/include/esp-tls" "-I{compiler.sdk.path}/include/ethernet" "-I{compiler.sdk.path}/include/fatfs" "-I{compiler.sdk.path}/include/freertos" "-I{compiler.sdk.path}/include/heap" "-I{compiler.sdk.path}/include/http_server" "-I{compiler.sdk.path}/include/jsmn" "-I{compiler.sdk.path}/include/log" "-I{compiler.sdk.path}/include/mdns" "-I{compiler.sdk.path}/include/mbedtls" "-I{compiler.sdk.path}/include/mbedtls_port" "-I{compiler.sdk.path}/include/newlib" "-I{compiler.sdk.path}/include/nvs_flash" "-I{compiler.sdk.path}/include/openssl" "-I{compiler.sdk.path}/include/spi_flash" "-I{compiler.sdk.path}/include/sdmmc" "-I{compiler.sdk.path}/include/smartconfig_ack" "-I{compiler.sdk.path}/include/spiffs" "-I{compiler.sdk.path}/include/tcpip_adapter" "-I{compiler.sdk.path}/include/tcp_transport" "-I{compiler.sdk.path}/include/ulp" "-I{compiler.sdk.path}/include/vfs" "-I{compiler.sdk.path}/include/wear_levelling" "-I{compiler.sdk.path}/include/xtensa-debug-module" "-I{compiler.sdk.path}/include/lwip" "-I{compiler.sdk.path}/include/coap" "-I{compiler.sdk.path}/include/console" "-I{compiler.sdk.path}/include/expat" "-I{compiler.sdk.path}/include/json" "-I{compiler.sdk.path}/include/newlib" "-I{compiler.sdk.path}/include/nghttp" "-I{compiler.sdk.path}/include/soc" "-I{compiler.sdk.path}/include/wpa_supplicant" +compiler.cpreprocessor.flags=-DESP_PLATFORM -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h" -DHAVE_CONFIG_H "-I{compiler.sdk.path}/include/config" "-I{compiler.sdk.path}/include/app_trace" "-I{compiler.sdk.path}/include/app_update" "-I{compiler.sdk.path}/include/asio" "-I{compiler.sdk.path}/include/bootloader_support" "-I{compiler.sdk.path}/include/bt" "-I{compiler.sdk.path}/include/coap" "-I{compiler.sdk.path}/include/console" "-I{compiler.sdk.path}/include/driver" "-I{compiler.sdk.path}/include/esp-tls" "-I{compiler.sdk.path}/include/esp32" "-I{compiler.sdk.path}/include/esp_adc_cal" "-I{compiler.sdk.path}/include/esp_event" "-I{compiler.sdk.path}/include/esp_http_client" "-I{compiler.sdk.path}/include/esp_http_server" "-I{compiler.sdk.path}/include/esp_https_ota" "-I{compiler.sdk.path}/include/esp_https_server" "-I{compiler.sdk.path}/include/esp_ringbuf" "-I{compiler.sdk.path}/include/ethernet" "-I{compiler.sdk.path}/include/expat" "-I{compiler.sdk.path}/include/fatfs" "-I{compiler.sdk.path}/include/freemodbus" "-I{compiler.sdk.path}/include/freertos" "-I{compiler.sdk.path}/include/heap" "-I{compiler.sdk.path}/include/idf_test" "-I{compiler.sdk.path}/include/jsmn" "-I{compiler.sdk.path}/include/json" "-I{compiler.sdk.path}/include/libsodium" "-I{compiler.sdk.path}/include/log" "-I{compiler.sdk.path}/include/lwip" "-I{compiler.sdk.path}/include/mbedtls" "-I{compiler.sdk.path}/include/mdns" "-I{compiler.sdk.path}/include/micro-ecc" "-I{compiler.sdk.path}/include/mqtt" "-I{compiler.sdk.path}/include/newlib" "-I{compiler.sdk.path}/include/nghttp" "-I{compiler.sdk.path}/include/nvs_flash" "-I{compiler.sdk.path}/include/openssl" "-I{compiler.sdk.path}/include/protobuf-c" "-I{compiler.sdk.path}/include/protocomm" "-I{compiler.sdk.path}/include/pthread" "-I{compiler.sdk.path}/include/sdmmc" "-I{compiler.sdk.path}/include/smartconfig_ack" "-I{compiler.sdk.path}/include/soc" "-I{compiler.sdk.path}/include/spi_flash" "-I{compiler.sdk.path}/include/spiffs" "-I{compiler.sdk.path}/include/tcp_transport" "-I{compiler.sdk.path}/include/tcpip_adapter" "-I{compiler.sdk.path}/include/ulp" "-I{compiler.sdk.path}/include/unity" "-I{compiler.sdk.path}/include/vfs" "-I{compiler.sdk.path}/include/wear_levelling" "-I{compiler.sdk.path}/include/wifi_provisioning" "-I{compiler.sdk.path}/include/wpa_supplicant" "-I{compiler.sdk.path}/include/xtensa-debug-module" compiler.c.cmd=xtensa-esp32-elf-gcc compiler.c.flags=-std=gnu99 -Os -g3 -fstack-protector -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -mlongcalls -nostdlib -Wpointer-arith {compiler.warning_flags} -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -Wno-old-style-declaration -MMD -c @@ -35,7 +35,7 @@ compiler.S.flags=-c -g3 -x assembler-with-cpp -MMD -mlongcalls compiler.c.elf.cmd=xtensa-esp32-elf-gcc compiler.c.elf.flags=-nostdlib "-L{compiler.sdk.path}/lib" "-L{compiler.sdk.path}/ld" -T esp32_out.ld -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld -T esp32.rom.spiram_incompatible_fns.ld -u ld_include_panic_highint_hdl -u call_user_start_cpu0 -Wl,--gc-sections -Wl,-static -Wl,--undefined=uxTopUsedPriority -u __cxa_guard_dummy -u __cxx_fatal_exception -compiler.c.elf.libs=-lgcc -lopenssl -lbtdm_app -lfatfs -lwps -lhttp_server -lcoexist -lwear_levelling -lesp_http_client -lhal -lnewlib -ldriver -lbootloader_support -lpp -lmesh -lsmartconfig -ljsmn -lwpa -lethernet -lphy -lapp_trace -lconsole -lulp -lwpa_supplicant -lfreertos -lbt -lmicro-ecc -lcxx -lxtensa-debug-module -ltcp_transport -lmdns -lvfs -lesp_ringbuf -lsoc -lcore -lsdmmc -lcoap -ltcpip_adapter -lc_nano -lesp-tls -lasio -lrtc -lspi_flash -lwpa2 -lesp32 -lapp_update -lnghttp -lspiffs -lespnow -lnvs_flash -lesp_adc_cal -llog -lsmartconfig_ack -lexpat -lm -lmqtt -lc -lheap -lmbedtls -llwip -lnet80211 -lpthread -ljson -lesp_https_ota -lstdc++ +compiler.c.elf.libs=-lgcc -lopenssl -lbtdm_app -lfatfs -lwps -lcoexist -lwear_levelling -lesp_http_client -lprotobuf-c -lhal -lnewlib -ldriver -lbootloader_support -lpp -lfreemodbus -lmesh -lsmartconfig -ljsmn -lwpa -lethernet -lphy -lapp_trace -lconsole -lulp -lwpa_supplicant -lfreertos -lbt -lmicro-ecc -lcxx -lxtensa-debug-module -ltcp_transport -lmdns -lvfs -lesp_ringbuf -lsoc -lcore -lsdmmc -llibsodium -lcoap -ltcpip_adapter -lprotocomm -lesp_event -lc_nano -lesp-tls -lasio -lrtc -lspi_flash -lwpa2 -lwifi_provisioning -lesp32 -lapp_update -lnghttp -lspiffs -lunity -lesp_https_server -lespnow -lnvs_flash -lesp_adc_cal -llog -lsmartconfig_ack -lexpat -lm -lmqtt -lc -lheap -lmbedtls -llwip -lnet80211 -lesp_http_server -lpthread -ljson -lesp_https_ota -lstdc++ compiler.as.cmd=xtensa-esp32-elf-as diff --git a/tools/esptool.py b/tools/esptool.py index bd89a7ff..a091a8f2 100755 --- a/tools/esptool.py +++ b/tools/esptool.py @@ -51,7 +51,7 @@ except TypeError: pass # __doc__ returns None for pyserial -__version__ = "2.5.0" +__version__ = "2.6-beta1" MAX_UINT32 = 0xffffffff MAX_UINT24 = 0xffffff @@ -243,17 +243,19 @@ class ESPLoader(object): """ detect_port = ESPLoader(port, baud, trace_enabled=trace_enabled) detect_port.connect(connect_mode) - print('Detecting chip type...', end='') - sys.stdout.flush() - date_reg = detect_port.read_reg(ESPLoader.UART_DATA_REG_ADDR) + try: + print('Detecting chip type...', end='') + sys.stdout.flush() + date_reg = detect_port.read_reg(ESPLoader.UART_DATA_REG_ADDR) - for cls in [ESP8266ROM, ESP32ROM]: - if date_reg == cls.DATE_REG_VALUE: - # don't connect a second time - inst = cls(detect_port._port, baud, trace_enabled=trace_enabled) - print(' %s' % inst.CHIP_NAME) - return inst - print('') + for cls in [ESP8266ROM, ESP32ROM]: + if date_reg == cls.DATE_REG_VALUE: + # don't connect a second time + inst = cls(detect_port._port, baud, trace_enabled=trace_enabled) + print(' %s' % inst.CHIP_NAME, end='') + return inst + finally: + print('') # end line raise FatalError("Unexpected UART datecode value 0x%08x. Failed to autodetect chip type." % date_reg) """ Read a SLIP packet from the serial port """ @@ -681,6 +683,8 @@ class ESPLoader(object): while len(data) < length: p = self.read() data += p + if len(data) < length and len(p) < self.FLASH_SECTOR_SIZE: + raise FatalError('Corrupt data, expected 0x%x bytes but received 0x%x bytes' % (self.FLASH_SECTOR_SIZE, len(p))) self.write(struct.pack('> 14 & 0x1 + if blk3_part_res: + features += ["BLK3 partially reserved"] + + word6 = self.read_efuse(6) + coding_scheme = word6 & 0x3 + features += ["Coding Scheme %s" % { + 0: "None", + 1: "3/4", + 2: "Repeat (UNSUPPORTED)", + 3: "Invalid"}[coding_scheme]] + return features def read_efuse(self, n): @@ -2549,7 +2565,7 @@ def main(): esp = chip_class(each_port, initial_baud, args.trace) esp.connect(args.before) break - except FatalError as err: + except (FatalError, OSError) as err: if args.port is not None: raise print("%s failed to connect: %s" % (each_port, err)) diff --git a/tools/gen_esp32part.py b/tools/gen_esp32part.py index 66f5b30b..e3c8a6dc 100755 --- a/tools/gen_esp32part.py +++ b/tools/gen_esp32part.py @@ -21,6 +21,7 @@ # See the License for the specific language governing permissions and # limitations under the License. from __future__ import print_function, division +from __future__ import unicode_literals import argparse import os import re @@ -54,6 +55,7 @@ SUBTYPES = { "phy" : 0x01, "nvs" : 0x02, "coredump" : 0x03, + "nvs_keys" : 0x04, "esphttpd" : 0x80, "fat" : 0x81, "spiffs" : 0x82, @@ -354,7 +356,7 @@ class PartitionDefinition(object): if self.name in all_subtype_names and SUBTYPES.get(self.type, {}).get(self.name, "") != self.subtype: critical("WARNING: Partition has name '%s' which is a partition subtype, but this partition has non-matching type 0x%x and subtype 0x%x. Mistake in partition table?" % (self.name, self.type, self.subtype)) - STRUCT_FORMAT = "<2sBBLL16sL" + STRUCT_FORMAT = b"<2sBBLL16sL" @classmethod def from_binary(cls, b): diff --git a/tools/platformio-build.py b/tools/platformio-build.py index a7619c2f..f74b5a37 100644 --- a/tools/platformio-build.py +++ b/tools/platformio-build.py @@ -96,52 +96,61 @@ env.Append( ], CPPPATH=[ - join(FRAMEWORK_DIR, "tools", "sdk", "include", "config"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "bluedroid"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "bluedroid", "api"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "config"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "app_trace"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "app_update"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "asio"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "bootloader_support"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "bt"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "driver"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp32"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp_adc_cal"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp_http_client"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp_https_ota"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp-mqtt"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp-tls"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "ethernet"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "fatfs"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "freertos"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "heap"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "http_server"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "jsmn"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "log"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "mdns"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "mbedtls"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "mbedtls_port"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "newlib"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "nvs_flash"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "openssl"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "spi_flash"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "sdmmc"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "smartconfig_ack"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "spiffs"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "tcpip_adapter"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "tcp_transport"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "ulp"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "vfs"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "wear_levelling"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "xtensa-debug-module"), - join(FRAMEWORK_DIR, "tools", "sdk", "include", "lwip"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "coap"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "console"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "driver"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp-tls"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp32"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp_adc_cal"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp_event"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp_http_client"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp_http_server"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp_https_ota"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp_https_server"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp_ringbuf"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "ethernet"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "expat"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "fatfs"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "freemodbus"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "freertos"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "heap"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "idf_test"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "jsmn"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "json"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "libsodium"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "log"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "lwip"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "mbedtls"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "mdns"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "micro-ecc"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "mqtt"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "newlib"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "nghttp"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "nvs_flash"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "openssl"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "protobuf-c"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "protocomm"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "pthread"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "sdmmc"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "smartconfig_ack"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "soc"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "spi_flash"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "spiffs"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "tcp_transport"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "tcpip_adapter"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "ulp"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "unity"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "vfs"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "wear_levelling"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "wifi_provisioning"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "wpa_supplicant"), + join(FRAMEWORK_DIR, "tools", "sdk", "include", "xtensa-debug-module"), join(FRAMEWORK_DIR, "cores", env.BoardConfig().get("build.core")) ], @@ -151,7 +160,7 @@ env.Append( ], LIBS=[ - "gcc", "openssl", "btdm_app", "fatfs", "wps", "http_server", "coexist", "wear_levelling", "esp_http_client", "hal", "newlib", "driver", "bootloader_support", "pp", "mesh", "smartconfig", "jsmn", "wpa", "ethernet", "phy", "app_trace", "console", "ulp", "wpa_supplicant", "freertos", "bt", "micro-ecc", "cxx", "xtensa-debug-module", "tcp_transport", "mdns", "vfs", "esp_ringbuf", "soc", "core", "sdmmc", "coap", "tcpip_adapter", "c_nano", "esp-tls", "asio", "rtc", "spi_flash", "wpa2", "esp32", "app_update", "nghttp", "spiffs", "espnow", "nvs_flash", "esp_adc_cal", "log", "smartconfig_ack", "expat", "m", "mqtt", "c", "heap", "mbedtls", "lwip", "net80211", "pthread", "json", "esp_https_ota", "stdc++" + "-lgcc", "-lopenssl", "-lbtdm_app", "-lfatfs", "-lwps", "-lcoexist", "-lwear_levelling", "-lesp_http_client", "-lprotobuf-c", "-lhal", "-lnewlib", "-ldriver", "-lbootloader_support", "-lpp", "-lfreemodbus", "-lmesh", "-lsmartconfig", "-ljsmn", "-lwpa", "-lethernet", "-lphy", "-lapp_trace", "-lconsole", "-lulp", "-lwpa_supplicant", "-lfreertos", "-lbt", "-lmicro-ecc", "-lcxx", "-lxtensa-debug-module", "-ltcp_transport", "-lmdns", "-lvfs", "-lesp_ringbuf", "-lsoc", "-lcore", "-lsdmmc", "-llibsodium", "-lcoap", "-ltcpip_adapter", "-lprotocomm", "-lesp_event", "-lc_nano", "-lesp-tls", "-lasio", "-lrtc", "-lspi_flash", "-lwpa2", "-lwifi_provisioning", "-lesp32", "-lapp_update", "-lnghttp", "-lspiffs", "-lunity", "-lesp_https_server", "-lespnow", "-lnvs_flash", "-lesp_adc_cal", "-llog", "-lsmartconfig_ack", "-lexpat", "-lm", "-lmqtt", "-lc", "-lheap", "-lmbedtls", "-llwip", "-lnet80211", "-lesp_http_server", "-lpthread", "-ljson", "-lesp_https_ota", "-lstdc++" ], LIBSOURCE_DIRS=[ diff --git a/tools/sdk/bin/bootloader_dio_40m.bin b/tools/sdk/bin/bootloader_dio_40m.bin index b07c320a10c1c44656ccd16a3f8dc1b8852faf38..bddfa73fb5eff0ff6773edbb2b83467f23768c82 100644 GIT binary patch delta 8662 zcmZX3d0-RO_W#VJX(#Cvl5Rj3m`NLG3rJG7vOSUt6%^mAs09U;0>#3^pBu`m$qho& zQl6a-N(-n-p-`%2DX56{XUjuGA1DR4r=mp+pgx~GMQxg8zURzLi_0IAd(Y=A_ug~Q z-A>xqTzy>sO$@`=iTW(YrxWuo38f1kd}KvVF2Az$QGQYB^5tcV`O+19@r}G~mDN_T zD#3UtfgZp}hhvsY4t)mmIWOI-A1C?r%MD{_dFo5>O_Ne$U)NC_CA}Y;>G~QFUMEkz z2IX8vp1Q+!bt(m44SZYRiviwpz>mY{hHn>qb$~NGMai;E!SB@Lp!)%Q3yx6^!1`0v zwKpk>Z3pIo4+!N5%kosp9q0JBFU|oN{m@rEQ=5w^>bvh`X-?eg!Mohorr!6~u>Jmt zpA`F`UJaj{qTE+>AWccjhGxafvP*s&Y)_5K(wR7cE0Vb!Pa)+gq{%cX5|=S&vdj(C zfQfQDPc^ZY{S=>PO0VbZd7$fA&Qe5CoP~@=wwHBRW-rOHiFQTUKy0$R*+fRk?kbe7 zG@uCs86iEyrns^-nJh)d@&}nAK${j=%x(*6<{C1uE}3f+2WUE}icZQObQ1rhLz3k# zmMU3h;u20LaPzpM#Ebw^E-sy0L;5Ksr_{M#7B`%$B5@iA>-s*@M@hA#dY`tmxoO__su zu~UHz;4yz^)aU)JuiuOQ(T~(PC$%JTx|OI}tav6`v&{s(s%NpUtaut|#V||$B}qn0 zcDrJp6_5Qv@XhOjN2Pxo^CrEd_Jh2Lje@aCgV?M>>rVC}nODUIO>Eb7F~9Ve_*Cb1 zWO&(A`6CPvRT&0%B`-dUSS8Fq1TFMjcqYm(bntu(0zkWKX};+(QiGlqYYsgVznh^i zOOyLeaeW%eyt?kk%&WpjPyyLeY68vaiw1!mzRYJo7qN{qk+TsmTah%CGeQk#(nva$ za>%TH=XD*YB3yh+JUNX}^}E14g*7xvQRH}J0t?XF2-(K9mv%&!jV`Abtn?M=Cd8%R zDRuWta=nJk1|LO^V8wBqZ_~9fjaGW35j0;$tc5B2Ngip`M&mpfDU6{?Vq%>KBIC#0 z>)ai26q+2C_Po*LrAXCio9$=N+l6{i?!+>pgPz88>{fgF0z%czz1pxPX&{aYP*6zi}H)Z5(O>e{{S{)eQ+rZIn8j4&+x zMUmc(fRri_D=vuCz`}rEE#y#;74PYz$vhOSV>66CZO1t{N4jhp<+?Q@&O#Q%SZ{fY zM&GQJGqF5kATuKFP3oEui!^BZb?8P7D(r)ZLxEUsX3chWA)p;roE)in-BjB^AsUP8 zrK3RFZqA6ykJOwuiTTq1H;+sn7HL0?q5lqh!HQNs>DQ4h$>tP}2L>8@hb4n0KCxi9 z8QD#2@4ztvFrfWEhXMB*mj`RS${I2fy|g}YitAUzkFdTM5#7uB0}5>9iFxI`F{5`Pebu=rNf5QsHlHFTd=%D9a&FlLIhh20gtT0aFX z)U)X;JwAD5(>G*OxN4f?p`V@Zuwyi=0aGLnBAq#{Qknh5eApX=~zYSQAMc_Y4FkH{~_dj9*0v9vwR^x8a+87#=aeq!YqoQN z*V|(0f#e*^=I}PjSsmUw##DPUo3HmZO&DIs*B>}JvrQ*@kyjzTnmjgXZP@>}aM><- ziZOK=dz$9b8|x)G`PrP=;a5j98?97hJ+dYmM(9uL+l(eZPiA3PPU~CGneO(JnNnLy zZMqd97+V&W4Lh$83s%HyA@Y&5EcIDBB+&zIcU=hqCytNK#jkNWEafHI9L3?5Z_yyOBICof%l4 z^GK+7Ns4!dw$*xkwEvFK)}xHaN4aZOklCRs3u3oP;-CzAp|o#My7_KU5$3`V#yvQ; zMEZ2l%25THp;F3mn78fZ%Wjo@6ZuokCo-v4AM4K#mCcihE#%3eQa_238zgty4F(Gg zI+msgFTI*}XaDXVnBg{>Z{V%(%LiF0Jw3yv!&x6`++jROg<5ph9=SzVRwN7EJ(*Wq zbdA&H-p)hdMo@i<5ssQJ`9IC%m!4rqMlQKM$9}D6Vm|q}XZ(>N_Mf0S{>T9Pk3ADD zQ`lig61cQj1}=8SjSwJQ8Xi!vhApMkSs%?+x5e08JNZDNT(ZVcy%On`xWH?&B^x9d zPc~g?-Zc8W{=xEa@}H7L|2HPrZ9O=7_T;uIvO_S(Y$6 zdwhNtJ?9X!F`t^9P1&Qt@hOQrUTr)d{d}3?%@0BD1Vg1(K#Wii?cvKBC3j|WdLR|I zjh?s>T${1M*VVj>II*uSx@Id^PNpIPfRxp&Y*(9p=(%&QhZMz6(B_l6KmB*W#EeWBb_#tF22OwXz$&bT*b ziZM2mIWTH3&N$7#aT3b$u{|u6Ntk<)|fTfo$nIXf0IAuuM za0-oh>9{LbbLd>1y5#Vh*TRsVAjraka=WujSebN7o*~XrR}idc-RsTbC9J~DArK^A zswg>+rDFbs9$Y7ONk0x5I^+XYu+}e=Gpe9?CP?1Vbl#T6^I7y;(ma0TU9ShN|CL*P zV_|`lgF)z-CyR1>&6PSe2JvWbVFKUDqzRStVQfo-WH;7foMb0fpu;5vGQ@D%H?qY? zDN9ahlrHe;BcBfjF3I-ig2EOQoWPJ;ES2usw+3PQzm~~Xgz8w~St(b@y|GFa5UYYU zO{T5emXb;Y;BMsz{{GB<3TPf!^{n5cSTGVQ=&m;rw{)K+#TDp=d70#OyI0hx4-2EX zDo7qj$$Iw0I&js;SD2#PDe(b>t{D8;LEk>*ih{2_pdSDl?e8_L>}F!~DAI`*!>a&- zE8&n}@58`MZft#i5N`kN{5Y!8DBc?+cWVtUz`3~{2~hrDckg}DU#uy=rzqcw zUC%g#4aNVq>;7q)*h#6zGVrgCAep4vh2?U&yuUalNXDyxa*~M?gJiTyizBgwHve_K z%{+wajHF3v)26s;qr@~#xf7I?yPAQlN5RhvRHN7N*nT*`ekk9NOOY3~ z);voozY)ROJj%15LI*wir_qU2(52do0k5LZD-HfgHr+|ArPmyG}?eCXFzjKpGapscxxxQkt<%Bae4W?@dY@epn;l=;m`xHe0rD zG;LFp46I_Fyrc=d+$|+d9%bBtB=kMETbec5npUfjZ0(Ek@0U?sx3p>U*t{n-!2Y0 zbH@|XiR{)4nxd)0kil^j_NUf=k$z*$f?uXW=H_zo2Ff8dS;t6MtOe5wAg#0uzGC>w zul_t$egQ;&fKR5}@I%ArT8{V+koa-Qva%;xw{_zd1$Eqco|bkE9Xd78(0$D3gOdmM z@Y^xp(Lx78vSf3c5c+GC zP7Slnv+8Kb-v~H1H5Q2l>ncJrP@|3|>2gKo|E%v(?agK~NOm7>IB)=;;DagL zt>4LD?=0Gz9k@MMwlv7C<&2FFVv$w`#Vyd;!2ICB<57T1f{h?EJ4lY9r8-vZz_Okd z)qIbEyxEtZDH|LtOO?8E2fJR5!byHy={XArrK!$Wn+q=J@B60M##6qf#T1-lC+Sz_ zeobDAatwb3VZIz;zBFkhEjC5T?r6np37vbQ9ebkl)BSs*0X;45>4kSkJN(i4!~Onf zSqx2fL@V+WIvb)LJEHKE*%5WYv}xe;(T=TAc*|^!258z}8||o#`cAcT@uXDqt6M44 z$dekamT6?2MsLAV*sKhmA=OdkyrC)?cyMh-7CMC?6@V*SHsjwIZI?oMgItwN<5zGO zsy3>bAY1}ZMBV>L;k|U%0rP=Yr~7rj^L^)_h5{|WR;N)8Dppx>I5dUI>5RQka`(93&sZL8WBgF>CS6f#~WvAh?qL$x}w4AuBt+;DR1I3qWx zc-wlYpIqhGOAGf!`5h)Ljk2oxnfMLDyeRKA;q8?bim^9Mt>T<$O`VC9NT-Hp++K_U zpdI^F*=bgux1>6LO<`Hh(JvtXv%#h@h7p)_qM#m3EI9 z?iz#{RG)>%#ac>{&oO%f3-q%HEKqV8DKGnLdCYtkUMwEpRk2?b&d<6*d+B;}t&ggO zOktgw7@|$IIwVgi6|ho1U-FqMTGRs!-gGzfd+9(PpfO#5Qoliuj5P;bxKSt@UPw*d zh&_F2Drg?AR=)y`vC^AKy(VoKIV1UEq^1`AQs1{jieE|>MkbH>ECScsPt~rkT$Ln# zq?k33ceFGa9Qs;|;`4h5x6zoI3S7-6L`5YyJbd&SQ0?Y-%^Jxz< z3m8yauc`^VG;=$p|K5Xl)AZ>NMUk}xXWuo)%5OaG9jkIEh3Myir& z@Q)y4)h3|(!dhv=D1OFD$k+<_1Ca@brm#Y(;`qeniV*|(8~DfsX<(a$);eow@aagp zYD)2iP%3>tYGD6`s4+LzSsHQNX>#UE$+o}Si%{&W?40sKSx~iB^lD{F*>=7t1<~`d++@|1Ss`P%`6`)!Wa9<-)WrGt zmTvI*$Sat{5rW|fc$raqs*gxj_G~&V?YBR6%Q?(Fd3EkhDMJTZs%H$%DcHzS_D>Pb z&!TL$E&2bX8-J2*RmUK(Hzrc{5Bpfjsf*~LNy5;q;Q_DQ=#{04e5c`c#U3lRNuBwr zE+uuB3!#Y7GQ!EbuTd5=xRA7>7&6p8!7Hj2JL=zyc%9Mn65cxF*Sp_f56iyzTK`djo1z>d0nAleNDPwoSk=g)0#2vOlYGt=;ma{B%-{Q~@h& z3PbKqaEAFTCGxNvWP`?gO5xr4TOM?NK3kD!_V|1iiHWe@D-x42Z?pmqKyF46{1KPN z&Dcnz!x@h+PF#(q_8R;Txv+A?C_Wgj*={QKn)}AG2pMosek_caYxq@HhtdCNxa@lw zyzwAn#BtgurKGNhTmW5mNp74&ElFa^w#fMws^lEiYGGa(p3{^M zZ$R+clB5BFXXUaxslX|@)j|gj$qg2r^?SL7qLySaW%pb|AuukCN6TIYUh598S(p;e z^NM4_HQold=R?6B=5su%T$xV}_~nvq6qnu-4=!$e241<4d!Vhi!jnG?SE7zl;Z7SQ ziam`cY1UZV9kFN_vT(ywmL$e<=_9HdKauUM(wa`l2*dthp|kkDzxH%u4`$)K1|e1D zWnZ<>y?^_u3{zM-Gd4MwQ+sTW58DbbN+#f0;bp+Ktw4z{1~!9mtMI*)Fm70?^;H>e zWGDJjf$!n4ej}}jqbU0q(#_*+GoHi-;qZ7O1cwKt#g5DVb0G-j#uGB!bC1de_SOzl z6Y(`|X*?vKO0(W1H*}a9zmP4*WTIp`E#=g#Zs8N@y>V&xoDK0=CbBzJQL6{91Rj@% zJ=*`^d!YjsH^g8(e{_B0Dj94w=o>dAmUa(yzUBs=U6)N6lFJD<$<4r!}H7{SIG5m^fRq_F^xnchc8u(nuolyUeNFj##|G(sHiPD3i%VgyD~+*$vlm zvJ^o$M9M>OV7vI5WLv$tH-7<~xvaP_RP)Sl58?Yz(pK{|bzShbEVSa)!<}uYB?tce zHQZz1=dFjlVtkWt`}#SR8LuV^o|93|;0DStq$4vF3;DE;^iUDzhB^j?V26RyH84~} zLxt){3ijnL?$8MWs>7-r=7e>Prz(E157-Xzm^J-c_8sNn&y|ET z&GdmbXW-Z`+M|#ppdxrYG4%V(P5)4h>vy-Em_Gy+YD{H$^?Ea#n#vkhto}=R^@?Tex|*eBOV?~D zt6XPZTUNsYxWQ}?%2YEgORHDiv6Q%Jv0?T44Qtjswyws!jK$g;%&V6^&Mtjyb>)iX z8`hQAtaxm-fw)C~poT$RkP?JkU-hb+buKs8l!ct!F3XVvdaP_sb#>XJRZkG>%{Sg-gwV@YtX@$A@!wJ%Az^20|!nYVcD}2p>Q!GJ9k_6R( z3~W2#TXKRZ0&EyTTz?A$9Umj22q-C>(^!SQVH~qqV$$lS5Oq^X^pNm=SRyl5Vn!;! zY~h!%QROqFZkDjo)~zX(X(s+2%(ZG!iDYflqiK?L8w`yan3Q@ThKrST(}Aw5HwMa(gjfdQFI zV4gr@WR78Q**GW}%WOleBEjWR0}=}}lW9ZoiU^lS4v3gLnLQ|4k>GM9E+5v&0Y@ML z2h3AaV;gSr!HB~|NC4;{6bRz(iMSQ=+zwf=<&B%z9_*|og1;g|TIf~#m7r+5wXZJ) zZ|`gFa?nP>pE1p4{5ROlrsXaLS;dC`Dg+JkpWntmtmQws4Zs6xi%_&9&`B(8rrC6P zT&3_PV+@ptL3mxLm053O!M(+#1(T0?NDT>{HQ0%&?cvL9R zX585(D{9d}+(2-)Rm-=ApiQR+kfc6dRMZ?d)m{`{(8d|ijLJ)~s>sFTE ziLtFPA7S!C;G7U-D~ecFtu(~iM6#_L(2gJs8NcJm4ej44(k<*|?y`IyNb1}4Yf>Ng zF%-bIoG2g}O-UU1Va;MzZ@@G`kIn^bbbWLoqk|HjggW%0Oh?~4^n%KDI>1D(Uv!`&><4&bzCTV zhwW0eQ)UC1sRPR+7z6e(c-^5{XV*i0wt#Fo&UJUm~xXV`el%mDvqEP^REKxZiYbcNo7=~3A50@m%J<;UNx zKvQo*#R^n32%$g85Y5bJd_Ghs_CxcN0*!C#n;Zm2!|-x(O%Qy;62nb_#tVAhB#hE$ z#ux+LJ$UB7Pk)64D`+@V)*n%MFYlrNx&qdXTn%FY`Lo=eKSTDcUb8(6yV;xsbO3U-mB)l}k5O zK2)G@2cg5~G1MA?dj0sQ_{tB%77obP2=t}!_sCIkhh;g<_xf+&IbIPiM8;X%FB4~< zV4|Q!^7Ml#2y5?g66WC!e`w}DBh&CLYG^Zo-t=4R#U?ueHMGzP8|y@AW9tuStAE?w zMQd&p|J7fV14}?32#1MI^{C_(`B&`VCc?y{$1##mq9^?ewU~_O!7O1mYFft{XU{f$)Sc;chh0qg~X4vlEBNT7* z@6OdXol0R_#MXkb&1_4@sTo}=ehZd8EsTiHiyr5<&+?o1OLysFSJFKslVIK@ltu4K zyWjst4zMWb+7EZ_PBKw8%;qxqRAAsC`MW5@UZ}FY>i$3>Zx`>U51?(H2 z>nq>lnf9-I&JMb0U2#bQ^gs8puZmi-BsWpBWPbPT1xvY4ebDAKs&tC9MMJP#ti|Vj zMbkx7o#;p-jFTnDG9tmSAlnT}#qavkgq+ye$?sv48B~}G4=5AEy%XX~!#$yST~3rn zk-cyDT>tWQidOp@K7Ax>K0wEQA5q*PJRLjQa>VC43?jkahDFBx^x;FkcFNf&A-fMY z6l*Ty**$V-@5?^d0Z`j*7kzF!-LXH?Y?2)11aof}3EDqN+%8`l#j?2#=X>ow*FI3) zXMfITe31r$+^E#3>k!`aq42oI0dUB5hJx96u_DraF?B_u=R=7Cw4((`YbQnpXBw<9{{9!k| zFv49V>tKx^N{2PVlW~dn6L{1!b$fM(1KxI((JQs9%q0?c!<*FCu5wP327-r)>%r!C z>ENWfC|%1yzj?v#PW-a~b%S|gp`OJA={#NCGdgpNb5 z3);fH34bszd>WrSVoMEC6}|Q!-sNvlB}<7Db^_M58toFegyL8&^t*HvGp*J z#F_)FvsKDgC&X^194SP0%EU=+<02fVFB;?VQul_BW4d$>@nYM4G!qX93>qtyUJgq& z%!GDl_8H!#iVPhFg9?V({DpK}_YB2QCE*acwL;7f3$F-Y`+&DL9A?GZxxy2P#g;8n;RMR{*0)4f4PQQS)k5P#r3>Cz7#0sP5NN#DYQ0|HGRdETcdJZqGSt%()xELZhLW z+UU~h64D91N%5pcxRw;JmplN&s<2v9N@)oNgxFEV7x^4+p$(Q#9QM*FXJ-Aj#`C9qvK|@d0<6dmE@hrBbDkj`J}-?u*v##(*Bai zeObzKc(@j9Q$V5Jn97l5?e(;)+?OP@7emc7_q@kN|!i@YwG`?Z$p8EQ3H_V3+<{ zfZ$G-;TgEt+m|WfT_+7&Hgl z@+Pi0;?}m zr~5A49eg$xKwzKV3~ano!4WyGy#F_@=LC@(ZW*l@e+|a+g-naK`SwhYiKO z5RLU6>F_pCYO7m8*oR@TDT7c(@5%pZF|Sdo(L%?|!>zSb7|L$ep)GQd^k9&Dm4V zL%AP5!IqlK#Hgjho$yVDPdJ{MuiFm=lSV2$t`>r+u^D+jOFlg=0Wp&!8v<>QCDO@7No}!QxA8 zFeqF|J89_+0`$w-;CFVS_e{`rCfMCcqBFr(8lA-waB@bWr!j>AKm_b(?g<3v3Ld1G zq{N0U(%uy`>tT3Gf27+<s?nv=-Ghk^i)AdR3CMWS}>shQ?q!4%fv%b3DCY#U4vm`8Y= zQT;F(+~*{i2|vUA20z0?PjLu5@!rE?5RRfla+ByV4PntYi_KcbEB-Ls#1i6)*#t`@ z*j`_Fh1(ruXzOv)DHWonuJ*Q$g2LLGf%i%w;r7 z>F`xDjYlgKK1Acua)q~G$~`Xk3WaKe%C1JiTc8$;pm&-nv>tGIqoM3;WmR1@UjHC$ zfg?Z=$7(Hg6@>FUIPe>EN>9NotHQcR)A;3>wxq$I)>_^?klK;A^;*8-4}94`sz;VL z^NS(hqURS4pv~AzGrtg9DVe5bM#mJy&EB&aM5k(t4wBs5AiGzuJmYH{o{M;zyAP6F zdf2HMnwyHFY3=0y9BgdXqZvZOxWsu=@$f6h*1CqB5qG1>LF?VJftt&bo9saOLF?c2 z#S?=?GxXNG@rF3V0e`Y9SS~kcpvc%MnpfP#My$NBCM!ztjT@tl!`$?BS#iSH%y=$R z=2To_kWFD{Q6NfJp$H7x=rR4*IjvBcIo84i;VCQ{SiDrr3G@+uy~D#qUY_Vei2J=t zy_nuY5Orc7PX=LYZ;m@iwnR3GL{l+gZH`3#Kr0z)Qe8RWHWH#3b8Z{S_X7;wX>DT< zlI{#Z)fWN%?H2TCUZk-OZxix9@pCA3!2dLuCV^n!s_-N5^6)E(yeq=AJEq5c8fa|7 z{n9eHKl0}V`yDa49|Yj?)e{PRV{J75zU)?ujw@*zIFFPX`4fuhZQ+MIQs#DIE=`O6 z8L-xcPCBfILu1(*lc^>)DvUdVb(*QVLvIaCQtnU)Lazp3mfj0#Y5Dk~_AbpjAe4xx8iP>@ap*3q#d#`buR@oilLY| zYx?GaptySB+wlonE7pKsLW0JWK4LxQwo(rJI5aL)1%%J77N(il=_?^&$l*UQGvNx& zEtiY9eS9cyrA1SqkMxj*G#N-GSgk`;p{S56xi7c}gm%-&Ve@fC3&V;Z2o%lN7pDmy zn^t8NV72q&-mQp>EGSsY>s%sRi7&Q4magPG|NMbwUy2;4P)0W>W%YFxix_;Yp& z`5)o2>cRHwBr zODxPX*}5ZaSxwkzs|r1VX)~Smtlw0C=PBfC>8#Bmp|M}OoSgt^Bf#@%uGSB^A1=$! zCd)GqSBTarvbC~o+O0B}3XAD_HY%x36zii#!Gf=kVtZ@-u3CSm{e=BdKO`}n0wJu< zjkPSrZVqbg4`F&#$3N(Ad|p4>7CCSqheQzw;PzJG$M@!C{((EJy~6LjCP9-I<0iY8 zz%qb(;kS>4au<{+X47P|xIr^s7PM;XULo*B)Pf&L_FP4IhO9hmP#KkNBO#V>iPKmvp)%=R%?~nld&?*#@HYBcjtly*@UrHQRUz8&*b- zaPE}MrG)de)M+4{hb4zWWv;v?HNvli$&~pzRs!c-3ifQH;5}Jni{!@nGi*EulfYrE z`-B_iXVdCJdd3$d=ZjM59)d||kH85d0p4ctgeHym5onYj?n16n{@&4$qpULz5w7N$ zEPbJT4m);uWmFiGFm9XsGb!s=4BAv&gdesB1DVVY{>Y``FUc}3rwPeY`V1sYLeNi_ ze?`%9k`Ij15Nk9R4Vq~=pKL~Dd3~mQtX+Ul4I34e^*aFaOrv05@ON^b2?r;PiFLmw z!PV^KP{REaoW;lEOW+s8tW(0}38n|CWlzdE0x7JwC409ICbj!rxaK&IO8HrxE`2K! zTX&idOJ~3AJ?nGzKvwH<`&pmSOgLP6_XWvtLPD=$KZYve-hS>q;gN~)54(Ku5=GDW z>YFssWA63RnDxUBclkODRwkZ_V2^EfZjivQL*v|r=}W`iXkhR;*;y;a9r3XldUoG% z)aiqnWF0%aqb~AXdL(~H_++BNa=?dA!~>d(ZIPRfS`DGY5xs;1X{N&;U%TllfJpSg z{%_r(?z2U1`cgFLp?guaj6JKq2-qs(bK|mIvR}$wPdcHnEfCgIm=_TXkwtcf_<@tkl#t2aI^%_;VY^G~=mzLOEKd8bAtHk}GG8puR8 zJ}n%u#k%XHIhF!h#pf+i5u0wffRe=ALz2tmwTJn{BaZVTA-+^+JpJFhbPFa8>Al0} zO7-3QrajeXo=Bin90SCgacjK5pYb+6hkF68410092l8G75s?Eo(q_z}k#g+x?^mhI zmgp;UKF2woW=-9z5+44$BbBR}rZOsWmIl|LF| zeZq8v#ksIcl6Z`Ty#J7MZDdDRvGZU5RbGq8hbw_zCw;fwdn|m=dmF(2`Uk%65ByHx zapNGlgC9`KaEl;)iF5Dea_hbgrKo^QcV$lIbr(Mxm13IBiQPF`V{DPw6RCL5Y=%8JS!V8MRIk_U?z2s!w7A%6s zCwqnK$;S9iGD|nTEZsh6k9mchlsrq7;>f5tnw=AQYs6@YB444%+1urzENE!V!sP$O u0?N1i_d{m?thbK~Lngh`w&U^Le=SI!`1j|pEsF8C%-g-`)7Tk28U26nBM}V% diff --git a/tools/sdk/bin/bootloader_dio_80m.bin b/tools/sdk/bin/bootloader_dio_80m.bin index d0d0a8b66404bf836a84de18cdf8f6944d4c6159..27580134c06ceaee7752f9927de538a7c0644838 100644 GIT binary patch delta 8634 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 diff --git a/tools/sdk/bin/bootloader_dout_40m.bin b/tools/sdk/bin/bootloader_dout_40m.bin index 82d8fd2abf50f9374c806af95bba5f06322f32d1..9fdb019d4db048f95a6068b0ec393e1a7e29bc14 100644 GIT binary patch delta 8662 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 GFa3Y%td-XQ delta 9052 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 delta 9059 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 diff --git a/tools/sdk/bin/bootloader_qio_40m.bin b/tools/sdk/bin/bootloader_qio_40m.bin index c01ad4a50011069b040fef3b4dbd2f4df4d45088..f3edde65b3a54dc8676fe6b5bb4098504e1d4ef6 100644 GIT binary patch delta 9789 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 Ut@`vX;hV2AN;W%gxc5K*2QvB|f&c&j delta 9984 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 n^XA!IPk(lO>iv25ran`Xohl4w=J!}3yE<9$K diff --git a/tools/sdk/bin/bootloader_qio_80m.bin b/tools/sdk/bin/bootloader_qio_80m.bin index 7525f2a57d2b6d4df397b2b92315f3ba14ce3c21..028eace5cac95aeb345aa09ae33edca3a198726a 100644 GIT binary patch delta 9717 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

0B0cqI~SpWb4 delta 9943 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 n^XA!IPk(lO>iv25ran`Xohl4w=J!}3yE<9$K diff --git a/tools/sdk/bin/bootloader_qout_80m.bin b/tools/sdk/bin/bootloader_qout_80m.bin index 63cc8e3b053a11f41dfe2c1cbc0227f77cbf2bb1..5e4b6bdcf088dc978d0d5a9f17a2154edf638b5b 100644 GIT binary patch delta 9717 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 +#include "esp_err.h" +#include "esp_app_trace_util.h" // ESP_APPTRACE_TMO_INFINITE + +/** + * Application trace data destinations bits. + */ +typedef enum { + ESP_APPTRACE_DEST_TRAX = 0x1, ///< JTAG destination + ESP_APPTRACE_DEST_UART0 = 0x2, ///< UART destination +} esp_apptrace_dest_t; + +/** + * @brief Initializes application tracing module. + * + * @note Should be called before any esp_apptrace_xxx call. + * + * @return ESP_OK on success, otherwise see esp_err_t + */ +esp_err_t esp_apptrace_init(); + +/** + * @brief Configures down buffer. + * @note Needs to be called before initiating any data transfer using esp_apptrace_buffer_get and esp_apptrace_write. + * This function does not protect internal data by lock. + * + * @param buf Address of buffer to use for down channel (host to target) data. + * @param size Size of the buffer. + */ +void esp_apptrace_down_buffer_config(uint8_t *buf, uint32_t size); + +/** + * @brief Allocates buffer for trace data. + * After data in buffer are ready to be sent off esp_apptrace_buffer_put must be called to indicate it. + * + * @param dest Indicates HW interface to send data. + * @param size Size of data to write to trace buffer. + * @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly. + * + * @return non-NULL on success, otherwise NULL. + */ +uint8_t *esp_apptrace_buffer_get(esp_apptrace_dest_t dest, uint32_t size, uint32_t tmo); + +/** + * @brief Indicates that the data in buffer are ready to be sent off. + * This function is a counterpart of and must be preceeded by esp_apptrace_buffer_get. + * + * @param dest Indicates HW interface to send data. Should be identical to the same parameter in call to esp_apptrace_buffer_get. + * @param ptr Address of trace buffer to release. Should be the value returned by call to esp_apptrace_buffer_get. + * @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly. + * + * @return ESP_OK on success, otherwise see esp_err_t + */ +esp_err_t esp_apptrace_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t tmo); + +/** + * @brief Writes data to trace buffer. + * + * @param dest Indicates HW interface to send data. + * @param data Address of data to write to trace buffer. + * @param size Size of data to write to trace buffer. + * @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly. + * + * @return ESP_OK on success, otherwise see esp_err_t + */ +esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_t size, uint32_t tmo); + +/** + * @brief vprintf-like function to sent log messages to host via specified HW interface. + * + * @param dest Indicates HW interface to send data. + * @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly. + * @param fmt Address of format string. + * @param ap List of arguments. + * + * @return Number of bytes written. + */ +int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t tmo, const char *fmt, va_list ap); + +/** + * @brief vprintf-like function to sent log messages to host. + * + * @param fmt Address of format string. + * @param ap List of arguments. + * + * @return Number of bytes written. + */ +int esp_apptrace_vprintf(const char *fmt, va_list ap); + +/** + * @brief Flushes remaining data in trace buffer to host. + * + * @param dest Indicates HW interface to flush data on. + * @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly. + * + * @return ESP_OK on success, otherwise see esp_err_t + */ +esp_err_t esp_apptrace_flush(esp_apptrace_dest_t dest, uint32_t tmo); + +/** + * @brief Flushes remaining data in trace buffer to host without locking internal data. + * This is special version of esp_apptrace_flush which should be called from panic handler. + * + * @param dest Indicates HW interface to flush data on. + * @param min_sz Threshold for flushing data. If current filling level is above this value, data will be flushed. TRAX destinations only. + * @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly. + * + * @return ESP_OK on success, otherwise see esp_err_t + */ +esp_err_t esp_apptrace_flush_nolock(esp_apptrace_dest_t dest, uint32_t min_sz, uint32_t tmo); + +/** + * @brief Reads host data from trace buffer. + * + * @param dest Indicates HW interface to read the data on. + * @param data Address of buffer to put data from trace buffer. + * @param size Pointer to store size of read data. Before call to this function pointed memory must hold requested size of data + * @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly. + * + * @return ESP_OK on success, otherwise see esp_err_t + */ +esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *data, uint32_t *size, uint32_t tmo); + +/** + * @brief Rertrieves incoming data buffer if any. + * After data in buffer are processed esp_apptrace_down_buffer_put must be called to indicate it. + * + * @param dest Indicates HW interface to receive data. + * @param size Address to store size of available data in down buffer. Must be initializaed with requested value. + * @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly. + * + * @return non-NULL on success, otherwise NULL. + */ +uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size, uint32_t tmo); + +/** + * @brief Indicates that the data in down buffer are processesd. + * This function is a counterpart of and must be preceeded by esp_apptrace_down_buffer_get. + * + * @param dest Indicates HW interface to receive data. Should be identical to the same parameter in call to esp_apptrace_down_buffer_get. + * @param ptr Address of trace buffer to release. Should be the value returned by call to esp_apptrace_down_buffer_get. + * @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly. + * + * @return ESP_OK on success, otherwise see esp_err_t + */ +esp_err_t esp_apptrace_down_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t tmo); + +/** + * @brief Checks whether host is connected. + * + * @param dest Indicates HW interface to use. + * + * @return true if host is connected, otherwise false + */ +bool esp_apptrace_host_is_connected(esp_apptrace_dest_t dest); + +/** + * @brief Opens file on host. + * This function has the same semantic as 'fopen' except for the first argument. + * + * @param dest Indicates HW interface to use. + * @param path Path to file. + * @param mode Mode string. See fopen for details. + * + * @return non zero file handle on success, otherwise 0 + */ +void *esp_apptrace_fopen(esp_apptrace_dest_t dest, const char *path, const char *mode); + +/** + * @brief Closes file on host. + * This function has the same semantic as 'fclose' except for the first argument. + * + * @param dest Indicates HW interface to use. + * @param stream File handle returned by esp_apptrace_fopen. + * + * @return Zero on success, otherwise non-zero. See fclose for details. + */ +int esp_apptrace_fclose(esp_apptrace_dest_t dest, void *stream); + +/** + * @brief Writes to file on host. + * This function has the same semantic as 'fwrite' except for the first argument. + * + * @param dest Indicates HW interface to use. + * @param ptr Address of data to write. + * @param size Size of an item. + * @param nmemb Number of items to write. + * @param stream File handle returned by esp_apptrace_fopen. + * + * @return Number of written items. See fwrite for details. + */ +size_t esp_apptrace_fwrite(esp_apptrace_dest_t dest, const void *ptr, size_t size, size_t nmemb, void *stream); + +/** + * @brief Read file on host. + * This function has the same semantic as 'fread' except for the first argument. + * + * @param dest Indicates HW interface to use. + * @param ptr Address to store read data. + * @param size Size of an item. + * @param nmemb Number of items to read. + * @param stream File handle returned by esp_apptrace_fopen. + * + * @return Number of read items. See fread for details. + */ +size_t esp_apptrace_fread(esp_apptrace_dest_t dest, void *ptr, size_t size, size_t nmemb, void *stream); + +/** + * @brief Set position indicator in file on host. + * This function has the same semantic as 'fseek' except for the first argument. + * + * @param dest Indicates HW interface to use. + * @param stream File handle returned by esp_apptrace_fopen. + * @param offset Offset. See fseek for details. + * @param whence Position in file. See fseek for details. + * + * @return Zero on success, otherwise non-zero. See fseek for details. + */ +int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int whence); + +/** + * @brief Get current position indicator for file on host. + * This function has the same semantic as 'ftell' except for the first argument. + * + * @param dest Indicates HW interface to use. + * @param stream File handle returned by esp_apptrace_fopen. + * + * @return Current position in file. See ftell for details. + */ +int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream); + +/** + * @brief Indicates to the host that all file operations are completed. + * This function should be called after all file operations are finished and + * indicate to the host that it can perform cleanup operations (close open files etc.). + * + * @param dest Indicates HW interface to use. + * + * @return ESP_OK on success, otherwise see esp_err_t + */ +int esp_apptrace_fstop(esp_apptrace_dest_t dest); + +/** + * @brief Triggers gcov info dump. + * This function waits for the host to connect to target before dumping data. + */ +void esp_gcov_dump(void); + +#endif diff --git a/tools/sdk/include/app_trace/esp_app_trace_util.h b/tools/sdk/include/app_trace/esp_app_trace_util.h new file mode 100644 index 00000000..6376008c --- /dev/null +++ b/tools/sdk/include/app_trace/esp_app_trace_util.h @@ -0,0 +1,167 @@ +// Copyright 2017 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef ESP_APP_TRACE_UTIL_H_ +#define ESP_APP_TRACE_UTIL_H_ + +#include "freertos/FreeRTOS.h" +#include "esp_err.h" + +/** Infinite waiting timeout */ +#define ESP_APPTRACE_TMO_INFINITE ((uint32_t)-1) + +/** Structure which holds data necessary for measuring time intervals. + * + * After initialization via esp_apptrace_tmo_init() user needs to call esp_apptrace_tmo_check() + * periodically to check timeout for expiration. + */ +typedef struct { + uint32_t start; ///< time interval start (in CPU ticks) + uint32_t tmo; ///< timeout value (in us) + uint32_t elapsed; ///< elapsed time (in us) +} esp_apptrace_tmo_t; + +/** + * @brief Initializes timeout structure. + * + * @param tmo Pointer to timeout structure to be initialized. + * @param user_tmo Timeout value (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly. +*/ +static inline void esp_apptrace_tmo_init(esp_apptrace_tmo_t *tmo, uint32_t user_tmo) +{ + tmo->start = portGET_RUN_TIME_COUNTER_VALUE(); + tmo->tmo = user_tmo; + tmo->elapsed = 0; +} + +/** + * @brief Checks timeout for expiration. + * + * @param tmo Pointer to timeout structure to be initialized. + * + * @return ESP_OK on success, otherwise \see esp_err_t + */ +esp_err_t esp_apptrace_tmo_check(esp_apptrace_tmo_t *tmo); + +static inline uint32_t esp_apptrace_tmo_remaining_us(esp_apptrace_tmo_t *tmo) +{ + return tmo->tmo != ESP_APPTRACE_TMO_INFINITE ? (tmo->elapsed - tmo->tmo) : ESP_APPTRACE_TMO_INFINITE; +} + +/** Tracing module synchronization lock */ +typedef struct { + portMUX_TYPE mux; + unsigned int_state; +} esp_apptrace_lock_t; + +/** + * @brief Initializes lock structure. + * + * @param lock Pointer to lock structure to be initialized. + */ +static inline void esp_apptrace_lock_init(esp_apptrace_lock_t *lock) +{ + vPortCPUInitializeMutex(&lock->mux); + lock->int_state = 0; +} + +/** + * @brief Tries to acquire lock in specified time period. + * + * @param lock Pointer to lock structure. + * @param tmo Pointer to timeout struct. + * + * @return ESP_OK on success, otherwise \see esp_err_t + */ +esp_err_t esp_apptrace_lock_take(esp_apptrace_lock_t *lock, esp_apptrace_tmo_t *tmo); + +/** + * @brief Releases lock. + * + * @param lock Pointer to lock structure. + * + * @return ESP_OK on success, otherwise \see esp_err_t + */ +esp_err_t esp_apptrace_lock_give(esp_apptrace_lock_t *lock); + +/** Ring buffer control structure. + * + * @note For purposes of application tracing module if there is no enough space for user data and write pointer can be wrapped + * current ring buffer size can be temporarily shrinked in order to provide buffer with requested size. + */ +typedef struct { + uint8_t *data; ///< pointer to data storage + volatile uint32_t size; ///< size of data storage + volatile uint32_t cur_size; ///< current size of data storage + volatile uint32_t rd; ///< read pointer + volatile uint32_t wr; ///< write pointer +} esp_apptrace_rb_t; + +/** + * @brief Initializes ring buffer control structure. + * + * @param rb Pointer to ring buffer structure to be initialized. + * @param data Pointer to buffer to be used as ring buffer's data storage. + * @param size Size of buffer to be used as ring buffer's data storage. + */ +static inline void esp_apptrace_rb_init(esp_apptrace_rb_t *rb, uint8_t *data, uint32_t size) +{ + rb->data = data; + rb->size = rb->cur_size = size; + rb->rd = 0; + rb->wr = 0; +} + +/** + * @brief Allocates memory chunk in ring buffer. + * + * @param rb Pointer to ring buffer structure. + * @param size Size of the memory to allocate. + * + * @return Pointer to the allocated memory or NULL in case of failure. + */ +uint8_t *esp_apptrace_rb_produce(esp_apptrace_rb_t *rb, uint32_t size); + +/** + * @brief Consumes memory chunk in ring buffer. + * + * @param rb Pointer to ring buffer structure. + * @param size Size of the memory to consume. + * + * @return Pointer to consumed memory chunk or NULL in case of failure. + */ +uint8_t *esp_apptrace_rb_consume(esp_apptrace_rb_t *rb, uint32_t size); + +/** + * @brief Gets size of memory which can consumed with single call to esp_apptrace_rb_consume(). + * + * @param rb Pointer to ring buffer structure. + * + * @return Size of memory which can consumed. + * + * @note Due to read pointer wrapping returned size can be less then the total size of available data. + */ +uint32_t esp_apptrace_rb_read_size_get(esp_apptrace_rb_t *rb); + +/** + * @brief Gets size of memory which can produced with single call to esp_apptrace_rb_produce(). + * + * @param rb Pointer to ring buffer structure. + * + * @return Size of memory which can produced. + * + * @note Due to write pointer wrapping returned size can be less then the total size of available data. + */ +uint32_t esp_apptrace_rb_write_size_get(esp_apptrace_rb_t *rb); + +#endif //ESP_APP_TRACE_UTIL_H_ diff --git a/tools/sdk/include/app_trace/esp_ota_ops.h b/tools/sdk/include/app_trace/esp_ota_ops.h deleted file mode 100644 index ca77b542..00000000 --- a/tools/sdk/include/app_trace/esp_ota_ops.h +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef _OTA_OPS_H -#define _OTA_OPS_H - -#include -#include -#include -#include "esp_err.h" -#include "esp_partition.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -#define OTA_SIZE_UNKNOWN 0xffffffff /*!< Used for esp_ota_begin() if new image size is unknown */ - -#define ESP_ERR_OTA_BASE 0x1500 /*!< Base error code for ota_ops api */ -#define ESP_ERR_OTA_PARTITION_CONFLICT (ESP_ERR_OTA_BASE + 0x01) /*!< Error if request was to write or erase the current running partition */ -#define ESP_ERR_OTA_SELECT_INFO_INVALID (ESP_ERR_OTA_BASE + 0x02) /*!< Error if OTA data partition contains invalid content */ -#define ESP_ERR_OTA_VALIDATE_FAILED (ESP_ERR_OTA_BASE + 0x03) /*!< Error if OTA app image is invalid */ - -/** - * @brief Opaque handle for an application OTA update - * - * esp_ota_begin() returns a handle which is then used for subsequent - * calls to esp_ota_write() and esp_ota_end(). - */ -typedef uint32_t esp_ota_handle_t; - -/** - * @brief Commence an OTA update writing to the specified partition. - - * The specified partition is erased to the specified image size. - * - * If image size is not yet known, pass OTA_SIZE_UNKNOWN which will - * cause the entire partition to be erased. - * - * On success, this function allocates memory that remains in use - * until esp_ota_end() is called with the returned handle. - * - * @param partition Pointer to info for partition which will receive the OTA update. Required. - * @param image_size Size of new OTA app image. Partition will be erased in order to receive this size of image. If 0 or OTA_SIZE_UNKNOWN, the entire partition is erased. - * @param out_handle On success, returns a handle which should be used for subsequent esp_ota_write() and esp_ota_end() calls. - - * @return - * - ESP_OK: OTA operation commenced successfully. - * - ESP_ERR_INVALID_ARG: partition or out_handle arguments were NULL, or partition doesn't point to an OTA app partition. - * - ESP_ERR_NO_MEM: Cannot allocate memory for OTA operation. - * - ESP_ERR_OTA_PARTITION_CONFLICT: Partition holds the currently running firmware, cannot update in place. - * - ESP_ERR_NOT_FOUND: Partition argument not found in partition table. - * - ESP_ERR_OTA_SELECT_INFO_INVALID: The OTA data partition contains invalid data. - * - ESP_ERR_INVALID_SIZE: Partition doesn't fit in configured flash size. - * - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed. - */ -esp_err_t esp_ota_begin(const esp_partition_t* partition, size_t image_size, esp_ota_handle_t* out_handle); - -/** - * @brief Write OTA update data to partition - * - * This function can be called multiple times as - * data is received during the OTA operation. Data is written - * sequentially to the partition. - * - * @param handle Handle obtained from esp_ota_begin - * @param data Data buffer to write - * @param size Size of data buffer in bytes. - * - * @return - * - ESP_OK: Data was written to flash successfully. - * - ESP_ERR_INVALID_ARG: handle is invalid. - * - ESP_ERR_OTA_VALIDATE_FAILED: First byte of image contains invalid app image magic byte. - * - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed. - * - ESP_ERR_OTA_SELECT_INFO_INVALID: OTA data partition has invalid contents - */ -esp_err_t esp_ota_write(esp_ota_handle_t handle, const void* data, size_t size); - -/** - * @brief Finish OTA update and validate newly written app image. - * - * @param handle Handle obtained from esp_ota_begin(). - * - * @note After calling esp_ota_end(), the handle is no longer valid and any memory associated with it is freed (regardless of result). - * - * @return - * - ESP_OK: Newly written OTA app image is valid. - * - ESP_ERR_NOT_FOUND: OTA handle was not found. - * - ESP_ERR_INVALID_ARG: Handle was never written to. - * - ESP_ERR_OTA_VALIDATE_FAILED: OTA image is invalid (either not a valid app image, or - if secure boot is enabled - signature failed to verify.) - * - ESP_ERR_INVALID_STATE: If flash encryption is enabled, this result indicates an internal error writing the final encrypted bytes to flash. - */ -esp_err_t esp_ota_end(esp_ota_handle_t handle); - -/** - * @brief Configure OTA data for a new boot partition - * - * @note If this function returns ESP_OK, calling esp_restart() will boot the newly configured app partition. - * - * @param partition Pointer to info for partition containing app image to boot. - * - * @return - * - ESP_OK: OTA data updated, next reboot will use specified partition. - * - ESP_ERR_INVALID_ARG: partition argument was NULL or didn't point to a valid OTA partition of type "app". - * - ESP_ERR_OTA_VALIDATE_FAILED: Partition contained invalid app image. Also returned if secure boot is enabled and signature validation failed. - * - ESP_ERR_NOT_FOUND: OTA data partition not found. - * - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash erase or write failed. - */ -esp_err_t esp_ota_set_boot_partition(const esp_partition_t* partition); - -/** - * @brief Get partition info of currently configured boot app - * - * If esp_ota_set_boot_partition() has been called, the partition which was set by that function will be returned. - * - * If esp_ota_set_boot_partition() has not been called, the result is usually the same as esp_ota_get_running_partition(). - * The two results are not equal if the configured boot partition does not contain a valid app (meaning that the running partition - * will be an app that the bootloader chose via fallback). - * - * If the OTA data partition is not present or not valid then the result is the first app partition found in the - * partition table. In priority order, this means: the factory app, the first OTA app slot, or the test app partition. - * - * Note that there is no guarantee the returned partition is a valid app. Use esp_image_verify(ESP_IMAGE_VERIFY, ...) to verify if the - * returned partition contains a bootable image. - * - * @return Pointer to info for partition structure, or NULL if partition table is invalid or a flash read operation failed. Any returned pointer is valid for the lifetime of the application. - */ -const esp_partition_t* esp_ota_get_boot_partition(void); - - -/** - * @brief Get partition info of currently running app - * - * This function is different to esp_ota_get_boot_partition() in that - * it ignores any change of selected boot partition caused by - * esp_ota_set_boot_partition(). Only the app whose code is currently - * running will have its partition information returned. - * - * The partition returned by this function may also differ from esp_ota_get_boot_partition() if the configured boot - * partition is somehow invalid, and the bootloader fell back to a different app partition at boot. - * - * @return Pointer to info for partition structure, or NULL if no partition is found or flash read operation failed. Returned pointer is valid for the lifetime of the application. - */ -const esp_partition_t* esp_ota_get_running_partition(void); - - -/** - * @brief Return the next OTA app partition which should be written with a new firmware. - * - * Call this function to find an OTA app partition which can be passed to esp_ota_begin(). - * - * Finds next partition round-robin, starting from the current running partition. - * - * @param start_from If set, treat this partition info as describing the current running partition. Can be NULL, in which case esp_ota_get_running_partition() is used to find the currently running partition. The result of this function is never the same as this argument. - * - * @return Pointer to info for partition which should be updated next. NULL result indicates invalid OTA data partition, or that no eligible OTA app slot partition was found. - * - */ -const esp_partition_t* esp_ota_get_next_update_partition(const esp_partition_t *start_from); - -#ifdef __cplusplus -} -#endif - -#endif /* OTA_OPS_H */ diff --git a/tools/sdk/include/asio/asio.hpp b/tools/sdk/include/asio/asio.hpp new file mode 100644 index 00000000..6a58006b --- /dev/null +++ b/tools/sdk/include/asio/asio.hpp @@ -0,0 +1,156 @@ +// +// asio.hpp +// ~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_HPP +#define ASIO_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if defined(ESP_PLATFORM) +# include "esp_asio_config.h" +#endif // defined(ESP_PLATFORM) + +#include "asio/associated_allocator.hpp" +#include "asio/associated_executor.hpp" +#include "asio/async_result.hpp" +#include "asio/basic_datagram_socket.hpp" +#include "asio/basic_deadline_timer.hpp" +#include "asio/basic_io_object.hpp" +#include "asio/basic_raw_socket.hpp" +#include "asio/basic_seq_packet_socket.hpp" +#include "asio/basic_serial_port.hpp" +#include "asio/basic_signal_set.hpp" +#include "asio/basic_socket_acceptor.hpp" +#include "asio/basic_socket_iostream.hpp" +#include "asio/basic_socket_streambuf.hpp" +#include "asio/basic_stream_socket.hpp" +#include "asio/basic_streambuf.hpp" +#include "asio/basic_waitable_timer.hpp" +#include "asio/bind_executor.hpp" +#include "asio/buffer.hpp" +#include "asio/buffered_read_stream_fwd.hpp" +#include "asio/buffered_read_stream.hpp" +#include "asio/buffered_stream_fwd.hpp" +#include "asio/buffered_stream.hpp" +#include "asio/buffered_write_stream_fwd.hpp" +#include "asio/buffered_write_stream.hpp" +#include "asio/buffers_iterator.hpp" +#include "asio/completion_condition.hpp" +#include "asio/connect.hpp" +#include "asio/coroutine.hpp" +#include "asio/datagram_socket_service.hpp" +#include "asio/deadline_timer_service.hpp" +#include "asio/deadline_timer.hpp" +#include "asio/defer.hpp" +#include "asio/dispatch.hpp" +#include "asio/error.hpp" +#include "asio/error_code.hpp" +#include "asio/execution_context.hpp" +#include "asio/executor.hpp" +#include "asio/executor_work_guard.hpp" +#include "asio/generic/basic_endpoint.hpp" +#include "asio/generic/datagram_protocol.hpp" +#include "asio/generic/raw_protocol.hpp" +#include "asio/generic/seq_packet_protocol.hpp" +#include "asio/generic/stream_protocol.hpp" +#include "asio/handler_alloc_hook.hpp" +#include "asio/handler_continuation_hook.hpp" +#include "asio/handler_invoke_hook.hpp" +#include "asio/handler_type.hpp" +#include "asio/high_resolution_timer.hpp" +#include "asio/io_context.hpp" +#include "asio/io_context_strand.hpp" +#include "asio/io_service.hpp" +#include "asio/io_service_strand.hpp" +#include "asio/ip/address.hpp" +#include "asio/ip/address_v4.hpp" +#include "asio/ip/address_v4_iterator.hpp" +#include "asio/ip/address_v4_range.hpp" +#include "asio/ip/address_v6.hpp" +#include "asio/ip/address_v6_iterator.hpp" +#include "asio/ip/address_v6_range.hpp" +#include "asio/ip/bad_address_cast.hpp" +#include "asio/ip/basic_endpoint.hpp" +#include "asio/ip/basic_resolver.hpp" +#include "asio/ip/basic_resolver_entry.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/ip/host_name.hpp" +#include "asio/ip/icmp.hpp" +#include "asio/ip/multicast.hpp" +#include "asio/ip/resolver_base.hpp" +#include "asio/ip/resolver_query_base.hpp" +#include "asio/ip/resolver_service.hpp" +#include "asio/ip/tcp.hpp" +#include "asio/ip/udp.hpp" +#include "asio/ip/unicast.hpp" +#include "asio/ip/v6_only.hpp" +#include "asio/is_executor.hpp" +#include "asio/is_read_buffered.hpp" +#include "asio/is_write_buffered.hpp" +#include "asio/local/basic_endpoint.hpp" +#include "asio/local/connect_pair.hpp" +#include "asio/local/datagram_protocol.hpp" +#include "asio/local/stream_protocol.hpp" +#include "asio/packaged_task.hpp" +#include "asio/placeholders.hpp" +#include "asio/posix/basic_descriptor.hpp" +#include "asio/posix/basic_stream_descriptor.hpp" +#include "asio/posix/descriptor.hpp" +#include "asio/posix/descriptor_base.hpp" +#include "asio/posix/stream_descriptor.hpp" +#include "asio/posix/stream_descriptor_service.hpp" +#include "asio/post.hpp" +#include "asio/raw_socket_service.hpp" +#include "asio/read.hpp" +#include "asio/read_at.hpp" +#include "asio/read_until.hpp" +#include "asio/seq_packet_socket_service.hpp" +#include "asio/serial_port.hpp" +#include "asio/serial_port_base.hpp" +#include "asio/serial_port_service.hpp" +#include "asio/signal_set.hpp" +#include "asio/signal_set_service.hpp" +#include "asio/socket_acceptor_service.hpp" +#include "asio/socket_base.hpp" +#include "asio/steady_timer.hpp" +#include "asio/strand.hpp" +#include "asio/stream_socket_service.hpp" +#include "asio/streambuf.hpp" +#include "asio/system_context.hpp" +#include "asio/system_error.hpp" +#include "asio/system_executor.hpp" +#include "asio/system_timer.hpp" +#include "asio/thread.hpp" +#include "asio/thread_pool.hpp" +#include "asio/time_traits.hpp" +#include "asio/use_future.hpp" +#include "asio/uses_executor.hpp" +#include "asio/version.hpp" +#include "asio/wait_traits.hpp" +#include "asio/waitable_timer_service.hpp" +#include "asio/windows/basic_handle.hpp" +#include "asio/windows/basic_object_handle.hpp" +#include "asio/windows/basic_random_access_handle.hpp" +#include "asio/windows/basic_stream_handle.hpp" +#include "asio/windows/object_handle.hpp" +#include "asio/windows/object_handle_service.hpp" +#include "asio/windows/overlapped_handle.hpp" +#include "asio/windows/overlapped_ptr.hpp" +#include "asio/windows/random_access_handle.hpp" +#include "asio/windows/random_access_handle_service.hpp" +#include "asio/windows/stream_handle.hpp" +#include "asio/windows/stream_handle_service.hpp" +#include "asio/write.hpp" +#include "asio/write_at.hpp" + +#endif // ASIO_HPP diff --git a/tools/sdk/include/asio/asio/associated_allocator.hpp b/tools/sdk/include/asio/asio/associated_allocator.hpp new file mode 100644 index 00000000..8b488bb3 --- /dev/null +++ b/tools/sdk/include/asio/asio/associated_allocator.hpp @@ -0,0 +1,131 @@ +// +// associated_allocator.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_ASSOCIATED_ALLOCATOR_HPP +#define ASIO_ASSOCIATED_ALLOCATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/detail/type_traits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +struct associated_allocator_check +{ + typedef void type; +}; + +template +struct associated_allocator_impl +{ + typedef E type; + + static type get(const T&, const E& e) ASIO_NOEXCEPT + { + return e; + } +}; + +template +struct associated_allocator_impl::type> +{ + typedef typename T::allocator_type type; + + static type get(const T& t, const E&) ASIO_NOEXCEPT + { + return t.get_allocator(); + } +}; + +} // namespace detail + +/// Traits type used to obtain the allocator associated with an object. +/** + * A program may specialise this traits type if the @c T template parameter in + * the specialisation is a user-defined type. The template parameter @c + * Allocator shall be a type meeting the Allocator requirements. + * + * Specialisations shall meet the following requirements, where @c t is a const + * reference to an object of type @c T, and @c a is an object of type @c + * Allocator. + * + * @li Provide a nested typedef @c type that identifies a type meeting the + * Allocator requirements. + * + * @li Provide a noexcept static member function named @c get, callable as @c + * get(t) and with return type @c type. + * + * @li Provide a noexcept static member function named @c get, callable as @c + * get(t,a) and with return type @c type. + */ +template > +struct associated_allocator +{ + /// If @c T has a nested type @c allocator_type, T::allocator_type. + /// Otherwise @c Allocator. +#if defined(GENERATING_DOCUMENTATION) + typedef see_below type; +#else // defined(GENERATING_DOCUMENTATION) + typedef typename detail::associated_allocator_impl::type type; +#endif // defined(GENERATING_DOCUMENTATION) + + /// If @c T has a nested type @c allocator_type, returns + /// t.get_allocator(). Otherwise returns @c a. + static type get(const T& t, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return detail::associated_allocator_impl::get(t, a); + } +}; + +/// Helper function to obtain an object's associated allocator. +/** + * @returns associated_allocator::get(t) + */ +template +inline typename associated_allocator::type +get_associated_allocator(const T& t) ASIO_NOEXCEPT +{ + return associated_allocator::get(t); +} + +/// Helper function to obtain an object's associated allocator. +/** + * @returns associated_allocator::get(t, a) + */ +template +inline typename associated_allocator::type +get_associated_allocator(const T& t, const Allocator& a) ASIO_NOEXCEPT +{ + return associated_allocator::get(t, a); +} + +#if defined(ASIO_HAS_ALIAS_TEMPLATES) + +template > +using associated_allocator_t + = typename associated_allocator::type; + +#endif // defined(ASIO_HAS_ALIAS_TEMPLATES) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_ASSOCIATED_ALLOCATOR_HPP diff --git a/tools/sdk/include/asio/asio/associated_executor.hpp b/tools/sdk/include/asio/asio/associated_executor.hpp new file mode 100644 index 00000000..4c5c2078 --- /dev/null +++ b/tools/sdk/include/asio/asio/associated_executor.hpp @@ -0,0 +1,149 @@ +// +// associated_executor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_ASSOCIATED_EXECUTOR_HPP +#define ASIO_ASSOCIATED_EXECUTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/is_executor.hpp" +#include "asio/system_executor.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +struct associated_executor_check +{ + typedef void type; +}; + +template +struct associated_executor_impl +{ + typedef E type; + + static type get(const T&, const E& e) ASIO_NOEXCEPT + { + return e; + } +}; + +template +struct associated_executor_impl::type> +{ + typedef typename T::executor_type type; + + static type get(const T& t, const E&) ASIO_NOEXCEPT + { + return t.get_executor(); + } +}; + +} // namespace detail + +/// Traits type used to obtain the executor associated with an object. +/** + * A program may specialise this traits type if the @c T template parameter in + * the specialisation is a user-defined type. The template parameter @c + * Executor shall be a type meeting the Executor requirements. + * + * Specialisations shall meet the following requirements, where @c t is a const + * reference to an object of type @c T, and @c e is an object of type @c + * Executor. + * + * @li Provide a nested typedef @c type that identifies a type meeting the + * Executor requirements. + * + * @li Provide a noexcept static member function named @c get, callable as @c + * get(t) and with return type @c type. + * + * @li Provide a noexcept static member function named @c get, callable as @c + * get(t,e) and with return type @c type. + */ +template +struct associated_executor +{ + /// If @c T has a nested type @c executor_type, T::executor_type. + /// Otherwise @c Executor. +#if defined(GENERATING_DOCUMENTATION) + typedef see_below type; +#else // defined(GENERATING_DOCUMENTATION) + typedef typename detail::associated_executor_impl::type type; +#endif // defined(GENERATING_DOCUMENTATION) + + /// If @c T has a nested type @c executor_type, returns + /// t.get_executor(). Otherwise returns @c ex. + static type get(const T& t, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return detail::associated_executor_impl::get(t, ex); + } +}; + +/// Helper function to obtain an object's associated executor. +/** + * @returns associated_executor::get(t) + */ +template +inline typename associated_executor::type +get_associated_executor(const T& t) ASIO_NOEXCEPT +{ + return associated_executor::get(t); +} + +/// Helper function to obtain an object's associated executor. +/** + * @returns associated_executor::get(t, ex) + */ +template +inline typename associated_executor::type +get_associated_executor(const T& t, const Executor& ex, + typename enable_if::value>::type* = 0) ASIO_NOEXCEPT +{ + return associated_executor::get(t, ex); +} + +/// Helper function to obtain an object's associated executor. +/** + * @returns associated_executor::get(t, ctx.get_executor()) + */ +template +inline typename associated_executor::type +get_associated_executor(const T& t, ExecutionContext& ctx, + typename enable_if::value>::type* = 0) ASIO_NOEXCEPT +{ + return associated_executor::get(t, ctx.get_executor()); +} + +#if defined(ASIO_HAS_ALIAS_TEMPLATES) + +template +using associated_executor_t = typename associated_executor::type; + +#endif // defined(ASIO_HAS_ALIAS_TEMPLATES) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_ASSOCIATED_EXECUTOR_HPP diff --git a/tools/sdk/include/asio/asio/async_result.hpp b/tools/sdk/include/asio/asio/async_result.hpp new file mode 100644 index 00000000..18acdf20 --- /dev/null +++ b/tools/sdk/include/asio/asio/async_result.hpp @@ -0,0 +1,221 @@ +// +// async_result.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_ASYNC_RESULT_HPP +#define ASIO_ASYNC_RESULT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/handler_type.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// An interface for customising the behaviour of an initiating function. +/** + * The async_result traits class is used for determining: + * + * @li the concrete completion handler type to be called at the end of the + * asynchronous operation; + * + * @li the initiating function return type; and + * + * @li how the return value of the initiating function is obtained. + * + * The trait allows the handler and return types to be determined at the point + * where the specific completion handler signature is known. + * + * This template may be specialised for user-defined completion token types. + * The primary template assumes that the CompletionToken is the completion + * handler. + */ +#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) +template +#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) +template +#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) +class async_result +{ +public: +#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) + /// The concrete completion handler type for the specific signature. + typedef CompletionToken completion_handler_type; + + /// The return type of the initiating function. + typedef void return_type; +#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) + // For backward compatibility, determine the concrete completion handler type + // by using the legacy handler_type trait. + typedef typename handler_type::type + completion_handler_type; + + // For backward compatibility, determine the initiating function return type + // using the legacy single-parameter version of async_result. + typedef typename async_result::type return_type; +#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) + + /// Construct an async result from a given handler. + /** + * When using a specalised async_result, the constructor has an opportunity + * to initialise some state associated with the completion handler, which is + * then returned from the initiating function. + */ + explicit async_result(completion_handler_type& h) +#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) + // No data members to initialise. +#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) + : legacy_result_(h) +#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) + { + (void)h; + } + + /// Obtain the value to be returned from the initiating function. + return_type get() + { +#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) + // Nothing to do. +#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) + return legacy_result_.get(); +#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) + } + +private: + async_result(const async_result&) ASIO_DELETED; + async_result& operator=(const async_result&) ASIO_DELETED; + +#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) + // No data members. +#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) + async_result legacy_result_; +#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) +}; + +#if !defined(ASIO_NO_DEPRECATED) + +/// (Deprecated: Use two-parameter version of async_result.) An interface for +/// customising the behaviour of an initiating function. +/** + * This template may be specialised for user-defined handler types. + */ +template +class async_result +{ +public: + /// The return type of the initiating function. + typedef void type; + + /// Construct an async result from a given handler. + /** + * When using a specalised async_result, the constructor has an opportunity + * to initialise some state associated with the handler, which is then + * returned from the initiating function. + */ + explicit async_result(Handler&) + { + } + + /// Obtain the value to be returned from the initiating function. + type get() + { + } +}; + +#endif // !defined(ASIO_NO_DEPRECATED) + +/// Helper template to deduce the handler type from a CompletionToken, capture +/// a local copy of the handler, and then create an async_result for the +/// handler. +template +struct async_completion +{ + /// The real handler type to be used for the asynchronous operation. + typedef typename asio::async_result< + typename decay::type, + Signature>::completion_handler_type completion_handler_type; + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Constructor. + /** + * The constructor creates the concrete completion handler and makes the link + * between the handler and the asynchronous result. + */ + explicit async_completion(CompletionToken& token) + : completion_handler(static_cast::value, + completion_handler_type&, CompletionToken&&>::type>(token)), + result(completion_handler) + { + } +#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + explicit async_completion(typename decay::type& token) + : completion_handler(token), + result(completion_handler) + { + } + + explicit async_completion(const typename decay::type& token) + : completion_handler(token), + result(completion_handler) + { + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// A copy of, or reference to, a real handler object. +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + typename conditional< + is_same::value, + completion_handler_type&, completion_handler_type>::type completion_handler; +#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + completion_handler_type completion_handler; +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// The result of the asynchronous operation's initiating function. + async_result::type, Signature> result; +}; + +namespace detail { + +template +struct async_result_helper + : async_result::type, Signature> +{ +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(GENERATING_DOCUMENTATION) +# define ASIO_INITFN_RESULT_TYPE(ct, sig) \ + void_or_deduced +#elif defined(_MSC_VER) && (_MSC_VER < 1500) +# define ASIO_INITFN_RESULT_TYPE(ct, sig) \ + typename ::asio::detail::async_result_helper< \ + ct, sig>::return_type +#define ASIO_HANDLER_TYPE(ct, sig) \ + typename ::asio::detail::async_result_helper< \ + ct, sig>::completion_handler_type +#else +# define ASIO_INITFN_RESULT_TYPE(ct, sig) \ + typename ::asio::async_result< \ + typename ::asio::decay::type, sig>::return_type +#define ASIO_HANDLER_TYPE(ct, sig) \ + typename ::asio::async_result< \ + typename ::asio::decay::type, sig>::completion_handler_type +#endif + +#endif // ASIO_ASYNC_RESULT_HPP diff --git a/tools/sdk/include/asio/asio/basic_datagram_socket.hpp b/tools/sdk/include/asio/asio/basic_datagram_socket.hpp new file mode 100644 index 00000000..346cc353 --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_datagram_socket.hpp @@ -0,0 +1,1040 @@ +// +// basic_datagram_socket.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BASIC_DATAGRAM_SOCKET_HPP +#define ASIO_BASIC_DATAGRAM_SOCKET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/basic_socket.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/datagram_socket_service.hpp" +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +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 + : public basic_socket +{ +public: + /// The native representation of a socket. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef typename basic_socket< + Protocol 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(asio::io_context& io_context) + : basic_socket(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 asio::system_error Thrown on failure. + */ + basic_datagram_socket(asio::io_context& io_context, + const protocol_type& protocol) + : basic_socket(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 asio::system_error Thrown on failure. + */ + basic_datagram_socket(asio::io_context& io_context, + const endpoint_type& endpoint) + : basic_socket(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 asio::system_error Thrown on failure. + */ + basic_datagram_socket(asio::io_context& io_context, + const protocol_type& protocol, const native_handle_type& native_socket) + : basic_socket( + io_context, protocol, native_socket) + { + } + +#if defined(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(basic_datagram_socket&& other) + : basic_socket(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& operator=(basic_datagram_socket&& other) + { + basic_socket::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( + basic_datagram_socket&& other, + typename enable_if::value>::type* = 0) + : basic_socket(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>::type& operator=( + basic_datagram_socket&& other) + { + basic_socket::operator=(std::move(other)); + return *this; + } +#endif // defined(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() + { + } + + /// 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 asio::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(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) + { + asio::error_code ec; + std::size_t s = this->get_service().send( + this->get_implementation(), buffers, 0, ec); + 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 asio::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) + { + asio::error_code ec; + std::size_t s = this->get_service().send( + this->get_implementation(), buffers, flags, ec); + 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, asio::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 asio::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 + * 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(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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send(const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_send(this->get_implementation(), + buffers, 0, ASIO_MOVE_CAST(WriteHandler)(handler)); +#else // defined(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(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 asio::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 + * 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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_send(this->get_implementation(), + buffers, flags, ASIO_MOVE_CAST(WriteHandler)(handler)); +#else // defined(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(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 asio::system_error Thrown on failure. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * asio::ip::udp::endpoint destination( + * asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.send_to(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) + { + asio::error_code ec; + std::size_t s = this->get_service().send_to( + this->get_implementation(), buffers, destination, 0, ec); + 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 asio::system_error Thrown on failure. + */ + template + std::size_t send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->get_service().send_to( + this->get_implementation(), buffers, destination, flags, ec); + 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, + asio::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 asio::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 + * asio::io_context::post(). + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * asio::ip::udp::endpoint destination( + * asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.async_send_to( + * 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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_send_to( + this->get_implementation(), buffers, destination, 0, + ASIO_MOVE_CAST(WriteHandler)(handler)); +#else // defined(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(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 asio::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 + * asio::io_context::post(). + */ + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_send_to( + this->get_implementation(), buffers, destination, flags, + ASIO_MOVE_CAST(WriteHandler)(handler)); +#else // defined(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(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 asio::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(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) + { + asio::error_code ec; + std::size_t s = this->get_service().receive( + this->get_implementation(), buffers, 0, ec); + 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 asio::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) + { + asio::error_code ec; + std::size_t s = this->get_service().receive( + this->get_implementation(), buffers, flags, ec); + 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, asio::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 asio::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 + * 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(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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive(const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_receive(this->get_implementation(), + buffers, 0, ASIO_MOVE_CAST(ReadHandler)(handler)); +#else // defined(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(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 asio::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 + * 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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_receive(this->get_implementation(), + buffers, flags, ASIO_MOVE_CAST(ReadHandler)(handler)); +#else // defined(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(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 asio::system_error Thrown on failure. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * asio::ip::udp::endpoint sender_endpoint; + * socket.receive_from( + * 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) + { + asio::error_code ec; + std::size_t s = this->get_service().receive_from( + this->get_implementation(), buffers, sender_endpoint, 0, ec); + 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 asio::system_error Thrown on failure. + */ + template + std::size_t receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->get_service().receive_from( + this->get_implementation(), buffers, sender_endpoint, flags, ec); + 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, + asio::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 asio::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 + * 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( + * 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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_receive_from( + this->get_implementation(), buffers, sender_endpoint, 0, + ASIO_MOVE_CAST(ReadHandler)(handler)); +#else // defined(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(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 asio::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 + * asio::io_context::post(). + */ + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_receive_from( + this->get_implementation(), buffers, sender_endpoint, flags, + ASIO_MOVE_CAST(ReadHandler)(handler)); +#else // defined(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(ASIO_ENABLE_OLD_SERVICES) + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_DATAGRAM_SOCKET_HPP diff --git a/tools/sdk/include/asio/asio/basic_deadline_timer.hpp b/tools/sdk/include/asio/asio/basic_deadline_timer.hpp new file mode 100644 index 00000000..5b20066d --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_deadline_timer.hpp @@ -0,0 +1,628 @@ +// +// basic_deadline_timer.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BASIC_DEADLINE_TIMER_HPP +#define ASIO_BASIC_DEADLINE_TIMER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_BOOST_DATE_TIME) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/basic_io_object.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/time_traits.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/deadline_timer_service.hpp" +#else // defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/detail/deadline_timer_service.hpp" +# define ASIO_SVC_T detail::deadline_timer_service +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Provides waitable timer functionality. +/** + * The basic_deadline_timer class template provides the ability to perform a + * blocking or asynchronous wait for a timer to expire. + * + * A deadline timer is always in one of two states: "expired" or "not expired". + * If the wait() or async_wait() function is called on an expired timer, the + * wait operation will complete immediately. + * + * Most applications will use the asio::deadline_timer typedef. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Examples + * Performing a blocking wait: + * @code + * // Construct a timer without setting an expiry time. + * asio::deadline_timer timer(io_context); + * + * // Set an expiry time relative to now. + * timer.expires_from_now(boost::posix_time::seconds(5)); + * + * // Wait for the timer to expire. + * timer.wait(); + * @endcode + * + * @par + * Performing an asynchronous wait: + * @code + * void handler(const asio::error_code& error) + * { + * if (!error) + * { + * // Timer expired. + * } + * } + * + * ... + * + * // Construct a timer with an absolute expiry time. + * asio::deadline_timer timer(io_context, + * boost::posix_time::time_from_string("2005-12-07 23:59:59.000")); + * + * // Start an asynchronous wait. + * timer.async_wait(handler); + * @endcode + * + * @par Changing an active deadline_timer's expiry time + * + * Changing the expiry time of a timer while there are pending asynchronous + * waits causes those wait operations to be cancelled. To ensure that the action + * associated with the timer is performed only once, use something like this: + * used: + * + * @code + * void on_some_event() + * { + * if (my_timer.expires_from_now(seconds(5)) > 0) + * { + * // We managed to cancel the timer. Start new asynchronous wait. + * my_timer.async_wait(on_timeout); + * } + * else + * { + * // Too late, timer has already expired! + * } + * } + * + * void on_timeout(const asio::error_code& e) + * { + * if (e != asio::error::operation_aborted) + * { + * // Timer was not cancelled, take necessary action. + * } + * } + * @endcode + * + * @li The asio::basic_deadline_timer::expires_from_now() function + * cancels any pending asynchronous waits, and returns the number of + * asynchronous waits that were cancelled. If it returns 0 then you were too + * late and the wait handler has already been executed, or will soon be + * executed. If it returns 1 then the wait handler was successfully cancelled. + * + * @li If a wait handler is cancelled, the asio::error_code passed to + * it contains the value asio::error::operation_aborted. + */ +template + ASIO_SVC_TPARAM_DEF2(= deadline_timer_service)> +class basic_deadline_timer + : ASIO_SVC_ACCESS basic_io_object +{ +public: + /// The type of the executor associated with the object. + typedef io_context::executor_type executor_type; + + /// The time traits type. + typedef TimeTraits traits_type; + + /// The time type. + typedef typename traits_type::time_type time_type; + + /// The duration type. + typedef typename traits_type::duration_type duration_type; + + /// Constructor. + /** + * This constructor creates a timer without setting an expiry time. The + * expires_at() or expires_from_now() functions must be called to set an + * expiry time before the timer can be waited on. + * + * @param io_context The io_context object that the timer will use to dispatch + * handlers for any asynchronous operations performed on the timer. + */ + explicit basic_deadline_timer(asio::io_context& io_context) + : basic_io_object(io_context) + { + } + + /// Constructor to set a particular expiry time as an absolute time. + /** + * This constructor creates a timer and sets the expiry time. + * + * @param io_context The io_context object that the timer will use to dispatch + * handlers for any asynchronous operations performed on the timer. + * + * @param expiry_time The expiry time to be used for the timer, expressed + * as an absolute time. + */ + basic_deadline_timer(asio::io_context& io_context, + const time_type& expiry_time) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().expires_at(this->get_implementation(), expiry_time, ec); + asio::detail::throw_error(ec, "expires_at"); + } + + /// Constructor to set a particular expiry time relative to now. + /** + * This constructor creates a timer and sets the expiry time. + * + * @param io_context The io_context object that the timer will use to dispatch + * handlers for any asynchronous operations performed on the timer. + * + * @param expiry_time The expiry time to be used for the timer, relative to + * now. + */ + basic_deadline_timer(asio::io_context& io_context, + const duration_type& expiry_time) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().expires_from_now( + this->get_implementation(), expiry_time, ec); + asio::detail::throw_error(ec, "expires_from_now"); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_deadline_timer from another. + /** + * This constructor moves a timer from one object to another. + * + * @param other The other basic_deadline_timer 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_deadline_timer(io_context&) constructor. + */ + basic_deadline_timer(basic_deadline_timer&& other) + : basic_io_object(std::move(other)) + { + } + + /// Move-assign a basic_deadline_timer from another. + /** + * This assignment operator moves a timer from one object to another. Cancels + * any outstanding asynchronous operations associated with the target object. + * + * @param other The other basic_deadline_timer 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_deadline_timer(io_context&) constructor. + */ + basic_deadline_timer& operator=(basic_deadline_timer&& other) + { + basic_io_object::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroys the timer. + /** + * This function destroys the timer, cancelling any outstanding asynchronous + * wait operations associated with the timer as if by calling @c cancel. + */ + ~basic_deadline_timer() + { + } + +#if defined(ASIO_ENABLE_OLD_SERVICES) + // These functions are provided by basic_io_object<>. +#else // defined(ASIO_ENABLE_OLD_SERVICES) +#if !defined(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. + */ + 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. + */ + asio::io_context& get_io_service() + { + return basic_io_object::get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return basic_io_object::get_executor(); + } +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + + /// Cancel any asynchronous operations that are waiting on the timer. + /** + * This function forces the completion of any pending asynchronous wait + * operations against the timer. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * Cancelling the timer does not change the expiry time. + * + * @return The number of asynchronous operations that were cancelled. + * + * @throws asio::system_error Thrown on failure. + * + * @note If the timer has already expired when cancel() is called, then the + * handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t cancel() + { + asio::error_code ec; + std::size_t s = this->get_service().cancel(this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel"); + return s; + } + + /// Cancel any asynchronous operations that are waiting on the timer. + /** + * This function forces the completion of any pending asynchronous wait + * operations against the timer. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * Cancelling the timer does not change the expiry time. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of asynchronous operations that were cancelled. + * + * @note If the timer has already expired when cancel() is called, then the + * handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t cancel(asio::error_code& ec) + { + return this->get_service().cancel(this->get_implementation(), ec); + } + + /// Cancels one asynchronous operation that is waiting on the timer. + /** + * This function forces the completion of one pending asynchronous wait + * operation against the timer. Handlers are cancelled in FIFO order. The + * handler for the cancelled operation will be invoked with the + * asio::error::operation_aborted error code. + * + * Cancelling the timer does not change the expiry time. + * + * @return The number of asynchronous operations that were cancelled. That is, + * either 0 or 1. + * + * @throws asio::system_error Thrown on failure. + * + * @note If the timer has already expired when cancel_one() is called, then + * the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t cancel_one() + { + asio::error_code ec; + std::size_t s = this->get_service().cancel_one( + this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel_one"); + return s; + } + + /// Cancels one asynchronous operation that is waiting on the timer. + /** + * This function forces the completion of one pending asynchronous wait + * operation against the timer. Handlers are cancelled in FIFO order. The + * handler for the cancelled operation will be invoked with the + * asio::error::operation_aborted error code. + * + * Cancelling the timer does not change the expiry time. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of asynchronous operations that were cancelled. That is, + * either 0 or 1. + * + * @note If the timer has already expired when cancel_one() is called, then + * the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t cancel_one(asio::error_code& ec) + { + return this->get_service().cancel_one(this->get_implementation(), ec); + } + + /// Get the timer's expiry time as an absolute time. + /** + * This function may be used to obtain the timer's current expiry time. + * Whether the timer has expired or not does not affect this value. + */ + time_type expires_at() const + { + return this->get_service().expires_at(this->get_implementation()); + } + + /// Set the timer's expiry time as an absolute time. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @return The number of asynchronous operations that were cancelled. + * + * @throws asio::system_error Thrown on failure. + * + * @note If the timer has already expired when expires_at() is called, then + * the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t expires_at(const time_type& expiry_time) + { + asio::error_code ec; + std::size_t s = this->get_service().expires_at( + this->get_implementation(), expiry_time, ec); + asio::detail::throw_error(ec, "expires_at"); + return s; + } + + /// Set the timer's expiry time as an absolute time. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of asynchronous operations that were cancelled. + * + * @note If the timer has already expired when expires_at() is called, then + * the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t expires_at(const time_type& expiry_time, + asio::error_code& ec) + { + return this->get_service().expires_at( + this->get_implementation(), expiry_time, ec); + } + + /// Get the timer's expiry time relative to now. + /** + * This function may be used to obtain the timer's current expiry time. + * Whether the timer has expired or not does not affect this value. + */ + duration_type expires_from_now() const + { + return this->get_service().expires_from_now(this->get_implementation()); + } + + /// Set the timer's expiry time relative to now. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @return The number of asynchronous operations that were cancelled. + * + * @throws asio::system_error Thrown on failure. + * + * @note If the timer has already expired when expires_from_now() is called, + * then the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t expires_from_now(const duration_type& expiry_time) + { + asio::error_code ec; + std::size_t s = this->get_service().expires_from_now( + this->get_implementation(), expiry_time, ec); + asio::detail::throw_error(ec, "expires_from_now"); + return s; + } + + /// Set the timer's expiry time relative to now. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of asynchronous operations that were cancelled. + * + * @note If the timer has already expired when expires_from_now() is called, + * then the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t expires_from_now(const duration_type& expiry_time, + asio::error_code& ec) + { + return this->get_service().expires_from_now( + this->get_implementation(), expiry_time, ec); + } + + /// Perform a blocking wait on the timer. + /** + * This function is used to wait for the timer to expire. This function + * blocks and does not return until the timer has expired. + * + * @throws asio::system_error Thrown on failure. + */ + void wait() + { + asio::error_code ec; + this->get_service().wait(this->get_implementation(), ec); + asio::detail::throw_error(ec, "wait"); + } + + /// Perform a blocking wait on the timer. + /** + * This function is used to wait for the timer to expire. This function + * blocks and does not return until the timer has expired. + * + * @param ec Set to indicate what error occurred, if any. + */ + void wait(asio::error_code& ec) + { + this->get_service().wait(this->get_implementation(), ec); + } + + /// Start an asynchronous wait on the timer. + /** + * This function may be used to initiate an asynchronous wait against the + * timer. It always returns immediately. + * + * For each call to async_wait(), the supplied handler will be called exactly + * once. The handler will be called when: + * + * @li The timer has expired. + * + * @li The timer was cancelled, in which case the handler is passed the error + * code asio::error::operation_aborted. + * + * @param handler The handler to be called when the timer expires. Copies + * will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const asio::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 + * asio::io_context::post(). + */ + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(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. + ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_wait(this->get_implementation(), + ASIO_MOVE_CAST(WaitHandler)(handler)); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + async_completion init(handler); + + this->get_service().async_wait(this->get_implementation(), + init.completion_handler); + + return init.result.get(); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if !defined(ASIO_ENABLE_OLD_SERVICES) +# undef ASIO_SVC_T +#endif // !defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_BASIC_DEADLINE_TIMER_HPP diff --git a/tools/sdk/include/asio/asio/basic_io_object.hpp b/tools/sdk/include/asio/asio/basic_io_object.hpp new file mode 100644 index 00000000..442e8542 --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_io_object.hpp @@ -0,0 +1,290 @@ +// +// basic_io_object.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BASIC_IO_OBJECT_HPP +#define ASIO_BASIC_IO_OBJECT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +#if defined(ASIO_HAS_MOVE) +namespace detail +{ + // Type trait used to determine whether a service supports move. + template + class service_has_move + { + private: + typedef IoObjectService service_type; + typedef typename service_type::implementation_type implementation_type; + + template + static auto asio_service_has_move_eval(T* t, U* u) + -> decltype(t->move_construct(*u, *u), char()); + static char (&asio_service_has_move_eval(...))[2]; + + public: + static const bool value = + sizeof(asio_service_has_move_eval( + static_cast(0), + static_cast(0))) == 1; + }; +} +#endif // defined(ASIO_HAS_MOVE) + +/// Base class for all I/O objects. +/** + * @note All I/O objects are non-copyable. However, when using C++0x, certain + * I/O objects do support move construction and move assignment. + */ +#if !defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) +template +#else +template ::value> +#endif +class basic_io_object +{ +public: + /// The type of the service that will be used to provide I/O operations. + typedef IoObjectService service_type; + + /// The underlying implementation type of I/O object. + typedef typename service_type::implementation_type implementation_type; + +#if !defined(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. + */ + asio::io_context& get_io_context() + { + return service_.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. + */ + asio::io_context& get_io_service() + { + return service_.get_io_context(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// The type of the executor associated with the object. + typedef asio::io_context::executor_type executor_type; + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return service_.get_io_context().get_executor(); + } + +protected: + /// Construct a basic_io_object. + /** + * Performs: + * @code get_service().construct(get_implementation()); @endcode + */ + explicit basic_io_object(asio::io_context& io_context) + : service_(asio::use_service(io_context)) + { + service_.construct(implementation_); + } + +#if defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_io_object. + /** + * Performs: + * @code get_service().move_construct( + * get_implementation(), other.get_implementation()); @endcode + * + * @note Available only for services that support movability, + */ + basic_io_object(basic_io_object&& other); + + /// Move-assign a basic_io_object. + /** + * Performs: + * @code get_service().move_assign(get_implementation(), + * other.get_service(), other.get_implementation()); @endcode + * + * @note Available only for services that support movability, + */ + basic_io_object& operator=(basic_io_object&& other); + + /// Perform a converting move-construction of a basic_io_object. + template + basic_io_object(IoObjectService1& other_service, + typename IoObjectService1::implementation_type& other_implementation); +#endif // defined(GENERATING_DOCUMENTATION) + + /// Protected destructor to prevent deletion through this type. + /** + * Performs: + * @code get_service().destroy(get_implementation()); @endcode + */ + ~basic_io_object() + { + service_.destroy(implementation_); + } + + /// Get the service associated with the I/O object. + service_type& get_service() + { + return service_; + } + + /// Get the service associated with the I/O object. + const service_type& get_service() const + { + return service_; + } + + /// Get the underlying implementation of the I/O object. + implementation_type& get_implementation() + { + return implementation_; + } + + /// Get the underlying implementation of the I/O object. + const implementation_type& get_implementation() const + { + return implementation_; + } + +private: + basic_io_object(const basic_io_object&); + basic_io_object& operator=(const basic_io_object&); + + // The service associated with the I/O object. + service_type& service_; + + /// The underlying implementation of the I/O object. + implementation_type implementation_; +}; + +#if defined(ASIO_HAS_MOVE) +// Specialisation for movable objects. +template +class basic_io_object +{ +public: + typedef IoObjectService service_type; + typedef typename service_type::implementation_type implementation_type; + +#if !defined(ASIO_NO_DEPRECATED) + asio::io_context& get_io_context() + { + return service_->get_io_context(); + } + + asio::io_context& get_io_service() + { + return service_->get_io_context(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + typedef asio::io_context::executor_type executor_type; + + executor_type get_executor() ASIO_NOEXCEPT + { + return service_->get_io_context().get_executor(); + } + +protected: + explicit basic_io_object(asio::io_context& io_context) + : service_(&asio::use_service(io_context)) + { + service_->construct(implementation_); + } + + basic_io_object(basic_io_object&& other) + : service_(&other.get_service()) + { + service_->move_construct(implementation_, other.implementation_); + } + + template + basic_io_object(IoObjectService1& other_service, + typename IoObjectService1::implementation_type& other_implementation) + : service_(&asio::use_service( + other_service.get_io_context())) + { + service_->converting_move_construct(implementation_, + other_service, other_implementation); + } + + ~basic_io_object() + { + service_->destroy(implementation_); + } + + basic_io_object& operator=(basic_io_object&& other) + { + service_->move_assign(implementation_, + *other.service_, other.implementation_); + service_ = other.service_; + return *this; + } + + service_type& get_service() + { + return *service_; + } + + const service_type& get_service() const + { + return *service_; + } + + implementation_type& get_implementation() + { + return implementation_; + } + + const implementation_type& get_implementation() const + { + return implementation_; + } + +private: + basic_io_object(const basic_io_object&); + void operator=(const basic_io_object&); + + IoObjectService* service_; + implementation_type implementation_; +}; +#endif // defined(ASIO_HAS_MOVE) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_IO_OBJECT_HPP diff --git a/tools/sdk/include/asio/asio/basic_raw_socket.hpp b/tools/sdk/include/asio/asio/basic_raw_socket.hpp new file mode 100644 index 00000000..0de7c776 --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_raw_socket.hpp @@ -0,0 +1,1030 @@ +// +// basic_raw_socket.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BASIC_RAW_SOCKET_HPP +#define ASIO_BASIC_RAW_SOCKET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/basic_socket.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/raw_socket_service.hpp" +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Provides raw-oriented socket functionality. +/** + * The basic_raw_socket class template provides asynchronous and blocking + * raw-oriented socket functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template )> +class basic_raw_socket + : public basic_socket +{ +public: + /// The native representation of a socket. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef typename basic_socket< + Protocol 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_raw_socket without opening it. + /** + * This constructor creates a raw 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 raw socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + */ + explicit basic_raw_socket(asio::io_context& io_context) + : basic_socket(io_context) + { + } + + /// Construct and open a basic_raw_socket. + /** + * This constructor creates and opens a raw socket. + * + * @param io_context The io_context object that the raw 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 asio::system_error Thrown on failure. + */ + basic_raw_socket(asio::io_context& io_context, + const protocol_type& protocol) + : basic_socket(io_context, protocol) + { + } + + /// Construct a basic_raw_socket, opening it and binding it to the given + /// local endpoint. + /** + * This constructor creates a raw 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 raw 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 raw + * socket will be bound. + * + * @throws asio::system_error Thrown on failure. + */ + basic_raw_socket(asio::io_context& io_context, + const endpoint_type& endpoint) + : basic_socket(io_context, endpoint) + { + } + + /// Construct a basic_raw_socket on an existing native socket. + /** + * This constructor creates a raw socket object to hold an existing + * native socket. + * + * @param io_context The io_context object that the raw 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 asio::system_error Thrown on failure. + */ + basic_raw_socket(asio::io_context& io_context, + const protocol_type& protocol, const native_handle_type& native_socket) + : basic_socket( + io_context, protocol, native_socket) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_raw_socket from another. + /** + * This constructor moves a raw socket from one object to another. + * + * @param other The other basic_raw_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_raw_socket(io_context&) constructor. + */ + basic_raw_socket(basic_raw_socket&& other) + : basic_socket(std::move(other)) + { + } + + /// Move-assign a basic_raw_socket from another. + /** + * This assignment operator moves a raw socket from one object to another. + * + * @param other The other basic_raw_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_raw_socket(io_context&) constructor. + */ + basic_raw_socket& operator=(basic_raw_socket&& other) + { + basic_socket::operator=(std::move(other)); + return *this; + } + + /// Move-construct a basic_raw_socket from a socket of another protocol type. + /** + * This constructor moves a raw socket from one object to another. + * + * @param other The other basic_raw_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_raw_socket(io_context&) constructor. + */ + template + basic_raw_socket(basic_raw_socket&& other, + typename enable_if::value>::type* = 0) + : basic_socket(std::move(other)) + { + } + + /// Move-assign a basic_raw_socket from a socket of another protocol type. + /** + * This assignment operator moves a raw socket from one object to another. + * + * @param other The other basic_raw_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_raw_socket(io_context&) constructor. + */ + template + typename enable_if::value, + basic_raw_socket>::type& operator=( + basic_raw_socket&& other) + { + basic_socket::operator=(std::move(other)); + return *this; + } +#endif // defined(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_raw_socket() + { + } + + /// Send some data on a connected socket. + /** + * This function is used to send data on the raw 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 asio::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 raw socket. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code socket.send(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) + { + asio::error_code ec; + std::size_t s = this->get_service().send( + this->get_implementation(), buffers, 0, ec); + asio::detail::throw_error(ec, "send"); + return s; + } + + /// Send some data on a connected socket. + /** + * This function is used to send data on the raw 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 asio::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 raw socket. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->get_service().send( + this->get_implementation(), buffers, flags, ec); + asio::detail::throw_error(ec, "send"); + return s; + } + + /// Send some data on a connected socket. + /** + * This function is used to send data on the raw 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 raw socket. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, asio::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 send data on the raw 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. 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 asio::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 + * 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 raw + * socket. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_send(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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send(const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_send(this->get_implementation(), + buffers, 0, ASIO_MOVE_CAST(WriteHandler)(handler)); +#else // defined(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(ASIO_ENABLE_OLD_SERVICES) + } + + /// Start an asynchronous send on a connected socket. + /** + * This function is used to send data on the raw 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. 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 asio::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 + * 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 raw + * socket. + */ + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_send(this->get_implementation(), + buffers, flags, ASIO_MOVE_CAST(WriteHandler)(handler)); +#else // defined(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(ASIO_ENABLE_OLD_SERVICES) + } + + /// Send raw data to the specified endpoint. + /** + * This function is used to send raw data 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 asio::system_error Thrown on failure. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * asio::ip::udp::endpoint destination( + * asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.send_to(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) + { + asio::error_code ec; + std::size_t s = this->get_service().send_to( + this->get_implementation(), buffers, destination, 0, ec); + asio::detail::throw_error(ec, "send_to"); + return s; + } + + /// Send raw data to the specified endpoint. + /** + * This function is used to send raw data 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 asio::system_error Thrown on failure. + */ + template + std::size_t send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->get_service().send_to( + this->get_implementation(), buffers, destination, flags, ec); + asio::detail::throw_error(ec, "send_to"); + return s; + } + + /// Send raw data to the specified endpoint. + /** + * This function is used to send raw data 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, + asio::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 raw data 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 asio::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 + * asio::io_context::post(). + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * asio::ip::udp::endpoint destination( + * asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.async_send_to( + * 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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_send_to(this->get_implementation(), + buffers, destination, 0, ASIO_MOVE_CAST(WriteHandler)(handler)); +#else // defined(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(ASIO_ENABLE_OLD_SERVICES) + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send raw data 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 asio::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 + * asio::io_context::post(). + */ + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_send_to( + this->get_implementation(), buffers, destination, flags, + ASIO_MOVE_CAST(WriteHandler)(handler)); +#else // defined(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(ASIO_ENABLE_OLD_SERVICES) + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the raw 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 asio::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 raw + * socket. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code socket.receive(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) + { + asio::error_code ec; + std::size_t s = this->get_service().receive( + this->get_implementation(), buffers, 0, ec); + asio::detail::throw_error(ec, "receive"); + return s; + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the raw 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 asio::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 raw + * socket. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->get_service().receive( + this->get_implementation(), buffers, flags, ec); + asio::detail::throw_error(ec, "receive"); + return s; + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the raw 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 raw + * socket. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, asio::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 raw + * 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 asio::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 + * 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 + * raw socket. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.async_receive(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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive(const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_receive(this->get_implementation(), + buffers, 0, ASIO_MOVE_CAST(ReadHandler)(handler)); +#else // defined(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(ASIO_ENABLE_OLD_SERVICES) + } + + /// Start an asynchronous receive on a connected socket. + /** + * This function is used to asynchronously receive data from the raw + * 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 asio::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 + * 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 + * raw socket. + */ + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_receive(this->get_implementation(), + buffers, flags, ASIO_MOVE_CAST(ReadHandler)(handler)); +#else // defined(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(ASIO_ENABLE_OLD_SERVICES) + } + + /// Receive raw data with the endpoint of the sender. + /** + * This function is used to receive raw data. 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 data. + * + * @returns The number of bytes received. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * asio::ip::udp::endpoint sender_endpoint; + * socket.receive_from( + * 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) + { + asio::error_code ec; + std::size_t s = this->get_service().receive_from( + this->get_implementation(), buffers, sender_endpoint, 0, ec); + asio::detail::throw_error(ec, "receive_from"); + return s; + } + + /// Receive raw data with the endpoint of the sender. + /** + * This function is used to receive raw data. 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 data. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @returns The number of bytes received. + * + * @throws asio::system_error Thrown on failure. + */ + template + std::size_t receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->get_service().receive_from( + this->get_implementation(), buffers, sender_endpoint, flags, ec); + asio::detail::throw_error(ec, "receive_from"); + return s; + } + + /// Receive raw data with the endpoint of the sender. + /** + * This function is used to receive raw data. 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 data. + * + * @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, + asio::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 raw data. 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 data. 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 asio::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 + * 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( + * asio::buffer(data, size), 0, 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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_receive_from( + this->get_implementation(), buffers, sender_endpoint, 0, + ASIO_MOVE_CAST(ReadHandler)(handler)); +#else // defined(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(ASIO_ENABLE_OLD_SERVICES) + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive raw data. 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 data. 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 asio::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 + * asio::io_context::post(). + */ + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_receive_from( + this->get_implementation(), buffers, sender_endpoint, flags, + ASIO_MOVE_CAST(ReadHandler)(handler)); +#else // defined(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(ASIO_ENABLE_OLD_SERVICES) + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_RAW_SOCKET_HPP diff --git a/tools/sdk/include/asio/asio/basic_seq_packet_socket.hpp b/tools/sdk/include/asio/asio/basic_seq_packet_socket.hpp new file mode 100644 index 00000000..3655d881 --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_seq_packet_socket.hpp @@ -0,0 +1,618 @@ +// +// basic_seq_packet_socket.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BASIC_SEQ_PACKET_SOCKET_HPP +#define ASIO_BASIC_SEQ_PACKET_SOCKET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/basic_socket.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/seq_packet_socket_service.hpp" +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Provides sequenced packet socket functionality. +/** + * The basic_seq_packet_socket class template provides asynchronous and blocking + * sequenced packet socket functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template )> +class basic_seq_packet_socket + : public basic_socket +{ +public: + /// The native representation of a socket. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef typename basic_socket< + Protocol 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_seq_packet_socket without opening it. + /** + * This constructor creates a sequenced packet 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 sequenced packet socket + * will use to dispatch handlers for any asynchronous operations performed on + * the socket. + */ + explicit basic_seq_packet_socket(asio::io_context& io_context) + : basic_socket(io_context) + { + } + + /// Construct and open a basic_seq_packet_socket. + /** + * This constructor creates and opens a sequenced_packet 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 sequenced packet 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 asio::system_error Thrown on failure. + */ + basic_seq_packet_socket(asio::io_context& io_context, + const protocol_type& protocol) + : basic_socket(io_context, protocol) + { + } + + /// Construct a basic_seq_packet_socket, opening it and binding it to the + /// given local endpoint. + /** + * This constructor creates a sequenced packet 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 sequenced packet 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 sequenced + * packet socket will be bound. + * + * @throws asio::system_error Thrown on failure. + */ + basic_seq_packet_socket(asio::io_context& io_context, + const endpoint_type& endpoint) + : basic_socket(io_context, endpoint) + { + } + + /// Construct a basic_seq_packet_socket on an existing native socket. + /** + * This constructor creates a sequenced packet socket object to hold an + * existing native socket. + * + * @param io_context The io_context object that the sequenced packet 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 asio::system_error Thrown on failure. + */ + basic_seq_packet_socket(asio::io_context& io_context, + const protocol_type& protocol, const native_handle_type& native_socket) + : basic_socket( + io_context, protocol, native_socket) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_seq_packet_socket from another. + /** + * This constructor moves a sequenced packet socket from one object to + * another. + * + * @param other The other basic_seq_packet_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_seq_packet_socket(io_context&) constructor. + */ + basic_seq_packet_socket(basic_seq_packet_socket&& other) + : basic_socket(std::move(other)) + { + } + + /// Move-assign a basic_seq_packet_socket from another. + /** + * This assignment operator moves a sequenced packet socket from one object to + * another. + * + * @param other The other basic_seq_packet_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_seq_packet_socket(io_context&) constructor. + */ + basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other) + { + basic_socket::operator=(std::move(other)); + return *this; + } + + /// Move-construct a basic_seq_packet_socket from a socket of another protocol + /// type. + /** + * This constructor moves a sequenced packet socket from one object to + * another. + * + * @param other The other basic_seq_packet_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_seq_packet_socket(io_context&) constructor. + */ + template + basic_seq_packet_socket( + basic_seq_packet_socket&& other, + typename enable_if::value>::type* = 0) + : basic_socket(std::move(other)) + { + } + + /// Move-assign a basic_seq_packet_socket from a socket of another protocol + /// type. + /** + * This assignment operator moves a sequenced packet socket from one object to + * another. + * + * @param other The other basic_seq_packet_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_seq_packet_socket(io_context&) constructor. + */ + template + typename enable_if::value, + basic_seq_packet_socket>::type& operator=( + basic_seq_packet_socket&& other) + { + basic_socket::operator=(std::move(other)); + return *this; + } +#endif // defined(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_seq_packet_socket() + { + } + + /// Send some data on the socket. + /** + * This function is used to send data on the sequenced packet socket. The + * function call will block until 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 asio::system_error Thrown on failure. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.send(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) + { + asio::error_code ec; + std::size_t s = this->get_service().send( + this->get_implementation(), buffers, flags, ec); + asio::detail::throw_error(ec, "send"); + return s; + } + + /// Send some data on the socket. + /** + * This function is used to send data on the sequenced packet socket. The + * function call will block 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, asio::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 sequenced packet + * 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 asio::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 + * asio::io_context::post(). + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_send(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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_send(this->get_implementation(), + buffers, flags, ASIO_MOVE_CAST(WriteHandler)(handler)); +#else // defined(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(ASIO_ENABLE_OLD_SERVICES) + } + + /// Receive some data on the socket. + /** + * This function is used to receive data on the sequenced packet socket. The + * function call will block until data has been received successfully, or + * until an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param out_flags After the receive call completes, contains flags + * associated with the received data. For example, if the + * socket_base::message_end_of_record bit is set then the received data marks + * the end of a record. + * + * @returns The number of bytes received. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.receive(asio::buffer(data, size), out_flags); + * @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& out_flags) + { + asio::error_code ec; +#if defined(ASIO_ENABLE_OLD_SERVICES) + std::size_t s = this->get_service().receive( + this->get_implementation(), buffers, 0, out_flags, ec); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + std::size_t s = this->get_service().receive_with_flags( + this->get_implementation(), buffers, 0, out_flags, ec); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + asio::detail::throw_error(ec, "receive"); + return s; + } + + /// Receive some data on the socket. + /** + * This function is used to receive data on the sequenced packet socket. The + * function call will block until data has been received successfully, or + * until an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param in_flags Flags specifying how the receive call is to be made. + * + * @param out_flags After the receive call completes, contains flags + * associated with the received data. For example, if the + * socket_base::message_end_of_record bit is set then the received data marks + * the end of a record. + * + * @returns The number of bytes received. + * + * @throws asio::system_error Thrown on failure. An error code of + * 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(asio::buffer(data, size), 0, out_flags); + * @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 in_flags, + socket_base::message_flags& out_flags) + { + asio::error_code ec; +#if defined(ASIO_ENABLE_OLD_SERVICES) + std::size_t s = this->get_service().receive( + this->get_implementation(), buffers, in_flags, out_flags, ec); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + std::size_t s = this->get_service().receive_with_flags( + this->get_implementation(), buffers, in_flags, out_flags, ec); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + asio::detail::throw_error(ec, "receive"); + return s; + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the sequenced packet socket. The + * function call will block until data has been received successfully, or + * until an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param in_flags Flags specifying how the receive call is to be made. + * + * @param out_flags After the receive call completes, contains flags + * associated with the received data. For example, if the + * socket_base::message_end_of_record bit is set then the received data marks + * the end of a record. + * + * @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 in_flags, + socket_base::message_flags& out_flags, asio::error_code& ec) + { +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().receive(this->get_implementation(), + buffers, in_flags, out_flags, ec); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().receive_with_flags(this->get_implementation(), + buffers, in_flags, out_flags, ec); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive data from the sequenced + * packet 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 out_flags Once the asynchronous operation completes, contains flags + * associated with the received data. For example, if the + * socket_base::message_end_of_record bit is set then the received data marks + * the end of a record. The caller must guarantee that the referenced + * variable remains 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 asio::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 + * asio::io_context::post(). + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.async_receive(asio::buffer(data, size), out_flags, 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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive(const MutableBufferSequence& buffers, + socket_base::message_flags& out_flags, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_receive( + this->get_implementation(), buffers, 0, out_flags, + ASIO_MOVE_CAST(ReadHandler)(handler)); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + async_completion init(handler); + + this->get_service().async_receive_with_flags( + this->get_implementation(), buffers, 0, out_flags, + init.completion_handler); + + return init.result.get(); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive data from the sequenced + * data 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 in_flags Flags specifying how the receive call is to be made. + * + * @param out_flags Once the asynchronous operation completes, contains flags + * associated with the received data. For example, if the + * socket_base::message_end_of_record bit is set then the received data marks + * the end of a record. The caller must guarantee that the referenced + * variable remains 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 asio::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 + * asio::io_context::post(). + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.async_receive( + * asio::buffer(data, size), + * 0, out_flags, 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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive(const MutableBufferSequence& buffers, + socket_base::message_flags in_flags, + socket_base::message_flags& out_flags, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_receive( + this->get_implementation(), buffers, in_flags, out_flags, + ASIO_MOVE_CAST(ReadHandler)(handler)); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + async_completion init(handler); + + this->get_service().async_receive_with_flags( + this->get_implementation(), buffers, in_flags, out_flags, + init.completion_handler); + + return init.result.get(); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_SEQ_PACKET_SOCKET_HPP diff --git a/tools/sdk/include/asio/asio/basic_serial_port.hpp b/tools/sdk/include/asio/asio/basic_serial_port.hpp new file mode 100644 index 00000000..32262f84 --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_serial_port.hpp @@ -0,0 +1,688 @@ +// +// basic_serial_port.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// 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 ASIO_BASIC_SERIAL_PORT_HPP +#define ASIO_BASIC_SERIAL_PORT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_SERIAL_PORT) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/basic_io_object.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/serial_port_base.hpp" +#include "asio/serial_port_service.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Provides serial port functionality. +/** + * The basic_serial_port class template provides functionality that is common + * to all serial ports. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_serial_port + : public basic_io_object, + public serial_port_base +{ +public: + /// The native representation of a serial port. + typedef typename SerialPortService::native_handle_type native_handle_type; + + /// A basic_serial_port is always the lowest layer. + typedef basic_serial_port lowest_layer_type; + + /// Construct a basic_serial_port without opening it. + /** + * This constructor creates a serial port without opening it. + * + * @param io_context The io_context object that the serial port will use to + * dispatch handlers for any asynchronous operations performed on the port. + */ + explicit basic_serial_port(asio::io_context& io_context) + : basic_io_object(io_context) + { + } + + /// Construct and open a basic_serial_port. + /** + * This constructor creates and opens a serial port for the specified device + * name. + * + * @param io_context The io_context object that the serial port will use to + * dispatch handlers for any asynchronous operations performed on the port. + * + * @param device The platform-specific device name for this serial + * port. + */ + explicit basic_serial_port(asio::io_context& io_context, + const char* device) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().open(this->get_implementation(), device, ec); + asio::detail::throw_error(ec, "open"); + } + + /// Construct and open a basic_serial_port. + /** + * This constructor creates and opens a serial port for the specified device + * name. + * + * @param io_context The io_context object that the serial port will use to + * dispatch handlers for any asynchronous operations performed on the port. + * + * @param device The platform-specific device name for this serial + * port. + */ + explicit basic_serial_port(asio::io_context& io_context, + const std::string& device) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().open(this->get_implementation(), device, ec); + asio::detail::throw_error(ec, "open"); + } + + /// Construct a basic_serial_port on an existing native serial port. + /** + * This constructor creates a serial port object to hold an existing native + * serial port. + * + * @param io_context The io_context object that the serial port will use to + * dispatch handlers for any asynchronous operations performed on the port. + * + * @param native_serial_port A native serial port. + * + * @throws asio::system_error Thrown on failure. + */ + basic_serial_port(asio::io_context& io_context, + const native_handle_type& native_serial_port) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), + native_serial_port, ec); + asio::detail::throw_error(ec, "assign"); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_serial_port from another. + /** + * This constructor moves a serial port from one object to another. + * + * @param other The other basic_serial_port 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_serial_port(io_context&) constructor. + */ + basic_serial_port(basic_serial_port&& other) + : basic_io_object( + ASIO_MOVE_CAST(basic_serial_port)(other)) + { + } + + /// Move-assign a basic_serial_port from another. + /** + * This assignment operator moves a serial port from one object to another. + * + * @param other The other basic_serial_port 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_serial_port(io_context&) constructor. + */ + basic_serial_port& operator=(basic_serial_port&& other) + { + basic_io_object::operator=( + ASIO_MOVE_CAST(basic_serial_port)(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since a basic_serial_port 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_serial_port 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; + } + + /// Open the serial port using the specified device name. + /** + * This function opens the serial port for the specified device name. + * + * @param device The platform-specific device name. + * + * @throws asio::system_error Thrown on failure. + */ + void open(const std::string& device) + { + asio::error_code ec; + this->get_service().open(this->get_implementation(), device, ec); + asio::detail::throw_error(ec, "open"); + } + + /// Open the serial port using the specified device name. + /** + * This function opens the serial port using the given platform-specific + * device name. + * + * @param device The platform-specific device name. + * + * @param ec Set the indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID open(const std::string& device, + asio::error_code& ec) + { + this->get_service().open(this->get_implementation(), device, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Assign an existing native serial port to the serial port. + /* + * This function opens the serial port to hold an existing native serial port. + * + * @param native_serial_port A native serial port. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const native_handle_type& native_serial_port) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), + native_serial_port, ec); + asio::detail::throw_error(ec, "assign"); + } + + /// Assign an existing native serial port to the serial port. + /* + * This function opens the serial port to hold an existing native serial port. + * + * @param native_serial_port A native serial port. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port, + asio::error_code& ec) + { + this->get_service().assign(this->get_implementation(), + native_serial_port, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the serial port is open. + bool is_open() const + { + return this->get_service().is_open(this->get_implementation()); + } + + /// Close the serial port. + /** + * This function is used to close the serial port. Any asynchronous read or + * write operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void close() + { + asio::error_code ec; + this->get_service().close(this->get_implementation(), ec); + asio::detail::throw_error(ec, "close"); + } + + /// Close the serial port. + /** + * This function is used to close the serial port. Any asynchronous read or + * write operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + this->get_service().close(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native serial port representation. + /** + * This function may be used to obtain the underlying representation of the + * serial port. This is intended to allow access to native serial port + * 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 serial port. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel"); + } + + /// Cancel all asynchronous operations associated with the serial port. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) + { + this->get_service().cancel(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Send a break sequence to the serial port. + /** + * This function causes a break sequence of platform-specific duration to be + * sent out the serial port. + * + * @throws asio::system_error Thrown on failure. + */ + void send_break() + { + asio::error_code ec; + this->get_service().send_break(this->get_implementation(), ec); + asio::detail::throw_error(ec, "send_break"); + } + + /// Send a break sequence to the serial port. + /** + * This function causes a break sequence of platform-specific duration to be + * sent out the serial port. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID send_break(asio::error_code& ec) + { + this->get_service().send_break(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Set an option on the serial port. + /** + * This function is used to set an option on the serial port. + * + * @param option The option value to be set on the serial port. + * + * @throws asio::system_error Thrown on failure. + * + * @sa SettableSerialPortOption @n + * asio::serial_port_base::baud_rate @n + * asio::serial_port_base::flow_control @n + * asio::serial_port_base::parity @n + * asio::serial_port_base::stop_bits @n + * asio::serial_port_base::character_size + */ + template + void set_option(const SettableSerialPortOption& option) + { + asio::error_code ec; + this->get_service().set_option(this->get_implementation(), option, ec); + asio::detail::throw_error(ec, "set_option"); + } + + /// Set an option on the serial port. + /** + * This function is used to set an option on the serial port. + * + * @param option The option value to be set on the serial port. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa SettableSerialPortOption @n + * asio::serial_port_base::baud_rate @n + * asio::serial_port_base::flow_control @n + * asio::serial_port_base::parity @n + * asio::serial_port_base::stop_bits @n + * asio::serial_port_base::character_size + */ + template + ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option, + asio::error_code& ec) + { + this->get_service().set_option(this->get_implementation(), option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get an option from the serial port. + /** + * This function is used to get the current value of an option on the serial + * port. + * + * @param option The option value to be obtained from the serial port. + * + * @throws asio::system_error Thrown on failure. + * + * @sa GettableSerialPortOption @n + * asio::serial_port_base::baud_rate @n + * asio::serial_port_base::flow_control @n + * asio::serial_port_base::parity @n + * asio::serial_port_base::stop_bits @n + * asio::serial_port_base::character_size + */ + template + void get_option(GettableSerialPortOption& option) + { + asio::error_code ec; + this->get_service().get_option(this->get_implementation(), option, ec); + asio::detail::throw_error(ec, "get_option"); + } + + /// Get an option from the serial port. + /** + * This function is used to get the current value of an option on the serial + * port. + * + * @param option The option value to be obtained from the serial port. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa GettableSerialPortOption @n + * asio::serial_port_base::baud_rate @n + * asio::serial_port_base::flow_control @n + * asio::serial_port_base::parity @n + * asio::serial_port_base::stop_bits @n + * asio::serial_port_base::character_size + */ + template + ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option, + asio::error_code& ec) + { + this->get_service().get_option(this->get_implementation(), option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Write some data to the serial port. + /** + * This function is used to write data to the serial port. 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 serial port. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * 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 + * serial_port.write_some(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) + { + asio::error_code ec; + std::size_t s = this->get_service().write_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "write_some"); + return s; + } + + /// Write some data to the serial port. + /** + * This function is used to write data to the serial port. 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 serial port. + * + * @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, + asio::error_code& ec) + { + return this->get_service().write_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write data to the serial port. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be written to the serial port. + * 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 asio::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 + * 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 + * serial_port.async_write_some(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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + return this->get_service().async_write_some(this->get_implementation(), + buffers, ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Read some data from the serial port. + /** + * This function is used to read data from the serial port. 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 asio::system_error Thrown on failure. An error code of + * 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 + * serial_port.read_some(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) + { + asio::error_code ec; + std::size_t s = this->get_service().read_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "read_some"); + return s; + } + + /// Read some data from the serial port. + /** + * This function is used to read data from the serial port. 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, + asio::error_code& ec) + { + return this->get_service().read_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read data from the serial port. + * 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 asio::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 + * 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 + * serial_port.async_read_some(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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + return this->get_service().async_read_some(this->get_implementation(), + buffers, ASIO_MOVE_CAST(ReadHandler)(handler)); + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_SERIAL_PORT) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_BASIC_SERIAL_PORT_HPP diff --git a/tools/sdk/include/asio/asio/basic_signal_set.hpp b/tools/sdk/include/asio/asio/basic_signal_set.hpp new file mode 100644 index 00000000..cf34643f --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_signal_set.hpp @@ -0,0 +1,391 @@ +// +// basic_signal_set.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BASIC_SIGNAL_SET_HPP +#define ASIO_BASIC_SIGNAL_SET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/basic_io_object.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/signal_set_service.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Provides signal functionality. +/** + * The basic_signal_set class template provides the ability to perform an + * asynchronous wait for one or more signals to occur. + * + * Most applications will use the asio::signal_set typedef. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Example + * Performing an asynchronous wait: + * @code + * void handler( + * const asio::error_code& error, + * int signal_number) + * { + * if (!error) + * { + * // A signal occurred. + * } + * } + * + * ... + * + * // Construct a signal set registered for process termination. + * asio::signal_set signals(io_context, SIGINT, SIGTERM); + * + * // Start an asynchronous wait for one of the signals to occur. + * signals.async_wait(handler); + * @endcode + * + * @par Queueing of signal notifications + * + * If a signal is registered with a signal_set, and the signal occurs when + * there are no waiting handlers, then the signal notification is queued. The + * next async_wait operation on that signal_set will dequeue the notification. + * If multiple notifications are queued, subsequent async_wait operations + * dequeue them one at a time. Signal notifications are dequeued in order of + * ascending signal number. + * + * If a signal number is removed from a signal_set (using the @c remove or @c + * erase member functions) then any queued notifications for that signal are + * discarded. + * + * @par Multiple registration of signals + * + * The same signal number may be registered with different signal_set objects. + * When the signal occurs, one handler is called for each signal_set object. + * + * Note that multiple registration only works for signals that are registered + * using Asio. The application must not also register a signal handler using + * functions such as @c signal() or @c sigaction(). + * + * @par Signal masking on POSIX platforms + * + * POSIX allows signals to be blocked using functions such as @c sigprocmask() + * and @c pthread_sigmask(). For signals to be delivered, programs must ensure + * that any signals registered using signal_set objects are unblocked in at + * least one thread. + */ +template +class basic_signal_set + : public basic_io_object +{ +public: + /// Construct a signal set without adding any signals. + /** + * This constructor creates a signal set without registering for any signals. + * + * @param io_context The io_context object that the signal set will use to + * dispatch handlers for any asynchronous operations performed on the set. + */ + explicit basic_signal_set(asio::io_context& io_context) + : basic_io_object(io_context) + { + } + + /// Construct a signal set and add one signal. + /** + * This constructor creates a signal set and registers for one signal. + * + * @param io_context The io_context object that the signal set will use to + * dispatch handlers for any asynchronous operations performed on the set. + * + * @param signal_number_1 The signal number to be added. + * + * @note This constructor is equivalent to performing: + * @code asio::signal_set signals(io_context); + * signals.add(signal_number_1); @endcode + */ + basic_signal_set(asio::io_context& io_context, int signal_number_1) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().add(this->get_implementation(), signal_number_1, ec); + asio::detail::throw_error(ec, "add"); + } + + /// Construct a signal set and add two signals. + /** + * This constructor creates a signal set and registers for two signals. + * + * @param io_context The io_context object that the signal set will use to + * dispatch handlers for any asynchronous operations performed on the set. + * + * @param signal_number_1 The first signal number to be added. + * + * @param signal_number_2 The second signal number to be added. + * + * @note This constructor is equivalent to performing: + * @code asio::signal_set signals(io_context); + * signals.add(signal_number_1); + * signals.add(signal_number_2); @endcode + */ + basic_signal_set(asio::io_context& io_context, int signal_number_1, + int signal_number_2) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().add(this->get_implementation(), signal_number_1, ec); + asio::detail::throw_error(ec, "add"); + this->get_service().add(this->get_implementation(), signal_number_2, ec); + asio::detail::throw_error(ec, "add"); + } + + /// Construct a signal set and add three signals. + /** + * This constructor creates a signal set and registers for three signals. + * + * @param io_context The io_context object that the signal set will use to + * dispatch handlers for any asynchronous operations performed on the set. + * + * @param signal_number_1 The first signal number to be added. + * + * @param signal_number_2 The second signal number to be added. + * + * @param signal_number_3 The third signal number to be added. + * + * @note This constructor is equivalent to performing: + * @code asio::signal_set signals(io_context); + * signals.add(signal_number_1); + * signals.add(signal_number_2); + * signals.add(signal_number_3); @endcode + */ + basic_signal_set(asio::io_context& io_context, int signal_number_1, + int signal_number_2, int signal_number_3) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().add(this->get_implementation(), signal_number_1, ec); + asio::detail::throw_error(ec, "add"); + this->get_service().add(this->get_implementation(), signal_number_2, ec); + asio::detail::throw_error(ec, "add"); + this->get_service().add(this->get_implementation(), signal_number_3, ec); + asio::detail::throw_error(ec, "add"); + } + + /// Add a signal to a signal_set. + /** + * This function adds the specified signal to the set. It has no effect if the + * signal is already in the set. + * + * @param signal_number The signal to be added to the set. + * + * @throws asio::system_error Thrown on failure. + */ + void add(int signal_number) + { + asio::error_code ec; + this->get_service().add(this->get_implementation(), signal_number, ec); + asio::detail::throw_error(ec, "add"); + } + + /// Add a signal to a signal_set. + /** + * This function adds the specified signal to the set. It has no effect if the + * signal is already in the set. + * + * @param signal_number The signal to be added to the set. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID add(int signal_number, asio::error_code& ec) + { + this->get_service().add(this->get_implementation(), signal_number, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Remove a signal from a signal_set. + /** + * This function removes the specified signal from the set. It has no effect + * if the signal is not in the set. + * + * @param signal_number The signal to be removed from the set. + * + * @throws asio::system_error Thrown on failure. + * + * @note Removes any notifications that have been queued for the specified + * signal number. + */ + void remove(int signal_number) + { + asio::error_code ec; + this->get_service().remove(this->get_implementation(), signal_number, ec); + asio::detail::throw_error(ec, "remove"); + } + + /// Remove a signal from a signal_set. + /** + * This function removes the specified signal from the set. It has no effect + * if the signal is not in the set. + * + * @param signal_number The signal to be removed from the set. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Removes any notifications that have been queued for the specified + * signal number. + */ + ASIO_SYNC_OP_VOID remove(int signal_number, + asio::error_code& ec) + { + this->get_service().remove(this->get_implementation(), signal_number, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Remove all signals from a signal_set. + /** + * This function removes all signals from the set. It has no effect if the set + * is already empty. + * + * @throws asio::system_error Thrown on failure. + * + * @note Removes all queued notifications. + */ + void clear() + { + asio::error_code ec; + this->get_service().clear(this->get_implementation(), ec); + asio::detail::throw_error(ec, "clear"); + } + + /// Remove all signals from a signal_set. + /** + * This function removes all signals from the set. It has no effect if the set + * is already empty. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Removes all queued notifications. + */ + ASIO_SYNC_OP_VOID clear(asio::error_code& ec) + { + this->get_service().clear(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Cancel all operations associated with the signal set. + /** + * This function forces the completion of any pending asynchronous wait + * operations against the signal set. The handler for each cancelled + * operation will be invoked with the asio::error::operation_aborted + * error code. + * + * Cancellation does not alter the set of registered signals. + * + * @throws asio::system_error Thrown on failure. + * + * @note If a registered signal occurred before cancel() is called, then the + * handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + void cancel() + { + asio::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel"); + } + + /// Cancel all operations associated with the signal set. + /** + * This function forces the completion of any pending asynchronous wait + * operations against the signal set. The handler for each cancelled + * operation will be invoked with the asio::error::operation_aborted + * error code. + * + * Cancellation does not alter the set of registered signals. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note If a registered signal occurred before cancel() is called, then the + * handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) + { + this->get_service().cancel(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Start an asynchronous operation to wait for a signal to be delivered. + /** + * This function may be used to initiate an asynchronous wait against the + * signal set. It always returns immediately. + * + * For each call to async_wait(), the supplied handler will be called exactly + * once. The handler will be called when: + * + * @li One of the registered signals in the signal set occurs; or + * + * @li The signal set was cancelled, in which case the handler is passed the + * error code asio::error::operation_aborted. + * + * @param handler The handler to be called when the signal occurs. Copies + * will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * int signal_number // Indicates which signal occurred. + * ); @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 + * asio::io_context::post(). + */ + template + ASIO_INITFN_RESULT_TYPE(SignalHandler, + void (asio::error_code, int)) + async_wait(ASIO_MOVE_ARG(SignalHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a SignalHandler. + ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check; + + return this->get_service().async_wait(this->get_implementation(), + ASIO_MOVE_CAST(SignalHandler)(handler)); + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_BASIC_SIGNAL_SET_HPP diff --git a/tools/sdk/include/asio/asio/basic_socket.hpp b/tools/sdk/include/asio/asio/basic_socket.hpp new file mode 100644 index 00000000..3dfacb42 --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_socket.hpp @@ -0,0 +1,1757 @@ +// +// basic_socket.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BASIC_SOCKET_HPP +#define ASIO_BASIC_SOCKET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/async_result.hpp" +#include "asio/basic_io_object.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error.hpp" +#include "asio/post.hpp" +#include "asio/socket_base.hpp" + +#if defined(ASIO_HAS_MOVE) +# include +#endif // defined(ASIO_HAS_MOVE) + +#if !defined(ASIO_ENABLE_OLD_SERVICES) +# if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/winrt_ssocket_service.hpp" +# define ASIO_SVC_T detail::winrt_ssocket_service +# elif defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_socket_service.hpp" +# define ASIO_SVC_T detail::win_iocp_socket_service +# else +# include "asio/detail/reactive_socket_service.hpp" +# define ASIO_SVC_T detail::reactive_socket_service +# endif +#endif // !defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +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 + : 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 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(ASIO_NO_EXTENSIONS) + /// A basic_socket is always the lowest layer. + typedef basic_socket lowest_layer_type; +#endif // !defined(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(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 asio::system_error Thrown on failure. + */ + basic_socket(asio::io_context& io_context, + const protocol_type& protocol) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().open(this->get_implementation(), protocol, ec); + 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 asio::system_error Thrown on failure. + */ + basic_socket(asio::io_context& io_context, + const endpoint_type& endpoint) + : basic_io_object(io_context) + { + asio::error_code ec; + const protocol_type protocol = endpoint.protocol(); + this->get_service().open(this->get_implementation(), protocol, ec); + asio::detail::throw_error(ec, "open"); + this->get_service().bind(this->get_implementation(), endpoint, ec); + 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 asio::system_error Thrown on failure. + */ + basic_socket(asio::io_context& io_context, + const protocol_type& protocol, const native_handle_type& native_socket) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), + protocol, native_socket, ec); + asio::detail::throw_error(ec, "assign"); + } + +#if defined(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(basic_socket&& 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& operator=(basic_socket&& 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(basic_socket&& 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>::type& operator=( + basic_socket&& other) + { + basic_socket tmp(std::move(other)); + basic_io_object::operator=(std::move(tmp)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + +#if defined(ASIO_ENABLE_OLD_SERVICES) + // These functions are provided by basic_io_object<>. +#else // defined(ASIO_ENABLE_OLD_SERVICES) +#if !defined(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. + */ + 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. + */ + asio::io_context& get_io_service() + { + return basic_io_object::get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return basic_io_object::get_executor(); + } +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#if !defined(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(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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_context); + * socket.open(asio::ip::tcp::v4()); + * @endcode + */ + void open(const protocol_type& protocol = protocol_type()) + { + asio::error_code ec; + this->get_service().open(this->get_implementation(), protocol, ec); + 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 + * asio::ip::tcp::socket socket(io_context); + * asio::error_code ec; + * socket.open(asio::ip::tcp::v4(), ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + ASIO_SYNC_OP_VOID open(const protocol_type& protocol, + asio::error_code& ec) + { + this->get_service().open(this->get_implementation(), protocol, ec); + 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 asio::system_error Thrown on failure. + */ + void assign(const protocol_type& protocol, + const native_handle_type& native_socket) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), + protocol, native_socket, ec); + 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. + */ + ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, + const native_handle_type& native_socket, asio::error_code& ec) + { + this->get_service().assign(this->get_implementation(), + protocol, native_socket, ec); + 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 asio::error::operation_aborted error. + * + * @throws asio::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() + { + asio::error_code ec; + this->get_service().close(this->get_implementation(), ec); + 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 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 + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::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. + */ + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + this->get_service().close(this->get_implementation(), ec); + 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 asio::error::operation_aborted error. Ownership + * of the native socket is then transferred to the caller. + * + * @throws asio::system_error Thrown on failure. + * + * @note This function is unsupported on Windows versions prior to Windows + * 8.1, and will fail with asio::error::operation_not_supported on + * these platforms. + */ +#if defined(ASIO_MSVC) && (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() + { + asio::error_code ec; + native_handle_type s = this->get_service().release( + this->get_implementation(), ec); + 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 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 asio::error::operation_not_supported on + * these platforms. + */ +#if defined(ASIO_MSVC) && (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(asio::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 asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls to cancel() will always fail with + * asio::error::operation_not_supported when run on Windows XP, Windows + * Server 2003, and earlier versions of Windows, unless + * 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 + * 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(ASIO_MSVC) && (ASIO_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ + && !defined(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() + { + asio::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + 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 asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls to cancel() will always fail with + * asio::error::operation_not_supported when run on Windows XP, Windows + * Server 2003, and earlier versions of Windows, unless + * 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 + * 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(ASIO_MSVC) && (ASIO_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ + && !defined(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 + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) + { + this->get_service().cancel(this->get_implementation(), ec); + 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 asio::system_error Thrown on failure. + */ + bool at_mark() const + { + asio::error_code ec; + bool b = this->get_service().at_mark(this->get_implementation(), ec); + 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(asio::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 asio::system_error Thrown on failure. + */ + std::size_t available() const + { + asio::error_code ec; + std::size_t s = this->get_service().available( + this->get_implementation(), ec); + 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(asio::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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_context); + * socket.open(asio::ip::tcp::v4()); + * socket.bind(asio::ip::tcp::endpoint( + * asio::ip::tcp::v4(), 12345)); + * @endcode + */ + void bind(const endpoint_type& endpoint) + { + asio::error_code ec; + this->get_service().bind(this->get_implementation(), endpoint, ec); + 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 + * asio::ip::tcp::socket socket(io_context); + * socket.open(asio::ip::tcp::v4()); + * asio::error_code ec; + * socket.bind(asio::ip::tcp::endpoint( + * asio::ip::tcp::v4(), 12345), ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, + asio::error_code& ec) + { + this->get_service().bind(this->get_implementation(), endpoint, ec); + 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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_context); + * asio::ip::tcp::endpoint endpoint( + * asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.connect(endpoint); + * @endcode + */ + void connect(const endpoint_type& peer_endpoint) + { + asio::error_code ec; + if (!is_open()) + { + this->get_service().open(this->get_implementation(), + peer_endpoint.protocol(), ec); + asio::detail::throw_error(ec, "connect"); + } + this->get_service().connect(this->get_implementation(), peer_endpoint, ec); + 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 + * asio::ip::tcp::socket socket(io_context); + * asio::ip::tcp::endpoint endpoint( + * asio::ip::address::from_string("1.2.3.4"), 12345); + * asio::error_code ec; + * socket.connect(endpoint, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, + asio::error_code& ec) + { + if (!is_open()) + { + this->get_service().open(this->get_implementation(), + peer_endpoint.protocol(), ec); + if (ec) + { + ASIO_SYNC_OP_VOID_RETURN(ec); + } + } + + this->get_service().connect(this->get_implementation(), peer_endpoint, ec); + 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 asio::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 + * asio::io_context::post(). + * + * @par Example + * @code + * void connect_handler(const asio::error_code& error) + * { + * if (!error) + * { + * // Connect succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::socket socket(io_context); + * asio::ip::tcp::endpoint endpoint( + * asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.async_connect(endpoint, connect_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(ConnectHandler, + void (asio::error_code)) + async_connect(const endpoint_type& peer_endpoint, + 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. + ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; + + if (!is_open()) + { + asio::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); + + asio::post(this->get_executor(), + asio::detail::bind_handler( + ASIO_MOVE_CAST(ASIO_HANDLER_TYPE( + ConnectHandler, void (asio::error_code)))( + init.completion_handler), ec)); + + return init.result.get(); + } + } + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_connect(this->get_implementation(), + peer_endpoint, ASIO_MOVE_CAST(ConnectHandler)(handler)); +#else // defined(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(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 asio::system_error Thrown on failure. + * + * @sa SettableSocketOption @n + * asio::socket_base::broadcast @n + * asio::socket_base::do_not_route @n + * asio::socket_base::keep_alive @n + * asio::socket_base::linger @n + * asio::socket_base::receive_buffer_size @n + * asio::socket_base::receive_low_watermark @n + * asio::socket_base::reuse_address @n + * asio::socket_base::send_buffer_size @n + * asio::socket_base::send_low_watermark @n + * asio::ip::multicast::join_group @n + * asio::ip::multicast::leave_group @n + * asio::ip::multicast::enable_loopback @n + * asio::ip::multicast::outbound_interface @n + * asio::ip::multicast::hops @n + * asio::ip::tcp::no_delay + * + * @par Example + * Setting the IPPROTO_TCP/TCP_NODELAY option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::tcp::no_delay option(true); + * socket.set_option(option); + * @endcode + */ + template + void set_option(const SettableSocketOption& option) + { + asio::error_code ec; + this->get_service().set_option(this->get_implementation(), option, ec); + 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 + * asio::socket_base::broadcast @n + * asio::socket_base::do_not_route @n + * asio::socket_base::keep_alive @n + * asio::socket_base::linger @n + * asio::socket_base::receive_buffer_size @n + * asio::socket_base::receive_low_watermark @n + * asio::socket_base::reuse_address @n + * asio::socket_base::send_buffer_size @n + * asio::socket_base::send_low_watermark @n + * asio::ip::multicast::join_group @n + * asio::ip::multicast::leave_group @n + * asio::ip::multicast::enable_loopback @n + * asio::ip::multicast::outbound_interface @n + * asio::ip::multicast::hops @n + * asio::ip::tcp::no_delay + * + * @par Example + * Setting the IPPROTO_TCP/TCP_NODELAY option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::tcp::no_delay option(true); + * asio::error_code ec; + * socket.set_option(option, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, + asio::error_code& ec) + { + this->get_service().set_option(this->get_implementation(), option, ec); + 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 asio::system_error Thrown on failure. + * + * @sa GettableSocketOption @n + * asio::socket_base::broadcast @n + * asio::socket_base::do_not_route @n + * asio::socket_base::keep_alive @n + * asio::socket_base::linger @n + * asio::socket_base::receive_buffer_size @n + * asio::socket_base::receive_low_watermark @n + * asio::socket_base::reuse_address @n + * asio::socket_base::send_buffer_size @n + * asio::socket_base::send_low_watermark @n + * asio::ip::multicast::join_group @n + * asio::ip::multicast::leave_group @n + * asio::ip::multicast::enable_loopback @n + * asio::ip::multicast::outbound_interface @n + * asio::ip::multicast::hops @n + * asio::ip::tcp::no_delay + * + * @par Example + * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::tcp::socket::keep_alive option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + */ + template + void get_option(GettableSocketOption& option) const + { + asio::error_code ec; + this->get_service().get_option(this->get_implementation(), option, ec); + 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 + * asio::socket_base::broadcast @n + * asio::socket_base::do_not_route @n + * asio::socket_base::keep_alive @n + * asio::socket_base::linger @n + * asio::socket_base::receive_buffer_size @n + * asio::socket_base::receive_low_watermark @n + * asio::socket_base::reuse_address @n + * asio::socket_base::send_buffer_size @n + * asio::socket_base::send_low_watermark @n + * asio::ip::multicast::join_group @n + * asio::ip::multicast::leave_group @n + * asio::ip::multicast::enable_loopback @n + * asio::ip::multicast::outbound_interface @n + * asio::ip::multicast::hops @n + * asio::ip::tcp::no_delay + * + * @par Example + * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::tcp::socket::keep_alive option; + * asio::error_code ec; + * socket.get_option(option, ec); + * if (ec) + * { + * // An error occurred. + * } + * bool is_set = option.value(); + * @endcode + */ + template + ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, + asio::error_code& ec) const + { + this->get_service().get_option(this->get_implementation(), option, ec); + 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 asio::system_error Thrown on failure. + * + * @sa IoControlCommand @n + * asio::socket_base::bytes_readable @n + * asio::socket_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * 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) + { + asio::error_code ec; + this->get_service().io_control(this->get_implementation(), command, ec); + 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 + * asio::socket_base::bytes_readable @n + * asio::socket_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::tcp::socket::bytes_readable command; + * asio::error_code ec; + * socket.io_control(command, ec); + * if (ec) + * { + * // An error occurred. + * } + * std::size_t bytes_readable = command.get(); + * @endcode + */ + template + ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, + asio::error_code& ec) + { + this->get_service().io_control(this->get_implementation(), command, ec); + 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 + * 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 + * 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 + * asio::error::would_block if they are unable to perform the requested + * operation immediately. If @c false, synchronous operations will block + * until complete. + * + * @throws asio::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 + * asio::error::would_block. + */ + void non_blocking(bool mode) + { + asio::error_code ec; + this->get_service().non_blocking(this->get_implementation(), mode, ec); + 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 + * 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 + * asio::error::would_block. + */ + ASIO_SYNC_OP_VOID non_blocking( + bool mode, asio::error_code& ec) + { + this->get_service().non_blocking(this->get_implementation(), mode, ec); + 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 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()(asio::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 = asio::error_code(n < 0 ? errno : 0, + * asio::error::get_system_category()); + * total_bytes_transferred_ += ec ? 0 : n; + * + * // Retry operation immediately if interrupted by signal. + * if (ec == asio::error::interrupted) + * continue; + * + * // Check if we need to run the operation again. + * if (ec == asio::error::would_block + * || ec == 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 asio::error::would_block + * (or the equivalent system error). + * + * @throws asio::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 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()(asio::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 = asio::error_code(n < 0 ? errno : 0, + * asio::error::get_system_category()); + * total_bytes_transferred_ += ec ? 0 : n; + * + * // Retry operation immediately if interrupted by signal. + * if (ec == asio::error::interrupted) + * continue; + * + * // Check if we need to run the operation again. + * if (ec == asio::error::would_block + * || ec == 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) + { + asio::error_code ec; + this->get_service().native_non_blocking( + this->get_implementation(), mode, ec); + 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 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 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()(asio::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 = asio::error_code(n < 0 ? errno : 0, + * asio::error::get_system_category()); + * total_bytes_transferred_ += ec ? 0 : n; + * + * // Retry operation immediately if interrupted by signal. + * if (ec == asio::error::interrupted) + * continue; + * + * // Check if we need to run the operation again. + * if (ec == asio::error::would_block + * || ec == 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 + */ + ASIO_SYNC_OP_VOID native_non_blocking( + bool mode, asio::error_code& ec) + { + this->get_service().native_non_blocking( + this->get_implementation(), mode, ec); + 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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); + * @endcode + */ + endpoint_type local_endpoint() const + { + asio::error_code ec; + endpoint_type ep = this->get_service().local_endpoint( + this->get_implementation(), ec); + 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 + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::error_code ec; + * asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + endpoint_type local_endpoint(asio::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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); + * @endcode + */ + endpoint_type remote_endpoint() const + { + asio::error_code ec; + endpoint_type ep = this->get_service().remote_endpoint( + this->get_implementation(), ec); + 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 + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::error_code ec; + * asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + endpoint_type remote_endpoint(asio::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 asio::system_error Thrown on failure. + * + * @par Example + * Shutting down the send side of the socket: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * socket.shutdown(asio::ip::tcp::socket::shutdown_send); + * @endcode + */ + void shutdown(shutdown_type what) + { + asio::error_code ec; + this->get_service().shutdown(this->get_implementation(), what, ec); + 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 + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::error_code ec; + * socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + ASIO_SYNC_OP_VOID shutdown(shutdown_type what, + asio::error_code& ec) + { + this->get_service().shutdown(this->get_implementation(), what, ec); + 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 + * asio::ip::tcp::socket socket(io_context); + * ... + * socket.wait(asio::ip::tcp::socket::wait_read); + * @endcode + */ + void wait(wait_type w) + { + asio::error_code ec; + this->get_service().wait(this->get_implementation(), w, ec); + 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 + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::error_code ec; + * socket.wait(asio::ip::tcp::socket::wait_read, ec); + * @endcode + */ + ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec) + { + this->get_service().wait(this->get_implementation(), w, ec); + 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 asio::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 + * asio::io_context::post(). + * + * @par Example + * @code + * void wait_handler(const asio::error_code& error) + * { + * if (!error) + * { + * // Wait succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::socket socket(io_context); + * ... + * socket.async_wait(asio::ip::tcp::socket::wait_read, wait_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(wait_type w, 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. + ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_wait(this->get_implementation(), + w, ASIO_MOVE_CAST(WaitHandler)(handler)); +#else // defined(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(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() + { + } + +private: + // Disallow copying and assignment. + basic_socket(const basic_socket&) ASIO_DELETED; + basic_socket& operator=(const basic_socket&) ASIO_DELETED; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if !defined(ASIO_ENABLE_OLD_SERVICES) +# undef ASIO_SVC_T +#endif // !defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_BASIC_SOCKET_HPP diff --git a/tools/sdk/include/asio/asio/basic_socket_acceptor.hpp b/tools/sdk/include/asio/asio/basic_socket_acceptor.hpp new file mode 100644 index 00000000..ed201bbc --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_socket_acceptor.hpp @@ -0,0 +1,1986 @@ +// +// basic_socket_acceptor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BASIC_SOCKET_ACCEPTOR_HPP +#define ASIO_BASIC_SOCKET_ACCEPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/basic_io_object.hpp" +#include "asio/basic_socket.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error.hpp" +#include "asio/socket_base.hpp" + +#if defined(ASIO_HAS_MOVE) +# include +#endif // defined(ASIO_HAS_MOVE) + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/socket_acceptor_service.hpp" +#else // defined(ASIO_ENABLE_OLD_SERVICES) +# if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/null_socket_service.hpp" +# define ASIO_SVC_T detail::null_socket_service +# elif defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_socket_service.hpp" +# define ASIO_SVC_T detail::win_iocp_socket_service +# else +# include "asio/detail/reactive_socket_service.hpp" +# define ASIO_SVC_T detail::reactive_socket_service +# endif +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Provides the ability to accept new connections. +/** + * The basic_socket_acceptor 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 + * asio::ip::tcp::acceptor acceptor(io_context); + * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port); + * acceptor.open(endpoint.protocol()); + * acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true)); + * acceptor.bind(endpoint); + * acceptor.listen(); + * @endcode + */ +template )> +class basic_socket_acceptor + : 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 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(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 asio::system_error Thrown on failure. + */ + basic_socket_acceptor(asio::io_context& io_context, + const protocol_type& protocol) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().open(this->get_implementation(), protocol, ec); + 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 asio::system_error Thrown on failure. + * + * @note This constructor is equivalent to the following code: + * @code + * basic_socket_acceptor 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(asio::io_context& io_context, + const endpoint_type& endpoint, bool reuse_addr = true) + : basic_io_object(io_context) + { + asio::error_code ec; + const protocol_type protocol = endpoint.protocol(); + this->get_service().open(this->get_implementation(), protocol, ec); + asio::detail::throw_error(ec, "open"); + if (reuse_addr) + { + this->get_service().set_option(this->get_implementation(), + socket_base::reuse_address(true), ec); + asio::detail::throw_error(ec, "set_option"); + } + this->get_service().bind(this->get_implementation(), endpoint, ec); + asio::detail::throw_error(ec, "bind"); + this->get_service().listen(this->get_implementation(), + socket_base::max_listen_connections, ec); + 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 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 asio::system_error Thrown on failure. + */ + basic_socket_acceptor(asio::io_context& io_context, + const protocol_type& protocol, const native_handle_type& native_acceptor) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), + protocol, native_acceptor, ec); + asio::detail::throw_error(ec, "assign"); + } + +#if defined(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(io_context&) constructor. + */ + basic_socket_acceptor(basic_socket_acceptor&& other) + : basic_io_object(std::move(other)) + { + } + + /// 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(io_context&) constructor. + */ + basic_socket_acceptor& operator=(basic_socket_acceptor&& 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; + + /// 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(io_context&) constructor. + */ + template + basic_socket_acceptor( + basic_socket_acceptor&& other, + typename enable_if::value>::type* = 0) + : basic_io_object( + other.get_service(), other.get_implementation()) + { + } + + /// 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(io_context&) constructor. + */ + template + typename enable_if::value, + basic_socket_acceptor>::type& operator=( + basic_socket_acceptor&& other) + { + basic_socket_acceptor tmp(std::move(other)); + basic_io_object::operator=(std::move(tmp)); + return *this; + } +#endif // defined(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() + { + } + +#if defined(ASIO_ENABLE_OLD_SERVICES) + // These functions are provided by basic_io_object<>. +#else // defined(ASIO_ENABLE_OLD_SERVICES) +#if !defined(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. + */ + 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. + */ + asio::io_context& get_io_service() + { + return basic_io_object::get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return basic_io_object::get_executor(); + } +#endif // defined(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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * acceptor.open(asio::ip::tcp::v4()); + * @endcode + */ + void open(const protocol_type& protocol = protocol_type()) + { + asio::error_code ec; + this->get_service().open(this->get_implementation(), protocol, ec); + 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 + * asio::ip::tcp::acceptor acceptor(io_context); + * asio::error_code ec; + * acceptor.open(asio::ip::tcp::v4(), ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + ASIO_SYNC_OP_VOID open(const protocol_type& protocol, + asio::error_code& ec) + { + this->get_service().open(this->get_implementation(), protocol, ec); + 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 asio::system_error Thrown on failure. + */ + void assign(const protocol_type& protocol, + const native_handle_type& native_acceptor) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), + protocol, native_acceptor, ec); + 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. + */ + ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, + const native_handle_type& native_acceptor, asio::error_code& ec) + { + this->get_service().assign(this->get_implementation(), + protocol, native_acceptor, ec); + 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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345); + * acceptor.open(endpoint.protocol()); + * acceptor.bind(endpoint); + * @endcode + */ + void bind(const endpoint_type& endpoint) + { + asio::error_code ec; + this->get_service().bind(this->get_implementation(), endpoint, ec); + 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 + * asio::ip::tcp::acceptor acceptor(io_context); + * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345); + * acceptor.open(endpoint.protocol()); + * asio::error_code ec; + * acceptor.bind(endpoint, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, + asio::error_code& ec) + { + this->get_service().bind(this->get_implementation(), endpoint, ec); + 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 asio::system_error Thrown on failure. + */ + void listen(int backlog = socket_base::max_listen_connections) + { + asio::error_code ec; + this->get_service().listen(this->get_implementation(), backlog, ec); + 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 + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::error_code ec; + * acceptor.listen(asio::socket_base::max_listen_connections, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + ASIO_SYNC_OP_VOID listen(int backlog, asio::error_code& ec) + { + this->get_service().listen(this->get_implementation(), backlog, ec); + 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 asio::system_error Thrown on failure. + */ + void close() + { + asio::error_code ec; + this->get_service().close(this->get_implementation(), ec); + 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 + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::error_code ec; + * acceptor.close(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + this->get_service().close(this->get_implementation(), ec); + 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 asio::error::operation_aborted error. Ownership of the + * native acceptor is then transferred to the caller. + * + * @throws asio::system_error Thrown on failure. + * + * @note This function is unsupported on Windows versions prior to Windows + * 8.1, and will fail with asio::error::operation_not_supported on + * these platforms. + */ +#if defined(ASIO_MSVC) && (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() + { + asio::error_code ec; + native_handle_type s = this->get_service().release( + this->get_implementation(), ec); + 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 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 asio::error::operation_not_supported on + * these platforms. + */ +#if defined(ASIO_MSVC) && (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(asio::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 asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + 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 asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) + { + this->get_service().cancel(this->get_implementation(), ec); + 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 asio::system_error Thrown on failure. + * + * @sa SettableSocketOption @n + * asio::socket_base::reuse_address + * asio::socket_base::enable_connection_aborted + * + * @par Example + * Setting the SOL_SOCKET/SO_REUSEADDR option: + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::acceptor::reuse_address option(true); + * acceptor.set_option(option); + * @endcode + */ + template + void set_option(const SettableSocketOption& option) + { + asio::error_code ec; + this->get_service().set_option(this->get_implementation(), option, ec); + 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 + * asio::socket_base::reuse_address + * asio::socket_base::enable_connection_aborted + * + * @par Example + * Setting the SOL_SOCKET/SO_REUSEADDR option: + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::acceptor::reuse_address option(true); + * asio::error_code ec; + * acceptor.set_option(option, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, + asio::error_code& ec) + { + this->get_service().set_option(this->get_implementation(), option, ec); + 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 asio::system_error Thrown on failure. + * + * @sa GettableSocketOption @n + * asio::socket_base::reuse_address + * + * @par Example + * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::acceptor::reuse_address option; + * acceptor.get_option(option); + * bool is_set = option.get(); + * @endcode + */ + template + void get_option(GettableSocketOption& option) const + { + asio::error_code ec; + this->get_service().get_option(this->get_implementation(), option, ec); + 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 + * asio::socket_base::reuse_address + * + * @par Example + * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::acceptor::reuse_address option; + * asio::error_code ec; + * acceptor.get_option(option, ec); + * if (ec) + * { + * // An error occurred. + * } + * bool is_set = option.get(); + * @endcode + */ + template + ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, + asio::error_code& ec) const + { + this->get_service().get_option(this->get_implementation(), option, ec); + 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 asio::system_error Thrown on failure. + * + * @sa IoControlCommand @n + * asio::socket_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::acceptor::non_blocking_io command(true); + * socket.io_control(command); + * @endcode + */ + template + void io_control(IoControlCommand& command) + { + asio::error_code ec; + this->get_service().io_control(this->get_implementation(), command, ec); + 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 + * asio::socket_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::acceptor::non_blocking_io command(true); + * asio::error_code ec; + * socket.io_control(command, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, + asio::error_code& ec) + { + this->get_service().io_control(this->get_implementation(), command, ec); + 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 + * 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 + * 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 asio::error::would_block if they are unable to perform the + * requested operation immediately. If @c false, synchronous operations will + * block until complete. + * + * @throws asio::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 + * asio::error::would_block. + */ + void non_blocking(bool mode) + { + asio::error_code ec; + this->get_service().non_blocking(this->get_implementation(), mode, ec); + 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 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 + * asio::error::would_block. + */ + ASIO_SYNC_OP_VOID non_blocking( + bool mode, asio::error_code& ec) + { + this->get_service().non_blocking(this->get_implementation(), mode, ec); + 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 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 asio::error::would_block + * (or the equivalent system error). + * + * @throws asio::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 asio::error::invalid_argument, as the + * combination does not make sense. + */ + void native_non_blocking(bool mode) + { + asio::error_code ec; + this->get_service().native_non_blocking( + this->get_implementation(), mode, ec); + 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 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 asio::error::invalid_argument, as the + * combination does not make sense. + */ + ASIO_SYNC_OP_VOID native_non_blocking( + bool mode, asio::error_code& ec) + { + this->get_service().native_non_blocking( + this->get_implementation(), mode, ec); + 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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); + * @endcode + */ + endpoint_type local_endpoint() const + { + asio::error_code ec; + endpoint_type ep = this->get_service().local_endpoint( + this->get_implementation(), ec); + 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 + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::error_code ec; + * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + endpoint_type local_endpoint(asio::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 + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * acceptor.wait(asio::ip::tcp::acceptor::wait_read); + * @endcode + */ + void wait(wait_type w) + { + asio::error_code ec; + this->get_service().wait(this->get_implementation(), w, ec); + 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 + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::error_code ec; + * acceptor.wait(asio::ip::tcp::acceptor::wait_read, ec); + * @endcode + */ + ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec) + { + this->get_service().wait(this->get_implementation(), w, ec); + 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 asio::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 + * asio::io_context::post(). + * + * @par Example + * @code + * void wait_handler(const asio::error_code& error) + * { + * if (!error) + * { + * // Wait succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * acceptor.async_wait( + * asio::ip::tcp::acceptor::wait_read, + * wait_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(wait_type w, 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. + ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_wait(this->get_implementation(), + w, ASIO_MOVE_CAST(WaitHandler)(handler)); +#else // defined(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(ASIO_ENABLE_OLD_SERVICES) + } + +#if !defined(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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::socket socket(io_context); + * acceptor.accept(socket); + * @endcode + */ +#if defined(ASIO_ENABLE_OLD_SERVICES) + template + void accept(basic_socket& peer, + typename enable_if::value>::type* = 0) +#else // defined(ASIO_ENABLE_OLD_SERVICES) + template + void accept(basic_socket& peer, + typename enable_if::value>::type* = 0) +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + { + asio::error_code ec; + this->get_service().accept(this->get_implementation(), + peer, static_cast(0), ec); + 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 + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::socket socket(io_context); + * asio::error_code ec; + * acceptor.accept(socket, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ +#if defined(ASIO_ENABLE_OLD_SERVICES) + template + ASIO_SYNC_OP_VOID accept( + basic_socket& peer, + asio::error_code& ec, + typename enable_if::value>::type* = 0) +#else // defined(ASIO_ENABLE_OLD_SERVICES) + template + ASIO_SYNC_OP_VOID accept( + basic_socket& peer, asio::error_code& ec, + typename enable_if::value>::type* = 0) +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + { + this->get_service().accept(this->get_implementation(), + peer, static_cast(0), ec); + 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 asio::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 + * asio::io_context::post(). + * + * @par Example + * @code + * void accept_handler(const asio::error_code& error) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::socket socket(io_context); + * acceptor.async_accept(socket, accept_handler); + * @endcode + */ +#if defined(ASIO_ENABLE_OLD_SERVICES) + template + ASIO_INITFN_RESULT_TYPE(AcceptHandler, + void (asio::error_code)) + async_accept(basic_socket& peer, + ASIO_MOVE_ARG(AcceptHandler) handler, + typename enable_if::value>::type* = 0) +#else // defined(ASIO_ENABLE_OLD_SERVICES) + template + ASIO_INITFN_RESULT_TYPE(AcceptHandler, + void (asio::error_code)) + async_accept(basic_socket& peer, + ASIO_MOVE_ARG(AcceptHandler) handler, + typename enable_if::value>::type* = 0) +#endif // defined(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. + ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_accept(this->get_implementation(), + peer, static_cast(0), + ASIO_MOVE_CAST(AcceptHandler)(handler)); +#else // defined(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(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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::socket socket(io_context); + * asio::ip::tcp::endpoint endpoint; + * acceptor.accept(socket, endpoint); + * @endcode + */ +#if defined(ASIO_ENABLE_OLD_SERVICES) + template + void accept(basic_socket& peer, + endpoint_type& peer_endpoint) +#else // defined(ASIO_ENABLE_OLD_SERVICES) + void accept(basic_socket& peer, endpoint_type& peer_endpoint) +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + { + asio::error_code ec; + this->get_service().accept(this->get_implementation(), + peer, &peer_endpoint, ec); + 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 + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::socket socket(io_context); + * asio::ip::tcp::endpoint endpoint; + * asio::error_code ec; + * acceptor.accept(socket, endpoint, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ +#if defined(ASIO_ENABLE_OLD_SERVICES) + template + ASIO_SYNC_OP_VOID accept( + basic_socket& peer, + endpoint_type& peer_endpoint, asio::error_code& ec) +#else // defined(ASIO_ENABLE_OLD_SERVICES) + ASIO_SYNC_OP_VOID accept(basic_socket& peer, + endpoint_type& peer_endpoint, asio::error_code& ec) +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + { + this->get_service().accept( + this->get_implementation(), peer, &peer_endpoint, ec); + 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 asio::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 + * asio::io_context::post(). + */ +#if defined(ASIO_ENABLE_OLD_SERVICES) + template + ASIO_INITFN_RESULT_TYPE(AcceptHandler, + void (asio::error_code)) + async_accept(basic_socket& peer, + endpoint_type& peer_endpoint, ASIO_MOVE_ARG(AcceptHandler) handler) +#else // defined(ASIO_ENABLE_OLD_SERVICES) + template + ASIO_INITFN_RESULT_TYPE(AcceptHandler, + void (asio::error_code)) + async_accept(basic_socket& peer, + endpoint_type& peer_endpoint, ASIO_MOVE_ARG(AcceptHandler) handler) +#endif // defined(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. + ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_accept(this->get_implementation(), peer, + &peer_endpoint, ASIO_MOVE_CAST(AcceptHandler)(handler)); +#else // defined(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(ASIO_ENABLE_OLD_SERVICES) + } +#endif // !defined(ASIO_NO_EXTENSIONS) + +#if defined(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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::socket socket(acceptor.accept()); + * @endcode + */ + typename Protocol::socket accept() + { + asio::error_code ec; + typename Protocol::socket peer( + this->get_service().accept( + this->get_implementation(), 0, 0, ec)); + 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 + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::socket socket(acceptor.accept(ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + typename Protocol::socket accept(asio::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 asio::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 + * asio::io_context::post(). + * + * @par Example + * @code + * void accept_handler(const asio::error_code& error, + * asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * acceptor.async_accept(accept_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (asio::error_code, typename Protocol::socket)) + async_accept(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. + ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler, + handler, typename Protocol::socket) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_accept( + this->get_implementation(), static_cast(0), + static_cast(0), + ASIO_MOVE_CAST(MoveAcceptHandler)(handler)); +#else // defined(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(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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::socket socket(acceptor.accept()); + * @endcode + */ + typename Protocol::socket accept(asio::io_context& io_context) + { + asio::error_code ec; + typename Protocol::socket peer( + this->get_service().accept(this->get_implementation(), + &io_context, static_cast(0), ec)); + 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 + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::socket socket(acceptor.accept(io_context2, ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + typename Protocol::socket accept( + asio::io_context& io_context, asio::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 asio::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 + * asio::io_context::post(). + * + * @par Example + * @code + * void accept_handler(const asio::error_code& error, + * asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * acceptor.async_accept(io_context2, accept_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (asio::error_code, typename Protocol::socket)) + async_accept(asio::io_context& io_context, + 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. + ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler, + handler, typename Protocol::socket) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_accept(this->get_implementation(), + &io_context, static_cast(0), + ASIO_MOVE_CAST(MoveAcceptHandler)(handler)); +#else // defined(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(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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * asio::ip::tcp::socket socket(acceptor.accept(endpoint)); + * @endcode + */ + typename Protocol::socket accept(endpoint_type& peer_endpoint) + { + asio::error_code ec; + typename Protocol::socket peer( + this->get_service().accept(this->get_implementation(), + static_cast(0), &peer_endpoint, ec)); + 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 + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + typename Protocol::socket accept( + endpoint_type& peer_endpoint, asio::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 asio::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 + * asio::io_context::post(). + * + * @par Example + * @code + * void accept_handler(const asio::error_code& error, + * asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * acceptor.async_accept(endpoint, accept_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (asio::error_code, typename Protocol::socket)) + async_accept(endpoint_type& peer_endpoint, + 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. + ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler, + handler, typename Protocol::socket) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_accept(this->get_implementation(), + static_cast(0), &peer_endpoint, + ASIO_MOVE_CAST(MoveAcceptHandler)(handler)); +#else // defined(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(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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * asio::ip::tcp::socket socket( + * acceptor.accept(io_context2, endpoint)); + * @endcode + */ + typename Protocol::socket accept( + asio::io_context& io_context, endpoint_type& peer_endpoint) + { + asio::error_code ec; + typename Protocol::socket peer( + this->get_service().accept(this->get_implementation(), + &io_context, &peer_endpoint, ec)); + 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 + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * asio::ip::tcp::socket socket( + * acceptor.accept(io_context2, endpoint, ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + typename Protocol::socket accept(asio::io_context& io_context, + endpoint_type& peer_endpoint, asio::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 asio::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 + * asio::io_context::post(). + * + * @par Example + * @code + * void accept_handler(const asio::error_code& error, + * asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * acceptor.async_accept(io_context2, endpoint, accept_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (asio::error_code, typename Protocol::socket)) + async_accept(asio::io_context& io_context, + endpoint_type& peer_endpoint, + 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. + ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler, + handler, typename Protocol::socket) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_accept( + this->get_implementation(), &io_context, &peer_endpoint, + ASIO_MOVE_CAST(MoveAcceptHandler)(handler)); +#else // defined(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(ASIO_ENABLE_OLD_SERVICES) + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if !defined(ASIO_ENABLE_OLD_SERVICES) +# undef ASIO_SVC_T +#endif // !defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_BASIC_SOCKET_ACCEPTOR_HPP diff --git a/tools/sdk/include/asio/asio/basic_socket_iostream.hpp b/tools/sdk/include/asio/asio/basic_socket_iostream.hpp new file mode 100644 index 00000000..6681367f --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_socket_iostream.hpp @@ -0,0 +1,430 @@ +// +// basic_socket_iostream.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BASIC_SOCKET_IOSTREAM_HPP +#define ASIO_BASIC_SOCKET_IOSTREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_NO_IOSTREAM) + +#include +#include +#include "asio/basic_socket_streambuf.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/stream_socket_service.hpp" +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#if !defined(ASIO_HAS_VARIADIC_TEMPLATES) + +# include "asio/detail/variadic_templates.hpp" + +// A macro that should expand to: +// template +// explicit basic_socket_iostream(T1 x1, ..., Tn xn) +// : std::basic_iostream( +// &this->detail::socket_iostream_base< +// Protocol ASIO_SVC_TARG, Clock, +// WaitTraits ASIO_SVC_TARG1>::streambuf_) +// { +// if (rdbuf()->connect(x1, ..., xn) == 0) +// this->setstate(std::ios_base::failbit); +// } +// This macro should only persist within this file. + +# define ASIO_PRIVATE_CTR_DEF(n) \ + template \ + explicit basic_socket_iostream(ASIO_VARIADIC_BYVAL_PARAMS(n)) \ + : std::basic_iostream( \ + &this->detail::socket_iostream_base< \ + Protocol ASIO_SVC_TARG, Clock, \ + WaitTraits ASIO_SVC_TARG1>::streambuf_) \ + { \ + this->setf(std::ios_base::unitbuf); \ + if (rdbuf()->connect(ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \ + this->setstate(std::ios_base::failbit); \ + } \ + /**/ + +// A macro that should expand to: +// template +// void connect(T1 x1, ..., Tn xn) +// { +// if (rdbuf()->connect(x1, ..., xn) == 0) +// this->setstate(std::ios_base::failbit); +// } +// This macro should only persist within this file. + +# define ASIO_PRIVATE_CONNECT_DEF(n) \ + template \ + void connect(ASIO_VARIADIC_BYVAL_PARAMS(n)) \ + { \ + if (rdbuf()->connect(ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \ + this->setstate(std::ios_base::failbit); \ + } \ + /**/ + +#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// A separate base class is used to ensure that the streambuf is initialised +// prior to the basic_socket_iostream's basic_iostream base class. +template +class socket_iostream_base +{ +protected: + socket_iostream_base() + { + } + +#if defined(ASIO_HAS_MOVE) + socket_iostream_base(socket_iostream_base&& other) + : streambuf_(std::move(other.streambuf_)) + { + } + + socket_iostream_base(basic_stream_socket s) + : streambuf_(std::move(s)) + { + } + + socket_iostream_base& operator=(socket_iostream_base&& other) + { + streambuf_ = std::move(other.streambuf_); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + basic_socket_streambuf streambuf_; +}; + +} // namespace detail + +#if !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL) +#define ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL + +// Forward declaration with defaulted arguments. +template ), +#if defined(ASIO_HAS_BOOST_DATE_TIME) \ + && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + typename Clock = boost::posix_time::ptime, + typename WaitTraits = time_traits + ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service)> +#else // defined(ASIO_HAS_BOOST_DATE_TIME) + // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + typename Clock = chrono::steady_clock, + typename WaitTraits = wait_traits + ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)> +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) +class basic_socket_iostream; + +#endif // !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL) + +/// Iostream interface for a socket. +#if defined(GENERATING_DOCUMENTATION) +template > +#else // defined(GENERATING_DOCUMENTATION) +template +#endif // defined(GENERATING_DOCUMENTATION) +class basic_socket_iostream + : private detail::socket_iostream_base, + public std::basic_iostream +{ +private: + // These typedefs are intended keep this class's implementation independent + // of whether it's using Boost.DateClock, Boost.Chrono or std::chrono. +#if defined(ASIO_HAS_BOOST_DATE_TIME) \ + && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + typedef WaitTraits traits_helper; +#else // defined(ASIO_HAS_BOOST_DATE_TIME) + // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + typedef detail::chrono_time_traits traits_helper; +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + +public: + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// The clock type. + typedef Clock clock_type; + +#if defined(GENERATING_DOCUMENTATION) + /// (Deprecated: Use time_point.) The time type. + typedef typename WaitTraits::time_type time_type; + + /// The time type. + typedef typename WaitTraits::time_point time_point; + + /// (Deprecated: Use duration.) The duration type. + typedef typename WaitTraits::duration_type duration_type; + + /// The duration type. + typedef typename WaitTraits::duration duration; +#else +# if !defined(ASIO_NO_DEPRECATED) + typedef typename traits_helper::time_type time_type; + typedef typename traits_helper::duration_type duration_type; +# endif // !defined(ASIO_NO_DEPRECATED) + typedef typename traits_helper::time_type time_point; + typedef typename traits_helper::duration_type duration; +#endif + + /// Construct a basic_socket_iostream without establishing a connection. + basic_socket_iostream() + : std::basic_iostream( + &this->detail::socket_iostream_base< + Protocol ASIO_SVC_TARG, Clock, + WaitTraits ASIO_SVC_TARG1>::streambuf_) + { + this->setf(std::ios_base::unitbuf); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Construct a basic_socket_iostream from the supplied socket. + explicit basic_socket_iostream(basic_stream_socket s) + : detail::socket_iostream_base< + Protocol ASIO_SVC_TARG, Clock, + WaitTraits ASIO_SVC_TARG1>(std::move(s)), + std::basic_iostream( + &this->detail::socket_iostream_base< + Protocol ASIO_SVC_TARG, Clock, + WaitTraits ASIO_SVC_TARG1>::streambuf_) + { + this->setf(std::ios_base::unitbuf); + } + +#if defined(ASIO_HAS_STD_IOSTREAM_MOVE) \ + || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_socket_iostream from another. + basic_socket_iostream(basic_socket_iostream&& other) + : detail::socket_iostream_base< + Protocol ASIO_SVC_TARG, Clock, + WaitTraits ASIO_SVC_TARG1>(std::move(other)), + std::basic_iostream(std::move(other)) + { + this->set_rdbuf(&this->detail::socket_iostream_base< + Protocol ASIO_SVC_TARG, Clock, + WaitTraits ASIO_SVC_TARG1>::streambuf_); + } + + /// Move-assign a basic_socket_iostream from another. + basic_socket_iostream& operator=(basic_socket_iostream&& other) + { + std::basic_iostream::operator=(std::move(other)); + detail::socket_iostream_base< + Protocol ASIO_SVC_TARG, Clock, + WaitTraits ASIO_SVC_TARG1>::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_STD_IOSTREAM_MOVE) + // || defined(GENERATING_DOCUMENTATION) +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + +#if defined(GENERATING_DOCUMENTATION) + /// Establish a connection to an endpoint corresponding to a resolver query. + /** + * This constructor automatically establishes a connection based on the + * supplied resolver query parameters. The arguments are used to construct + * a resolver query object. + */ + template + explicit basic_socket_iostream(T1 t1, ..., TN tn); +#elif defined(ASIO_HAS_VARIADIC_TEMPLATES) + template + explicit basic_socket_iostream(T... x) + : std::basic_iostream( + &this->detail::socket_iostream_base< + Protocol ASIO_SVC_TARG, Clock, + WaitTraits ASIO_SVC_TARG1>::streambuf_) + { + this->setf(std::ios_base::unitbuf); + if (rdbuf()->connect(x...) == 0) + this->setstate(std::ios_base::failbit); + } +#else + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CTR_DEF) +#endif + +#if defined(GENERATING_DOCUMENTATION) + /// Establish a connection to an endpoint corresponding to a resolver query. + /** + * This function automatically establishes a connection based on the supplied + * resolver query parameters. The arguments are used to construct a resolver + * query object. + */ + template + void connect(T1 t1, ..., TN tn); +#elif defined(ASIO_HAS_VARIADIC_TEMPLATES) + template + void connect(T... x) + { + if (rdbuf()->connect(x...) == 0) + this->setstate(std::ios_base::failbit); + } +#else + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CONNECT_DEF) +#endif + + /// Close the connection. + void close() + { + if (rdbuf()->close() == 0) + this->setstate(std::ios_base::failbit); + } + + /// Return a pointer to the underlying streambuf. + basic_socket_streambuf* rdbuf() const + { + return const_cast*>( + &this->detail::socket_iostream_base< + Protocol ASIO_SVC_TARG, Clock, + WaitTraits ASIO_SVC_TARG1>::streambuf_); + } + + /// Get a reference to the underlying socket. + basic_socket& socket() + { + return rdbuf()->socket(); + } + + /// Get the last error associated with the stream. + /** + * @return An \c error_code corresponding to the last error from the stream. + * + * @par Example + * To print the error associated with a failure to establish a connection: + * @code tcp::iostream s("www.boost.org", "http"); + * if (!s) + * { + * std::cout << "Error: " << s.error().message() << std::endl; + * } @endcode + */ + const asio::error_code& error() const + { + return rdbuf()->error(); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use expiry().) Get the stream's expiry time as an absolute + /// time. + /** + * @return An absolute time value representing the stream's expiry time. + */ + time_point expires_at() const + { + return rdbuf()->expires_at(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the stream's expiry time as an absolute time. + /** + * @return An absolute time value representing the stream's expiry time. + */ + time_point expiry() const + { + return rdbuf()->expiry(); + } + + /// Set the stream's expiry time as an absolute time. + /** + * This function sets the expiry time associated with the stream. Stream + * operations performed after this time (where the operations cannot be + * completed using the internal buffers) will fail with the error + * asio::error::operation_aborted. + * + * @param expiry_time The expiry time to be used for the stream. + */ + void expires_at(const time_point& expiry_time) + { + rdbuf()->expires_at(expiry_time); + } + + /// Set the stream's expiry time relative to now. + /** + * This function sets the expiry time associated with the stream. Stream + * operations performed after this time (where the operations cannot be + * completed using the internal buffers) will fail with the error + * asio::error::operation_aborted. + * + * @param expiry_time The expiry time to be used for the timer. + */ + void expires_after(const duration& expiry_time) + { + rdbuf()->expires_after(expiry_time); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use expiry().) Get the stream's expiry time relative to now. + /** + * @return A relative time value representing the stream's expiry time. + */ + duration expires_from_now() const + { + return rdbuf()->expires_from_now(); + } + + /// (Deprecated: Use expires_after().) Set the stream's expiry time relative + /// to now. + /** + * This function sets the expiry time associated with the stream. Stream + * operations performed after this time (where the operations cannot be + * completed using the internal buffers) will fail with the error + * asio::error::operation_aborted. + * + * @param expiry_time The expiry time to be used for the timer. + */ + void expires_from_now(const duration& expiry_time) + { + rdbuf()->expires_from_now(expiry_time); + } +#endif // !defined(ASIO_NO_DEPRECATED) + +private: + // Disallow copying and assignment. + basic_socket_iostream(const basic_socket_iostream&) ASIO_DELETED; + basic_socket_iostream& operator=( + const basic_socket_iostream&) ASIO_DELETED; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if !defined(ASIO_HAS_VARIADIC_TEMPLATES) +# undef ASIO_PRIVATE_CTR_DEF +# undef ASIO_PRIVATE_CONNECT_DEF +#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_BASIC_SOCKET_IOSTREAM_HPP diff --git a/tools/sdk/include/asio/asio/basic_socket_streambuf.hpp b/tools/sdk/include/asio/asio/basic_socket_streambuf.hpp new file mode 100644 index 00000000..56a3637d --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_socket_streambuf.hpp @@ -0,0 +1,707 @@ +// +// basic_socket_streambuf.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BASIC_SOCKET_STREAMBUF_HPP +#define ASIO_BASIC_SOCKET_STREAMBUF_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_NO_IOSTREAM) + +#include +#include +#include "asio/basic_socket.hpp" +#include "asio/basic_stream_socket.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/io_context.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/stream_socket_service.hpp" +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_BOOST_DATE_TIME) \ + && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) +# if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/deadline_timer_service.hpp" +# else // defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/detail/deadline_timer_service.hpp" +# endif // defined(ASIO_ENABLE_OLD_SERVICES) +#else // defined(ASIO_HAS_BOOST_DATE_TIME) + // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) +# include "asio/steady_timer.hpp" +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + +#if !defined(ASIO_HAS_VARIADIC_TEMPLATES) + +# include "asio/detail/variadic_templates.hpp" + +// A macro that should expand to: +// template +// basic_socket_streambuf* connect(T1 x1, ..., Tn xn) +// { +// init_buffers(); +// typedef typename Protocol::resolver resolver_type; +// resolver_type resolver(socket().get_executor().context()); +// connect_to_endpoints( +// resolver.resolve(x1, ..., xn, ec_)); +// return !ec_ ? this : 0; +// } +// This macro should only persist within this file. + +# define ASIO_PRIVATE_CONNECT_DEF(n) \ + template \ + basic_socket_streambuf* connect(ASIO_VARIADIC_BYVAL_PARAMS(n)) \ + { \ + init_buffers(); \ + typedef typename Protocol::resolver resolver_type; \ + resolver_type resolver(socket().get_executor().context()); \ + connect_to_endpoints( \ + resolver.resolve(ASIO_VARIADIC_BYVAL_ARGS(n), ec_)); \ + return !ec_ ? this : 0; \ + } \ + /**/ + +#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) + +#if !defined(ASIO_ENABLE_OLD_SERVICES) +# define ASIO_SVC_T1 detail::deadline_timer_service +#endif // !defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// A separate base class is used to ensure that the io_context member is +// initialised prior to the basic_socket_streambuf's basic_socket base class. +class socket_streambuf_io_context +{ +protected: + socket_streambuf_io_context(io_context* ctx) + : default_io_context_(ctx) + { + } + + shared_ptr default_io_context_; +}; + +// A separate base class is used to ensure that the dynamically allocated +// buffers are constructed prior to the basic_socket_streambuf's basic_socket +// base class. This makes moving the socket is the last potentially throwing +// step in the streambuf's move constructor, giving the constructor a strong +// exception safety guarantee. +class socket_streambuf_buffers +{ +protected: + socket_streambuf_buffers() + : get_buffer_(buffer_size), + put_buffer_(buffer_size) + { + } + + enum { buffer_size = 512 }; + std::vector get_buffer_; + std::vector put_buffer_; +}; + +} // namespace detail + +#if !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL) +#define ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL + +// Forward declaration with defaulted arguments. +template ), +#if defined(ASIO_HAS_BOOST_DATE_TIME) \ + && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + typename Clock = boost::posix_time::ptime, + typename WaitTraits = time_traits + ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service)> +#else // defined(ASIO_HAS_BOOST_DATE_TIME) + // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + typename Clock = chrono::steady_clock, + typename WaitTraits = wait_traits + ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)> +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) +class basic_socket_streambuf; + +#endif // !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL) + +/// Iostream streambuf for a socket. +#if defined(GENERATING_DOCUMENTATION) +template > +#else // defined(GENERATING_DOCUMENTATION) +template +#endif // defined(GENERATING_DOCUMENTATION) +class basic_socket_streambuf + : public std::streambuf, + private detail::socket_streambuf_io_context, + private detail::socket_streambuf_buffers, +#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) + private basic_socket +#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) + public basic_socket +#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) +{ +private: + // These typedefs are intended keep this class's implementation independent + // of whether it's using Boost.DateClock, Boost.Chrono or std::chrono. +#if defined(ASIO_HAS_BOOST_DATE_TIME) \ + && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + typedef WaitTraits traits_helper; +#else // defined(ASIO_HAS_BOOST_DATE_TIME) + // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + typedef detail::chrono_time_traits traits_helper; +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + +public: + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// The clock type. + typedef Clock clock_type; + +#if defined(GENERATING_DOCUMENTATION) + /// (Deprecated: Use time_point.) The time type. + typedef typename WaitTraits::time_type time_type; + + /// The time type. + typedef typename WaitTraits::time_point time_point; + + /// (Deprecated: Use duration.) The duration type. + typedef typename WaitTraits::duration_type duration_type; + + /// The duration type. + typedef typename WaitTraits::duration duration; +#else +# if !defined(ASIO_NO_DEPRECATED) + typedef typename traits_helper::time_type time_type; + typedef typename traits_helper::duration_type duration_type; +# endif // !defined(ASIO_NO_DEPRECATED) + typedef typename traits_helper::time_type time_point; + typedef typename traits_helper::duration_type duration; +#endif + + /// Construct a basic_socket_streambuf without establishing a connection. + basic_socket_streambuf() + : detail::socket_streambuf_io_context(new io_context), + basic_socket(*default_io_context_), + expiry_time_(max_expiry_time()) + { + init_buffers(); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Construct a basic_socket_streambuf from the supplied socket. + explicit basic_socket_streambuf(basic_stream_socket s) + : detail::socket_streambuf_io_context(0), + basic_socket(std::move(s)), + expiry_time_(max_expiry_time()) + { + init_buffers(); + } + + /// Move-construct a basic_socket_streambuf from another. + basic_socket_streambuf(basic_socket_streambuf&& other) + : detail::socket_streambuf_io_context(other), + basic_socket(std::move(other.socket())), + ec_(other.ec_), + expiry_time_(other.expiry_time_) + { + get_buffer_.swap(other.get_buffer_); + put_buffer_.swap(other.put_buffer_); + setg(other.eback(), other.gptr(), other.egptr()); + setp(other.pptr(), other.epptr()); + other.ec_ = asio::error_code(); + other.expiry_time_ = max_expiry_time(); + other.init_buffers(); + } + + /// Move-assign a basic_socket_streambuf from another. + basic_socket_streambuf& operator=(basic_socket_streambuf&& other) + { + this->close(); + socket() = std::move(other.socket()); + detail::socket_streambuf_io_context::operator=(other); + ec_ = other.ec_; + expiry_time_ = other.expiry_time_; + get_buffer_.swap(other.get_buffer_); + put_buffer_.swap(other.put_buffer_); + setg(other.eback(), other.gptr(), other.egptr()); + setp(other.pptr(), other.epptr()); + other.ec_ = asio::error_code(); + other.expiry_time_ = max_expiry_time(); + other.put_buffer_.resize(buffer_size); + other.init_buffers(); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destructor flushes buffered data. + virtual ~basic_socket_streambuf() + { + if (pptr() != pbase()) + overflow(traits_type::eof()); + } + + /// Establish a connection. + /** + * This function establishes a connection to the specified endpoint. + * + * @return \c this if a connection was successfully established, a null + * pointer otherwise. + */ + basic_socket_streambuf* connect(const endpoint_type& endpoint) + { + init_buffers(); + ec_ = asio::error_code(); + this->connect_to_endpoints(&endpoint, &endpoint + 1); + return !ec_ ? this : 0; + } + +#if defined(GENERATING_DOCUMENTATION) + /// Establish a connection. + /** + * This function automatically establishes a connection based on the supplied + * resolver query parameters. The arguments are used to construct a resolver + * query object. + * + * @return \c this if a connection was successfully established, a null + * pointer otherwise. + */ + template + basic_socket_streambuf* connect(T1 t1, ..., TN tn); +#elif defined(ASIO_HAS_VARIADIC_TEMPLATES) + template + basic_socket_streambuf* connect(T... x) + { + init_buffers(); + typedef typename Protocol::resolver resolver_type; + resolver_type resolver(socket().get_executor().context()); + connect_to_endpoints(resolver.resolve(x..., ec_)); + return !ec_ ? this : 0; + } +#else + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CONNECT_DEF) +#endif + + /// Close the connection. + /** + * @return \c this if a connection was successfully established, a null + * pointer otherwise. + */ + basic_socket_streambuf* close() + { + sync(); + socket().close(ec_); + if (!ec_) + init_buffers(); + return !ec_ ? this : 0; + } + + /// Get a reference to the underlying socket. + basic_socket& socket() + { + return *this; + } + + /// Get the last error associated with the stream buffer. + /** + * @return An \c error_code corresponding to the last error from the stream + * buffer. + */ + const asio::error_code& error() const + { + return ec_; + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use error().) Get the last error associated with the stream + /// buffer. + /** + * @return An \c error_code corresponding to the last error from the stream + * buffer. + */ + const asio::error_code& puberror() const + { + return error(); + } + + /// (Deprecated: Use expiry().) Get the stream buffer's expiry time as an + /// absolute time. + /** + * @return An absolute time value representing the stream buffer's expiry + * time. + */ + time_point expires_at() const + { + return expiry_time_; + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the stream buffer's expiry time as an absolute time. + /** + * @return An absolute time value representing the stream buffer's expiry + * time. + */ + time_point expiry() const + { + return expiry_time_; + } + + /// Set the stream buffer's expiry time as an absolute time. + /** + * This function sets the expiry time associated with the stream. Stream + * operations performed after this time (where the operations cannot be + * completed using the internal buffers) will fail with the error + * asio::error::operation_aborted. + * + * @param expiry_time The expiry time to be used for the stream. + */ + void expires_at(const time_point& expiry_time) + { + expiry_time_ = expiry_time; + } + + /// Set the stream buffer's expiry time relative to now. + /** + * This function sets the expiry time associated with the stream. Stream + * operations performed after this time (where the operations cannot be + * completed using the internal buffers) will fail with the error + * asio::error::operation_aborted. + * + * @param expiry_time The expiry time to be used for the timer. + */ + void expires_after(const duration& expiry_time) + { + expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use expiry().) Get the stream buffer's expiry time relative + /// to now. + /** + * @return A relative time value representing the stream buffer's expiry time. + */ + duration expires_from_now() const + { + return traits_helper::subtract(expires_at(), traits_helper::now()); + } + + /// (Deprecated: Use expires_after().) Set the stream buffer's expiry time + /// relative to now. + /** + * This function sets the expiry time associated with the stream. Stream + * operations performed after this time (where the operations cannot be + * completed using the internal buffers) will fail with the error + * asio::error::operation_aborted. + * + * @param expiry_time The expiry time to be used for the timer. + */ + void expires_from_now(const duration& expiry_time) + { + expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time); + } +#endif // !defined(ASIO_NO_DEPRECATED) + +protected: + int_type underflow() + { +#if defined(ASIO_WINDOWS_RUNTIME) + ec_ = asio::error::operation_not_supported; + return traits_type::eof(); +#else // defined(ASIO_WINDOWS_RUNTIME) + if (gptr() != egptr()) + return traits_type::eof(); + + for (;;) + { + // Check if we are past the expiry time. + if (traits_helper::less_than(expiry_time_, traits_helper::now())) + { + ec_ = asio::error::timed_out; + return traits_type::eof(); + } + + // Try to complete the operation without blocking. + if (!socket().native_non_blocking()) + socket().native_non_blocking(true, ec_); + detail::buffer_sequence_adapter + bufs(asio::buffer(get_buffer_) + putback_max); + detail::signed_size_type bytes = detail::socket_ops::recv( + socket().native_handle(), bufs.buffers(), bufs.count(), 0, ec_); + + // Check if operation succeeded. + if (bytes > 0) + { + setg(&get_buffer_[0], &get_buffer_[0] + putback_max, + &get_buffer_[0] + putback_max + bytes); + return traits_type::to_int_type(*gptr()); + } + + // Check for EOF. + if (bytes == 0) + { + ec_ = asio::error::eof; + return traits_type::eof(); + } + + // Operation failed. + if (ec_ != asio::error::would_block + && ec_ != asio::error::try_again) + return traits_type::eof(); + + // Wait for socket to become ready. + if (detail::socket_ops::poll_read( + socket().native_handle(), 0, timeout(), ec_) < 0) + return traits_type::eof(); + } +#endif // defined(ASIO_WINDOWS_RUNTIME) + } + + int_type overflow(int_type c) + { +#if defined(ASIO_WINDOWS_RUNTIME) + ec_ = asio::error::operation_not_supported; + return traits_type::eof(); +#else // defined(ASIO_WINDOWS_RUNTIME) + char_type ch = traits_type::to_char_type(c); + + // Determine what needs to be sent. + const_buffer output_buffer; + if (put_buffer_.empty()) + { + if (traits_type::eq_int_type(c, traits_type::eof())) + return traits_type::not_eof(c); // Nothing to do. + output_buffer = asio::buffer(&ch, sizeof(char_type)); + } + else + { + output_buffer = asio::buffer(pbase(), + (pptr() - pbase()) * sizeof(char_type)); + } + + while (output_buffer.size() > 0) + { + // Check if we are past the expiry time. + if (traits_helper::less_than(expiry_time_, traits_helper::now())) + { + ec_ = asio::error::timed_out; + return traits_type::eof(); + } + + // Try to complete the operation without blocking. + if (!socket().native_non_blocking()) + socket().native_non_blocking(true, ec_); + detail::buffer_sequence_adapter< + const_buffer, const_buffer> bufs(output_buffer); + detail::signed_size_type bytes = detail::socket_ops::send( + socket().native_handle(), bufs.buffers(), bufs.count(), 0, ec_); + + // Check if operation succeeded. + if (bytes > 0) + { + output_buffer += static_cast(bytes); + continue; + } + + // Operation failed. + if (ec_ != asio::error::would_block + && ec_ != asio::error::try_again) + return traits_type::eof(); + + // Wait for socket to become ready. + if (detail::socket_ops::poll_write( + socket().native_handle(), 0, timeout(), ec_) < 0) + return traits_type::eof(); + } + + if (!put_buffer_.empty()) + { + setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size()); + + // If the new character is eof then our work here is done. + if (traits_type::eq_int_type(c, traits_type::eof())) + return traits_type::not_eof(c); + + // Add the new character to the output buffer. + *pptr() = ch; + pbump(1); + } + + return c; +#endif // defined(ASIO_WINDOWS_RUNTIME) + } + + int sync() + { + return overflow(traits_type::eof()); + } + + std::streambuf* setbuf(char_type* s, std::streamsize n) + { + if (pptr() == pbase() && s == 0 && n == 0) + { + put_buffer_.clear(); + setp(0, 0); + sync(); + return this; + } + + return 0; + } + +private: + // Disallow copying and assignment. + basic_socket_streambuf(const basic_socket_streambuf&) ASIO_DELETED; + basic_socket_streambuf& operator=( + const basic_socket_streambuf&) ASIO_DELETED; + + void init_buffers() + { + setg(&get_buffer_[0], + &get_buffer_[0] + putback_max, + &get_buffer_[0] + putback_max); + + if (put_buffer_.empty()) + setp(0, 0); + else + setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size()); + } + + int timeout() const + { + int64_t msec = traits_helper::to_posix_duration( + traits_helper::subtract(expiry_time_, + traits_helper::now())).total_milliseconds(); + if (msec > (std::numeric_limits::max)()) + msec = (std::numeric_limits::max)(); + else if (msec < 0) + msec = 0; + return static_cast(msec); + } + + template + void connect_to_endpoints(const EndpointSequence& endpoints) + { + this->connect_to_endpoints(endpoints.begin(), endpoints.end()); + } + + template + void connect_to_endpoints(EndpointIterator begin, EndpointIterator end) + { +#if defined(ASIO_WINDOWS_RUNTIME) + ec_ = asio::error::operation_not_supported; +#else // defined(ASIO_WINDOWS_RUNTIME) + if (ec_) + return; + + ec_ = asio::error::not_found; + for (EndpointIterator i = begin; i != end; ++i) + { + // Check if we are past the expiry time. + if (traits_helper::less_than(expiry_time_, traits_helper::now())) + { + ec_ = asio::error::timed_out; + return; + } + + // Close and reopen the socket. + typename Protocol::endpoint ep(*i); + socket().close(ec_); + socket().open(ep.protocol(), ec_); + if (ec_) + continue; + + // Try to complete the operation without blocking. + if (!socket().native_non_blocking()) + socket().native_non_blocking(true, ec_); + detail::socket_ops::connect(socket().native_handle(), + ep.data(), ep.size(), ec_); + + // Check if operation succeeded. + if (!ec_) + return; + + // Operation failed. + if (ec_ != asio::error::in_progress + && ec_ != asio::error::would_block) + continue; + + // Wait for socket to become ready. + if (detail::socket_ops::poll_connect( + socket().native_handle(), timeout(), ec_) < 0) + continue; + + // Get the error code from the connect operation. + int connect_error = 0; + size_t connect_error_len = sizeof(connect_error); + if (detail::socket_ops::getsockopt(socket().native_handle(), 0, + SOL_SOCKET, SO_ERROR, &connect_error, &connect_error_len, ec_) + == detail::socket_error_retval) + return; + + // Check the result of the connect operation. + ec_ = asio::error_code(connect_error, + asio::error::get_system_category()); + if (!ec_) + return; + } +#endif // defined(ASIO_WINDOWS_RUNTIME) + } + + // Helper function to get the maximum expiry time. + static time_point max_expiry_time() + { +#if defined(ASIO_HAS_BOOST_DATE_TIME) \ + && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + return boost::posix_time::pos_infin; +#else // defined(ASIO_HAS_BOOST_DATE_TIME) + // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + return (time_point::max)(); +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + } + + enum { putback_max = 8 }; + asio::error_code ec_; + time_point expiry_time_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if !defined(ASIO_ENABLE_OLD_SERVICES) +# undef ASIO_SVC_T1 +#endif // !defined(ASIO_ENABLE_OLD_SERVICES) + +#if !defined(ASIO_HAS_VARIADIC_TEMPLATES) +# undef ASIO_PRIVATE_CONNECT_DEF +#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_BASIC_SOCKET_STREAMBUF_HPP diff --git a/tools/sdk/include/asio/asio/basic_stream_socket.hpp b/tools/sdk/include/asio/asio/basic_stream_socket.hpp new file mode 100644 index 00000000..eea88627 --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_stream_socket.hpp @@ -0,0 +1,921 @@ +// +// basic_stream_socket.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BASIC_STREAM_SOCKET_HPP +#define ASIO_BASIC_STREAM_SOCKET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/async_result.hpp" +#include "asio/basic_socket.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/stream_socket_service.hpp" +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Provides stream-oriented socket functionality. +/** + * The basic_stream_socket 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 + : public basic_socket +{ +public: + /// The native representation of a socket. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef typename basic_socket< + Protocol 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 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(asio::io_context& io_context) + : basic_socket(io_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 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 asio::system_error Thrown on failure. + */ + basic_stream_socket(asio::io_context& io_context, + const protocol_type& protocol) + : basic_socket(io_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 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 asio::system_error Thrown on failure. + */ + basic_stream_socket(asio::io_context& io_context, + const endpoint_type& endpoint) + : basic_socket(io_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 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 asio::system_error Thrown on failure. + */ + basic_stream_socket(asio::io_context& io_context, + const protocol_type& protocol, const native_handle_type& native_socket) + : basic_socket( + io_context, protocol, native_socket) + { + } + +#if defined(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(io_context&) constructor. + */ + basic_stream_socket(basic_stream_socket&& other) + : basic_socket(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(io_context&) constructor. + */ + basic_stream_socket& operator=(basic_stream_socket&& other) + { + basic_socket::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(io_context&) constructor. + */ + template + basic_stream_socket( + basic_stream_socket&& other, + typename enable_if::value>::type* = 0) + : basic_socket(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(io_context&) constructor. + */ + template + typename enable_if::value, + basic_stream_socket>::type& operator=( + basic_stream_socket&& other) + { + basic_socket::operator=(std::move(other)); + return *this; + } +#endif // defined(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() + { + } + + /// 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 asio::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(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) + { + asio::error_code ec; + std::size_t s = this->get_service().send( + this->get_implementation(), buffers, 0, ec); + 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 asio::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(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) + { + asio::error_code ec; + std::size_t s = this->get_service().send( + this->get_implementation(), buffers, flags, ec); + 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, asio::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 asio::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 + * 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(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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send(const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_send( + this->get_implementation(), buffers, 0, + ASIO_MOVE_CAST(WriteHandler)(handler)); +#else // defined(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(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 asio::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 + * 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(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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_send( + this->get_implementation(), buffers, flags, + ASIO_MOVE_CAST(WriteHandler)(handler)); +#else // defined(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(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 asio::system_error Thrown on failure. An error code of + * 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(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) + { + asio::error_code ec; + std::size_t s = this->get_service().receive( + this->get_implementation(), buffers, 0, ec); + 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 asio::system_error Thrown on failure. An error code of + * 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(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) + { + asio::error_code ec; + std::size_t s = this->get_service().receive( + this->get_implementation(), buffers, flags, ec); + 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, asio::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 asio::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 + * 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(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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive(const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_receive(this->get_implementation(), + buffers, 0, ASIO_MOVE_CAST(ReadHandler)(handler)); +#else // defined(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(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 asio::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 + * 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(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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_receive(this->get_implementation(), + buffers, flags, ASIO_MOVE_CAST(ReadHandler)(handler)); +#else // defined(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(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 asio::system_error Thrown on failure. An error code of + * 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(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) + { + asio::error_code ec; + std::size_t s = this->get_service().send( + this->get_implementation(), buffers, 0, ec); + 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, + asio::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 asio::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 + * 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(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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_send(this->get_implementation(), + buffers, 0, ASIO_MOVE_CAST(WriteHandler)(handler)); +#else // defined(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(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 asio::system_error Thrown on failure. An error code of + * 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(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) + { + asio::error_code ec; + std::size_t s = this->get_service().receive( + this->get_implementation(), buffers, 0, ec); + 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, + asio::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 asio::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 + * 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(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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_receive(this->get_implementation(), + buffers, 0, ASIO_MOVE_CAST(ReadHandler)(handler)); +#else // defined(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(ASIO_ENABLE_OLD_SERVICES) + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_STREAM_SOCKET_HPP diff --git a/tools/sdk/include/asio/asio/basic_streambuf.hpp b/tools/sdk/include/asio/asio/basic_streambuf.hpp new file mode 100644 index 00000000..14f85d22 --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_streambuf.hpp @@ -0,0 +1,452 @@ +// +// basic_streambuf.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BASIC_STREAMBUF_HPP +#define ASIO_BASIC_STREAMBUF_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_NO_IOSTREAM) + +#include +#include +#include +#include +#include +#include "asio/basic_streambuf_fwd.hpp" +#include "asio/buffer.hpp" +#include "asio/detail/limits.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/throw_exception.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Automatically resizable buffer class based on std::streambuf. +/** + * The @c basic_streambuf class is derived from @c std::streambuf to associate + * the streambuf's input and output sequences with one or more character + * arrays. These character arrays are internal to the @c basic_streambuf + * object, but direct access to the array elements is provided to permit them + * to be used efficiently with I/O operations. Characters written to the output + * sequence of a @c basic_streambuf object are appended to the input sequence + * of the same object. + * + * The @c basic_streambuf class's public interface is intended to permit the + * following implementation strategies: + * + * @li A single contiguous character array, which is reallocated as necessary + * to accommodate changes in the size of the character sequence. This is the + * implementation approach currently used in Asio. + * + * @li A sequence of one or more character arrays, where each array is of the + * same size. Additional character array objects are appended to the sequence + * to accommodate changes in the size of the character sequence. + * + * @li A sequence of one or more character arrays of varying sizes. Additional + * character array objects are appended to the sequence to accommodate changes + * in the size of the character sequence. + * + * The constructor for basic_streambuf accepts a @c size_t argument specifying + * the maximum of the sum of the sizes of the input sequence and output + * sequence. During the lifetime of the @c basic_streambuf object, the following + * invariant holds: + * @code size() <= max_size()@endcode + * Any member function that would, if successful, cause the invariant to be + * violated shall throw an exception of class @c std::length_error. + * + * The constructor for @c basic_streambuf takes an Allocator argument. A copy + * of this argument is used for any memory allocation performed, by the + * constructor and by all member functions, during the lifetime of each @c + * basic_streambuf object. + * + * @par Examples + * Writing directly from an streambuf to a socket: + * @code + * asio::streambuf b; + * std::ostream os(&b); + * os << "Hello, World!\n"; + * + * // try sending some data in input sequence + * size_t n = sock.send(b.data()); + * + * b.consume(n); // sent data is removed from input sequence + * @endcode + * + * Reading from a socket directly into a streambuf: + * @code + * asio::streambuf b; + * + * // reserve 512 bytes in output sequence + * asio::streambuf::mutable_buffers_type bufs = b.prepare(512); + * + * size_t n = sock.receive(bufs); + * + * // received data is "committed" from output sequence to input sequence + * b.commit(n); + * + * std::istream is(&b); + * std::string s; + * is >> s; + * @endcode + */ +#if defined(GENERATING_DOCUMENTATION) +template > +#else +template +#endif +class basic_streambuf + : public std::streambuf, + private noncopyable +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The type used to represent the input sequence as a list of buffers. + typedef implementation_defined const_buffers_type; + + /// The type used to represent the output sequence as a list of buffers. + typedef implementation_defined mutable_buffers_type; +#else + typedef ASIO_CONST_BUFFER const_buffers_type; + typedef ASIO_MUTABLE_BUFFER mutable_buffers_type; +#endif + + /// Construct a basic_streambuf object. + /** + * Constructs a streambuf with the specified maximum size. The initial size + * of the streambuf's input sequence is 0. + */ + explicit basic_streambuf( + std::size_t maximum_size = (std::numeric_limits::max)(), + const Allocator& allocator = Allocator()) + : max_size_(maximum_size), + buffer_(allocator) + { + std::size_t pend = (std::min)(max_size_, buffer_delta); + buffer_.resize((std::max)(pend, 1)); + setg(&buffer_[0], &buffer_[0], &buffer_[0]); + setp(&buffer_[0], &buffer_[0] + pend); + } + + /// Get the size of the input sequence. + /** + * @returns The size of the input sequence. The value is equal to that + * calculated for @c s in the following code: + * @code + * size_t s = 0; + * const_buffers_type bufs = data(); + * const_buffers_type::const_iterator i = bufs.begin(); + * while (i != bufs.end()) + * { + * const_buffer buf(*i++); + * s += buf.size(); + * } + * @endcode + */ + std::size_t size() const ASIO_NOEXCEPT + { + return pptr() - gptr(); + } + + /// Get the maximum size of the basic_streambuf. + /** + * @returns The allowed maximum of the sum of the sizes of the input sequence + * and output sequence. + */ + std::size_t max_size() const ASIO_NOEXCEPT + { + return max_size_; + } + + /// Get the current capacity of the basic_streambuf. + /** + * @returns The current total capacity of the streambuf, i.e. for both the + * input sequence and output sequence. + */ + std::size_t capacity() const ASIO_NOEXCEPT + { + return buffer_.capacity(); + } + + /// Get a list of buffers that represents the input sequence. + /** + * @returns An object of type @c const_buffers_type that satisfies + * ConstBufferSequence requirements, representing all character arrays in the + * input sequence. + * + * @note The returned object is invalidated by any @c basic_streambuf member + * function that modifies the input sequence or output sequence. + */ + const_buffers_type data() const ASIO_NOEXCEPT + { + return asio::buffer(asio::const_buffer(gptr(), + (pptr() - gptr()) * sizeof(char_type))); + } + + /// Get a list of buffers that represents the output sequence, with the given + /// size. + /** + * Ensures that the output sequence can accommodate @c n characters, + * reallocating character array objects as necessary. + * + * @returns An object of type @c mutable_buffers_type that satisfies + * MutableBufferSequence requirements, representing character array objects + * at the start of the output sequence such that the sum of the buffer sizes + * is @c n. + * + * @throws std::length_error If size() + n > max_size(). + * + * @note The returned object is invalidated by any @c basic_streambuf member + * function that modifies the input sequence or output sequence. + */ + mutable_buffers_type prepare(std::size_t n) + { + reserve(n); + return asio::buffer(asio::mutable_buffer( + pptr(), n * sizeof(char_type))); + } + + /// Move characters from the output sequence to the input sequence. + /** + * Appends @c n characters from the start of the output sequence to the input + * sequence. The beginning of the output sequence is advanced by @c n + * characters. + * + * Requires a preceding call prepare(x) where x >= n, and + * no intervening operations that modify the input or output sequence. + * + * @note If @c n is greater than the size of the output sequence, the entire + * output sequence is moved to the input sequence and no error is issued. + */ + void commit(std::size_t n) + { + n = std::min(n, epptr() - pptr()); + pbump(static_cast(n)); + setg(eback(), gptr(), pptr()); + } + + /// Remove characters from the input sequence. + /** + * Removes @c n characters from the beginning of the input sequence. + * + * @note If @c n is greater than the size of the input sequence, the entire + * input sequence is consumed and no error is issued. + */ + void consume(std::size_t n) + { + if (egptr() < pptr()) + setg(&buffer_[0], gptr(), pptr()); + if (gptr() + n > pptr()) + n = pptr() - gptr(); + gbump(static_cast(n)); + } + +protected: + enum { buffer_delta = 128 }; + + /// Override std::streambuf behaviour. + /** + * Behaves according to the specification of @c std::streambuf::underflow(). + */ + int_type underflow() + { + if (gptr() < pptr()) + { + setg(&buffer_[0], gptr(), pptr()); + return traits_type::to_int_type(*gptr()); + } + else + { + return traits_type::eof(); + } + } + + /// Override std::streambuf behaviour. + /** + * Behaves according to the specification of @c std::streambuf::overflow(), + * with the specialisation that @c std::length_error is thrown if appending + * the character to the input sequence would require the condition + * size() > max_size() to be true. + */ + int_type overflow(int_type c) + { + if (!traits_type::eq_int_type(c, traits_type::eof())) + { + if (pptr() == epptr()) + { + std::size_t buffer_size = pptr() - gptr(); + if (buffer_size < max_size_ && max_size_ - buffer_size < buffer_delta) + { + reserve(max_size_ - buffer_size); + } + else + { + reserve(buffer_delta); + } + } + + *pptr() = traits_type::to_char_type(c); + pbump(1); + return c; + } + + return traits_type::not_eof(c); + } + + void reserve(std::size_t n) + { + // Get current stream positions as offsets. + std::size_t gnext = gptr() - &buffer_[0]; + std::size_t pnext = pptr() - &buffer_[0]; + std::size_t pend = epptr() - &buffer_[0]; + + // Check if there is already enough space in the put area. + if (n <= pend - pnext) + { + return; + } + + // Shift existing contents of get area to start of buffer. + if (gnext > 0) + { + pnext -= gnext; + std::memmove(&buffer_[0], &buffer_[0] + gnext, pnext); + } + + // Ensure buffer is large enough to hold at least the specified size. + if (n > pend - pnext) + { + if (n <= max_size_ && pnext <= max_size_ - n) + { + pend = pnext + n; + buffer_.resize((std::max)(pend, 1)); + } + else + { + std::length_error ex("asio::streambuf too long"); + asio::detail::throw_exception(ex); + } + } + + // Update stream positions. + setg(&buffer_[0], &buffer_[0], &buffer_[0] + pnext); + setp(&buffer_[0] + pnext, &buffer_[0] + pend); + } + +private: + std::size_t max_size_; + std::vector buffer_; + + // Helper function to get the preferred size for reading data. + friend std::size_t read_size_helper( + basic_streambuf& sb, std::size_t max_size) + { + return std::min( + std::max(512, sb.buffer_.capacity() - sb.size()), + std::min(max_size, sb.max_size() - sb.size())); + } +}; + +/// Adapts basic_streambuf to the dynamic buffer sequence type requirements. +#if defined(GENERATING_DOCUMENTATION) +template > +#else +template +#endif +class basic_streambuf_ref +{ +public: + /// The type used to represent the input sequence as a list of buffers. + typedef typename basic_streambuf::const_buffers_type + const_buffers_type; + + /// The type used to represent the output sequence as a list of buffers. + typedef typename basic_streambuf::mutable_buffers_type + mutable_buffers_type; + + /// Construct a basic_streambuf_ref for the given basic_streambuf object. + explicit basic_streambuf_ref(basic_streambuf& sb) + : sb_(sb) + { + } + + /// Copy construct a basic_streambuf_ref. + basic_streambuf_ref(const basic_streambuf_ref& other) ASIO_NOEXCEPT + : sb_(other.sb_) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move construct a basic_streambuf_ref. + basic_streambuf_ref(basic_streambuf_ref&& other) ASIO_NOEXCEPT + : sb_(other.sb_) + { + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Get the size of the input sequence. + std::size_t size() const ASIO_NOEXCEPT + { + return sb_.size(); + } + + /// Get the maximum size of the dynamic buffer. + std::size_t max_size() const ASIO_NOEXCEPT + { + return sb_.max_size(); + } + + /// Get the current capacity of the dynamic buffer. + std::size_t capacity() const ASIO_NOEXCEPT + { + return sb_.capacity(); + } + + /// Get a list of buffers that represents the input sequence. + const_buffers_type data() const ASIO_NOEXCEPT + { + return sb_.data(); + } + + /// Get a list of buffers that represents the output sequence, with the given + /// size. + mutable_buffers_type prepare(std::size_t n) + { + return sb_.prepare(n); + } + + /// Move bytes from the output sequence to the input sequence. + void commit(std::size_t n) + { + return sb_.commit(n); + } + + /// Remove characters from the input sequence. + void consume(std::size_t n) + { + return sb_.consume(n); + } + +private: + basic_streambuf& sb_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_BASIC_STREAMBUF_HPP diff --git a/tools/sdk/include/asio/asio/basic_streambuf_fwd.hpp b/tools/sdk/include/asio/asio/basic_streambuf_fwd.hpp new file mode 100644 index 00000000..ed54fe95 --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_streambuf_fwd.hpp @@ -0,0 +1,36 @@ +// +// basic_streambuf_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BASIC_STREAMBUF_FWD_HPP +#define ASIO_BASIC_STREAMBUF_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_NO_IOSTREAM) + +#include + +namespace asio { + +template > +class basic_streambuf; + +template > +class basic_streambuf_ref; + +} // namespace asio + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_BASIC_STREAMBUF_FWD_HPP diff --git a/tools/sdk/include/asio/asio/basic_waitable_timer.hpp b/tools/sdk/include/asio/asio/basic_waitable_timer.hpp new file mode 100644 index 00000000..22b85a69 --- /dev/null +++ b/tools/sdk/include/asio/asio/basic_waitable_timer.hpp @@ -0,0 +1,705 @@ +// +// basic_waitable_timer.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BASIC_WAITABLE_TIMER_HPP +#define ASIO_BASIC_WAITABLE_TIMER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/basic_io_object.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/wait_traits.hpp" + +#if defined(ASIO_HAS_MOVE) +# include +#endif // defined(ASIO_HAS_MOVE) + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/waitable_timer_service.hpp" +#else // defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/detail/chrono_time_traits.hpp" +# include "asio/detail/deadline_timer_service.hpp" +# define ASIO_SVC_T \ + detail::deadline_timer_service< \ + detail::chrono_time_traits > +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +#if !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) +#define ASIO_BASIC_WAITABLE_TIMER_FWD_DECL + +// Forward declaration with defaulted arguments. +template + ASIO_SVC_TPARAM_DEF2(= waitable_timer_service)> +class basic_waitable_timer; + +#endif // !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) + +/// Provides waitable timer functionality. +/** + * The basic_waitable_timer class template provides the ability to perform a + * blocking or asynchronous wait for a timer to expire. + * + * A waitable timer is always in one of two states: "expired" or "not expired". + * If the wait() or async_wait() function is called on an expired timer, the + * wait operation will complete immediately. + * + * Most applications will use one of the asio::steady_timer, + * asio::system_timer or asio::high_resolution_timer typedefs. + * + * @note This waitable timer functionality is for use with the C++11 standard + * library's @c <chrono> facility, or with the Boost.Chrono library. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Examples + * Performing a blocking wait (C++11): + * @code + * // Construct a timer without setting an expiry time. + * asio::steady_timer timer(io_context); + * + * // Set an expiry time relative to now. + * timer.expires_after(std::chrono::seconds(5)); + * + * // Wait for the timer to expire. + * timer.wait(); + * @endcode + * + * @par + * Performing an asynchronous wait (C++11): + * @code + * void handler(const asio::error_code& error) + * { + * if (!error) + * { + * // Timer expired. + * } + * } + * + * ... + * + * // Construct a timer with an absolute expiry time. + * asio::steady_timer timer(io_context, + * std::chrono::steady_clock::now() + std::chrono::seconds(60)); + * + * // Start an asynchronous wait. + * timer.async_wait(handler); + * @endcode + * + * @par Changing an active waitable timer's expiry time + * + * Changing the expiry time of a timer while there are pending asynchronous + * waits causes those wait operations to be cancelled. To ensure that the action + * associated with the timer is performed only once, use something like this: + * used: + * + * @code + * void on_some_event() + * { + * if (my_timer.expires_after(seconds(5)) > 0) + * { + * // We managed to cancel the timer. Start new asynchronous wait. + * my_timer.async_wait(on_timeout); + * } + * else + * { + * // Too late, timer has already expired! + * } + * } + * + * void on_timeout(const asio::error_code& e) + * { + * if (e != asio::error::operation_aborted) + * { + * // Timer was not cancelled, take necessary action. + * } + * } + * @endcode + * + * @li The asio::basic_waitable_timer::expires_after() function + * cancels any pending asynchronous waits, and returns the number of + * asynchronous waits that were cancelled. If it returns 0 then you were too + * late and the wait handler has already been executed, or will soon be + * executed. If it returns 1 then the wait handler was successfully cancelled. + * + * @li If a wait handler is cancelled, the asio::error_code passed to + * it contains the value asio::error::operation_aborted. + */ +template +class basic_waitable_timer + : ASIO_SVC_ACCESS basic_io_object +{ +public: + /// The type of the executor associated with the object. + typedef io_context::executor_type executor_type; + + /// The clock type. + typedef Clock clock_type; + + /// The duration type of the clock. + typedef typename clock_type::duration duration; + + /// The time point type of the clock. + typedef typename clock_type::time_point time_point; + + /// The wait traits type. + typedef WaitTraits traits_type; + + /// Constructor. + /** + * This constructor creates a timer without setting an expiry time. The + * expires_at() or expires_after() functions must be called to set an expiry + * time before the timer can be waited on. + * + * @param io_context The io_context object that the timer will use to dispatch + * handlers for any asynchronous operations performed on the timer. + */ + explicit basic_waitable_timer(asio::io_context& io_context) + : basic_io_object(io_context) + { + } + + /// Constructor to set a particular expiry time as an absolute time. + /** + * This constructor creates a timer and sets the expiry time. + * + * @param io_context The io_context object that the timer will use to dispatch + * handlers for any asynchronous operations performed on the timer. + * + * @param expiry_time The expiry time to be used for the timer, expressed + * as an absolute time. + */ + basic_waitable_timer(asio::io_context& io_context, + const time_point& expiry_time) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().expires_at(this->get_implementation(), expiry_time, ec); + asio::detail::throw_error(ec, "expires_at"); + } + + /// Constructor to set a particular expiry time relative to now. + /** + * This constructor creates a timer and sets the expiry time. + * + * @param io_context The io_context object that the timer will use to dispatch + * handlers for any asynchronous operations performed on the timer. + * + * @param expiry_time The expiry time to be used for the timer, relative to + * now. + */ + basic_waitable_timer(asio::io_context& io_context, + const duration& expiry_time) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().expires_after( + this->get_implementation(), expiry_time, ec); + asio::detail::throw_error(ec, "expires_after"); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_waitable_timer from another. + /** + * This constructor moves a timer from one object to another. + * + * @param other The other basic_waitable_timer 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_waitable_timer(io_context&) constructor. + */ + basic_waitable_timer(basic_waitable_timer&& other) + : basic_io_object(std::move(other)) + { + } + + /// Move-assign a basic_waitable_timer from another. + /** + * This assignment operator moves a timer from one object to another. Cancels + * any outstanding asynchronous operations associated with the target object. + * + * @param other The other basic_waitable_timer 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_waitable_timer(io_context&) constructor. + */ + basic_waitable_timer& operator=(basic_waitable_timer&& other) + { + basic_io_object::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroys the timer. + /** + * This function destroys the timer, cancelling any outstanding asynchronous + * wait operations associated with the timer as if by calling @c cancel. + */ + ~basic_waitable_timer() + { + } + +#if defined(ASIO_ENABLE_OLD_SERVICES) + // These functions are provided by basic_io_object<>. +#else // defined(ASIO_ENABLE_OLD_SERVICES) +#if !defined(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. + */ + 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. + */ + asio::io_context& get_io_service() + { + return basic_io_object::get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return basic_io_object::get_executor(); + } +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + + /// Cancel any asynchronous operations that are waiting on the timer. + /** + * This function forces the completion of any pending asynchronous wait + * operations against the timer. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * Cancelling the timer does not change the expiry time. + * + * @return The number of asynchronous operations that were cancelled. + * + * @throws asio::system_error Thrown on failure. + * + * @note If the timer has already expired when cancel() is called, then the + * handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t cancel() + { + asio::error_code ec; + std::size_t s = this->get_service().cancel(this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel"); + return s; + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use non-error_code overload.) Cancel any asynchronous + /// operations that are waiting on the timer. + /** + * This function forces the completion of any pending asynchronous wait + * operations against the timer. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * Cancelling the timer does not change the expiry time. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of asynchronous operations that were cancelled. + * + * @note If the timer has already expired when cancel() is called, then the + * handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t cancel(asio::error_code& ec) + { + return this->get_service().cancel(this->get_implementation(), ec); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Cancels one asynchronous operation that is waiting on the timer. + /** + * This function forces the completion of one pending asynchronous wait + * operation against the timer. Handlers are cancelled in FIFO order. The + * handler for the cancelled operation will be invoked with the + * asio::error::operation_aborted error code. + * + * Cancelling the timer does not change the expiry time. + * + * @return The number of asynchronous operations that were cancelled. That is, + * either 0 or 1. + * + * @throws asio::system_error Thrown on failure. + * + * @note If the timer has already expired when cancel_one() is called, then + * the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t cancel_one() + { + asio::error_code ec; + std::size_t s = this->get_service().cancel_one( + this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel_one"); + return s; + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use non-error_code overload.) Cancels one asynchronous + /// operation that is waiting on the timer. + /** + * This function forces the completion of one pending asynchronous wait + * operation against the timer. Handlers are cancelled in FIFO order. The + * handler for the cancelled operation will be invoked with the + * asio::error::operation_aborted error code. + * + * Cancelling the timer does not change the expiry time. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of asynchronous operations that were cancelled. That is, + * either 0 or 1. + * + * @note If the timer has already expired when cancel_one() is called, then + * the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t cancel_one(asio::error_code& ec) + { + return this->get_service().cancel_one(this->get_implementation(), ec); + } + + /// (Deprecated: Use expiry().) Get the timer's expiry time as an absolute + /// time. + /** + * This function may be used to obtain the timer's current expiry time. + * Whether the timer has expired or not does not affect this value. + */ + time_point expires_at() const + { + return this->get_service().expires_at(this->get_implementation()); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the timer's expiry time as an absolute time. + /** + * This function may be used to obtain the timer's current expiry time. + * Whether the timer has expired or not does not affect this value. + */ + time_point expiry() const + { + return this->get_service().expiry(this->get_implementation()); + } + + /// Set the timer's expiry time as an absolute time. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @return The number of asynchronous operations that were cancelled. + * + * @throws asio::system_error Thrown on failure. + * + * @note If the timer has already expired when expires_at() is called, then + * the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t expires_at(const time_point& expiry_time) + { + asio::error_code ec; + std::size_t s = this->get_service().expires_at( + this->get_implementation(), expiry_time, ec); + asio::detail::throw_error(ec, "expires_at"); + return s; + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use non-error_code overload.) Set the timer's expiry time as + /// an absolute time. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of asynchronous operations that were cancelled. + * + * @note If the timer has already expired when expires_at() is called, then + * the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t expires_at(const time_point& expiry_time, + asio::error_code& ec) + { + return this->get_service().expires_at( + this->get_implementation(), expiry_time, ec); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Set the timer's expiry time relative to now. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @return The number of asynchronous operations that were cancelled. + * + * @throws asio::system_error Thrown on failure. + * + * @note If the timer has already expired when expires_after() is called, + * then the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t expires_after(const duration& expiry_time) + { + asio::error_code ec; + std::size_t s = this->get_service().expires_after( + this->get_implementation(), expiry_time, ec); + asio::detail::throw_error(ec, "expires_after"); + return s; + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use expiry().) Get the timer's expiry time relative to now. + /** + * This function may be used to obtain the timer's current expiry time. + * Whether the timer has expired or not does not affect this value. + */ + duration expires_from_now() const + { + return this->get_service().expires_from_now(this->get_implementation()); + } + + /// (Deprecated: Use expires_after().) Set the timer's expiry time relative + /// to now. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @return The number of asynchronous operations that were cancelled. + * + * @throws asio::system_error Thrown on failure. + * + * @note If the timer has already expired when expires_from_now() is called, + * then the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t expires_from_now(const duration& expiry_time) + { + asio::error_code ec; + std::size_t s = this->get_service().expires_from_now( + this->get_implementation(), expiry_time, ec); + asio::detail::throw_error(ec, "expires_from_now"); + return s; + } + + /// (Deprecated: Use expires_after().) Set the timer's expiry time relative + /// to now. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of asynchronous operations that were cancelled. + * + * @note If the timer has already expired when expires_from_now() is called, + * then the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t expires_from_now(const duration& expiry_time, + asio::error_code& ec) + { + return this->get_service().expires_from_now( + this->get_implementation(), expiry_time, ec); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Perform a blocking wait on the timer. + /** + * This function is used to wait for the timer to expire. This function + * blocks and does not return until the timer has expired. + * + * @throws asio::system_error Thrown on failure. + */ + void wait() + { + asio::error_code ec; + this->get_service().wait(this->get_implementation(), ec); + asio::detail::throw_error(ec, "wait"); + } + + /// Perform a blocking wait on the timer. + /** + * This function is used to wait for the timer to expire. This function + * blocks and does not return until the timer has expired. + * + * @param ec Set to indicate what error occurred, if any. + */ + void wait(asio::error_code& ec) + { + this->get_service().wait(this->get_implementation(), ec); + } + + /// Start an asynchronous wait on the timer. + /** + * This function may be used to initiate an asynchronous wait against the + * timer. It always returns immediately. + * + * For each call to async_wait(), the supplied handler will be called exactly + * once. The handler will be called when: + * + * @li The timer has expired. + * + * @li The timer was cancelled, in which case the handler is passed the error + * code asio::error::operation_aborted. + * + * @param handler The handler to be called when the timer expires. Copies + * will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const asio::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 + * asio::io_context::post(). + */ + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(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. + ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_wait(this->get_implementation(), + ASIO_MOVE_CAST(WaitHandler)(handler)); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + async_completion init(handler); + + this->get_service().async_wait(this->get_implementation(), + init.completion_handler); + + return init.result.get(); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + } + +private: + // Disallow copying and assignment. + basic_waitable_timer(const basic_waitable_timer&) ASIO_DELETED; + basic_waitable_timer& operator=( + const basic_waitable_timer&) ASIO_DELETED; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if !defined(ASIO_ENABLE_OLD_SERVICES) +# undef ASIO_SVC_T +#endif // !defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_BASIC_WAITABLE_TIMER_HPP diff --git a/tools/sdk/include/asio/asio/bind_executor.hpp b/tools/sdk/include/asio/asio/bind_executor.hpp new file mode 100644 index 00000000..9e2094b5 --- /dev/null +++ b/tools/sdk/include/asio/asio/bind_executor.hpp @@ -0,0 +1,611 @@ +// +// bind_executor.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BIND_EXECUTOR_HPP +#define ASIO_BIND_EXECUTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/detail/variadic_templates.hpp" +#include "asio/associated_executor.hpp" +#include "asio/associated_allocator.hpp" +#include "asio/async_result.hpp" +#include "asio/execution_context.hpp" +#include "asio/is_executor.hpp" +#include "asio/uses_executor.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +struct executor_binder_check +{ + typedef void type; +}; + +// Helper to automatically define nested typedef result_type. + +template +struct executor_binder_result_type +{ +protected: + typedef void result_type_or_void; +}; + +template +struct executor_binder_result_type::type> +{ + typedef typename T::result_type result_type; +protected: + typedef result_type result_type_or_void; +}; + +template +struct executor_binder_result_type +{ + typedef R result_type; +protected: + typedef result_type result_type_or_void; +}; + +template +struct executor_binder_result_type +{ + typedef R result_type; +protected: + typedef result_type result_type_or_void; +}; + +template +struct executor_binder_result_type +{ + typedef R result_type; +protected: + typedef result_type result_type_or_void; +}; + +template +struct executor_binder_result_type +{ + typedef R result_type; +protected: + typedef result_type result_type_or_void; +}; + +template +struct executor_binder_result_type +{ + typedef R result_type; +protected: + typedef result_type result_type_or_void; +}; + +template +struct executor_binder_result_type +{ + typedef R result_type; +protected: + typedef result_type result_type_or_void; +}; + +// Helper to automatically define nested typedef argument_type. + +template +struct executor_binder_argument_type {}; + +template +struct executor_binder_argument_type::type> +{ + typedef typename T::argument_type argument_type; +}; + +template +struct executor_binder_argument_type +{ + typedef A1 argument_type; +}; + +template +struct executor_binder_argument_type +{ + typedef A1 argument_type; +}; + +// Helper to automatically define nested typedefs first_argument_type and +// second_argument_type. + +template +struct executor_binder_argument_types {}; + +template +struct executor_binder_argument_types::type> +{ + typedef typename T::first_argument_type first_argument_type; + typedef typename T::second_argument_type second_argument_type; +}; + +template +struct executor_binder_argument_type +{ + typedef A1 first_argument_type; + typedef A2 second_argument_type; +}; + +template +struct executor_binder_argument_type +{ + typedef A1 first_argument_type; + typedef A2 second_argument_type; +}; + +// Helper to: +// - Apply the empty base optimisation to the executor. +// - Perform uses_executor construction of the target type, if required. + +template +class executor_binder_base; + +template +class executor_binder_base + : protected Executor +{ +protected: + template + executor_binder_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u) + : executor_(ASIO_MOVE_CAST(E)(e)), + target_(executor_arg_t(), executor_, ASIO_MOVE_CAST(U)(u)) + { + } + + Executor executor_; + T target_; +}; + +template +class executor_binder_base +{ +protected: + template + executor_binder_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u) + : executor_(ASIO_MOVE_CAST(E)(e)), + target_(ASIO_MOVE_CAST(U)(u)) + { + } + + Executor executor_; + T target_; +}; + +// Helper to enable SFINAE on zero-argument operator() below. + +template +struct executor_binder_result_of0 +{ + typedef void type; +}; + +template +struct executor_binder_result_of0::type>::type> +{ + typedef typename result_of::type type; +}; + +} // namespace detail + +/// A call wrapper type to bind an executor of type @c Executor to an object of +/// type @c T. +template +class executor_binder +#if !defined(GENERATING_DOCUMENTATION) + : public detail::executor_binder_result_type, + public detail::executor_binder_argument_type, + public detail::executor_binder_argument_types, + private detail::executor_binder_base< + T, Executor, uses_executor::value> +#endif // !defined(GENERATING_DOCUMENTATION) +{ +public: + /// The type of the target object. + typedef T target_type; + + /// The type of the associated executor. + typedef Executor executor_type; + +#if defined(GENERATING_DOCUMENTATION) + /// The return type if a function. + /** + * The type of @c result_type is based on the type @c T of the wrapper's + * target object: + * + * @li if @c T is a pointer to function type, @c result_type is a synonym for + * the return type of @c T; + * + * @li if @c T is a class type with a member type @c result_type, then @c + * result_type is a synonym for @c T::result_type; + * + * @li otherwise @c result_type is not defined. + */ + typedef see_below result_type; + + /// The type of the function's argument. + /** + * The type of @c argument_type is based on the type @c T of the wrapper's + * target object: + * + * @li if @c T is a pointer to a function type accepting a single argument, + * @c argument_type is a synonym for the return type of @c T; + * + * @li if @c T is a class type with a member type @c argument_type, then @c + * argument_type is a synonym for @c T::argument_type; + * + * @li otherwise @c argument_type is not defined. + */ + typedef see_below argument_type; + + /// The type of the function's first argument. + /** + * The type of @c first_argument_type is based on the type @c T of the + * wrapper's target object: + * + * @li if @c T is a pointer to a function type accepting two arguments, @c + * first_argument_type is a synonym for the return type of @c T; + * + * @li if @c T is a class type with a member type @c first_argument_type, + * then @c first_argument_type is a synonym for @c T::first_argument_type; + * + * @li otherwise @c first_argument_type is not defined. + */ + typedef see_below first_argument_type; + + /// The type of the function's second argument. + /** + * The type of @c second_argument_type is based on the type @c T of the + * wrapper's target object: + * + * @li if @c T is a pointer to a function type accepting two arguments, @c + * second_argument_type is a synonym for the return type of @c T; + * + * @li if @c T is a class type with a member type @c first_argument_type, + * then @c second_argument_type is a synonym for @c T::second_argument_type; + * + * @li otherwise @c second_argument_type is not defined. + */ + typedef see_below second_argument_type; +#endif // defined(GENERATING_DOCUMENTATION) + + /// Construct an executor wrapper for the specified object. + /** + * This constructor is only valid if the type @c T is constructible from type + * @c U. + */ + template + executor_binder(executor_arg_t, const executor_type& e, + ASIO_MOVE_ARG(U) u) + : base_type(e, ASIO_MOVE_CAST(U)(u)) + { + } + + /// Copy constructor. + executor_binder(const executor_binder& other) + : base_type(other.get_executor(), other.get()) + { + } + + /// Construct a copy, but specify a different executor. + executor_binder(executor_arg_t, const executor_type& e, + const executor_binder& other) + : base_type(e, other.get()) + { + } + + /// Construct a copy of a different executor wrapper type. + /** + * This constructor is only valid if the @c Executor type is constructible + * from type @c OtherExecutor, and the type @c T is constructible from type + * @c U. + */ + template + executor_binder(const executor_binder& other) + : base_type(other.get_executor(), other.get()) + { + } + + /// Construct a copy of a different executor wrapper type, but specify a + /// different executor. + /** + * This constructor is only valid if the type @c T is constructible from type + * @c U. + */ + template + executor_binder(executor_arg_t, const executor_type& e, + const executor_binder& other) + : base_type(e, other.get()) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Move constructor. + executor_binder(executor_binder&& other) + : base_type(ASIO_MOVE_CAST(executor_type)(other.get_executor()), + ASIO_MOVE_CAST(T)(other.get())) + { + } + + /// Move construct the target object, but specify a different executor. + executor_binder(executor_arg_t, const executor_type& e, + executor_binder&& other) + : base_type(e, ASIO_MOVE_CAST(T)(other.get())) + { + } + + /// Move construct from a different executor wrapper type. + template + executor_binder(executor_binder&& other) + : base_type(ASIO_MOVE_CAST(OtherExecutor)(other.get_executor()), + ASIO_MOVE_CAST(U)(other.get())) + { + } + + /// Move construct from a different executor wrapper type, but specify a + /// different executor. + template + executor_binder(executor_arg_t, const executor_type& e, + executor_binder&& other) + : base_type(e, ASIO_MOVE_CAST(U)(other.get())) + { + } + +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destructor. + ~executor_binder() + { + } + + /// Obtain a reference to the target object. + target_type& get() ASIO_NOEXCEPT + { + return this->target_; + } + + /// Obtain a reference to the target object. + const target_type& get() const ASIO_NOEXCEPT + { + return this->target_; + } + + /// Obtain the associated executor. + executor_type get_executor() const ASIO_NOEXCEPT + { + return this->executor_; + } + +#if defined(GENERATING_DOCUMENTATION) + + template auto operator()(Args&& ...); + template auto operator()(Args&& ...) const; + +#elif defined(ASIO_HAS_VARIADIC_TEMPLATES) + + /// Forwarding function call operator. + template + typename result_of::type operator()( + ASIO_MOVE_ARG(Args)... args) + { + return this->target_(ASIO_MOVE_CAST(Args)(args)...); + } + + /// Forwarding function call operator. + template + typename result_of::type operator()( + ASIO_MOVE_ARG(Args)... args) const + { + return this->target_(ASIO_MOVE_CAST(Args)(args)...); + } + +#elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER) + + typename detail::executor_binder_result_of0::type operator()() + { + return this->target_(); + } + + typename detail::executor_binder_result_of0::type operator()() const + { + return this->target_(); + } + +#define ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \ + template \ + typename result_of::type operator()( \ + ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \ + } \ + \ + template \ + typename result_of::type operator()( \ + ASIO_VARIADIC_MOVE_PARAMS(n)) const \ + { \ + return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \ + } \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF) +#undef ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF + +#else // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER) + + typedef typename detail::executor_binder_result_type::result_type_or_void + result_type_or_void; + + result_type_or_void operator()() + { + return this->target_(); + } + + result_type_or_void operator()() const + { + return this->target_(); + } + +#define ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \ + template \ + result_type_or_void operator()( \ + ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \ + } \ + \ + template \ + result_type_or_void operator()( \ + ASIO_VARIADIC_MOVE_PARAMS(n)) const \ + { \ + return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \ + } \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF) +#undef ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF + +#endif // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER) + +private: + typedef detail::executor_binder_base::value> base_type; +}; + +/// Associate an object of type @c T with an executor of type @c Executor. +template +inline executor_binder::type, Executor> +bind_executor(const Executor& ex, ASIO_MOVE_ARG(T) t, + typename enable_if::value>::type* = 0) +{ + return executor_binder::type, Executor>( + executor_arg_t(), ex, ASIO_MOVE_CAST(T)(t)); +} + +/// Associate an object of type @c T with an execution context's executor. +template +inline executor_binder::type, + typename ExecutionContext::executor_type> +bind_executor(ExecutionContext& ctx, ASIO_MOVE_ARG(T) t, + typename enable_if::value>::type* = 0) +{ + return executor_binder::type, + typename ExecutionContext::executor_type>( + executor_arg_t(), ctx.get_executor(), ASIO_MOVE_CAST(T)(t)); +} + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct uses_executor, Executor> + : true_type {}; + +template +class async_result, Signature> +{ +public: + typedef executor_binder< + typename async_result::completion_handler_type, Executor> + completion_handler_type; + + typedef typename async_result::return_type return_type; + + explicit async_result(executor_binder& b) + : target_(b.get()) + { + } + + return_type get() + { + return target_.get(); + } + +private: + async_result(const async_result&) ASIO_DELETED; + async_result& operator=(const async_result&) ASIO_DELETED; + + async_result target_; +}; + +#if !defined(ASIO_NO_DEPRECATED) + +template +struct handler_type, Signature> +{ + typedef executor_binder< + typename handler_type::type, Executor> type; +}; + +template +class async_result > +{ +public: + typedef typename async_result::type type; + + explicit async_result(executor_binder& b) + : target_(b.get()) + { + } + + type get() + { + return target_.get(); + } + +private: + async_result target_; +}; + +#endif // !defined(ASIO_NO_DEPRECATED) + +template +struct associated_allocator, Allocator> +{ + typedef typename associated_allocator::type type; + + static type get(const executor_binder& b, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(b.get(), a); + } +}; + +template +struct associated_executor, Executor1> +{ + typedef Executor type; + + static type get(const executor_binder& b, + const Executor1& = Executor1()) ASIO_NOEXCEPT + { + return b.get_executor(); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BIND_EXECUTOR_HPP diff --git a/tools/sdk/include/asio/asio/buffer.hpp b/tools/sdk/include/asio/asio/buffer.hpp new file mode 100644 index 00000000..a9aa8aad --- /dev/null +++ b/tools/sdk/include/asio/asio/buffer.hpp @@ -0,0 +1,2162 @@ +// +// buffer.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BUFFER_HPP +#define ASIO_BUFFER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include +#include +#include +#include +#include +#include "asio/detail/array_fwd.hpp" +#include "asio/detail/is_buffer_sequence.hpp" +#include "asio/detail/string_view.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/detail/type_traits.hpp" + +#if defined(ASIO_MSVC) && (ASIO_MSVC >= 1700) +# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0) +# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING) +# define ASIO_ENABLE_BUFFER_DEBUGGING +# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING) +# endif // defined(_HAS_ITERATOR_DEBUGGING) +#endif // defined(ASIO_MSVC) && (ASIO_MSVC >= 1700) + +#if defined(__GNUC__) +# if defined(_GLIBCXX_DEBUG) +# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING) +# define ASIO_ENABLE_BUFFER_DEBUGGING +# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING) +# endif // defined(_GLIBCXX_DEBUG) +#endif // defined(__GNUC__) + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) +# include "asio/detail/functional.hpp" +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + +#if defined(ASIO_HAS_BOOST_WORKAROUND) +# include +# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \ + || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) +# define ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND +# endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) + // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) +#endif // defined(ASIO_HAS_BOOST_WORKAROUND) + +#if defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) +# include "asio/detail/type_traits.hpp" +#endif // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +class mutable_buffer; +class const_buffer; + +/// Holds a buffer that can be modified. +/** + * The mutable_buffer class provides a safe representation of a buffer that can + * be modified. It does not own the underlying data, and so is cheap to copy or + * assign. + * + * @par Accessing Buffer Contents + * + * The contents of a buffer may be accessed using the @c data() and @c size() + * member functions: + * + * @code asio::mutable_buffer b1 = ...; + * std::size_t s1 = b1.size(); + * unsigned char* p1 = static_cast(b1.data()); + * @endcode + * + * The @c data() member function permits violations of type safety, so uses of + * it in application code should be carefully considered. + */ +class mutable_buffer +{ +public: + /// Construct an empty buffer. + mutable_buffer() ASIO_NOEXCEPT + : data_(0), + size_(0) + { + } + + /// Construct a buffer to represent a given memory range. + mutable_buffer(void* data, std::size_t size) ASIO_NOEXCEPT + : data_(data), + size_(size) + { + } + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + mutable_buffer(void* data, std::size_t size, + asio::detail::function debug_check) + : data_(data), + size_(size), + debug_check_(debug_check) + { + } + + const asio::detail::function& get_debug_check() const + { + return debug_check_; + } +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + + /// Get a pointer to the beginning of the memory range. + void* data() const ASIO_NOEXCEPT + { +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + if (size_ && debug_check_) + debug_check_(); +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + return data_; + } + + /// Get the size of the memory range. + std::size_t size() const ASIO_NOEXCEPT + { + return size_; + } + + /// Move the start of the buffer by the specified number of bytes. + mutable_buffer& operator+=(std::size_t n) ASIO_NOEXCEPT + { + std::size_t offset = n < size_ ? n : size_; + data_ = static_cast(data_) + offset; + size_ -= offset; + return *this; + } + +private: + void* data_; + std::size_t size_; + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + asio::detail::function debug_check_; +#endif // ASIO_ENABLE_BUFFER_DEBUGGING +}; + +#if !defined(ASIO_NO_DEPRECATED) + +/// (Deprecated: Use mutable_buffer.) Adapts a single modifiable buffer so that +/// it meets the requirements of the MutableBufferSequence concept. +class mutable_buffers_1 + : public mutable_buffer +{ +public: + /// The type for each element in the list of buffers. + typedef mutable_buffer value_type; + + /// A random-access iterator type that may be used to read elements. + typedef const mutable_buffer* const_iterator; + + /// Construct to represent a given memory range. + mutable_buffers_1(void* data, std::size_t size) ASIO_NOEXCEPT + : mutable_buffer(data, size) + { + } + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + mutable_buffers_1(void* data, std::size_t size, + asio::detail::function debug_check) + : mutable_buffer(data, size, debug_check) + { + } +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + + /// Construct to represent a single modifiable buffer. + explicit mutable_buffers_1(const mutable_buffer& b) ASIO_NOEXCEPT + : mutable_buffer(b) + { + } + + /// Get a random-access iterator to the first element. + const_iterator begin() const ASIO_NOEXCEPT + { + return this; + } + + /// Get a random-access iterator for one past the last element. + const_iterator end() const ASIO_NOEXCEPT + { + return begin() + 1; + } +}; + +#endif // !defined(ASIO_NO_DEPRECATED) + +/// Holds a buffer that cannot be modified. +/** + * The const_buffer class provides a safe representation of a buffer that cannot + * be modified. It does not own the underlying data, and so is cheap to copy or + * assign. + * + * @par Accessing Buffer Contents + * + * The contents of a buffer may be accessed using the @c data() and @c size() + * member functions: + * + * @code asio::const_buffer b1 = ...; + * std::size_t s1 = b1.size(); + * const unsigned char* p1 = static_cast(b1.data()); + * @endcode + * + * The @c data() member function permits violations of type safety, so uses of + * it in application code should be carefully considered. + */ +class const_buffer +{ +public: + /// Construct an empty buffer. + const_buffer() ASIO_NOEXCEPT + : data_(0), + size_(0) + { + } + + /// Construct a buffer to represent a given memory range. + const_buffer(const void* data, std::size_t size) ASIO_NOEXCEPT + : data_(data), + size_(size) + { + } + + /// Construct a non-modifiable buffer from a modifiable one. + const_buffer(const mutable_buffer& b) ASIO_NOEXCEPT + : data_(b.data()), + size_(b.size()) +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , debug_check_(b.get_debug_check()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + { + } + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + const_buffer(const void* data, std::size_t size, + asio::detail::function debug_check) + : data_(data), + size_(size), + debug_check_(debug_check) + { + } + + const asio::detail::function& get_debug_check() const + { + return debug_check_; + } +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + + /// Get a pointer to the beginning of the memory range. + const void* data() const ASIO_NOEXCEPT + { +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + if (size_ && debug_check_) + debug_check_(); +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + return data_; + } + + /// Get the size of the memory range. + std::size_t size() const ASIO_NOEXCEPT + { + return size_; + } + + /// Move the start of the buffer by the specified number of bytes. + const_buffer& operator+=(std::size_t n) ASIO_NOEXCEPT + { + std::size_t offset = n < size_ ? n : size_; + data_ = static_cast(data_) + offset; + size_ -= offset; + return *this; + } + +private: + const void* data_; + std::size_t size_; + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + asio::detail::function debug_check_; +#endif // ASIO_ENABLE_BUFFER_DEBUGGING +}; + +#if !defined(ASIO_NO_DEPRECATED) + +/// (Deprecated: Use const_buffer.) Adapts a single non-modifiable buffer so +/// that it meets the requirements of the ConstBufferSequence concept. +class const_buffers_1 + : public const_buffer +{ +public: + /// The type for each element in the list of buffers. + typedef const_buffer value_type; + + /// A random-access iterator type that may be used to read elements. + typedef const const_buffer* const_iterator; + + /// Construct to represent a given memory range. + const_buffers_1(const void* data, std::size_t size) ASIO_NOEXCEPT + : const_buffer(data, size) + { + } + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + const_buffers_1(const void* data, std::size_t size, + asio::detail::function debug_check) + : const_buffer(data, size, debug_check) + { + } +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + + /// Construct to represent a single non-modifiable buffer. + explicit const_buffers_1(const const_buffer& b) ASIO_NOEXCEPT + : const_buffer(b) + { + } + + /// Get a random-access iterator to the first element. + const_iterator begin() const ASIO_NOEXCEPT + { + return this; + } + + /// Get a random-access iterator for one past the last element. + const_iterator end() const ASIO_NOEXCEPT + { + return begin() + 1; + } +}; + +#endif // !defined(ASIO_NO_DEPRECATED) + +/// Trait to determine whether a type satisfies the MutableBufferSequence +/// requirements. +template +struct is_mutable_buffer_sequence +#if defined(GENERATING_DOCUMENTATION) + : integral_constant +#else // defined(GENERATING_DOCUMENTATION) + : asio::detail::is_buffer_sequence +#endif // defined(GENERATING_DOCUMENTATION) +{ +}; + +/// Trait to determine whether a type satisfies the ConstBufferSequence +/// requirements. +template +struct is_const_buffer_sequence +#if defined(GENERATING_DOCUMENTATION) + : integral_constant +#else // defined(GENERATING_DOCUMENTATION) + : asio::detail::is_buffer_sequence +#endif // defined(GENERATING_DOCUMENTATION) +{ +}; + +/// Trait to determine whether a type satisfies the DynamicBuffer requirements. +template +struct is_dynamic_buffer +#if defined(GENERATING_DOCUMENTATION) + : integral_constant +#else // defined(GENERATING_DOCUMENTATION) + : asio::detail::is_dynamic_buffer +#endif // defined(GENERATING_DOCUMENTATION) +{ +}; + +/// (Deprecated: Use the socket/descriptor wait() and async_wait() member +/// functions.) An implementation of both the ConstBufferSequence and +/// MutableBufferSequence concepts to represent a null buffer sequence. +class null_buffers +{ +public: + /// The type for each element in the list of buffers. + typedef mutable_buffer value_type; + + /// A random-access iterator type that may be used to read elements. + typedef const mutable_buffer* const_iterator; + + /// Get a random-access iterator to the first element. + const_iterator begin() const ASIO_NOEXCEPT + { + return &buf_; + } + + /// Get a random-access iterator for one past the last element. + const_iterator end() const ASIO_NOEXCEPT + { + return &buf_; + } + +private: + mutable_buffer buf_; +}; + +/** @defgroup buffer_sequence_begin asio::buffer_sequence_begin + * + * @brief The asio::buffer_sequence_begin function returns an iterator + * pointing to the first element in a buffer sequence. + */ +/*@{*/ + +/// Get an iterator to the first element in a buffer sequence. +inline const mutable_buffer* buffer_sequence_begin(const mutable_buffer& b) +{ + return &b; +} + +/// Get an iterator to the first element in a buffer sequence. +inline const const_buffer* buffer_sequence_begin(const const_buffer& b) +{ + return &b; +} + +#if defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) + +/// Get an iterator to the first element in a buffer sequence. +template +inline auto buffer_sequence_begin(C& c) -> decltype(c.begin()) +{ + return c.begin(); +} + +/// Get an iterator to the first element in a buffer sequence. +template +inline auto buffer_sequence_begin(const C& c) -> decltype(c.begin()) +{ + return c.begin(); +} + +#else // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) + +template +inline typename C::iterator buffer_sequence_begin(C& c) +{ + return c.begin(); +} + +template +inline typename C::const_iterator buffer_sequence_begin(const C& c) +{ + return c.begin(); +} + +#endif // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) + +/*@}*/ + +/** @defgroup buffer_sequence_end asio::buffer_sequence_end + * + * @brief The asio::buffer_sequence_end function returns an iterator + * pointing to one past the end element in a buffer sequence. + */ +/*@{*/ + +/// Get an iterator to one past the end element in a buffer sequence. +inline const mutable_buffer* buffer_sequence_end(const mutable_buffer& b) +{ + return &b + 1; +} + +/// Get an iterator to one past the end element in a buffer sequence. +inline const const_buffer* buffer_sequence_end(const const_buffer& b) +{ + return &b + 1; +} + +#if defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) + +/// Get an iterator to one past the end element in a buffer sequence. +template +inline auto buffer_sequence_end(C& c) -> decltype(c.end()) +{ + return c.end(); +} + +/// Get an iterator to one past the end element in a buffer sequence. +template +inline auto buffer_sequence_end(const C& c) -> decltype(c.end()) +{ + return c.end(); +} + +#else // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) + +template +inline typename C::iterator buffer_sequence_end(C& c) +{ + return c.end(); +} + +template +inline typename C::const_iterator buffer_sequence_end(const C& c) +{ + return c.end(); +} + +#endif // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) + +/*@}*/ + +namespace detail { + +// Tag types used to select appropriately optimised overloads. +struct one_buffer {}; +struct multiple_buffers {}; + +// Helper trait to detect single buffers. +template +struct buffer_sequence_cardinality : + conditional< + is_same::value +#if !defined(ASIO_NO_DEPRECATED) + || is_same::value + || is_same::value +#endif // !defined(ASIO_NO_DEPRECATED) + || is_same::value, + one_buffer, multiple_buffers>::type {}; + +template +inline std::size_t buffer_size(one_buffer, + Iterator begin, Iterator) ASIO_NOEXCEPT +{ + return const_buffer(*begin).size(); +} + +template +inline std::size_t buffer_size(multiple_buffers, + Iterator begin, Iterator end) ASIO_NOEXCEPT +{ + std::size_t total_buffer_size = 0; + + Iterator iter = begin; + for (; iter != end; ++iter) + { + const_buffer b(*iter); + total_buffer_size += b.size(); + } + + return total_buffer_size; +} + +} // namespace detail + +/// Get the total number of bytes in a buffer sequence. +/** + * The @c buffer_size function determines the total size of all buffers in the + * buffer sequence, as if computed as follows: + * + * @code size_t total_size = 0; + * auto i = asio::buffer_sequence_begin(buffers); + * auto end = asio::buffer_sequence_end(buffers); + * for (; i != end; ++i) + * { + * const_buffer b(*i); + * total_size += b.size(); + * } + * return total_size; @endcode + * + * The @c BufferSequence template parameter may meet either of the @c + * ConstBufferSequence or @c MutableBufferSequence type requirements. + */ +template +inline std::size_t buffer_size(const BufferSequence& b) ASIO_NOEXCEPT +{ + return detail::buffer_size( + detail::buffer_sequence_cardinality(), + asio::buffer_sequence_begin(b), + asio::buffer_sequence_end(b)); +} + +#if !defined(ASIO_NO_DEPRECATED) + +/** @defgroup buffer_cast asio::buffer_cast + * + * @brief (Deprecated: Use the @c data() member function.) The + * asio::buffer_cast function is used to obtain a pointer to the + * underlying memory region associated with a buffer. + * + * @par Examples: + * + * To access the memory of a non-modifiable buffer, use: + * @code asio::const_buffer b1 = ...; + * const unsigned char* p1 = asio::buffer_cast(b1); + * @endcode + * + * To access the memory of a modifiable buffer, use: + * @code asio::mutable_buffer b2 = ...; + * unsigned char* p2 = asio::buffer_cast(b2); + * @endcode + * + * The asio::buffer_cast function permits violations of type safety, so + * uses of it in application code should be carefully considered. + */ +/*@{*/ + +/// Cast a non-modifiable buffer to a specified pointer to POD type. +template +inline PointerToPodType buffer_cast(const mutable_buffer& b) ASIO_NOEXCEPT +{ + return static_cast(b.data()); +} + +/// Cast a non-modifiable buffer to a specified pointer to POD type. +template +inline PointerToPodType buffer_cast(const const_buffer& b) ASIO_NOEXCEPT +{ + return static_cast(b.data()); +} + +/*@}*/ + +#endif // !defined(ASIO_NO_DEPRECATED) + +/// Create a new modifiable buffer that is offset from the start of another. +/** + * @relates mutable_buffer + */ +inline mutable_buffer operator+(const mutable_buffer& b, + std::size_t n) ASIO_NOEXCEPT +{ + std::size_t offset = n < b.size() ? n : b.size(); + char* new_data = static_cast(b.data()) + offset; + std::size_t new_size = b.size() - offset; + return mutable_buffer(new_data, new_size +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new modifiable buffer that is offset from the start of another. +/** + * @relates mutable_buffer + */ +inline mutable_buffer operator+(std::size_t n, + const mutable_buffer& b) ASIO_NOEXCEPT +{ + return b + n; +} + +/// Create a new non-modifiable buffer that is offset from the start of another. +/** + * @relates const_buffer + */ +inline const_buffer operator+(const const_buffer& b, + std::size_t n) ASIO_NOEXCEPT +{ + std::size_t offset = n < b.size() ? n : b.size(); + const char* new_data = static_cast(b.data()) + offset; + std::size_t new_size = b.size() - offset; + return const_buffer(new_data, new_size +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new non-modifiable buffer that is offset from the start of another. +/** + * @relates const_buffer + */ +inline const_buffer operator+(std::size_t n, + const const_buffer& b) ASIO_NOEXCEPT +{ + return b + n; +} + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) +namespace detail { + +template +class buffer_debug_check +{ +public: + buffer_debug_check(Iterator iter) + : iter_(iter) + { + } + + ~buffer_debug_check() + { +#if defined(ASIO_MSVC) && (ASIO_MSVC == 1400) + // MSVC 8's string iterator checking may crash in a std::string::iterator + // object's destructor when the iterator points to an already-destroyed + // std::string object, unless the iterator is cleared first. + iter_ = Iterator(); +#endif // defined(ASIO_MSVC) && (ASIO_MSVC == 1400) + } + + void operator()() + { + (void)*iter_; + } + +private: + Iterator iter_; +}; + +} // namespace detail +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + +/** @defgroup buffer asio::buffer + * + * @brief The asio::buffer function is used to create a buffer object to + * represent raw memory, an array of POD elements, a vector of POD elements, + * or a std::string. + * + * A buffer object represents a contiguous region of memory as a 2-tuple + * consisting of a pointer and size in bytes. A tuple of the form {void*, + * size_t} specifies a mutable (modifiable) region of memory. Similarly, a + * tuple of the form {const void*, size_t} specifies a const + * (non-modifiable) region of memory. These two forms correspond to the classes + * mutable_buffer and const_buffer, respectively. To mirror C++'s conversion + * rules, a mutable_buffer is implicitly convertible to a const_buffer, and the + * opposite conversion is not permitted. + * + * The simplest use case involves reading or writing a single buffer of a + * specified size: + * + * @code sock.send(asio::buffer(data, size)); @endcode + * + * In the above example, the return value of asio::buffer meets the + * requirements of the ConstBufferSequence concept so that it may be directly + * passed to the socket's write function. A buffer created for modifiable + * memory also meets the requirements of the MutableBufferSequence concept. + * + * An individual buffer may be created from a builtin array, std::vector, + * std::array or boost::array of POD elements. This helps prevent buffer + * overruns by automatically determining the size of the buffer: + * + * @code char d1[128]; + * size_t bytes_transferred = sock.receive(asio::buffer(d1)); + * + * std::vector d2(128); + * bytes_transferred = sock.receive(asio::buffer(d2)); + * + * std::array d3; + * bytes_transferred = sock.receive(asio::buffer(d3)); + * + * boost::array d4; + * bytes_transferred = sock.receive(asio::buffer(d4)); @endcode + * + * In all three cases above, the buffers created are exactly 128 bytes long. + * Note that a vector is @e never automatically resized when creating or using + * a buffer. The buffer size is determined using the vector's size() + * member function, and not its capacity. + * + * @par Accessing Buffer Contents + * + * The contents of a buffer may be accessed using the @c data() and @c size() + * member functions: + * + * @code asio::mutable_buffer b1 = ...; + * std::size_t s1 = b1.size(); + * unsigned char* p1 = static_cast(b1.data()); + * + * asio::const_buffer b2 = ...; + * std::size_t s2 = b2.size(); + * const void* p2 = b2.data(); @endcode + * + * The @c data() member function permits violations of type safety, so + * uses of it in application code should be carefully considered. + * + * For convenience, a @ref buffer_size function is provided that works with + * both buffers and buffer sequences (that is, types meeting the + * ConstBufferSequence or MutableBufferSequence type requirements). In this + * case, the function returns the total size of all buffers in the sequence. + * + * @par Buffer Copying + * + * The @ref buffer_copy function may be used to copy raw bytes between + * individual buffers and buffer sequences. +* + * In particular, when used with the @ref buffer_size function, the @ref + * buffer_copy function can be used to linearise a sequence of buffers. For + * example: + * + * @code vector buffers = ...; + * + * vector data(asio::buffer_size(buffers)); + * asio::buffer_copy(asio::buffer(data), buffers); @endcode + * + * Note that @ref buffer_copy is implemented in terms of @c memcpy, and + * consequently it cannot be used to copy between overlapping memory regions. + * + * @par Buffer Invalidation + * + * A buffer object does not have any ownership of the memory it refers to. It + * is the responsibility of the application to ensure the memory region remains + * valid until it is no longer required for an I/O operation. When the memory + * is no longer available, the buffer is said to have been invalidated. + * + * For the asio::buffer overloads that accept an argument of type + * std::vector, the buffer objects returned are invalidated by any vector + * operation that also invalidates all references, pointers and iterators + * referring to the elements in the sequence (C++ Std, 23.2.4) + * + * For the asio::buffer overloads that accept an argument of type + * std::basic_string, the buffer objects returned are invalidated according to + * the rules defined for invalidation of references, pointers and iterators + * referring to elements of the sequence (C++ Std, 21.3). + * + * @par Buffer Arithmetic + * + * Buffer objects may be manipulated using simple arithmetic in a safe way + * which helps prevent buffer overruns. Consider an array initialised as + * follows: + * + * @code boost::array a = { 'a', 'b', 'c', 'd', 'e' }; @endcode + * + * A buffer object @c b1 created using: + * + * @code b1 = asio::buffer(a); @endcode + * + * represents the entire array, { 'a', 'b', 'c', 'd', 'e' }. An + * optional second argument to the asio::buffer function may be used to + * limit the size, in bytes, of the buffer: + * + * @code b2 = asio::buffer(a, 3); @endcode + * + * such that @c b2 represents the data { 'a', 'b', 'c' }. Even if the + * size argument exceeds the actual size of the array, the size of the buffer + * object created will be limited to the array size. + * + * An offset may be applied to an existing buffer to create a new one: + * + * @code b3 = b1 + 2; @endcode + * + * where @c b3 will set to represent { 'c', 'd', 'e' }. If the offset + * exceeds the size of the existing buffer, the newly created buffer will be + * empty. + * + * Both an offset and size may be specified to create a buffer that corresponds + * to a specific range of bytes within an existing buffer: + * + * @code b4 = asio::buffer(b1 + 1, 3); @endcode + * + * so that @c b4 will refer to the bytes { 'b', 'c', 'd' }. + * + * @par Buffers and Scatter-Gather I/O + * + * To read or write using multiple buffers (i.e. scatter-gather I/O), multiple + * buffer objects may be assigned into a container that supports the + * MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts: + * + * @code + * char d1[128]; + * std::vector d2(128); + * boost::array d3; + * + * boost::array bufs1 = { + * asio::buffer(d1), + * asio::buffer(d2), + * asio::buffer(d3) }; + * bytes_transferred = sock.receive(bufs1); + * + * std::vector bufs2; + * bufs2.push_back(asio::buffer(d1)); + * bufs2.push_back(asio::buffer(d2)); + * bufs2.push_back(asio::buffer(d3)); + * bytes_transferred = sock.send(bufs2); @endcode + */ +/*@{*/ + +#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) +# define ASIO_MUTABLE_BUFFER mutable_buffer +# define ASIO_CONST_BUFFER const_buffer +#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) +# define ASIO_MUTABLE_BUFFER mutable_buffers_1 +# define ASIO_CONST_BUFFER const_buffers_1 +#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) + +/// Create a new modifiable buffer from an existing buffer. +/** + * @returns mutable_buffer(b). + */ +inline ASIO_MUTABLE_BUFFER buffer( + const mutable_buffer& b) ASIO_NOEXCEPT +{ + return ASIO_MUTABLE_BUFFER(b); +} + +/// Create a new modifiable buffer from an existing buffer. +/** + * @returns A mutable_buffer value equivalent to: + * @code mutable_buffer( + * b.data(), + * min(b.size(), max_size_in_bytes)); @endcode + */ +inline ASIO_MUTABLE_BUFFER buffer(const mutable_buffer& b, + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_MUTABLE_BUFFER( + mutable_buffer(b.data(), + b.size() < max_size_in_bytes + ? b.size() : max_size_in_bytes +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new non-modifiable buffer from an existing buffer. +/** + * @returns const_buffer(b). + */ +inline ASIO_CONST_BUFFER buffer( + const const_buffer& b) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(b); +} + +/// Create a new non-modifiable buffer from an existing buffer. +/** + * @returns A const_buffer value equivalent to: + * @code const_buffer( + * b.data(), + * min(b.size(), max_size_in_bytes)); @endcode + */ +inline ASIO_CONST_BUFFER buffer(const const_buffer& b, + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(b.data(), + b.size() < max_size_in_bytes + ? b.size() : max_size_in_bytes +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new modifiable buffer that represents the given memory range. +/** + * @returns mutable_buffer(data, size_in_bytes). + */ +inline ASIO_MUTABLE_BUFFER buffer(void* data, + std::size_t size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_MUTABLE_BUFFER(data, size_in_bytes); +} + +/// Create a new non-modifiable buffer that represents the given memory range. +/** + * @returns const_buffer(data, size_in_bytes). + */ +inline ASIO_CONST_BUFFER buffer(const void* data, + std::size_t size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data, size_in_bytes); +} + +/// Create a new modifiable buffer that represents the given POD array. +/** + * @returns A mutable_buffer value equivalent to: + * @code mutable_buffer( + * static_cast(data), + * N * sizeof(PodType)); @endcode + */ +template +inline ASIO_MUTABLE_BUFFER buffer(PodType (&data)[N]) ASIO_NOEXCEPT +{ + return ASIO_MUTABLE_BUFFER(data, N * sizeof(PodType)); +} + +/// Create a new modifiable buffer that represents the given POD array. +/** + * @returns A mutable_buffer value equivalent to: + * @code mutable_buffer( + * static_cast(data), + * min(N * sizeof(PodType), max_size_in_bytes)); @endcode + */ +template +inline ASIO_MUTABLE_BUFFER buffer(PodType (&data)[N], + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_MUTABLE_BUFFER(data, + N * sizeof(PodType) < max_size_in_bytes + ? N * sizeof(PodType) : max_size_in_bytes); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffer value equivalent to: + * @code const_buffer( + * static_cast(data), + * N * sizeof(PodType)); @endcode + */ +template +inline ASIO_CONST_BUFFER buffer( + const PodType (&data)[N]) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data, N * sizeof(PodType)); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffer value equivalent to: + * @code const_buffer( + * static_cast(data), + * min(N * sizeof(PodType), max_size_in_bytes)); @endcode + */ +template +inline ASIO_CONST_BUFFER buffer(const PodType (&data)[N], + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data, + N * sizeof(PodType) < max_size_in_bytes + ? N * sizeof(PodType) : max_size_in_bytes); +} + +#if defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) + +// Borland C++ and Sun Studio think the overloads: +// +// unspecified buffer(boost::array& array ...); +// +// and +// +// unspecified buffer(boost::array& array ...); +// +// are ambiguous. This will be worked around by using a buffer_types traits +// class that contains typedefs for the appropriate buffer and container +// classes, based on whether PodType is const or non-const. + +namespace detail { + +template +struct buffer_types_base; + +template <> +struct buffer_types_base +{ + typedef mutable_buffer buffer_type; + typedef ASIO_MUTABLE_BUFFER container_type; +}; + +template <> +struct buffer_types_base +{ + typedef const_buffer buffer_type; + typedef ASIO_CONST_BUFFER container_type; +}; + +template +struct buffer_types + : public buffer_types_base::value> +{ +}; + +} // namespace detail + +template +inline typename detail::buffer_types::container_type +buffer(boost::array& data) ASIO_NOEXCEPT +{ + typedef typename asio::detail::buffer_types::buffer_type + buffer_type; + typedef typename asio::detail::buffer_types::container_type + container_type; + return container_type( + buffer_type(data.c_array(), data.size() * sizeof(PodType))); +} + +template +inline typename detail::buffer_types::container_type +buffer(boost::array& data, + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + typedef typename asio::detail::buffer_types::buffer_type + buffer_type; + typedef typename asio::detail::buffer_types::container_type + container_type; + return container_type( + buffer_type(data.c_array(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes)); +} + +#else // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) + +/// Create a new modifiable buffer that represents the given POD array. +/** + * @returns A mutable_buffer value equivalent to: + * @code mutable_buffer( + * data.data(), + * data.size() * sizeof(PodType)); @endcode + */ +template +inline ASIO_MUTABLE_BUFFER buffer( + boost::array& data) ASIO_NOEXCEPT +{ + return ASIO_MUTABLE_BUFFER( + data.c_array(), data.size() * sizeof(PodType)); +} + +/// Create a new modifiable buffer that represents the given POD array. +/** + * @returns A mutable_buffer value equivalent to: + * @code mutable_buffer( + * data.data(), + * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode + */ +template +inline ASIO_MUTABLE_BUFFER buffer(boost::array& data, + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_MUTABLE_BUFFER(data.c_array(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffer value equivalent to: + * @code const_buffer( + * data.data(), + * data.size() * sizeof(PodType)); @endcode + */ +template +inline ASIO_CONST_BUFFER buffer( + boost::array& data) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType)); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffer value equivalent to: + * @code const_buffer( + * data.data(), + * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode + */ +template +inline ASIO_CONST_BUFFER buffer(boost::array& data, + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data.data(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes); +} + +#endif // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffer value equivalent to: + * @code const_buffer( + * data.data(), + * data.size() * sizeof(PodType)); @endcode + */ +template +inline ASIO_CONST_BUFFER buffer( + const boost::array& data) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType)); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffer value equivalent to: + * @code const_buffer( + * data.data(), + * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode + */ +template +inline ASIO_CONST_BUFFER buffer(const boost::array& data, + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data.data(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes); +} + +#if defined(ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION) + +/// Create a new modifiable buffer that represents the given POD array. +/** + * @returns A mutable_buffer value equivalent to: + * @code mutable_buffer( + * data.data(), + * data.size() * sizeof(PodType)); @endcode + */ +template +inline ASIO_MUTABLE_BUFFER buffer( + std::array& data) ASIO_NOEXCEPT +{ + return ASIO_MUTABLE_BUFFER(data.data(), data.size() * sizeof(PodType)); +} + +/// Create a new modifiable buffer that represents the given POD array. +/** + * @returns A mutable_buffer value equivalent to: + * @code mutable_buffer( + * data.data(), + * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode + */ +template +inline ASIO_MUTABLE_BUFFER buffer(std::array& data, + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_MUTABLE_BUFFER(data.data(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffer value equivalent to: + * @code const_buffer( + * data.data(), + * data.size() * sizeof(PodType)); @endcode + */ +template +inline ASIO_CONST_BUFFER buffer( + std::array& data) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType)); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffer value equivalent to: + * @code const_buffer( + * data.data(), + * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode + */ +template +inline ASIO_CONST_BUFFER buffer(std::array& data, + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data.data(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffer value equivalent to: + * @code const_buffer( + * data.data(), + * data.size() * sizeof(PodType)); @endcode + */ +template +inline ASIO_CONST_BUFFER buffer( + const std::array& data) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType)); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffer value equivalent to: + * @code const_buffer( + * data.data(), + * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode + */ +template +inline ASIO_CONST_BUFFER buffer(const std::array& data, + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data.data(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes); +} + +#endif // defined(ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION) + +/// Create a new modifiable buffer that represents the given POD vector. +/** + * @returns A mutable_buffer value equivalent to: + * @code mutable_buffer( + * data.size() ? &data[0] : 0, + * data.size() * sizeof(PodType)); @endcode + * + * @note The buffer is invalidated by any vector operation that would also + * invalidate iterators. + */ +template +inline ASIO_MUTABLE_BUFFER buffer( + std::vector& data) ASIO_NOEXCEPT +{ + return ASIO_MUTABLE_BUFFER( + data.size() ? &data[0] : 0, data.size() * sizeof(PodType) +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::vector::iterator + >(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new modifiable buffer that represents the given POD vector. +/** + * @returns A mutable_buffer value equivalent to: + * @code mutable_buffer( + * data.size() ? &data[0] : 0, + * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode + * + * @note The buffer is invalidated by any vector operation that would also + * invalidate iterators. + */ +template +inline ASIO_MUTABLE_BUFFER buffer(std::vector& data, + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0, + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::vector::iterator + >(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new non-modifiable buffer that represents the given POD vector. +/** + * @returns A const_buffer value equivalent to: + * @code const_buffer( + * data.size() ? &data[0] : 0, + * data.size() * sizeof(PodType)); @endcode + * + * @note The buffer is invalidated by any vector operation that would also + * invalidate iterators. + */ +template +inline ASIO_CONST_BUFFER buffer( + const std::vector& data) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER( + data.size() ? &data[0] : 0, data.size() * sizeof(PodType) +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::vector::const_iterator + >(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new non-modifiable buffer that represents the given POD vector. +/** + * @returns A const_buffer value equivalent to: + * @code const_buffer( + * data.size() ? &data[0] : 0, + * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode + * + * @note The buffer is invalidated by any vector operation that would also + * invalidate iterators. + */ +template +inline ASIO_CONST_BUFFER buffer( + const std::vector& data, + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data.size() ? &data[0] : 0, + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::vector::const_iterator + >(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new modifiable buffer that represents the given string. +/** + * @returns mutable_buffer(data.size() ? &data[0] : 0, + * data.size() * sizeof(Elem)). + * + * @note The buffer is invalidated by any non-const operation called on the + * given string object. + */ +template +inline ASIO_MUTABLE_BUFFER buffer( + std::basic_string& data) ASIO_NOEXCEPT +{ + return ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0, + data.size() * sizeof(Elem) +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::basic_string::iterator + >(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new non-modifiable buffer that represents the given string. +/** + * @returns A mutable_buffer value equivalent to: + * @code mutable_buffer( + * data.size() ? &data[0] : 0, + * min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode + * + * @note The buffer is invalidated by any non-const operation called on the + * given string object. + */ +template +inline ASIO_MUTABLE_BUFFER buffer( + std::basic_string& data, + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0, + data.size() * sizeof(Elem) < max_size_in_bytes + ? data.size() * sizeof(Elem) : max_size_in_bytes +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::basic_string::iterator + >(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new non-modifiable buffer that represents the given string. +/** + * @returns const_buffer(data.data(), data.size() * sizeof(Elem)). + * + * @note The buffer is invalidated by any non-const operation called on the + * given string object. + */ +template +inline ASIO_CONST_BUFFER buffer( + const std::basic_string& data) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(Elem) +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::basic_string::const_iterator + >(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new non-modifiable buffer that represents the given string. +/** + * @returns A const_buffer value equivalent to: + * @code const_buffer( + * data.data(), + * min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode + * + * @note The buffer is invalidated by any non-const operation called on the + * given string object. + */ +template +inline ASIO_CONST_BUFFER buffer( + const std::basic_string& data, + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data.data(), + data.size() * sizeof(Elem) < max_size_in_bytes + ? data.size() * sizeof(Elem) : max_size_in_bytes +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::basic_string::const_iterator + >(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +#if defined(ASIO_HAS_STRING_VIEW) \ + || defined(GENERATING_DOCUMENTATION) + +/// Create a new modifiable buffer that represents the given string_view. +/** + * @returns mutable_buffer(data.size() ? &data[0] : 0, + * data.size() * sizeof(Elem)). + */ +template +inline ASIO_CONST_BUFFER buffer( + basic_string_view data) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data.size() ? &data[0] : 0, + data.size() * sizeof(Elem) +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename basic_string_view::iterator + >(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new non-modifiable buffer that represents the given string. +/** + * @returns A mutable_buffer value equivalent to: + * @code mutable_buffer( + * data.size() ? &data[0] : 0, + * min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode + */ +template +inline ASIO_CONST_BUFFER buffer( + basic_string_view data, + std::size_t max_size_in_bytes) ASIO_NOEXCEPT +{ + return ASIO_CONST_BUFFER(data.size() ? &data[0] : 0, + data.size() * sizeof(Elem) < max_size_in_bytes + ? data.size() * sizeof(Elem) : max_size_in_bytes +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename basic_string_view::iterator + >(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +#endif // defined(ASIO_HAS_STRING_VIEW) + // || defined(GENERATING_DOCUMENTATION) + +/*@}*/ + +/// Adapt a basic_string to the DynamicBuffer requirements. +/** + * Requires that sizeof(Elem) == 1. + */ +template +class dynamic_string_buffer +{ +public: + /// The type used to represent the input sequence as a list of buffers. + typedef ASIO_CONST_BUFFER const_buffers_type; + + /// The type used to represent the output sequence as a list of buffers. + typedef ASIO_MUTABLE_BUFFER mutable_buffers_type; + + /// Construct a dynamic buffer from a string. + /** + * @param s The string to be used as backing storage for the dynamic buffer. + * Any existing data in the string is treated as the dynamic buffer's input + * sequence. The object stores a reference to the string and the user is + * responsible for ensuring that the string object remains valid until the + * dynamic_string_buffer object is destroyed. + * + * @param maximum_size Specifies a maximum size for the buffer, in bytes. + */ + explicit dynamic_string_buffer(std::basic_string& s, + std::size_t maximum_size = + (std::numeric_limits::max)()) ASIO_NOEXCEPT + : string_(s), + size_(string_.size()), + max_size_(maximum_size) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move construct a dynamic buffer. + dynamic_string_buffer(dynamic_string_buffer&& other) ASIO_NOEXCEPT + : string_(other.string_), + size_(other.size_), + max_size_(other.max_size_) + { + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Get the size of the input sequence. + std::size_t size() const ASIO_NOEXCEPT + { + return size_; + } + + /// Get the maximum size of the dynamic buffer. + /** + * @returns The allowed maximum of the sum of the sizes of the input sequence + * and output sequence. + */ + std::size_t max_size() const ASIO_NOEXCEPT + { + return max_size_; + } + + /// Get the current capacity of the dynamic buffer. + /** + * @returns The current total capacity of the buffer, i.e. for both the input + * sequence and output sequence. + */ + std::size_t capacity() const ASIO_NOEXCEPT + { + return string_.capacity(); + } + + /// Get a list of buffers that represents the input sequence. + /** + * @returns An object of type @c const_buffers_type that satisfies + * ConstBufferSequence requirements, representing the basic_string memory in + * input sequence. + * + * @note The returned object is invalidated by any @c dynamic_string_buffer + * or @c basic_string member function that modifies the input sequence or + * output sequence. + */ + const_buffers_type data() const ASIO_NOEXCEPT + { + return const_buffers_type(asio::buffer(string_, size_)); + } + + /// Get a list of buffers that represents the output sequence, with the given + /// size. + /** + * Ensures that the output sequence can accommodate @c n bytes, resizing the + * basic_string object as necessary. + * + * @returns An object of type @c mutable_buffers_type that satisfies + * MutableBufferSequence requirements, representing basic_string memory + * at the start of the output sequence of size @c n. + * + * @throws std::length_error If size() + n > max_size(). + * + * @note The returned object is invalidated by any @c dynamic_string_buffer + * or @c basic_string member function that modifies the input sequence or + * output sequence. + */ + mutable_buffers_type prepare(std::size_t n) + { + if (size () > max_size() || max_size() - size() < n) + { + std::length_error ex("dynamic_string_buffer too long"); + asio::detail::throw_exception(ex); + } + + string_.resize(size_ + n); + + return asio::buffer(asio::buffer(string_) + size_, n); + } + + /// Move bytes from the output sequence to the input sequence. + /** + * @param n The number of bytes to append from the start of the output + * sequence to the end of the input sequence. The remainder of the output + * sequence is discarded. + * + * Requires a preceding call prepare(x) where x >= n, and + * no intervening operations that modify the input or output sequence. + * + * @note If @c n is greater than the size of the output sequence, the entire + * output sequence is moved to the input sequence and no error is issued. + */ + void commit(std::size_t n) + { + size_ += (std::min)(n, string_.size() - size_); + string_.resize(size_); + } + + /// Remove characters from the input sequence. + /** + * Removes @c n characters from the beginning of the input sequence. + * + * @note If @c n is greater than the size of the input sequence, the entire + * input sequence is consumed and no error is issued. + */ + void consume(std::size_t n) + { + std::size_t consume_length = (std::min)(n, size_); + string_.erase(0, consume_length); + size_ -= consume_length; + } + +private: + std::basic_string& string_; + std::size_t size_; + const std::size_t max_size_; +}; + +/// Adapt a vector to the DynamicBuffer requirements. +/** + * Requires that sizeof(Elem) == 1. + */ +template +class dynamic_vector_buffer +{ +public: + /// The type used to represent the input sequence as a list of buffers. + typedef ASIO_CONST_BUFFER const_buffers_type; + + /// The type used to represent the output sequence as a list of buffers. + typedef ASIO_MUTABLE_BUFFER mutable_buffers_type; + + /// Construct a dynamic buffer from a string. + /** + * @param v The vector to be used as backing storage for the dynamic buffer. + * Any existing data in the vector is treated as the dynamic buffer's input + * sequence. The object stores a reference to the vector and the user is + * responsible for ensuring that the vector object remains valid until the + * dynamic_vector_buffer object is destroyed. + * + * @param maximum_size Specifies a maximum size for the buffer, in bytes. + */ + explicit dynamic_vector_buffer(std::vector& v, + std::size_t maximum_size = + (std::numeric_limits::max)()) ASIO_NOEXCEPT + : vector_(v), + size_(vector_.size()), + max_size_(maximum_size) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move construct a dynamic buffer. + dynamic_vector_buffer(dynamic_vector_buffer&& other) ASIO_NOEXCEPT + : vector_(other.vector_), + size_(other.size_), + max_size_(other.max_size_) + { + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Get the size of the input sequence. + std::size_t size() const ASIO_NOEXCEPT + { + return size_; + } + + /// Get the maximum size of the dynamic buffer. + /** + * @returns The allowed maximum of the sum of the sizes of the input sequence + * and output sequence. + */ + std::size_t max_size() const ASIO_NOEXCEPT + { + return max_size_; + } + + /// Get the current capacity of the dynamic buffer. + /** + * @returns The current total capacity of the buffer, i.e. for both the input + * sequence and output sequence. + */ + std::size_t capacity() const ASIO_NOEXCEPT + { + return vector_.capacity(); + } + + /// Get a list of buffers that represents the input sequence. + /** + * @returns An object of type @c const_buffers_type that satisfies + * ConstBufferSequence requirements, representing the basic_string memory in + * input sequence. + * + * @note The returned object is invalidated by any @c dynamic_vector_buffer + * or @c basic_string member function that modifies the input sequence or + * output sequence. + */ + const_buffers_type data() const ASIO_NOEXCEPT + { + return const_buffers_type(asio::buffer(vector_, size_)); + } + + /// Get a list of buffers that represents the output sequence, with the given + /// size. + /** + * Ensures that the output sequence can accommodate @c n bytes, resizing the + * basic_string object as necessary. + * + * @returns An object of type @c mutable_buffers_type that satisfies + * MutableBufferSequence requirements, representing basic_string memory + * at the start of the output sequence of size @c n. + * + * @throws std::length_error If size() + n > max_size(). + * + * @note The returned object is invalidated by any @c dynamic_vector_buffer + * or @c basic_string member function that modifies the input sequence or + * output sequence. + */ + mutable_buffers_type prepare(std::size_t n) + { + if (size () > max_size() || max_size() - size() < n) + { + std::length_error ex("dynamic_vector_buffer too long"); + asio::detail::throw_exception(ex); + } + + vector_.resize(size_ + n); + + return asio::buffer(asio::buffer(vector_) + size_, n); + } + + /// Move bytes from the output sequence to the input sequence. + /** + * @param n The number of bytes to append from the start of the output + * sequence to the end of the input sequence. The remainder of the output + * sequence is discarded. + * + * Requires a preceding call prepare(x) where x >= n, and + * no intervening operations that modify the input or output sequence. + * + * @note If @c n is greater than the size of the output sequence, the entire + * output sequence is moved to the input sequence and no error is issued. + */ + void commit(std::size_t n) + { + size_ += (std::min)(n, vector_.size() - size_); + vector_.resize(size_); + } + + /// Remove characters from the input sequence. + /** + * Removes @c n characters from the beginning of the input sequence. + * + * @note If @c n is greater than the size of the input sequence, the entire + * input sequence is consumed and no error is issued. + */ + void consume(std::size_t n) + { + std::size_t consume_length = (std::min)(n, size_); + vector_.erase(vector_.begin(), vector_.begin() + consume_length); + size_ -= consume_length; + } + +private: + std::vector& vector_; + std::size_t size_; + const std::size_t max_size_; +}; + +/** @defgroup dynamic_buffer asio::dynamic_buffer + * + * @brief The asio::dynamic_buffer function is used to create a + * dynamically resized buffer from a @c std::basic_string or @c std::vector. + */ +/*@{*/ + +/// Create a new dynamic buffer that represents the given string. +/** + * @returns dynamic_string_buffer(data). + */ +template +inline dynamic_string_buffer dynamic_buffer( + std::basic_string& data) ASIO_NOEXCEPT +{ + return dynamic_string_buffer(data); +} + +/// Create a new dynamic buffer that represents the given string. +/** + * @returns dynamic_string_buffer(data, + * max_size). + */ +template +inline dynamic_string_buffer dynamic_buffer( + std::basic_string& data, + std::size_t max_size) ASIO_NOEXCEPT +{ + return dynamic_string_buffer(data, max_size); +} + +/// Create a new dynamic buffer that represents the given vector. +/** + * @returns dynamic_vector_buffer(data). + */ +template +inline dynamic_vector_buffer dynamic_buffer( + std::vector& data) ASIO_NOEXCEPT +{ + return dynamic_vector_buffer(data); +} + +/// Create a new dynamic buffer that represents the given vector. +/** + * @returns dynamic_vector_buffer(data, max_size). + */ +template +inline dynamic_vector_buffer dynamic_buffer( + std::vector& data, + std::size_t max_size) ASIO_NOEXCEPT +{ + return dynamic_vector_buffer(data, max_size); +} + +/*@}*/ + +/** @defgroup buffer_copy asio::buffer_copy + * + * @brief The asio::buffer_copy function is used to copy bytes from a + * source buffer (or buffer sequence) to a target buffer (or buffer sequence). + * + * The @c buffer_copy function is available in two forms: + * + * @li A 2-argument form: @c buffer_copy(target, source) + * + * @li A 3-argument form: @c buffer_copy(target, source, max_bytes_to_copy) + * + * Both forms return the number of bytes actually copied. The number of bytes + * copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c If specified, @c max_bytes_to_copy. + * + * This prevents buffer overflow, regardless of the buffer sizes used in the + * copy operation. + * + * Note that @ref buffer_copy is implemented in terms of @c memcpy, and + * consequently it cannot be used to copy between overlapping memory regions. + */ +/*@{*/ + +namespace detail { + +inline std::size_t buffer_copy_1(const mutable_buffer& target, + const const_buffer& source) +{ + using namespace std; // For memcpy. + std::size_t target_size = target.size(); + std::size_t source_size = source.size(); + std::size_t n = target_size < source_size ? target_size : source_size; + if (n > 0) + memcpy(target.data(), source.data(), n); + return n; +} + +template +inline std::size_t buffer_copy(one_buffer, one_buffer, + TargetIterator target_begin, TargetIterator, + SourceIterator source_begin, SourceIterator) ASIO_NOEXCEPT +{ + return (buffer_copy_1)(*target_begin, *source_begin); +} + +template +inline std::size_t buffer_copy(one_buffer, one_buffer, + TargetIterator target_begin, TargetIterator, + SourceIterator source_begin, SourceIterator, + std::size_t max_bytes_to_copy) ASIO_NOEXCEPT +{ + return (buffer_copy_1)(*target_begin, + asio::buffer(*source_begin, max_bytes_to_copy)); +} + +template +std::size_t buffer_copy(one_buffer, multiple_buffers, + TargetIterator target_begin, TargetIterator, + SourceIterator source_begin, SourceIterator source_end, + std::size_t max_bytes_to_copy + = (std::numeric_limits::max)()) ASIO_NOEXCEPT +{ + std::size_t total_bytes_copied = 0; + SourceIterator source_iter = source_begin; + + for (mutable_buffer target_buffer( + asio::buffer(*target_begin, max_bytes_to_copy)); + target_buffer.size() && source_iter != source_end; ++source_iter) + { + const_buffer source_buffer(*source_iter); + std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer); + total_bytes_copied += bytes_copied; + target_buffer += bytes_copied; + } + + return total_bytes_copied; +} + +template +std::size_t buffer_copy(multiple_buffers, one_buffer, + TargetIterator target_begin, TargetIterator target_end, + SourceIterator source_begin, SourceIterator, + std::size_t max_bytes_to_copy + = (std::numeric_limits::max)()) ASIO_NOEXCEPT +{ + std::size_t total_bytes_copied = 0; + TargetIterator target_iter = target_begin; + + for (const_buffer source_buffer( + asio::buffer(*source_begin, max_bytes_to_copy)); + source_buffer.size() && target_iter != target_end; ++target_iter) + { + mutable_buffer target_buffer(*target_iter); + std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer); + total_bytes_copied += bytes_copied; + source_buffer += bytes_copied; + } + + return total_bytes_copied; +} + +template +std::size_t buffer_copy(multiple_buffers, multiple_buffers, + TargetIterator target_begin, TargetIterator target_end, + SourceIterator source_begin, SourceIterator source_end) ASIO_NOEXCEPT +{ + std::size_t total_bytes_copied = 0; + + TargetIterator target_iter = target_begin; + std::size_t target_buffer_offset = 0; + + SourceIterator source_iter = source_begin; + std::size_t source_buffer_offset = 0; + + while (target_iter != target_end && source_iter != source_end) + { + mutable_buffer target_buffer = + mutable_buffer(*target_iter) + target_buffer_offset; + + const_buffer source_buffer = + const_buffer(*source_iter) + source_buffer_offset; + + std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer); + total_bytes_copied += bytes_copied; + + if (bytes_copied == target_buffer.size()) + { + ++target_iter; + target_buffer_offset = 0; + } + else + target_buffer_offset += bytes_copied; + + if (bytes_copied == source_buffer.size()) + { + ++source_iter; + source_buffer_offset = 0; + } + else + source_buffer_offset += bytes_copied; + } + + return total_bytes_copied; +} + +template +std::size_t buffer_copy(multiple_buffers, multiple_buffers, + TargetIterator target_begin, TargetIterator target_end, + SourceIterator source_begin, SourceIterator source_end, + std::size_t max_bytes_to_copy) ASIO_NOEXCEPT +{ + std::size_t total_bytes_copied = 0; + + TargetIterator target_iter = target_begin; + std::size_t target_buffer_offset = 0; + + SourceIterator source_iter = source_begin; + std::size_t source_buffer_offset = 0; + + while (total_bytes_copied != max_bytes_to_copy + && target_iter != target_end && source_iter != source_end) + { + mutable_buffer target_buffer = + mutable_buffer(*target_iter) + target_buffer_offset; + + const_buffer source_buffer = + const_buffer(*source_iter) + source_buffer_offset; + + std::size_t bytes_copied = (buffer_copy_1)( + target_buffer, asio::buffer(source_buffer, + max_bytes_to_copy - total_bytes_copied)); + total_bytes_copied += bytes_copied; + + if (bytes_copied == target_buffer.size()) + { + ++target_iter; + target_buffer_offset = 0; + } + else + target_buffer_offset += bytes_copied; + + if (bytes_copied == source_buffer.size()) + { + ++source_iter; + source_buffer_offset = 0; + } + else + source_buffer_offset += bytes_copied; + } + + return total_bytes_copied; +} + +} // namespace detail + +/// Copies bytes from a source buffer sequence to a target buffer sequence. +/** + * @param target A modifiable buffer sequence representing the memory regions to + * which the bytes will be copied. + * + * @param source A non-modifiable buffer sequence representing the memory + * regions from which the bytes will be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * This function is implemented in terms of @c memcpy, and consequently it + * cannot be used to copy between overlapping memory regions. + */ +template +inline std::size_t buffer_copy(const MutableBufferSequence& target, + const ConstBufferSequence& source) ASIO_NOEXCEPT +{ + return detail::buffer_copy( + detail::buffer_sequence_cardinality(), + detail::buffer_sequence_cardinality(), + asio::buffer_sequence_begin(target), + asio::buffer_sequence_end(target), + asio::buffer_sequence_begin(source), + asio::buffer_sequence_end(source)); +} + +/// Copies a limited number of bytes from a source buffer sequence to a target +/// buffer sequence. +/** + * @param target A modifiable buffer sequence representing the memory regions to + * which the bytes will be copied. + * + * @param source A non-modifiable buffer sequence representing the memory + * regions from which the bytes will be copied. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + * + * This function is implemented in terms of @c memcpy, and consequently it + * cannot be used to copy between overlapping memory regions. + */ +template +inline std::size_t buffer_copy(const MutableBufferSequence& target, + const ConstBufferSequence& source, + std::size_t max_bytes_to_copy) ASIO_NOEXCEPT +{ + return detail::buffer_copy( + detail::buffer_sequence_cardinality(), + detail::buffer_sequence_cardinality(), + asio::buffer_sequence_begin(target), + asio::buffer_sequence_end(target), + asio::buffer_sequence_begin(source), + asio::buffer_sequence_end(source), max_bytes_to_copy); +} + +/*@}*/ + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BUFFER_HPP diff --git a/tools/sdk/include/asio/asio/buffered_read_stream.hpp b/tools/sdk/include/asio/asio/buffered_read_stream.hpp new file mode 100644 index 00000000..c3e7f0b5 --- /dev/null +++ b/tools/sdk/include/asio/asio/buffered_read_stream.hpp @@ -0,0 +1,257 @@ +// +// buffered_read_stream.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BUFFERED_READ_STREAM_HPP +#define ASIO_BUFFERED_READ_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/async_result.hpp" +#include "asio/buffered_read_stream_fwd.hpp" +#include "asio/buffer.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_resize_guard.hpp" +#include "asio/detail/buffered_stream_storage.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Adds buffering to the read-related operations of a stream. +/** + * The buffered_read_stream class template can be used to add buffering to the + * synchronous and asynchronous read operations of a stream. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +template +class buffered_read_stream + : private noncopyable +{ +public: + /// The type of the next layer. + typedef typename remove_reference::type next_layer_type; + + /// The type of the lowest layer. + typedef typename next_layer_type::lowest_layer_type lowest_layer_type; + + /// The type of the executor associated with the object. + typedef typename lowest_layer_type::executor_type executor_type; + +#if defined(GENERATING_DOCUMENTATION) + /// The default buffer size. + static const std::size_t default_buffer_size = implementation_defined; +#else + ASIO_STATIC_CONSTANT(std::size_t, default_buffer_size = 1024); +#endif + + /// Construct, passing the specified argument to initialise the next layer. + template + explicit buffered_read_stream(Arg& a) + : next_layer_(a), + storage_(default_buffer_size) + { + } + + /// Construct, passing the specified argument to initialise the next layer. + template + buffered_read_stream(Arg& a, std::size_t buffer_size) + : next_layer_(a), + storage_(buffer_size) + { + } + + /// Get a reference to the next layer. + next_layer_type& next_layer() + { + return next_layer_; + } + + /// Get a reference to the lowest layer. + lowest_layer_type& lowest_layer() + { + return next_layer_.lowest_layer(); + } + + /// Get a const reference to the lowest layer. + const lowest_layer_type& lowest_layer() const + { + return next_layer_.lowest_layer(); + } + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return next_layer_.lowest_layer().get_executor(); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + asio::io_context& get_io_context() + { + return next_layer_.get_io_context(); + } + + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + asio::io_context& get_io_service() + { + return next_layer_.get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Close the stream. + void close() + { + next_layer_.close(); + } + + /// Close the stream. + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + next_layer_.close(ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Write the given data to the stream. Returns the number of bytes written. + /// Throws an exception on failure. + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + return next_layer_.write_some(buffers); + } + + /// Write the given data to the stream. Returns the number of bytes written, + /// or 0 if an error occurred. + template + std::size_t write_some(const ConstBufferSequence& buffers, + asio::error_code& ec) + { + return next_layer_.write_some(buffers, ec); + } + + /// Start an asynchronous write. The data being written must be valid for the + /// lifetime of the asynchronous operation. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) + { + return next_layer_.async_write_some(buffers, + ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Fill the buffer with some data. Returns the number of bytes placed in the + /// buffer as a result of the operation. Throws an exception on failure. + std::size_t fill(); + + /// Fill the buffer with some data. Returns the number of bytes placed in the + /// buffer as a result of the operation, or 0 if an error occurred. + std::size_t fill(asio::error_code& ec); + + /// Start an asynchronous fill. + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_fill(ASIO_MOVE_ARG(ReadHandler) handler); + + /// Read some data from the stream. Returns the number of bytes read. Throws + /// an exception on failure. + template + std::size_t read_some(const MutableBufferSequence& buffers); + + /// Read some data from the stream. Returns the number of bytes read or 0 if + /// an error occurred. + template + std::size_t read_some(const MutableBufferSequence& buffers, + asio::error_code& ec); + + /// Start an asynchronous read. The buffer into which the data will be read + /// must be valid for the lifetime of the asynchronous operation. + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler); + + /// Peek at the incoming data on the stream. Returns the number of bytes read. + /// Throws an exception on failure. + template + std::size_t peek(const MutableBufferSequence& buffers); + + /// Peek at the incoming data on the stream. Returns the number of bytes read, + /// or 0 if an error occurred. + template + std::size_t peek(const MutableBufferSequence& buffers, + asio::error_code& ec); + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail() + { + return storage_.size(); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail(asio::error_code& ec) + { + ec = asio::error_code(); + return storage_.size(); + } + +private: + /// Copy data out of the internal buffer to the specified target buffer. + /// Returns the number of bytes copied. + template + std::size_t copy(const MutableBufferSequence& buffers) + { + std::size_t bytes_copied = asio::buffer_copy( + buffers, storage_.data(), storage_.size()); + storage_.consume(bytes_copied); + return bytes_copied; + } + + /// Copy data from the internal buffer to the specified target buffer, without + /// removing the data from the internal buffer. Returns the number of bytes + /// copied. + template + std::size_t peek_copy(const MutableBufferSequence& buffers) + { + return asio::buffer_copy(buffers, storage_.data(), storage_.size()); + } + + /// The next layer. + Stream next_layer_; + + // The data in the buffer. + detail::buffered_stream_storage storage_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/buffered_read_stream.hpp" + +#endif // ASIO_BUFFERED_READ_STREAM_HPP diff --git a/tools/sdk/include/asio/asio/buffered_read_stream_fwd.hpp b/tools/sdk/include/asio/asio/buffered_read_stream_fwd.hpp new file mode 100644 index 00000000..334b88a5 --- /dev/null +++ b/tools/sdk/include/asio/asio/buffered_read_stream_fwd.hpp @@ -0,0 +1,25 @@ +// +// buffered_read_stream_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BUFFERED_READ_STREAM_FWD_HPP +#define ASIO_BUFFERED_READ_STREAM_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +namespace asio { + +template +class buffered_read_stream; + +} // namespace asio + +#endif // ASIO_BUFFERED_READ_STREAM_FWD_HPP diff --git a/tools/sdk/include/asio/asio/buffered_stream.hpp b/tools/sdk/include/asio/asio/buffered_stream.hpp new file mode 100644 index 00000000..8014fa4d --- /dev/null +++ b/tools/sdk/include/asio/asio/buffered_stream.hpp @@ -0,0 +1,278 @@ +// +// buffered_stream.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BUFFERED_STREAM_HPP +#define ASIO_BUFFERED_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/async_result.hpp" +#include "asio/buffered_read_stream.hpp" +#include "asio/buffered_write_stream.hpp" +#include "asio/buffered_stream_fwd.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Adds buffering to the read- and write-related operations of a stream. +/** + * The buffered_stream class template can be used to add buffering to the + * synchronous and asynchronous read and write operations of a stream. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +template +class buffered_stream + : private noncopyable +{ +public: + /// The type of the next layer. + typedef typename remove_reference::type next_layer_type; + + /// The type of the lowest layer. + typedef typename next_layer_type::lowest_layer_type lowest_layer_type; + + /// The type of the executor associated with the object. + typedef typename lowest_layer_type::executor_type executor_type; + + /// Construct, passing the specified argument to initialise the next layer. + template + explicit buffered_stream(Arg& a) + : inner_stream_impl_(a), + stream_impl_(inner_stream_impl_) + { + } + + /// Construct, passing the specified argument to initialise the next layer. + template + explicit buffered_stream(Arg& a, std::size_t read_buffer_size, + std::size_t write_buffer_size) + : inner_stream_impl_(a, write_buffer_size), + stream_impl_(inner_stream_impl_, read_buffer_size) + { + } + + /// Get a reference to the next layer. + next_layer_type& next_layer() + { + return stream_impl_.next_layer().next_layer(); + } + + /// Get a reference to the lowest layer. + lowest_layer_type& lowest_layer() + { + return stream_impl_.lowest_layer(); + } + + /// Get a const reference to the lowest layer. + const lowest_layer_type& lowest_layer() const + { + return stream_impl_.lowest_layer(); + } + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return stream_impl_.lowest_layer().get_executor(); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + asio::io_context& get_io_context() + { + return stream_impl_.get_io_context(); + } + + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + asio::io_context& get_io_service() + { + return stream_impl_.get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Close the stream. + void close() + { + stream_impl_.close(); + } + + /// Close the stream. + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + stream_impl_.close(ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Flush all data from the buffer to the next layer. Returns the number of + /// bytes written to the next layer on the last write operation. Throws an + /// exception on failure. + std::size_t flush() + { + return stream_impl_.next_layer().flush(); + } + + /// Flush all data from the buffer to the next layer. Returns the number of + /// bytes written to the next layer on the last write operation, or 0 if an + /// error occurred. + std::size_t flush(asio::error_code& ec) + { + return stream_impl_.next_layer().flush(ec); + } + + /// Start an asynchronous flush. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_flush(ASIO_MOVE_ARG(WriteHandler) handler) + { + return stream_impl_.next_layer().async_flush( + ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Write the given data to the stream. Returns the number of bytes written. + /// Throws an exception on failure. + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + return stream_impl_.write_some(buffers); + } + + /// Write the given data to the stream. Returns the number of bytes written, + /// or 0 if an error occurred. + template + std::size_t write_some(const ConstBufferSequence& buffers, + asio::error_code& ec) + { + return stream_impl_.write_some(buffers, ec); + } + + /// Start an asynchronous write. The data being written must be valid for the + /// lifetime of the asynchronous operation. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) + { + return stream_impl_.async_write_some(buffers, + ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Fill the buffer with some data. Returns the number of bytes placed in the + /// buffer as a result of the operation. Throws an exception on failure. + std::size_t fill() + { + return stream_impl_.fill(); + } + + /// Fill the buffer with some data. Returns the number of bytes placed in the + /// buffer as a result of the operation, or 0 if an error occurred. + std::size_t fill(asio::error_code& ec) + { + return stream_impl_.fill(ec); + } + + /// Start an asynchronous fill. + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_fill(ASIO_MOVE_ARG(ReadHandler) handler) + { + return stream_impl_.async_fill(ASIO_MOVE_CAST(ReadHandler)(handler)); + } + + /// Read some data from the stream. Returns the number of bytes read. Throws + /// an exception on failure. + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + return stream_impl_.read_some(buffers); + } + + /// Read some data from the stream. Returns the number of bytes read or 0 if + /// an error occurred. + template + std::size_t read_some(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return stream_impl_.read_some(buffers, ec); + } + + /// Start an asynchronous read. The buffer into which the data will be read + /// must be valid for the lifetime of the asynchronous operation. + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) + { + return stream_impl_.async_read_some(buffers, + ASIO_MOVE_CAST(ReadHandler)(handler)); + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read. + /// Throws an exception on failure. + template + std::size_t peek(const MutableBufferSequence& buffers) + { + return stream_impl_.peek(buffers); + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read, + /// or 0 if an error occurred. + template + std::size_t peek(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return stream_impl_.peek(buffers, ec); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail() + { + return stream_impl_.in_avail(); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail(asio::error_code& ec) + { + return stream_impl_.in_avail(ec); + } + +private: + // The buffered write stream. + typedef buffered_write_stream write_stream_type; + write_stream_type inner_stream_impl_; + + // The buffered read stream. + typedef buffered_read_stream read_stream_type; + read_stream_type stream_impl_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BUFFERED_STREAM_HPP diff --git a/tools/sdk/include/asio/asio/buffered_stream_fwd.hpp b/tools/sdk/include/asio/asio/buffered_stream_fwd.hpp new file mode 100644 index 00000000..3492979d --- /dev/null +++ b/tools/sdk/include/asio/asio/buffered_stream_fwd.hpp @@ -0,0 +1,25 @@ +// +// buffered_stream_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BUFFERED_STREAM_FWD_HPP +#define ASIO_BUFFERED_STREAM_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +namespace asio { + +template +class buffered_stream; + +} // namespace asio + +#endif // ASIO_BUFFERED_STREAM_FWD_HPP diff --git a/tools/sdk/include/asio/asio/buffered_write_stream.hpp b/tools/sdk/include/asio/asio/buffered_write_stream.hpp new file mode 100644 index 00000000..aac33d38 --- /dev/null +++ b/tools/sdk/include/asio/asio/buffered_write_stream.hpp @@ -0,0 +1,249 @@ +// +// buffered_write_stream.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BUFFERED_WRITE_STREAM_HPP +#define ASIO_BUFFERED_WRITE_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/buffered_write_stream_fwd.hpp" +#include "asio/buffer.hpp" +#include "asio/completion_condition.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffered_stream_storage.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/write.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Adds buffering to the write-related operations of a stream. +/** + * The buffered_write_stream class template can be used to add buffering to the + * synchronous and asynchronous write operations of a stream. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +template +class buffered_write_stream + : private noncopyable +{ +public: + /// The type of the next layer. + typedef typename remove_reference::type next_layer_type; + + /// The type of the lowest layer. + typedef typename next_layer_type::lowest_layer_type lowest_layer_type; + + /// The type of the executor associated with the object. + typedef typename lowest_layer_type::executor_type executor_type; + +#if defined(GENERATING_DOCUMENTATION) + /// The default buffer size. + static const std::size_t default_buffer_size = implementation_defined; +#else + ASIO_STATIC_CONSTANT(std::size_t, default_buffer_size = 1024); +#endif + + /// Construct, passing the specified argument to initialise the next layer. + template + explicit buffered_write_stream(Arg& a) + : next_layer_(a), + storage_(default_buffer_size) + { + } + + /// Construct, passing the specified argument to initialise the next layer. + template + buffered_write_stream(Arg& a, std::size_t buffer_size) + : next_layer_(a), + storage_(buffer_size) + { + } + + /// Get a reference to the next layer. + next_layer_type& next_layer() + { + return next_layer_; + } + + /// Get a reference to the lowest layer. + lowest_layer_type& lowest_layer() + { + return next_layer_.lowest_layer(); + } + + /// Get a const reference to the lowest layer. + const lowest_layer_type& lowest_layer() const + { + return next_layer_.lowest_layer(); + } + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return next_layer_.lowest_layer().get_executor(); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + asio::io_context& get_io_context() + { + return next_layer_.get_io_context(); + } + + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + asio::io_context& get_io_service() + { + return next_layer_.get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Close the stream. + void close() + { + next_layer_.close(); + } + + /// Close the stream. + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + next_layer_.close(ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Flush all data from the buffer to the next layer. Returns the number of + /// bytes written to the next layer on the last write operation. Throws an + /// exception on failure. + std::size_t flush(); + + /// Flush all data from the buffer to the next layer. Returns the number of + /// bytes written to the next layer on the last write operation, or 0 if an + /// error occurred. + std::size_t flush(asio::error_code& ec); + + /// Start an asynchronous flush. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_flush(ASIO_MOVE_ARG(WriteHandler) handler); + + /// Write the given data to the stream. Returns the number of bytes written. + /// Throws an exception on failure. + template + std::size_t write_some(const ConstBufferSequence& buffers); + + /// Write the given data to the stream. Returns the number of bytes written, + /// or 0 if an error occurred and the error handler did not throw. + template + std::size_t write_some(const ConstBufferSequence& buffers, + asio::error_code& ec); + + /// Start an asynchronous write. The data being written must be valid for the + /// lifetime of the asynchronous operation. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler); + + /// Read some data from the stream. Returns the number of bytes read. Throws + /// an exception on failure. + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + return next_layer_.read_some(buffers); + } + + /// Read some data from the stream. Returns the number of bytes read or 0 if + /// an error occurred. + template + std::size_t read_some(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return next_layer_.read_some(buffers, ec); + } + + /// Start an asynchronous read. The buffer into which the data will be read + /// must be valid for the lifetime of the asynchronous operation. + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) + { + return next_layer_.async_read_some(buffers, + ASIO_MOVE_CAST(ReadHandler)(handler)); + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read. + /// Throws an exception on failure. + template + std::size_t peek(const MutableBufferSequence& buffers) + { + return next_layer_.peek(buffers); + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read, + /// or 0 if an error occurred. + template + std::size_t peek(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return next_layer_.peek(buffers, ec); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail() + { + return next_layer_.in_avail(); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail(asio::error_code& ec) + { + return next_layer_.in_avail(ec); + } + +private: + /// Copy data into the internal buffer from the specified source buffer. + /// Returns the number of bytes copied. + template + std::size_t copy(const ConstBufferSequence& buffers); + + /// The next layer. + Stream next_layer_; + + // The data in the buffer. + detail::buffered_stream_storage storage_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/buffered_write_stream.hpp" + +#endif // ASIO_BUFFERED_WRITE_STREAM_HPP diff --git a/tools/sdk/include/asio/asio/buffered_write_stream_fwd.hpp b/tools/sdk/include/asio/asio/buffered_write_stream_fwd.hpp new file mode 100644 index 00000000..6ef54ba0 --- /dev/null +++ b/tools/sdk/include/asio/asio/buffered_write_stream_fwd.hpp @@ -0,0 +1,25 @@ +// +// buffered_write_stream_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BUFFERED_WRITE_STREAM_FWD_HPP +#define ASIO_BUFFERED_WRITE_STREAM_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +namespace asio { + +template +class buffered_write_stream; + +} // namespace asio + +#endif // ASIO_BUFFERED_WRITE_STREAM_FWD_HPP diff --git a/tools/sdk/include/asio/asio/buffers_iterator.hpp b/tools/sdk/include/asio/asio/buffers_iterator.hpp new file mode 100644 index 00000000..f5c9d4c3 --- /dev/null +++ b/tools/sdk/include/asio/asio/buffers_iterator.hpp @@ -0,0 +1,521 @@ +// +// buffers_iterator.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_BUFFERS_ITERATOR_HPP +#define ASIO_BUFFERS_ITERATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include +#include "asio/buffer.hpp" +#include "asio/detail/assert.hpp" +#include "asio/detail/type_traits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +namespace detail +{ + template + struct buffers_iterator_types_helper; + + template <> + struct buffers_iterator_types_helper + { + typedef const_buffer buffer_type; + template + struct byte_type + { + typedef typename add_const::type type; + }; + }; + + template <> + struct buffers_iterator_types_helper + { + typedef mutable_buffer buffer_type; + template + struct byte_type + { + typedef ByteType type; + }; + }; + + template + struct buffers_iterator_types + { + enum + { + is_mutable = is_convertible< + typename BufferSequence::value_type, + mutable_buffer>::value + }; + typedef buffers_iterator_types_helper helper; + typedef typename helper::buffer_type buffer_type; + typedef typename helper::template byte_type::type byte_type; + typedef typename BufferSequence::const_iterator const_iterator; + }; + + template + struct buffers_iterator_types + { + typedef mutable_buffer buffer_type; + typedef ByteType byte_type; + typedef const mutable_buffer* const_iterator; + }; + + template + struct buffers_iterator_types + { + typedef const_buffer buffer_type; + typedef typename add_const::type byte_type; + typedef const const_buffer* const_iterator; + }; + +#if !defined(ASIO_NO_DEPRECATED) + + template + struct buffers_iterator_types + { + typedef mutable_buffer buffer_type; + typedef ByteType byte_type; + typedef const mutable_buffer* const_iterator; + }; + + template + struct buffers_iterator_types + { + typedef const_buffer buffer_type; + typedef typename add_const::type byte_type; + typedef const const_buffer* const_iterator; + }; + +#endif // !defined(ASIO_NO_DEPRECATED) +} + +/// A random access iterator over the bytes in a buffer sequence. +template +class buffers_iterator +{ +private: + typedef typename detail::buffers_iterator_types< + BufferSequence, ByteType>::buffer_type buffer_type; + + typedef typename detail::buffers_iterator_types::const_iterator buffer_sequence_iterator_type; + +public: + /// The type used for the distance between two iterators. + typedef std::ptrdiff_t difference_type; + + /// The type of the value pointed to by the iterator. + typedef ByteType value_type; + +#if defined(GENERATING_DOCUMENTATION) + /// The type of the result of applying operator->() to the iterator. + /** + * If the buffer sequence stores buffer objects that are convertible to + * mutable_buffer, this is a pointer to a non-const ByteType. Otherwise, a + * pointer to a const ByteType. + */ + typedef const_or_non_const_ByteType* pointer; +#else // defined(GENERATING_DOCUMENTATION) + typedef typename detail::buffers_iterator_types< + BufferSequence, ByteType>::byte_type* pointer; +#endif // defined(GENERATING_DOCUMENTATION) + +#if defined(GENERATING_DOCUMENTATION) + /// The type of the result of applying operator*() to the iterator. + /** + * If the buffer sequence stores buffer objects that are convertible to + * mutable_buffer, this is a reference to a non-const ByteType. Otherwise, a + * reference to a const ByteType. + */ + typedef const_or_non_const_ByteType& reference; +#else // defined(GENERATING_DOCUMENTATION) + typedef typename detail::buffers_iterator_types< + BufferSequence, ByteType>::byte_type& reference; +#endif // defined(GENERATING_DOCUMENTATION) + + /// The iterator category. + typedef std::random_access_iterator_tag iterator_category; + + /// Default constructor. Creates an iterator in an undefined state. + buffers_iterator() + : current_buffer_(), + current_buffer_position_(0), + begin_(), + current_(), + end_(), + position_(0) + { + } + + /// Construct an iterator representing the beginning of the buffers' data. + static buffers_iterator begin(const BufferSequence& buffers) +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3) + __attribute__ ((__noinline__)) +#endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3) + { + buffers_iterator new_iter; + new_iter.begin_ = asio::buffer_sequence_begin(buffers); + new_iter.current_ = asio::buffer_sequence_begin(buffers); + new_iter.end_ = asio::buffer_sequence_end(buffers); + while (new_iter.current_ != new_iter.end_) + { + new_iter.current_buffer_ = *new_iter.current_; + if (new_iter.current_buffer_.size() > 0) + break; + ++new_iter.current_; + } + return new_iter; + } + + /// Construct an iterator representing the end of the buffers' data. + static buffers_iterator end(const BufferSequence& buffers) +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3) + __attribute__ ((__noinline__)) +#endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3) + { + buffers_iterator new_iter; + new_iter.begin_ = asio::buffer_sequence_begin(buffers); + new_iter.current_ = asio::buffer_sequence_begin(buffers); + new_iter.end_ = asio::buffer_sequence_end(buffers); + while (new_iter.current_ != new_iter.end_) + { + buffer_type buffer = *new_iter.current_; + new_iter.position_ += buffer.size(); + ++new_iter.current_; + } + return new_iter; + } + + /// Dereference an iterator. + reference operator*() const + { + return dereference(); + } + + /// Dereference an iterator. + pointer operator->() const + { + return &dereference(); + } + + /// Access an individual element. + reference operator[](std::ptrdiff_t difference) const + { + buffers_iterator tmp(*this); + tmp.advance(difference); + return *tmp; + } + + /// Increment operator (prefix). + buffers_iterator& operator++() + { + increment(); + return *this; + } + + /// Increment operator (postfix). + buffers_iterator operator++(int) + { + buffers_iterator tmp(*this); + ++*this; + return tmp; + } + + /// Decrement operator (prefix). + buffers_iterator& operator--() + { + decrement(); + return *this; + } + + /// Decrement operator (postfix). + buffers_iterator operator--(int) + { + buffers_iterator tmp(*this); + --*this; + return tmp; + } + + /// Addition operator. + buffers_iterator& operator+=(std::ptrdiff_t difference) + { + advance(difference); + return *this; + } + + /// Subtraction operator. + buffers_iterator& operator-=(std::ptrdiff_t difference) + { + advance(-difference); + return *this; + } + + /// Addition operator. + friend buffers_iterator operator+(const buffers_iterator& iter, + std::ptrdiff_t difference) + { + buffers_iterator tmp(iter); + tmp.advance(difference); + return tmp; + } + + /// Addition operator. + friend buffers_iterator operator+(std::ptrdiff_t difference, + const buffers_iterator& iter) + { + buffers_iterator tmp(iter); + tmp.advance(difference); + return tmp; + } + + /// Subtraction operator. + friend buffers_iterator operator-(const buffers_iterator& iter, + std::ptrdiff_t difference) + { + buffers_iterator tmp(iter); + tmp.advance(-difference); + return tmp; + } + + /// Subtraction operator. + friend std::ptrdiff_t operator-(const buffers_iterator& a, + const buffers_iterator& b) + { + return b.distance_to(a); + } + + /// Test two iterators for equality. + friend bool operator==(const buffers_iterator& a, const buffers_iterator& b) + { + return a.equal(b); + } + + /// Test two iterators for inequality. + friend bool operator!=(const buffers_iterator& a, const buffers_iterator& b) + { + return !a.equal(b); + } + + /// Compare two iterators. + friend bool operator<(const buffers_iterator& a, const buffers_iterator& b) + { + return a.distance_to(b) > 0; + } + + /// Compare two iterators. + friend bool operator<=(const buffers_iterator& a, const buffers_iterator& b) + { + return !(b < a); + } + + /// Compare two iterators. + friend bool operator>(const buffers_iterator& a, const buffers_iterator& b) + { + return b < a; + } + + /// Compare two iterators. + friend bool operator>=(const buffers_iterator& a, const buffers_iterator& b) + { + return !(a < b); + } + +private: + // Dereference the iterator. + reference dereference() const + { + return static_cast( + current_buffer_.data())[current_buffer_position_]; + } + + // Compare two iterators for equality. + bool equal(const buffers_iterator& other) const + { + return position_ == other.position_; + } + + // Increment the iterator. + void increment() + { + ASIO_ASSERT(current_ != end_ && "iterator out of bounds"); + ++position_; + + // Check if the increment can be satisfied by the current buffer. + ++current_buffer_position_; + if (current_buffer_position_ != current_buffer_.size()) + return; + + // Find the next non-empty buffer. + ++current_; + current_buffer_position_ = 0; + while (current_ != end_) + { + current_buffer_ = *current_; + if (current_buffer_.size() > 0) + return; + ++current_; + } + } + + // Decrement the iterator. + void decrement() + { + ASIO_ASSERT(position_ > 0 && "iterator out of bounds"); + --position_; + + // Check if the decrement can be satisfied by the current buffer. + if (current_buffer_position_ != 0) + { + --current_buffer_position_; + return; + } + + // Find the previous non-empty buffer. + buffer_sequence_iterator_type iter = current_; + while (iter != begin_) + { + --iter; + buffer_type buffer = *iter; + std::size_t buffer_size = buffer.size(); + if (buffer_size > 0) + { + current_ = iter; + current_buffer_ = buffer; + current_buffer_position_ = buffer_size - 1; + return; + } + } + } + + // Advance the iterator by the specified distance. + void advance(std::ptrdiff_t n) + { + if (n > 0) + { + ASIO_ASSERT(current_ != end_ && "iterator out of bounds"); + for (;;) + { + std::ptrdiff_t current_buffer_balance + = current_buffer_.size() - current_buffer_position_; + + // Check if the advance can be satisfied by the current buffer. + if (current_buffer_balance > n) + { + position_ += n; + current_buffer_position_ += n; + return; + } + + // Update position. + n -= current_buffer_balance; + position_ += current_buffer_balance; + + // Move to next buffer. If it is empty then it will be skipped on the + // next iteration of this loop. + if (++current_ == end_) + { + ASIO_ASSERT(n == 0 && "iterator out of bounds"); + current_buffer_ = buffer_type(); + current_buffer_position_ = 0; + return; + } + current_buffer_ = *current_; + current_buffer_position_ = 0; + } + } + else if (n < 0) + { + std::size_t abs_n = -n; + ASIO_ASSERT(position_ >= abs_n && "iterator out of bounds"); + for (;;) + { + // Check if the advance can be satisfied by the current buffer. + if (current_buffer_position_ >= abs_n) + { + position_ -= abs_n; + current_buffer_position_ -= abs_n; + return; + } + + // Update position. + abs_n -= current_buffer_position_; + position_ -= current_buffer_position_; + + // Check if we've reached the beginning of the buffers. + if (current_ == begin_) + { + ASIO_ASSERT(abs_n == 0 && "iterator out of bounds"); + current_buffer_position_ = 0; + return; + } + + // Find the previous non-empty buffer. + buffer_sequence_iterator_type iter = current_; + while (iter != begin_) + { + --iter; + buffer_type buffer = *iter; + std::size_t buffer_size = buffer.size(); + if (buffer_size > 0) + { + current_ = iter; + current_buffer_ = buffer; + current_buffer_position_ = buffer_size; + break; + } + } + } + } + } + + // Determine the distance between two iterators. + std::ptrdiff_t distance_to(const buffers_iterator& other) const + { + return other.position_ - position_; + } + + buffer_type current_buffer_; + std::size_t current_buffer_position_; + buffer_sequence_iterator_type begin_; + buffer_sequence_iterator_type current_; + buffer_sequence_iterator_type end_; + std::size_t position_; +}; + +/// Construct an iterator representing the beginning of the buffers' data. +template +inline buffers_iterator buffers_begin( + const BufferSequence& buffers) +{ + return buffers_iterator::begin(buffers); +} + +/// Construct an iterator representing the end of the buffers' data. +template +inline buffers_iterator buffers_end( + const BufferSequence& buffers) +{ + return buffers_iterator::end(buffers); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BUFFERS_ITERATOR_HPP diff --git a/tools/sdk/include/asio/asio/completion_condition.hpp b/tools/sdk/include/asio/asio/completion_condition.hpp new file mode 100644 index 00000000..563f417d --- /dev/null +++ b/tools/sdk/include/asio/asio/completion_condition.hpp @@ -0,0 +1,218 @@ +// +// completion_condition.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_COMPLETION_CONDITION_HPP +#define ASIO_COMPLETION_CONDITION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include + +#include "asio/detail/push_options.hpp" + +namespace asio { + +namespace detail { + +// The default maximum number of bytes to transfer in a single operation. +enum default_max_transfer_size_t { default_max_transfer_size = 65536 }; + +// Adapt result of old-style completion conditions (which had a bool result +// where true indicated that the operation was complete). +inline std::size_t adapt_completion_condition_result(bool result) +{ + return result ? 0 : default_max_transfer_size; +} + +// Adapt result of current completion conditions (which have a size_t result +// where 0 means the operation is complete, and otherwise the result is the +// maximum number of bytes to transfer on the next underlying operation). +inline std::size_t adapt_completion_condition_result(std::size_t result) +{ + return result; +} + +class transfer_all_t +{ +public: + typedef std::size_t result_type; + + template + std::size_t operator()(const Error& err, std::size_t) + { + return !!err ? 0 : default_max_transfer_size; + } +}; + +class transfer_at_least_t +{ +public: + typedef std::size_t result_type; + + explicit transfer_at_least_t(std::size_t minimum) + : minimum_(minimum) + { + } + + template + std::size_t operator()(const Error& err, std::size_t bytes_transferred) + { + return (!!err || bytes_transferred >= minimum_) + ? 0 : default_max_transfer_size; + } + +private: + std::size_t minimum_; +}; + +class transfer_exactly_t +{ +public: + typedef std::size_t result_type; + + explicit transfer_exactly_t(std::size_t size) + : size_(size) + { + } + + template + std::size_t operator()(const Error& err, std::size_t bytes_transferred) + { + return (!!err || bytes_transferred >= size_) ? 0 : + (size_ - bytes_transferred < default_max_transfer_size + ? size_ - bytes_transferred : std::size_t(default_max_transfer_size)); + } + +private: + std::size_t size_; +}; + +} // namespace detail + +/** + * @defgroup completion_condition Completion Condition Function Objects + * + * Function objects used for determining when a read or write operation should + * complete. + */ +/*@{*/ + +/// Return a completion condition function object that indicates that a read or +/// write operation should continue until all of the data has been transferred, +/// or until an error occurs. +/** + * This function is used to create an object, of unspecified type, that meets + * CompletionCondition requirements. + * + * @par Example + * Reading until a buffer is full: + * @code + * boost::array buf; + * asio::error_code ec; + * std::size_t n = asio::read( + * sock, asio::buffer(buf), + * asio::transfer_all(), ec); + * if (ec) + * { + * // An error occurred. + * } + * else + * { + * // n == 128 + * } + * @endcode + */ +#if defined(GENERATING_DOCUMENTATION) +unspecified transfer_all(); +#else +inline detail::transfer_all_t transfer_all() +{ + return detail::transfer_all_t(); +} +#endif + +/// Return a completion condition function object that indicates that a read or +/// write operation should continue until a minimum number of bytes has been +/// transferred, or until an error occurs. +/** + * This function is used to create an object, of unspecified type, that meets + * CompletionCondition requirements. + * + * @par Example + * Reading until a buffer is full or contains at least 64 bytes: + * @code + * boost::array buf; + * asio::error_code ec; + * std::size_t n = asio::read( + * sock, asio::buffer(buf), + * asio::transfer_at_least(64), ec); + * if (ec) + * { + * // An error occurred. + * } + * else + * { + * // n >= 64 && n <= 128 + * } + * @endcode + */ +#if defined(GENERATING_DOCUMENTATION) +unspecified transfer_at_least(std::size_t minimum); +#else +inline detail::transfer_at_least_t transfer_at_least(std::size_t minimum) +{ + return detail::transfer_at_least_t(minimum); +} +#endif + +/// Return a completion condition function object that indicates that a read or +/// write operation should continue until an exact number of bytes has been +/// transferred, or until an error occurs. +/** + * This function is used to create an object, of unspecified type, that meets + * CompletionCondition requirements. + * + * @par Example + * Reading until a buffer is full or contains exactly 64 bytes: + * @code + * boost::array buf; + * asio::error_code ec; + * std::size_t n = asio::read( + * sock, asio::buffer(buf), + * asio::transfer_exactly(64), ec); + * if (ec) + * { + * // An error occurred. + * } + * else + * { + * // n == 64 + * } + * @endcode + */ +#if defined(GENERATING_DOCUMENTATION) +unspecified transfer_exactly(std::size_t size); +#else +inline detail::transfer_exactly_t transfer_exactly(std::size_t size) +{ + return detail::transfer_exactly_t(size); +} +#endif + +/*@}*/ + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_COMPLETION_CONDITION_HPP diff --git a/tools/sdk/include/asio/asio/connect.hpp b/tools/sdk/include/asio/asio/connect.hpp new file mode 100644 index 00000000..487ce3e0 --- /dev/null +++ b/tools/sdk/include/asio/asio/connect.hpp @@ -0,0 +1,1059 @@ +// +// connect.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_CONNECT_HPP +#define ASIO_CONNECT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/async_result.hpp" +#include "asio/basic_socket.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +namespace detail +{ + char (&has_iterator_helper(...))[2]; + + template + char has_iterator_helper(T*, typename T::iterator* = 0); + + template + struct has_iterator_typedef + { + enum { value = (sizeof((has_iterator_helper)((T*)(0))) == 1) }; + }; +} // namespace detail + +/// Type trait used to determine whether a type is an endpoint sequence that can +/// be used with with @c connect and @c async_connect. +template +struct is_endpoint_sequence +{ +#if defined(GENERATING_DOCUMENTATION) + /// The value member is true if the type may be used as an endpoint sequence. + static const bool value; +#else + enum + { + value = detail::has_iterator_typedef::value + }; +#endif +}; + +/** + * @defgroup connect asio::connect + * + * @brief Establishes a socket connection by trying each endpoint in a sequence. + */ +/*@{*/ + +/// Establishes a socket connection by trying each endpoint in a sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c connect member + * function, once for each endpoint in the sequence, until a connection is + * successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param endpoints A sequence of endpoints. + * + * @returns The successfully connected endpoint. + * + * @throws asio::system_error Thrown on failure. If the sequence is + * empty, the associated @c error_code is asio::error::not_found. + * Otherwise, contains the error from the last connection attempt. + * + * @par Example + * @code tcp::resolver r(io_context); + * tcp::resolver::query q("host", "service"); + * tcp::socket s(io_context); + * asio::connect(s, r.resolve(q)); @endcode + */ +template +typename Protocol::endpoint connect( + basic_socket& s, + const EndpointSequence& endpoints, + typename enable_if::value>::type* = 0); + +/// Establishes a socket connection by trying each endpoint in a sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c connect member + * function, once for each endpoint in the sequence, until a connection is + * successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param endpoints A sequence of endpoints. + * + * @param ec Set to indicate what error occurred, if any. If the sequence is + * empty, set to asio::error::not_found. Otherwise, contains the error + * from the last connection attempt. + * + * @returns On success, the successfully connected endpoint. Otherwise, a + * default-constructed endpoint. + * + * @par Example + * @code tcp::resolver r(io_context); + * tcp::resolver::query q("host", "service"); + * tcp::socket s(io_context); + * asio::error_code ec; + * asio::connect(s, r.resolve(q), ec); + * if (ec) + * { + * // An error occurred. + * } @endcode + */ +template +typename Protocol::endpoint connect( + basic_socket& s, + const EndpointSequence& endpoints, asio::error_code& ec, + typename enable_if::value>::type* = 0); + +#if !defined(ASIO_NO_DEPRECATED) +/// (Deprecated.) Establishes a socket connection by trying each endpoint in a +/// sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c connect member + * function, once for each endpoint in the sequence, until a connection is + * successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param begin An iterator pointing to the start of a sequence of endpoints. + * + * @returns On success, an iterator denoting the successfully connected + * endpoint. Otherwise, the end iterator. + * + * @throws asio::system_error Thrown on failure. If the sequence is + * empty, the associated @c error_code is asio::error::not_found. + * Otherwise, contains the error from the last connection attempt. + * + * @note This overload assumes that a default constructed object of type @c + * Iterator represents the end of the sequence. This is a valid assumption for + * iterator types such as @c asio::ip::tcp::resolver::iterator. + */ +template +Iterator connect(basic_socket& s, Iterator begin, + typename enable_if::value>::type* = 0); + +/// (Deprecated.) Establishes a socket connection by trying each endpoint in a +/// sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c connect member + * function, once for each endpoint in the sequence, until a connection is + * successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param begin An iterator pointing to the start of a sequence of endpoints. + * + * @param ec Set to indicate what error occurred, if any. If the sequence is + * empty, set to asio::error::not_found. Otherwise, contains the error + * from the last connection attempt. + * + * @returns On success, an iterator denoting the successfully connected + * endpoint. Otherwise, the end iterator. + * + * @note This overload assumes that a default constructed object of type @c + * Iterator represents the end of the sequence. This is a valid assumption for + * iterator types such as @c asio::ip::tcp::resolver::iterator. + */ +template +Iterator connect(basic_socket& s, + Iterator begin, asio::error_code& ec, + typename enable_if::value>::type* = 0); +#endif // !defined(ASIO_NO_DEPRECATED) + +/// Establishes a socket connection by trying each endpoint in a sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c connect member + * function, once for each endpoint in the sequence, until a connection is + * successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param begin An iterator pointing to the start of a sequence of endpoints. + * + * @param end An iterator pointing to the end of a sequence of endpoints. + * + * @returns An iterator denoting the successfully connected endpoint. + * + * @throws asio::system_error Thrown on failure. If the sequence is + * empty, the associated @c error_code is asio::error::not_found. + * Otherwise, contains the error from the last connection attempt. + * + * @par Example + * @code tcp::resolver r(io_context); + * tcp::resolver::query q("host", "service"); + * tcp::resolver::results_type e = r.resolve(q); + * tcp::socket s(io_context); + * asio::connect(s, e.begin(), e.end()); @endcode + */ +template +Iterator connect(basic_socket& s, + Iterator begin, Iterator end); + +/// Establishes a socket connection by trying each endpoint in a sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c connect member + * function, once for each endpoint in the sequence, until a connection is + * successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param begin An iterator pointing to the start of a sequence of endpoints. + * + * @param end An iterator pointing to the end of a sequence of endpoints. + * + * @param ec Set to indicate what error occurred, if any. If the sequence is + * empty, set to asio::error::not_found. Otherwise, contains the error + * from the last connection attempt. + * + * @returns On success, an iterator denoting the successfully connected + * endpoint. Otherwise, the end iterator. + * + * @par Example + * @code tcp::resolver r(io_context); + * tcp::resolver::query q("host", "service"); + * tcp::resolver::results_type e = r.resolve(q); + * tcp::socket s(io_context); + * asio::error_code ec; + * asio::connect(s, e.begin(), e.end(), ec); + * if (ec) + * { + * // An error occurred. + * } @endcode + */ +template +Iterator connect(basic_socket& s, + Iterator begin, Iterator end, asio::error_code& ec); + +/// Establishes a socket connection by trying each endpoint in a sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c connect member + * function, once for each endpoint in the sequence, until a connection is + * successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param endpoints A sequence of endpoints. + * + * @param connect_condition A function object that is called prior to each + * connection attempt. The signature of the function object must be: + * @code bool connect_condition( + * const asio::error_code& ec, + * const typename Protocol::endpoint& next); @endcode + * The @c ec parameter contains the result from the most recent connect + * operation. Before the first connection attempt, @c ec is always set to + * indicate success. The @c next parameter is the next endpoint to be tried. + * The function object should return true if the next endpoint should be tried, + * and false if it should be skipped. + * + * @returns The successfully connected endpoint. + * + * @throws asio::system_error Thrown on failure. If the sequence is + * empty, the associated @c error_code is asio::error::not_found. + * Otherwise, contains the error from the last connection attempt. + * + * @par Example + * The following connect condition function object can be used to output + * information about the individual connection attempts: + * @code struct my_connect_condition + * { + * bool operator()( + * const asio::error_code& ec, + * const::tcp::endpoint& next) + * { + * if (ec) std::cout << "Error: " << ec.message() << std::endl; + * std::cout << "Trying: " << next << std::endl; + * return true; + * } + * }; @endcode + * It would be used with the asio::connect function as follows: + * @code tcp::resolver r(io_context); + * tcp::resolver::query q("host", "service"); + * tcp::socket s(io_context); + * tcp::endpoint e = asio::connect(s, + * r.resolve(q), my_connect_condition()); + * std::cout << "Connected to: " << e << std::endl; @endcode + */ +template +typename Protocol::endpoint connect( + basic_socket& s, + const EndpointSequence& endpoints, ConnectCondition connect_condition, + typename enable_if::value>::type* = 0); + +/// Establishes a socket connection by trying each endpoint in a sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c connect member + * function, once for each endpoint in the sequence, until a connection is + * successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param endpoints A sequence of endpoints. + * + * @param connect_condition A function object that is called prior to each + * connection attempt. The signature of the function object must be: + * @code bool connect_condition( + * const asio::error_code& ec, + * const typename Protocol::endpoint& next); @endcode + * The @c ec parameter contains the result from the most recent connect + * operation. Before the first connection attempt, @c ec is always set to + * indicate success. The @c next parameter is the next endpoint to be tried. + * The function object should return true if the next endpoint should be tried, + * and false if it should be skipped. + * + * @param ec Set to indicate what error occurred, if any. If the sequence is + * empty, set to asio::error::not_found. Otherwise, contains the error + * from the last connection attempt. + * + * @returns On success, the successfully connected endpoint. Otherwise, a + * default-constructed endpoint. + * + * @par Example + * The following connect condition function object can be used to output + * information about the individual connection attempts: + * @code struct my_connect_condition + * { + * bool operator()( + * const asio::error_code& ec, + * const::tcp::endpoint& next) + * { + * if (ec) std::cout << "Error: " << ec.message() << std::endl; + * std::cout << "Trying: " << next << std::endl; + * return true; + * } + * }; @endcode + * It would be used with the asio::connect function as follows: + * @code tcp::resolver r(io_context); + * tcp::resolver::query q("host", "service"); + * tcp::socket s(io_context); + * asio::error_code ec; + * tcp::endpoint e = asio::connect(s, + * r.resolve(q), my_connect_condition(), ec); + * if (ec) + * { + * // An error occurred. + * } + * else + * { + * std::cout << "Connected to: " << e << std::endl; + * } @endcode + */ +template +typename Protocol::endpoint connect( + basic_socket& s, + const EndpointSequence& endpoints, ConnectCondition connect_condition, + asio::error_code& ec, + typename enable_if::value>::type* = 0); + +#if !defined(ASIO_NO_DEPRECATED) +/// (Deprecated.) Establishes a socket connection by trying each endpoint in a +/// sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c connect member + * function, once for each endpoint in the sequence, until a connection is + * successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param begin An iterator pointing to the start of a sequence of endpoints. + * + * @param connect_condition A function object that is called prior to each + * connection attempt. The signature of the function object must be: + * @code bool connect_condition( + * const asio::error_code& ec, + * const typename Protocol::endpoint& next); @endcode + * The @c ec parameter contains the result from the most recent connect + * operation. Before the first connection attempt, @c ec is always set to + * indicate success. The @c next parameter is the next endpoint to be tried. + * The function object should return true if the next endpoint should be tried, + * and false if it should be skipped. + * + * @returns On success, an iterator denoting the successfully connected + * endpoint. Otherwise, the end iterator. + * + * @throws asio::system_error Thrown on failure. If the sequence is + * empty, the associated @c error_code is asio::error::not_found. + * Otherwise, contains the error from the last connection attempt. + * + * @note This overload assumes that a default constructed object of type @c + * Iterator represents the end of the sequence. This is a valid assumption for + * iterator types such as @c asio::ip::tcp::resolver::iterator. + */ +template +Iterator connect(basic_socket& s, + Iterator begin, ConnectCondition connect_condition, + typename enable_if::value>::type* = 0); + +/// (Deprecated.) Establishes a socket connection by trying each endpoint in a +/// sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c connect member + * function, once for each endpoint in the sequence, until a connection is + * successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param begin An iterator pointing to the start of a sequence of endpoints. + * + * @param connect_condition A function object that is called prior to each + * connection attempt. The signature of the function object must be: + * @code bool connect_condition( + * const asio::error_code& ec, + * const typename Protocol::endpoint& next); @endcode + * The @c ec parameter contains the result from the most recent connect + * operation. Before the first connection attempt, @c ec is always set to + * indicate success. The @c next parameter is the next endpoint to be tried. + * The function object should return true if the next endpoint should be tried, + * and false if it should be skipped. + * + * @param ec Set to indicate what error occurred, if any. If the sequence is + * empty, set to asio::error::not_found. Otherwise, contains the error + * from the last connection attempt. + * + * @returns On success, an iterator denoting the successfully connected + * endpoint. Otherwise, the end iterator. + * + * @note This overload assumes that a default constructed object of type @c + * Iterator represents the end of the sequence. This is a valid assumption for + * iterator types such as @c asio::ip::tcp::resolver::iterator. + */ +template +Iterator connect(basic_socket& s, Iterator begin, + ConnectCondition connect_condition, asio::error_code& ec, + typename enable_if::value>::type* = 0); +#endif // !defined(ASIO_NO_DEPRECATED) + +/// Establishes a socket connection by trying each endpoint in a sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c connect member + * function, once for each endpoint in the sequence, until a connection is + * successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param begin An iterator pointing to the start of a sequence of endpoints. + * + * @param end An iterator pointing to the end of a sequence of endpoints. + * + * @param connect_condition A function object that is called prior to each + * connection attempt. The signature of the function object must be: + * @code bool connect_condition( + * const asio::error_code& ec, + * const typename Protocol::endpoint& next); @endcode + * The @c ec parameter contains the result from the most recent connect + * operation. Before the first connection attempt, @c ec is always set to + * indicate success. The @c next parameter is the next endpoint to be tried. + * The function object should return true if the next endpoint should be tried, + * and false if it should be skipped. + * + * @returns An iterator denoting the successfully connected endpoint. + * + * @throws asio::system_error Thrown on failure. If the sequence is + * empty, the associated @c error_code is asio::error::not_found. + * Otherwise, contains the error from the last connection attempt. + * + * @par Example + * The following connect condition function object can be used to output + * information about the individual connection attempts: + * @code struct my_connect_condition + * { + * bool operator()( + * const asio::error_code& ec, + * const::tcp::endpoint& next) + * { + * if (ec) std::cout << "Error: " << ec.message() << std::endl; + * std::cout << "Trying: " << next << std::endl; + * return true; + * } + * }; @endcode + * It would be used with the asio::connect function as follows: + * @code tcp::resolver r(io_context); + * tcp::resolver::query q("host", "service"); + * tcp::resolver::results_type e = r.resolve(q); + * tcp::socket s(io_context); + * tcp::resolver::results_type::iterator i = asio::connect( + * s, e.begin(), e.end(), my_connect_condition()); + * std::cout << "Connected to: " << i->endpoint() << std::endl; @endcode + */ +template +Iterator connect(basic_socket& s, Iterator begin, + Iterator end, ConnectCondition connect_condition); + +/// Establishes a socket connection by trying each endpoint in a sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c connect member + * function, once for each endpoint in the sequence, until a connection is + * successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param begin An iterator pointing to the start of a sequence of endpoints. + * + * @param end An iterator pointing to the end of a sequence of endpoints. + * + * @param connect_condition A function object that is called prior to each + * connection attempt. The signature of the function object must be: + * @code bool connect_condition( + * const asio::error_code& ec, + * const typename Protocol::endpoint& next); @endcode + * The @c ec parameter contains the result from the most recent connect + * operation. Before the first connection attempt, @c ec is always set to + * indicate success. The @c next parameter is the next endpoint to be tried. + * The function object should return true if the next endpoint should be tried, + * and false if it should be skipped. + * + * @param ec Set to indicate what error occurred, if any. If the sequence is + * empty, set to asio::error::not_found. Otherwise, contains the error + * from the last connection attempt. + * + * @returns On success, an iterator denoting the successfully connected + * endpoint. Otherwise, the end iterator. + * + * @par Example + * The following connect condition function object can be used to output + * information about the individual connection attempts: + * @code struct my_connect_condition + * { + * bool operator()( + * const asio::error_code& ec, + * const::tcp::endpoint& next) + * { + * if (ec) std::cout << "Error: " << ec.message() << std::endl; + * std::cout << "Trying: " << next << std::endl; + * return true; + * } + * }; @endcode + * It would be used with the asio::connect function as follows: + * @code tcp::resolver r(io_context); + * tcp::resolver::query q("host", "service"); + * tcp::resolver::results_type e = r.resolve(q); + * tcp::socket s(io_context); + * asio::error_code ec; + * tcp::resolver::results_type::iterator i = asio::connect( + * s, e.begin(), e.end(), my_connect_condition()); + * if (ec) + * { + * // An error occurred. + * } + * else + * { + * std::cout << "Connected to: " << i->endpoint() << std::endl; + * } @endcode + */ +template +Iterator connect(basic_socket& s, + Iterator begin, Iterator end, ConnectCondition connect_condition, + asio::error_code& ec); + +/*@}*/ + +/** + * @defgroup async_connect asio::async_connect + * + * @brief Asynchronously establishes a socket connection by trying each + * endpoint in a sequence. + */ +/*@{*/ + +/// Asynchronously establishes a socket connection by trying each endpoint in a +/// sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c async_connect + * member function, once for each endpoint in the sequence, until a connection + * is successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param endpoints A sequence of endpoints. + * + * @param handler The handler to be called when the connect operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * // Result of operation. if the sequence is empty, set to + * // asio::error::not_found. Otherwise, contains the + * // error from the last connection attempt. + * const asio::error_code& error, + * + * // On success, the successfully connected endpoint. + * // Otherwise, a default-constructed endpoint. + * const typename Protocol::endpoint& endpoint + * ); @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 + * asio::io_context::post(). + * + * @par Example + * @code tcp::resolver r(io_context); + * tcp::resolver::query q("host", "service"); + * tcp::socket s(io_context); + * + * // ... + * + * r.async_resolve(q, resolve_handler); + * + * // ... + * + * void resolve_handler( + * const asio::error_code& ec, + * tcp::resolver::results_type results) + * { + * if (!ec) + * { + * asio::async_connect(s, results, connect_handler); + * } + * } + * + * // ... + * + * void connect_handler( + * const asio::error_code& ec, + * const tcp::endpoint& endpoint) + * { + * // ... + * } @endcode + */ +template +ASIO_INITFN_RESULT_TYPE(RangeConnectHandler, + void (asio::error_code, typename Protocol::endpoint)) +async_connect(basic_socket& s, + const EndpointSequence& endpoints, + ASIO_MOVE_ARG(RangeConnectHandler) handler, + typename enable_if::value>::type* = 0); + +#if !defined(ASIO_NO_DEPRECATED) +/// (Deprecated.) Asynchronously establishes a socket connection by trying each +/// endpoint in a sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c async_connect + * member function, once for each endpoint in the sequence, until a connection + * is successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param begin An iterator pointing to the start of a sequence of endpoints. + * + * @param handler The handler to be called when the connect operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * // Result of operation. if the sequence is empty, set to + * // asio::error::not_found. Otherwise, contains the + * // error from the last connection attempt. + * const asio::error_code& error, + * + * // On success, an iterator denoting the successfully + * // connected endpoint. Otherwise, the end iterator. + * Iterator iterator + * ); @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 + * asio::io_context::post(). + * + * @note This overload assumes that a default constructed object of type @c + * Iterator represents the end of the sequence. This is a valid assumption for + * iterator types such as @c asio::ip::tcp::resolver::iterator. + */ +template +ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, + void (asio::error_code, Iterator)) +async_connect(basic_socket& s, + Iterator begin, ASIO_MOVE_ARG(IteratorConnectHandler) handler, + typename enable_if::value>::type* = 0); +#endif // !defined(ASIO_NO_DEPRECATED) + +/// Asynchronously establishes a socket connection by trying each endpoint in a +/// sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c async_connect + * member function, once for each endpoint in the sequence, until a connection + * is successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param begin An iterator pointing to the start of a sequence of endpoints. + * + * @param end An iterator pointing to the end of a sequence of endpoints. + * + * @param handler The handler to be called when the connect operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * // Result of operation. if the sequence is empty, set to + * // asio::error::not_found. Otherwise, contains the + * // error from the last connection attempt. + * const asio::error_code& error, + * + * // On success, an iterator denoting the successfully + * // connected endpoint. Otherwise, the end iterator. + * Iterator iterator + * ); @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 + * asio::io_context::post(). + * + * @par Example + * @code std::vector endpoints = ...; + * tcp::socket s(io_context); + * asio::async_connect(s, + * endpoints.begin(), endpoints.end(), + * connect_handler); + * + * // ... + * + * void connect_handler( + * const asio::error_code& ec, + * std::vector::iterator i) + * { + * // ... + * } @endcode + */ +template +ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, + void (asio::error_code, Iterator)) +async_connect(basic_socket& s, + Iterator begin, Iterator end, + ASIO_MOVE_ARG(IteratorConnectHandler) handler); + +/// Asynchronously establishes a socket connection by trying each endpoint in a +/// sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c async_connect + * member function, once for each endpoint in the sequence, until a connection + * is successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param endpoints A sequence of endpoints. + * + * @param connect_condition A function object that is called prior to each + * connection attempt. The signature of the function object must be: + * @code bool connect_condition( + * const asio::error_code& ec, + * const typename Protocol::endpoint& next); @endcode + * The @c ec parameter contains the result from the most recent connect + * operation. Before the first connection attempt, @c ec is always set to + * indicate success. The @c next parameter is the next endpoint to be tried. + * The function object should return true if the next endpoint should be tried, + * and false if it should be skipped. + * + * @param handler The handler to be called when the connect operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * // Result of operation. if the sequence is empty, set to + * // asio::error::not_found. Otherwise, contains the + * // error from the last connection attempt. + * const asio::error_code& error, + * + * // On success, an iterator denoting the successfully + * // connected endpoint. Otherwise, the end iterator. + * Iterator iterator + * ); @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 + * asio::io_context::post(). + * + * @par Example + * The following connect condition function object can be used to output + * information about the individual connection attempts: + * @code struct my_connect_condition + * { + * bool operator()( + * const asio::error_code& ec, + * const::tcp::endpoint& next) + * { + * if (ec) std::cout << "Error: " << ec.message() << std::endl; + * std::cout << "Trying: " << next << std::endl; + * return true; + * } + * }; @endcode + * It would be used with the asio::connect function as follows: + * @code tcp::resolver r(io_context); + * tcp::resolver::query q("host", "service"); + * tcp::socket s(io_context); + * + * // ... + * + * r.async_resolve(q, resolve_handler); + * + * // ... + * + * void resolve_handler( + * const asio::error_code& ec, + * tcp::resolver::results_type results) + * { + * if (!ec) + * { + * asio::async_connect(s, results, + * my_connect_condition(), + * connect_handler); + * } + * } + * + * // ... + * + * void connect_handler( + * const asio::error_code& ec, + * const tcp::endpoint& endpoint) + * { + * if (ec) + * { + * // An error occurred. + * } + * else + * { + * std::cout << "Connected to: " << endpoint << std::endl; + * } + * } @endcode + */ +template +ASIO_INITFN_RESULT_TYPE(RangeConnectHandler, + void (asio::error_code, typename Protocol::endpoint)) +async_connect(basic_socket& s, + const EndpointSequence& endpoints, ConnectCondition connect_condition, + ASIO_MOVE_ARG(RangeConnectHandler) handler, + typename enable_if::value>::type* = 0); + +#if !defined(ASIO_NO_DEPRECATED) +/// (Deprecated.) Asynchronously establishes a socket connection by trying each +/// endpoint in a sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c async_connect + * member function, once for each endpoint in the sequence, until a connection + * is successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param begin An iterator pointing to the start of a sequence of endpoints. + * + * @param connect_condition A function object that is called prior to each + * connection attempt. The signature of the function object must be: + * @code bool connect_condition( + * const asio::error_code& ec, + * const typename Protocol::endpoint& next); @endcode + * The @c ec parameter contains the result from the most recent connect + * operation. Before the first connection attempt, @c ec is always set to + * indicate success. The @c next parameter is the next endpoint to be tried. + * The function object should return true if the next endpoint should be tried, + * and false if it should be skipped. + * + * @param handler The handler to be called when the connect operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * // Result of operation. if the sequence is empty, set to + * // asio::error::not_found. Otherwise, contains the + * // error from the last connection attempt. + * const asio::error_code& error, + * + * // On success, an iterator denoting the successfully + * // connected endpoint. Otherwise, the end iterator. + * Iterator iterator + * ); @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 + * asio::io_context::post(). + * + * @note This overload assumes that a default constructed object of type @c + * Iterator represents the end of the sequence. This is a valid assumption for + * iterator types such as @c asio::ip::tcp::resolver::iterator. + */ +template +ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, + void (asio::error_code, Iterator)) +async_connect(basic_socket& s, Iterator begin, + ConnectCondition connect_condition, + ASIO_MOVE_ARG(IteratorConnectHandler) handler, + typename enable_if::value>::type* = 0); +#endif // !defined(ASIO_NO_DEPRECATED) + +/// Asynchronously establishes a socket connection by trying each endpoint in a +/// sequence. +/** + * This function attempts to connect a socket to one of a sequence of + * endpoints. It does this by repeated calls to the socket's @c async_connect + * member function, once for each endpoint in the sequence, until a connection + * is successfully established. + * + * @param s The socket to be connected. If the socket is already open, it will + * be closed. + * + * @param begin An iterator pointing to the start of a sequence of endpoints. + * + * @param end An iterator pointing to the end of a sequence of endpoints. + * + * @param connect_condition A function object that is called prior to each + * connection attempt. The signature of the function object must be: + * @code bool connect_condition( + * const asio::error_code& ec, + * const typename Protocol::endpoint& next); @endcode + * The @c ec parameter contains the result from the most recent connect + * operation. Before the first connection attempt, @c ec is always set to + * indicate success. The @c next parameter is the next endpoint to be tried. + * The function object should return true if the next endpoint should be tried, + * and false if it should be skipped. + * + * @param handler The handler to be called when the connect operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * // Result of operation. if the sequence is empty, set to + * // asio::error::not_found. Otherwise, contains the + * // error from the last connection attempt. + * const asio::error_code& error, + * + * // On success, an iterator denoting the successfully + * // connected endpoint. Otherwise, the end iterator. + * Iterator iterator + * ); @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 + * asio::io_context::post(). + * + * @par Example + * The following connect condition function object can be used to output + * information about the individual connection attempts: + * @code struct my_connect_condition + * { + * bool operator()( + * const asio::error_code& ec, + * const::tcp::endpoint& next) + * { + * if (ec) std::cout << "Error: " << ec.message() << std::endl; + * std::cout << "Trying: " << next << std::endl; + * return true; + * } + * }; @endcode + * It would be used with the asio::connect function as follows: + * @code tcp::resolver r(io_context); + * tcp::resolver::query q("host", "service"); + * tcp::socket s(io_context); + * + * // ... + * + * r.async_resolve(q, resolve_handler); + * + * // ... + * + * void resolve_handler( + * const asio::error_code& ec, + * tcp::resolver::iterator i) + * { + * if (!ec) + * { + * tcp::resolver::iterator end; + * asio::async_connect(s, i, end, + * my_connect_condition(), + * connect_handler); + * } + * } + * + * // ... + * + * void connect_handler( + * const asio::error_code& ec, + * tcp::resolver::iterator i) + * { + * if (ec) + * { + * // An error occurred. + * } + * else + * { + * std::cout << "Connected to: " << i->endpoint() << std::endl; + * } + * } @endcode + */ +template +ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, + void (asio::error_code, Iterator)) +async_connect(basic_socket& s, + Iterator begin, Iterator end, ConnectCondition connect_condition, + ASIO_MOVE_ARG(IteratorConnectHandler) handler); + +/*@}*/ + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/connect.hpp" + +#endif diff --git a/tools/sdk/include/asio/asio/coroutine.hpp b/tools/sdk/include/asio/asio/coroutine.hpp new file mode 100644 index 00000000..cd2d99e5 --- /dev/null +++ b/tools/sdk/include/asio/asio/coroutine.hpp @@ -0,0 +1,328 @@ +// +// coroutine.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_COROUTINE_HPP +#define ASIO_COROUTINE_HPP + +namespace asio { +namespace detail { + +class coroutine_ref; + +} // namespace detail + +/// Provides support for implementing stackless coroutines. +/** + * The @c coroutine class may be used to implement stackless coroutines. The + * class itself is used to store the current state of the coroutine. + * + * Coroutines are copy-constructible and assignable, and the space overhead is + * a single int. They can be used as a base class: + * + * @code class session : coroutine + * { + * ... + * }; @endcode + * + * or as a data member: + * + * @code class session + * { + * ... + * coroutine coro_; + * }; @endcode + * + * or even bound in as a function argument using lambdas or @c bind(). The + * important thing is that as the application maintains a copy of the object + * for as long as the coroutine must be kept alive. + * + * @par Pseudo-keywords + * + * A coroutine is used in conjunction with certain "pseudo-keywords", which + * are implemented as macros. These macros are defined by a header file: + * + * @code #include @endcode + * + * and may conversely be undefined as follows: + * + * @code #include @endcode + * + * reenter + * + * The @c reenter macro is used to define the body of a coroutine. It takes a + * single argument: a pointer or reference to a coroutine object. For example, + * if the base class is a coroutine object you may write: + * + * @code reenter (this) + * { + * ... coroutine body ... + * } @endcode + * + * and if a data member or other variable you can write: + * + * @code reenter (coro_) + * { + * ... coroutine body ... + * } @endcode + * + * When @c reenter is executed at runtime, control jumps to the location of the + * last @c yield or @c fork. + * + * The coroutine body may also be a single statement, such as: + * + * @code reenter (this) for (;;) + * { + * ... + * } @endcode + * + * @b Limitation: The @c reenter macro is implemented using a switch. This + * means that you must take care when using local variables within the + * coroutine body. The local variable is not allowed in a position where + * reentering the coroutine could bypass the variable definition. + * + * yield statement + * + * This form of the @c yield keyword is often used with asynchronous operations: + * + * @code yield socket_->async_read_some(buffer(*buffer_), *this); @endcode + * + * This divides into four logical steps: + * + * @li @c yield saves the current state of the coroutine. + * @li The statement initiates the asynchronous operation. + * @li The resume point is defined immediately following the statement. + * @li Control is transferred to the end of the coroutine body. + * + * When the asynchronous operation completes, the function object is invoked + * and @c reenter causes control to transfer to the resume point. It is + * important to remember to carry the coroutine state forward with the + * asynchronous operation. In the above snippet, the current class is a + * function object object with a coroutine object as base class or data member. + * + * The statement may also be a compound statement, and this permits us to + * define local variables with limited scope: + * + * @code yield + * { + * mutable_buffers_1 b = buffer(*buffer_); + * socket_->async_read_some(b, *this); + * } @endcode + * + * yield return expression ; + * + * This form of @c yield is often used in generators or coroutine-based parsers. + * For example, the function object: + * + * @code struct interleave : coroutine + * { + * istream& is1; + * istream& is2; + * char operator()(char c) + * { + * reenter (this) for (;;) + * { + * yield return is1.get(); + * yield return is2.get(); + * } + * } + * }; @endcode + * + * defines a trivial coroutine that interleaves the characters from two input + * streams. + * + * This type of @c yield divides into three logical steps: + * + * @li @c yield saves the current state of the coroutine. + * @li The resume point is defined immediately following the semicolon. + * @li The value of the expression is returned from the function. + * + * yield ; + * + * This form of @c yield is equivalent to the following steps: + * + * @li @c yield saves the current state of the coroutine. + * @li The resume point is defined immediately following the semicolon. + * @li Control is transferred to the end of the coroutine body. + * + * This form might be applied when coroutines are used for cooperative + * threading and scheduling is explicitly managed. For example: + * + * @code struct task : coroutine + * { + * ... + * void operator()() + * { + * reenter (this) + * { + * while (... not finished ...) + * { + * ... do something ... + * yield; + * ... do some more ... + * yield; + * } + * } + * } + * ... + * }; + * ... + * task t1, t2; + * for (;;) + * { + * t1(); + * t2(); + * } @endcode + * + * yield break ; + * + * The final form of @c yield is used to explicitly terminate the coroutine. + * This form is comprised of two steps: + * + * @li @c yield sets the coroutine state to indicate termination. + * @li Control is transferred to the end of the coroutine body. + * + * Once terminated, calls to is_complete() return true and the coroutine cannot + * be reentered. + * + * Note that a coroutine may also be implicitly terminated if the coroutine + * body is exited without a yield, e.g. by return, throw or by running to the + * end of the body. + * + * fork statement + * + * The @c fork pseudo-keyword is used when "forking" a coroutine, i.e. splitting + * it into two (or more) copies. One use of @c fork is in a server, where a new + * coroutine is created to handle each client connection: + * + * @code reenter (this) + * { + * do + * { + * socket_.reset(new tcp::socket(io_context_)); + * yield acceptor->async_accept(*socket_, *this); + * fork server(*this)(); + * } while (is_parent()); + * ... client-specific handling follows ... + * } @endcode + * + * The logical steps involved in a @c fork are: + * + * @li @c fork saves the current state of the coroutine. + * @li The statement creates a copy of the coroutine and either executes it + * immediately or schedules it for later execution. + * @li The resume point is defined immediately following the semicolon. + * @li For the "parent", control immediately continues from the next line. + * + * The functions is_parent() and is_child() can be used to differentiate + * between parent and child. You would use these functions to alter subsequent + * control flow. + * + * Note that @c fork doesn't do the actual forking by itself. It is the + * application's responsibility to create a clone of the coroutine and call it. + * The clone can be called immediately, as above, or scheduled for delayed + * execution using something like io_context::post(). + * + * @par Alternate macro names + * + * If preferred, an application can use macro names that follow a more typical + * naming convention, rather than the pseudo-keywords. These are: + * + * @li @c ASIO_CORO_REENTER instead of @c reenter + * @li @c ASIO_CORO_YIELD instead of @c yield + * @li @c ASIO_CORO_FORK instead of @c fork + */ +class coroutine +{ +public: + /// Constructs a coroutine in its initial state. + coroutine() : value_(0) {} + + /// Returns true if the coroutine is the child of a fork. + bool is_child() const { return value_ < 0; } + + /// Returns true if the coroutine is the parent of a fork. + bool is_parent() const { return !is_child(); } + + /// Returns true if the coroutine has reached its terminal state. + bool is_complete() const { return value_ == -1; } + +private: + friend class detail::coroutine_ref; + int value_; +}; + + +namespace detail { + +class coroutine_ref +{ +public: + coroutine_ref(coroutine& c) : value_(c.value_), modified_(false) {} + coroutine_ref(coroutine* c) : value_(c->value_), modified_(false) {} + ~coroutine_ref() { if (!modified_) value_ = -1; } + operator int() const { return value_; } + int& operator=(int v) { modified_ = true; return value_ = v; } +private: + void operator=(const coroutine_ref&); + int& value_; + bool modified_; +}; + +} // namespace detail +} // namespace asio + +#define ASIO_CORO_REENTER(c) \ + switch (::asio::detail::coroutine_ref _coro_value = c) \ + case -1: if (_coro_value) \ + { \ + goto terminate_coroutine; \ + terminate_coroutine: \ + _coro_value = -1; \ + goto bail_out_of_coroutine; \ + bail_out_of_coroutine: \ + break; \ + } \ + else /* fall-through */ case 0: + +#define ASIO_CORO_YIELD_IMPL(n) \ + for (_coro_value = (n);;) \ + if (_coro_value == 0) \ + { \ + case (n): ; \ + break; \ + } \ + else \ + switch (_coro_value ? 0 : 1) \ + for (;;) \ + /* fall-through */ case -1: if (_coro_value) \ + goto terminate_coroutine; \ + else for (;;) \ + /* fall-through */ case 1: if (_coro_value) \ + goto bail_out_of_coroutine; \ + else /* fall-through */ case 0: + +#define ASIO_CORO_FORK_IMPL(n) \ + for (_coro_value = -(n);; _coro_value = (n)) \ + if (_coro_value == (n)) \ + { \ + case -(n): ; \ + break; \ + } \ + else + +#if defined(_MSC_VER) +# define ASIO_CORO_YIELD ASIO_CORO_YIELD_IMPL(__COUNTER__ + 1) +# define ASIO_CORO_FORK ASIO_CORO_FORK_IMPL(__COUNTER__ + 1) +#else // defined(_MSC_VER) +# define ASIO_CORO_YIELD ASIO_CORO_YIELD_IMPL(__LINE__) +# define ASIO_CORO_FORK ASIO_CORO_FORK_IMPL(__LINE__) +#endif // defined(_MSC_VER) + +#endif // ASIO_COROUTINE_HPP diff --git a/tools/sdk/include/asio/asio/datagram_socket_service.hpp b/tools/sdk/include/asio/asio/datagram_socket_service.hpp new file mode 100644 index 00000000..7dc1a3b3 --- /dev/null +++ b/tools/sdk/include/asio/asio/datagram_socket_service.hpp @@ -0,0 +1,466 @@ +// +// datagram_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DATAGRAM_SOCKET_SERVICE_HPP +#define ASIO_DATAGRAM_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#include +#include "asio/async_result.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/null_socket_service.hpp" +#elif defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_socket_service.hpp" +#else +# include "asio/detail/reactive_socket_service.hpp" +#endif + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Default service implementation for a datagram socket. +template +class datagram_socket_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static 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(ASIO_WINDOWS_RUNTIME) + typedef detail::null_socket_service service_impl_type; +#elif defined(ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service service_impl_type; +#else + typedef detail::reactive_socket_service 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 + + /// 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_context. + explicit datagram_socket_service(asio::io_context& io_context) + : asio::detail::service_base< + datagram_socket_service >(io_context), + service_impl_(io_context) + { + } + + /// Construct a new datagram socket implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(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& 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 datagram_socket_service; + + /// Move-construct a new datagram socket implementation from another protocol + /// type. + template + void converting_move_construct(implementation_type& impl, + datagram_socket_service& other_service, + typename datagram_socket_service< + 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(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. + ASIO_SYNC_OP_VOID open(implementation_type& impl, + const protocol_type& protocol, asio::error_code& ec) + { + if (protocol.type() == ASIO_OS_DEF(SOCK_DGRAM)) + service_impl_.open(impl, protocol, ec); + else + ec = asio::error::invalid_argument; + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Assign an existing native socket to a datagram socket. + ASIO_SYNC_OP_VOID assign(implementation_type& impl, + const protocol_type& protocol, const native_handle_type& native_socket, + asio::error_code& ec) + { + service_impl_.assign(impl, protocol, native_socket, ec); + 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 datagram socket implementation. + ASIO_SYNC_OP_VOID close(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.close(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Release ownership of the underlying socket. + native_handle_type release(implementation_type& impl, + asio::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. + ASIO_SYNC_OP_VOID cancel(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.cancel(impl, ec); + 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, + asio::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, + asio::error_code& ec) const + { + return service_impl_.available(impl, ec); + } + + // Bind the datagram socket to the specified local endpoint. + ASIO_SYNC_OP_VOID bind(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + service_impl_.bind(impl, endpoint, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Connect the datagram socket to the specified endpoint. + ASIO_SYNC_OP_VOID connect(implementation_type& impl, + const endpoint_type& peer_endpoint, asio::error_code& ec) + { + service_impl_.connect(impl, peer_endpoint, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Start an asynchronous connect. + template + ASIO_INITFN_RESULT_TYPE(ConnectHandler, + void (asio::error_code)) + async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, + 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 + ASIO_SYNC_OP_VOID set_option(implementation_type& impl, + const SettableSocketOption& option, asio::error_code& ec) + { + service_impl_.set_option(impl, option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get a socket option. + template + ASIO_SYNC_OP_VOID get_option(const implementation_type& impl, + GettableSocketOption& option, asio::error_code& ec) const + { + service_impl_.get_option(impl, option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Perform an IO control command on the socket. + template + ASIO_SYNC_OP_VOID io_control(implementation_type& impl, + IoControlCommand& command, asio::error_code& ec) + { + service_impl_.io_control(impl, command, ec); + 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. + ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl, + bool mode, asio::error_code& ec) + { + service_impl_.non_blocking(impl, mode, ec); + 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. + ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl, + bool mode, asio::error_code& ec) + { + service_impl_.native_non_blocking(impl, mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.remote_endpoint(impl, ec); + } + + /// Disable sends or receives on the socket. + ASIO_SYNC_OP_VOID shutdown(implementation_type& impl, + socket_base::shutdown_type what, asio::error_code& ec) + { + service_impl_.shutdown(impl, what, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Wait for the socket to become ready to read, ready to write, or to have + /// pending error conditions. + ASIO_SYNC_OP_VOID wait(implementation_type& impl, + socket_base::wait_type w, asio::error_code& ec) + { + service_impl_.wait(impl, w, ec); + 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 + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(implementation_type& impl, socket_base::wait_type w, + 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, asio::error_code& ec) + { + return service_impl_.send(impl, buffers, flags, ec); + } + + /// Start an asynchronous send. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send(implementation_type& impl, const ConstBufferSequence& buffers, + socket_base::message_flags flags, + ASIO_MOVE_ARG(WriteHandler) handler) + { + async_completion init(handler); + + service_impl_.async_send(impl, buffers, flags, init.completion_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, asio::error_code& ec) + { + return service_impl_.send_to(impl, buffers, destination, flags, ec); + } + + /// Start an asynchronous send. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send_to(implementation_type& impl, + const ConstBufferSequence& buffers, const endpoint_type& destination, + socket_base::message_flags flags, + ASIO_MOVE_ARG(WriteHandler) handler) + { + async_completion init(handler); + + service_impl_.async_send_to(impl, buffers, + destination, 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, asio::error_code& ec) + { + return service_impl_.receive(impl, buffers, flags, ec); + } + + /// Start an asynchronous receive. + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, + ASIO_MOVE_ARG(ReadHandler) handler) + { + async_completion init(handler); + + service_impl_.async_receive(impl, buffers, flags, init.completion_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, asio::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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, + socket_base::message_flags flags, + ASIO_MOVE_ARG(ReadHandler) handler) + { + async_completion init(handler); + + service_impl_.async_receive_from(impl, buffers, + sender_endpoint, 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 + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_DATAGRAM_SOCKET_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/deadline_timer.hpp b/tools/sdk/include/asio/asio/deadline_timer.hpp new file mode 100644 index 00000000..5a215547 --- /dev/null +++ b/tools/sdk/include/asio/asio/deadline_timer.hpp @@ -0,0 +1,38 @@ +// +// deadline_timer.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DEADLINE_TIMER_HPP +#define ASIO_DEADLINE_TIMER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_BOOST_DATE_TIME) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/socket_types.hpp" // Must come before posix_time. +#include "asio/basic_deadline_timer.hpp" + +#include + +namespace asio { + +/// Typedef for the typical usage of timer. Uses a UTC clock. +typedef basic_deadline_timer deadline_timer; + +} // namespace asio + +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_DEADLINE_TIMER_HPP diff --git a/tools/sdk/include/asio/asio/deadline_timer_service.hpp b/tools/sdk/include/asio/asio/deadline_timer_service.hpp new file mode 100644 index 00000000..2dcc83e2 --- /dev/null +++ b/tools/sdk/include/asio/asio/deadline_timer_service.hpp @@ -0,0 +1,173 @@ +// +// deadline_timer_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DEADLINE_TIMER_SERVICE_HPP +#define ASIO_DEADLINE_TIMER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_BOOST_DATE_TIME) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/async_result.hpp" +#include "asio/detail/deadline_timer_service.hpp" +#include "asio/io_context.hpp" +#include "asio/time_traits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Default service implementation for a timer. +template > +class deadline_timer_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base< + deadline_timer_service > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_context::id id; +#endif + + /// The time traits type. + typedef TimeTraits traits_type; + + /// The time type. + typedef typename traits_type::time_type time_type; + + /// The duration type. + typedef typename traits_type::duration_type duration_type; + +private: + // The type of the platform-specific implementation. + typedef detail::deadline_timer_service service_impl_type; + +public: + /// The implementation type of the deadline timer. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// Construct a new timer service for the specified io_context. + explicit deadline_timer_service(asio::io_context& io_context) + : asio::detail::service_base< + deadline_timer_service >(io_context), + service_impl_(io_context) + { + } + + /// Construct a new timer implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a timer implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Cancel any asynchronous wait operations associated with the timer. + std::size_t cancel(implementation_type& impl, asio::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Cancels one asynchronous wait operation associated with the timer. + std::size_t cancel_one(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.cancel_one(impl, ec); + } + + /// Get the expiry time for the timer as an absolute time. + time_type expires_at(const implementation_type& impl) const + { + return service_impl_.expiry(impl); + } + + /// Set the expiry time for the timer as an absolute time. + std::size_t expires_at(implementation_type& impl, + const time_type& expiry_time, asio::error_code& ec) + { + return service_impl_.expires_at(impl, expiry_time, ec); + } + + /// Get the expiry time for the timer relative to now. + duration_type expires_from_now(const implementation_type& impl) const + { + return TimeTraits::subtract(service_impl_.expiry(impl), TimeTraits::now()); + } + + /// Set the expiry time for the timer relative to now. + std::size_t expires_from_now(implementation_type& impl, + const duration_type& expiry_time, asio::error_code& ec) + { + return service_impl_.expires_after(impl, expiry_time, ec); + } + + // Perform a blocking wait on the timer. + void wait(implementation_type& impl, asio::error_code& ec) + { + service_impl_.wait(impl, ec); + } + + // Start an asynchronous wait on the timer. + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(implementation_type& impl, + ASIO_MOVE_ARG(WaitHandler) handler) + { + async_completion init(handler); + + service_impl_.async_wait(impl, 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 + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_DEADLINE_TIMER_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/defer.hpp b/tools/sdk/include/asio/asio/defer.hpp new file mode 100644 index 00000000..a0897f2f --- /dev/null +++ b/tools/sdk/include/asio/asio/defer.hpp @@ -0,0 +1,107 @@ +// +// defer.hpp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DEFER_HPP +#define ASIO_DEFER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/async_result.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/execution_context.hpp" +#include "asio/is_executor.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Submits a completion token or function object for execution. +/** + * This function submits an object for execution using the object's associated + * executor. The function object is queued for execution, and is never called + * from the current thread prior to returning from defer(). + * + * This function has the following effects: + * + * @li Constructs a function object handler of type @c Handler, initialized + * with handler(forward(token)). + * + * @li Constructs an object @c result of type async_result, + * initializing the object as result(handler). + * + * @li Obtains the handler's associated executor object @c ex by performing + * get_associated_executor(handler). + * + * @li Obtains the handler's associated allocator object @c alloc by performing + * get_associated_allocator(handler). + * + * @li Performs ex.defer(std::move(handler), alloc). + * + * @li Returns result.get(). + */ +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer( + ASIO_MOVE_ARG(CompletionToken) token); + +/// Submits a completion token or function object for execution. +/** + * This function submits an object for execution using the specified executor. + * The function object is queued for execution, and is never called from the + * current thread prior to returning from defer(). + * + * This function has the following effects: + * + * @li Constructs a function object handler of type @c Handler, initialized + * with handler(forward(token)). + * + * @li Constructs an object @c result of type async_result, + * initializing the object as result(handler). + * + * @li Obtains the handler's associated executor object @c ex1 by performing + * get_associated_executor(handler). + * + * @li Creates a work object @c w by performing make_work(ex1). + * + * @li Obtains the handler's associated allocator object @c alloc by performing + * get_associated_allocator(handler). + * + * @li Constructs a function object @c f with a function call operator that + * performs ex1.dispatch(std::move(handler), alloc) followed by + * w.reset(). + * + * @li Performs Executor(ex).defer(std::move(f), alloc). + * + * @li Returns result.get(). + */ +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer( + const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token, + typename enable_if::value>::type* = 0); + +/// Submits a completion token or function object for execution. +/** + * @returns defer(ctx.get_executor(), forward(token)). + */ +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer( + ExecutionContext& ctx, ASIO_MOVE_ARG(CompletionToken) token, + typename enable_if::value>::type* = 0); + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/defer.hpp" + +#endif // ASIO_DEFER_HPP diff --git a/tools/sdk/include/asio/asio/detail/array.hpp b/tools/sdk/include/asio/asio/detail/array.hpp new file mode 100644 index 00000000..ba429746 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/array.hpp @@ -0,0 +1,38 @@ +// +// detail/array.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_ARRAY_HPP +#define ASIO_DETAIL_ARRAY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_STD_ARRAY) +# include +#else // defined(ASIO_HAS_STD_ARRAY) +# include +#endif // defined(ASIO_HAS_STD_ARRAY) + +namespace asio { +namespace detail { + +#if defined(ASIO_HAS_STD_ARRAY) +using std::array; +#else // defined(ASIO_HAS_STD_ARRAY) +using boost::array; +#endif // defined(ASIO_HAS_STD_ARRAY) + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_ARRAY_HPP diff --git a/tools/sdk/include/asio/asio/detail/array_fwd.hpp b/tools/sdk/include/asio/asio/detail/array_fwd.hpp new file mode 100644 index 00000000..4161db0d --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/array_fwd.hpp @@ -0,0 +1,34 @@ +// +// detail/array_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_ARRAY_FWD_HPP +#define ASIO_DETAIL_ARRAY_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +namespace boost { + +template +class array; + +} // namespace boost + +// Standard library components can't be forward declared, so we'll have to +// include the array header. Fortunately, it's fairly lightweight and doesn't +// add significantly to the compile time. +#if defined(ASIO_HAS_STD_ARRAY) +# include +#endif // defined(ASIO_HAS_STD_ARRAY) + +#endif // ASIO_DETAIL_ARRAY_FWD_HPP diff --git a/tools/sdk/include/asio/asio/detail/assert.hpp b/tools/sdk/include/asio/asio/detail/assert.hpp new file mode 100644 index 00000000..a952a441 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/assert.hpp @@ -0,0 +1,32 @@ +// +// detail/assert.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_ASSERT_HPP +#define ASIO_DETAIL_ASSERT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_BOOST_ASSERT) +# include +#else // defined(ASIO_HAS_BOOST_ASSERT) +# include +#endif // defined(ASIO_HAS_BOOST_ASSERT) + +#if defined(ASIO_HAS_BOOST_ASSERT) +# define ASIO_ASSERT(expr) BOOST_ASSERT(expr) +#else // defined(ASIO_HAS_BOOST_ASSERT) +# define ASIO_ASSERT(expr) assert(expr) +#endif // defined(ASIO_HAS_BOOST_ASSERT) + +#endif // ASIO_DETAIL_ASSERT_HPP diff --git a/tools/sdk/include/asio/asio/detail/atomic_count.hpp b/tools/sdk/include/asio/asio/detail/atomic_count.hpp new file mode 100644 index 00000000..2bf75a53 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/atomic_count.hpp @@ -0,0 +1,45 @@ +// +// detail/atomic_count.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_ATOMIC_COUNT_HPP +#define ASIO_DETAIL_ATOMIC_COUNT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_THREADS) +// Nothing to include. +#elif defined(ASIO_HAS_STD_ATOMIC) +# include +#else // defined(ASIO_HAS_STD_ATOMIC) +# include +#endif // defined(ASIO_HAS_STD_ATOMIC) + +namespace asio { +namespace detail { + +#if !defined(ASIO_HAS_THREADS) +typedef long atomic_count; +inline void increment(atomic_count& a, long b) { a += b; } +#elif defined(ASIO_HAS_STD_ATOMIC) +typedef std::atomic atomic_count; +inline void increment(atomic_count& a, long b) { a += b; } +#else // defined(ASIO_HAS_STD_ATOMIC) +typedef boost::detail::atomic_count atomic_count; +inline void increment(atomic_count& a, long b) { while (b > 0) ++a, --b; } +#endif // defined(ASIO_HAS_STD_ATOMIC) + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_ATOMIC_COUNT_HPP diff --git a/tools/sdk/include/asio/asio/detail/base_from_completion_cond.hpp b/tools/sdk/include/asio/asio/detail/base_from_completion_cond.hpp new file mode 100644 index 00000000..73b4a957 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/base_from_completion_cond.hpp @@ -0,0 +1,68 @@ +// +// detail/base_from_completion_cond.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_BASE_FROM_COMPLETION_COND_HPP +#define ASIO_DETAIL_BASE_FROM_COMPLETION_COND_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/completion_condition.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class base_from_completion_cond +{ +protected: + explicit base_from_completion_cond(CompletionCondition completion_condition) + : completion_condition_(completion_condition) + { + } + + std::size_t check_for_completion( + const asio::error_code& ec, + std::size_t total_transferred) + { + return detail::adapt_completion_condition_result( + completion_condition_(ec, total_transferred)); + } + +private: + CompletionCondition completion_condition_; +}; + +template <> +class base_from_completion_cond +{ +protected: + explicit base_from_completion_cond(transfer_all_t) + { + } + + static std::size_t check_for_completion( + const asio::error_code& ec, + std::size_t total_transferred) + { + return transfer_all_t()(ec, total_transferred); + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_BASE_FROM_COMPLETION_COND_HPP diff --git a/tools/sdk/include/asio/asio/detail/bind_handler.hpp b/tools/sdk/include/asio/asio/detail/bind_handler.hpp new file mode 100644 index 00000000..0f4f066d --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/bind_handler.hpp @@ -0,0 +1,816 @@ +// +// detail/bind_handler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_BIND_HANDLER_HPP +#define ASIO_DETAIL_BIND_HANDLER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/associated_allocator.hpp" +#include "asio/associated_executor.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/type_traits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class binder1 +{ +public: + template + binder1(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1) + : handler_(ASIO_MOVE_CAST(T)(handler)), + arg1_(arg1) + { + } + + binder1(Handler& handler, const Arg1& arg1) + : handler_(ASIO_MOVE_CAST(Handler)(handler)), + arg1_(arg1) + { + } + +#if defined(ASIO_HAS_MOVE) + binder1(const binder1& other) + : handler_(other.handler_), + arg1_(other.arg1_) + { + } + + binder1(binder1&& other) + : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), + arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()() + { + handler_(static_cast(arg1_)); + } + + void operator()() const + { + handler_(arg1_); + } + +//private: + Handler handler_; + Arg1 arg1_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder1* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder1* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline bool asio_handler_is_continuation( + binder1* this_handler) +{ + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); +} + +template +inline void asio_handler_invoke(Function& function, + binder1* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder1* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline binder1::type, Arg1> bind_handler( + ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1) +{ + return binder1::type, Arg1>(0, + ASIO_MOVE_CAST(Handler)(handler), arg1); +} + +template +class binder2 +{ +public: + template + binder2(int, ASIO_MOVE_ARG(T) handler, + const Arg1& arg1, const Arg2& arg2) + : handler_(ASIO_MOVE_CAST(T)(handler)), + arg1_(arg1), + arg2_(arg2) + { + } + + binder2(Handler& handler, const Arg1& arg1, const Arg2& arg2) + : handler_(ASIO_MOVE_CAST(Handler)(handler)), + arg1_(arg1), + arg2_(arg2) + { + } + +#if defined(ASIO_HAS_MOVE) + binder2(const binder2& other) + : handler_(other.handler_), + arg1_(other.arg1_), + arg2_(other.arg2_) + { + } + + binder2(binder2&& other) + : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), + arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)), + arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()() + { + handler_(static_cast(arg1_), + static_cast(arg2_)); + } + + void operator()() const + { + handler_(arg1_, arg2_); + } + +//private: + Handler handler_; + Arg1 arg1_; + Arg2 arg2_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder2* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder2* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline bool asio_handler_is_continuation( + binder2* this_handler) +{ + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); +} + +template +inline void asio_handler_invoke(Function& function, + binder2* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder2* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline binder2::type, Arg1, Arg2> bind_handler( + ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2) +{ + return binder2::type, Arg1, Arg2>(0, + ASIO_MOVE_CAST(Handler)(handler), arg1, arg2); +} + +template +class binder3 +{ +public: + template + binder3(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1, + const Arg2& arg2, const Arg3& arg3) + : handler_(ASIO_MOVE_CAST(T)(handler)), + arg1_(arg1), + arg2_(arg2), + arg3_(arg3) + { + } + + binder3(Handler& handler, const Arg1& arg1, + const Arg2& arg2, const Arg3& arg3) + : handler_(ASIO_MOVE_CAST(Handler)(handler)), + arg1_(arg1), + arg2_(arg2), + arg3_(arg3) + { + } + +#if defined(ASIO_HAS_MOVE) + binder3(const binder3& other) + : handler_(other.handler_), + arg1_(other.arg1_), + arg2_(other.arg2_), + arg3_(other.arg3_) + { + } + + binder3(binder3&& other) + : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), + arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)), + arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)), + arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()() + { + handler_(static_cast(arg1_), + static_cast(arg2_), static_cast(arg3_)); + } + + void operator()() const + { + handler_(arg1_, arg2_, arg3_); + } + +//private: + Handler handler_; + Arg1 arg1_; + Arg2 arg2_; + Arg3 arg3_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder3* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder3* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline bool asio_handler_is_continuation( + binder3* this_handler) +{ + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); +} + +template +inline void asio_handler_invoke(Function& function, + binder3* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder3* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline binder3::type, Arg1, Arg2, Arg3> bind_handler( + ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3) +{ + return binder3::type, Arg1, Arg2, Arg3>(0, + ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3); +} + +template +class binder4 +{ +public: + template + binder4(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1, + const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) + : handler_(ASIO_MOVE_CAST(T)(handler)), + arg1_(arg1), + arg2_(arg2), + arg3_(arg3), + arg4_(arg4) + { + } + + binder4(Handler& handler, const Arg1& arg1, + const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) + : handler_(ASIO_MOVE_CAST(Handler)(handler)), + arg1_(arg1), + arg2_(arg2), + arg3_(arg3), + arg4_(arg4) + { + } + +#if defined(ASIO_HAS_MOVE) + binder4(const binder4& other) + : handler_(other.handler_), + arg1_(other.arg1_), + arg2_(other.arg2_), + arg3_(other.arg3_), + arg4_(other.arg4_) + { + } + + binder4(binder4&& other) + : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), + arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)), + arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)), + arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_)), + arg4_(ASIO_MOVE_CAST(Arg4)(other.arg4_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()() + { + handler_(static_cast(arg1_), + static_cast(arg2_), static_cast(arg3_), + static_cast(arg4_)); + } + + void operator()() const + { + handler_(arg1_, arg2_, arg3_, arg4_); + } + +//private: + Handler handler_; + Arg1 arg1_; + Arg2 arg2_; + Arg3 arg3_; + Arg4 arg4_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder4* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder4* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline bool asio_handler_is_continuation( + binder4* this_handler) +{ + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); +} + +template +inline void asio_handler_invoke(Function& function, + binder4* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder4* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline binder4::type, Arg1, Arg2, Arg3, Arg4> +bind_handler(ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, + const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) +{ + return binder4::type, Arg1, Arg2, Arg3, Arg4>(0, + ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4); +} + +template +class binder5 +{ +public: + template + binder5(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1, + const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) + : handler_(ASIO_MOVE_CAST(T)(handler)), + arg1_(arg1), + arg2_(arg2), + arg3_(arg3), + arg4_(arg4), + arg5_(arg5) + { + } + + binder5(Handler& handler, const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) + : handler_(ASIO_MOVE_CAST(Handler)(handler)), + arg1_(arg1), + arg2_(arg2), + arg3_(arg3), + arg4_(arg4), + arg5_(arg5) + { + } + +#if defined(ASIO_HAS_MOVE) + binder5(const binder5& other) + : handler_(other.handler_), + arg1_(other.arg1_), + arg2_(other.arg2_), + arg3_(other.arg3_), + arg4_(other.arg4_), + arg5_(other.arg5_) + { + } + + binder5(binder5&& other) + : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), + arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)), + arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)), + arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_)), + arg4_(ASIO_MOVE_CAST(Arg4)(other.arg4_)), + arg5_(ASIO_MOVE_CAST(Arg5)(other.arg5_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()() + { + handler_(static_cast(arg1_), + static_cast(arg2_), static_cast(arg3_), + static_cast(arg4_), static_cast(arg5_)); + } + + void operator()() const + { + handler_(arg1_, arg2_, arg3_, arg4_, arg5_); + } + +//private: + Handler handler_; + Arg1 arg1_; + Arg2 arg2_; + Arg3 arg3_; + Arg4 arg4_; + Arg5 arg5_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder5* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder5* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline bool asio_handler_is_continuation( + binder5* this_handler) +{ + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); +} + +template +inline void asio_handler_invoke(Function& function, + binder5* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder5* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline binder5::type, Arg1, Arg2, Arg3, Arg4, Arg5> +bind_handler(ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, + const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) +{ + return binder5::type, Arg1, Arg2, Arg3, Arg4, Arg5>(0, + ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4, arg5); +} + +#if defined(ASIO_HAS_MOVE) + +template +class move_binder1 +{ +public: + move_binder1(int, ASIO_MOVE_ARG(Handler) handler, + ASIO_MOVE_ARG(Arg1) arg1) + : handler_(ASIO_MOVE_CAST(Handler)(handler)), + arg1_(ASIO_MOVE_CAST(Arg1)(arg1)) + { + } + + move_binder1(move_binder1&& other) + : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), + arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)) + { + } + + void operator()() + { + handler_(ASIO_MOVE_CAST(Arg1)(arg1_)); + } + +//private: + Handler handler_; + Arg1 arg1_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + move_binder1* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + move_binder1* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline bool asio_handler_is_continuation( + move_binder1* this_handler) +{ + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); +} + +template +inline void asio_handler_invoke(ASIO_MOVE_ARG(Function) function, + move_binder1* this_handler) +{ + asio_handler_invoke_helpers::invoke( + ASIO_MOVE_CAST(Function)(function), this_handler->handler_); +} + +template +class move_binder2 +{ +public: + move_binder2(int, ASIO_MOVE_ARG(Handler) handler, + const Arg1& arg1, ASIO_MOVE_ARG(Arg2) arg2) + : handler_(ASIO_MOVE_CAST(Handler)(handler)), + arg1_(arg1), + arg2_(ASIO_MOVE_CAST(Arg2)(arg2)) + { + } + + move_binder2(move_binder2&& other) + : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), + arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)), + arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)) + { + } + + void operator()() + { + handler_(static_cast(arg1_), + ASIO_MOVE_CAST(Arg2)(arg2_)); + } + +//private: + Handler handler_; + Arg1 arg1_; + Arg2 arg2_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + move_binder2* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + move_binder2* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline bool asio_handler_is_continuation( + move_binder2* this_handler) +{ + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); +} + +template +inline void asio_handler_invoke(ASIO_MOVE_ARG(Function) function, + move_binder2* this_handler) +{ + asio_handler_invoke_helpers::invoke( + ASIO_MOVE_CAST(Function)(function), this_handler->handler_); +} + +#endif // defined(ASIO_HAS_MOVE) + +} // namespace detail + +template +struct associated_allocator, Allocator> +{ + typedef typename associated_allocator::type type; + + static type get(const detail::binder1& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_allocator, Allocator> +{ + typedef typename associated_allocator::type type; + + static type get(const detail::binder2& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor, Executor> +{ + typedef typename associated_executor::type type; + + static type get(const detail::binder1& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +template +struct associated_executor, Executor> +{ + typedef typename associated_executor::type type; + + static type get(const detail::binder2& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#if defined(ASIO_HAS_MOVE) + +template +struct associated_allocator, Allocator> +{ + typedef typename associated_allocator::type type; + + static type get(const detail::move_binder1& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_allocator< + detail::move_binder2, Allocator> +{ + typedef typename associated_allocator::type type; + + static type get(const detail::move_binder2& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor, Executor> +{ + typedef typename associated_executor::type type; + + static type get(const detail::move_binder1& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +template +struct associated_executor, Executor> +{ + typedef typename associated_executor::type type; + + static type get(const detail::move_binder2& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // defined(ASIO_HAS_MOVE) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_BIND_HANDLER_HPP diff --git a/tools/sdk/include/asio/asio/detail/buffer_resize_guard.hpp b/tools/sdk/include/asio/asio/detail/buffer_resize_guard.hpp new file mode 100644 index 00000000..58ebc4cc --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/buffer_resize_guard.hpp @@ -0,0 +1,66 @@ +// +// detail/buffer_resize_guard.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP +#define ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/limits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Helper class to manage buffer resizing in an exception safe way. +template +class buffer_resize_guard +{ +public: + // Constructor. + buffer_resize_guard(Buffer& buffer) + : buffer_(buffer), + old_size_(buffer.size()) + { + } + + // Destructor rolls back the buffer resize unless commit was called. + ~buffer_resize_guard() + { + if (old_size_ != (std::numeric_limits::max)()) + { + buffer_.resize(old_size_); + } + } + + // Commit the resize transaction. + void commit() + { + old_size_ = (std::numeric_limits::max)(); + } + +private: + // The buffer being managed. + Buffer& buffer_; + + // The size of the buffer at the time the guard was constructed. + size_t old_size_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP diff --git a/tools/sdk/include/asio/asio/detail/buffer_sequence_adapter.hpp b/tools/sdk/include/asio/asio/detail/buffer_sequence_adapter.hpp new file mode 100644 index 00000000..92a8e3d2 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/buffer_sequence_adapter.hpp @@ -0,0 +1,544 @@ +// +// detail/buffer_sequence_adapter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP +#define ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/buffer.hpp" +#include "asio/detail/array_fwd.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class buffer_sequence_adapter_base +{ +#if defined(ASIO_WINDOWS_RUNTIME) +public: + // The maximum number of buffers to support in a single operation. + enum { max_buffers = 1 }; + +protected: + typedef Windows::Storage::Streams::IBuffer^ native_buffer_type; + + ASIO_DECL static void init_native_buffer( + native_buffer_type& buf, + const asio::mutable_buffer& buffer); + + ASIO_DECL static void init_native_buffer( + native_buffer_type& buf, + const asio::const_buffer& buffer); +#elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) +public: + // The maximum number of buffers to support in a single operation. + enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len }; + +protected: + typedef WSABUF native_buffer_type; + + static void init_native_buffer(WSABUF& buf, + const asio::mutable_buffer& buffer) + { + buf.buf = static_cast(buffer.data()); + buf.len = static_cast(buffer.size()); + } + + static void init_native_buffer(WSABUF& buf, + const asio::const_buffer& buffer) + { + buf.buf = const_cast(static_cast(buffer.data())); + buf.len = static_cast(buffer.size()); + } +#else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) +public: + // The maximum number of buffers to support in a single operation. + enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len }; + +protected: + typedef iovec native_buffer_type; + + static void init_iov_base(void*& base, void* addr) + { + base = addr; + } + + template + static void init_iov_base(T& base, void* addr) + { + base = static_cast(addr); + } + + static void init_native_buffer(iovec& iov, + const asio::mutable_buffer& buffer) + { + init_iov_base(iov.iov_base, buffer.data()); + iov.iov_len = buffer.size(); + } + + static void init_native_buffer(iovec& iov, + const asio::const_buffer& buffer) + { + init_iov_base(iov.iov_base, const_cast(buffer.data())); + iov.iov_len = buffer.size(); + } +#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) +}; + +// Helper class to translate buffers into the native buffer representation. +template +class buffer_sequence_adapter + : buffer_sequence_adapter_base +{ +public: + explicit buffer_sequence_adapter(const Buffers& buffer_sequence) + : count_(0), total_buffer_size_(0) + { + buffer_sequence_adapter::init( + asio::buffer_sequence_begin(buffer_sequence), + asio::buffer_sequence_end(buffer_sequence)); + } + + native_buffer_type* buffers() + { + return buffers_; + } + + std::size_t count() const + { + return count_; + } + + std::size_t total_size() const + { + return total_buffer_size_; + } + + bool all_empty() const + { + return total_buffer_size_ == 0; + } + + static bool all_empty(const Buffers& buffer_sequence) + { + return buffer_sequence_adapter::all_empty( + asio::buffer_sequence_begin(buffer_sequence), + asio::buffer_sequence_end(buffer_sequence)); + } + + static void validate(const Buffers& buffer_sequence) + { + buffer_sequence_adapter::validate( + asio::buffer_sequence_begin(buffer_sequence), + asio::buffer_sequence_end(buffer_sequence)); + } + + static Buffer first(const Buffers& buffer_sequence) + { + return buffer_sequence_adapter::first( + asio::buffer_sequence_begin(buffer_sequence), + asio::buffer_sequence_end(buffer_sequence)); + } + +private: + template + void init(Iterator begin, Iterator end) + { + Iterator iter = begin; + for (; iter != end && count_ < max_buffers; ++iter, ++count_) + { + Buffer buffer(*iter); + init_native_buffer(buffers_[count_], buffer); + total_buffer_size_ += buffer.size(); + } + } + + template + static bool all_empty(Iterator begin, Iterator end) + { + Iterator iter = begin; + std::size_t i = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + if (Buffer(*iter).size() > 0) + return false; + return true; + } + + template + static void validate(Iterator begin, Iterator end) + { + Iterator iter = begin; + for (; iter != end; ++iter) + { + Buffer buffer(*iter); + buffer.data(); + } + } + + template + static Buffer first(Iterator begin, Iterator end) + { + Iterator iter = begin; + for (; iter != end; ++iter) + { + Buffer buffer(*iter); + if (buffer.size() != 0) + return buffer; + } + return Buffer(); + } + + native_buffer_type buffers_[max_buffers]; + std::size_t count_; + std::size_t total_buffer_size_; +}; + +template +class buffer_sequence_adapter + : buffer_sequence_adapter_base +{ +public: + explicit buffer_sequence_adapter( + const asio::mutable_buffer& buffer_sequence) + { + init_native_buffer(buffer_, Buffer(buffer_sequence)); + total_buffer_size_ = buffer_sequence.size(); + } + + native_buffer_type* buffers() + { + return &buffer_; + } + + std::size_t count() const + { + return 1; + } + + std::size_t total_size() const + { + return total_buffer_size_; + } + + bool all_empty() const + { + return total_buffer_size_ == 0; + } + + static bool all_empty(const asio::mutable_buffer& buffer_sequence) + { + return buffer_sequence.size() == 0; + } + + static void validate(const asio::mutable_buffer& buffer_sequence) + { + buffer_sequence.data(); + } + + static Buffer first(const asio::mutable_buffer& buffer_sequence) + { + return Buffer(buffer_sequence); + } + +private: + native_buffer_type buffer_; + std::size_t total_buffer_size_; +}; + +template +class buffer_sequence_adapter + : buffer_sequence_adapter_base +{ +public: + explicit buffer_sequence_adapter( + const asio::const_buffer& buffer_sequence) + { + init_native_buffer(buffer_, Buffer(buffer_sequence)); + total_buffer_size_ = buffer_sequence.size(); + } + + native_buffer_type* buffers() + { + return &buffer_; + } + + std::size_t count() const + { + return 1; + } + + std::size_t total_size() const + { + return total_buffer_size_; + } + + bool all_empty() const + { + return total_buffer_size_ == 0; + } + + static bool all_empty(const asio::const_buffer& buffer_sequence) + { + return buffer_sequence.size() == 0; + } + + static void validate(const asio::const_buffer& buffer_sequence) + { + buffer_sequence.data(); + } + + static Buffer first(const asio::const_buffer& buffer_sequence) + { + return Buffer(buffer_sequence); + } + +private: + native_buffer_type buffer_; + std::size_t total_buffer_size_; +}; + +#if !defined(ASIO_NO_DEPRECATED) + +template +class buffer_sequence_adapter + : buffer_sequence_adapter_base +{ +public: + explicit buffer_sequence_adapter( + const asio::mutable_buffers_1& buffer_sequence) + { + init_native_buffer(buffer_, Buffer(buffer_sequence)); + total_buffer_size_ = buffer_sequence.size(); + } + + native_buffer_type* buffers() + { + return &buffer_; + } + + std::size_t count() const + { + return 1; + } + + std::size_t total_size() const + { + return total_buffer_size_; + } + + bool all_empty() const + { + return total_buffer_size_ == 0; + } + + static bool all_empty(const asio::mutable_buffers_1& buffer_sequence) + { + return buffer_sequence.size() == 0; + } + + static void validate(const asio::mutable_buffers_1& buffer_sequence) + { + buffer_sequence.data(); + } + + static Buffer first(const asio::mutable_buffers_1& buffer_sequence) + { + return Buffer(buffer_sequence); + } + +private: + native_buffer_type buffer_; + std::size_t total_buffer_size_; +}; + +template +class buffer_sequence_adapter + : buffer_sequence_adapter_base +{ +public: + explicit buffer_sequence_adapter( + const asio::const_buffers_1& buffer_sequence) + { + init_native_buffer(buffer_, Buffer(buffer_sequence)); + total_buffer_size_ = buffer_sequence.size(); + } + + native_buffer_type* buffers() + { + return &buffer_; + } + + std::size_t count() const + { + return 1; + } + + std::size_t total_size() const + { + return total_buffer_size_; + } + + bool all_empty() const + { + return total_buffer_size_ == 0; + } + + static bool all_empty(const asio::const_buffers_1& buffer_sequence) + { + return buffer_sequence.size() == 0; + } + + static void validate(const asio::const_buffers_1& buffer_sequence) + { + buffer_sequence.data(); + } + + static Buffer first(const asio::const_buffers_1& buffer_sequence) + { + return Buffer(buffer_sequence); + } + +private: + native_buffer_type buffer_; + std::size_t total_buffer_size_; +}; + +#endif // !defined(ASIO_NO_DEPRECATED) + +template +class buffer_sequence_adapter > + : buffer_sequence_adapter_base +{ +public: + explicit buffer_sequence_adapter( + const boost::array& buffer_sequence) + { + init_native_buffer(buffers_[0], Buffer(buffer_sequence[0])); + init_native_buffer(buffers_[1], Buffer(buffer_sequence[1])); + total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size(); + } + + native_buffer_type* buffers() + { + return buffers_; + } + + std::size_t count() const + { + return 2; + } + + std::size_t total_size() const + { + return total_buffer_size_; + } + + bool all_empty() const + { + return total_buffer_size_ == 0; + } + + static bool all_empty(const boost::array& buffer_sequence) + { + return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0; + } + + static void validate(const boost::array& buffer_sequence) + { + buffer_sequence[0].data(); + buffer_sequence[1].data(); + } + + static Buffer first(const boost::array& buffer_sequence) + { + return Buffer(buffer_sequence[0].size() != 0 + ? buffer_sequence[0] : buffer_sequence[1]); + } + +private: + native_buffer_type buffers_[2]; + std::size_t total_buffer_size_; +}; + +#if defined(ASIO_HAS_STD_ARRAY) + +template +class buffer_sequence_adapter > + : buffer_sequence_adapter_base +{ +public: + explicit buffer_sequence_adapter( + const std::array& buffer_sequence) + { + init_native_buffer(buffers_[0], Buffer(buffer_sequence[0])); + init_native_buffer(buffers_[1], Buffer(buffer_sequence[1])); + total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size(); + } + + native_buffer_type* buffers() + { + return buffers_; + } + + std::size_t count() const + { + return 2; + } + + std::size_t total_size() const + { + return total_buffer_size_; + } + + bool all_empty() const + { + return total_buffer_size_ == 0; + } + + static bool all_empty(const std::array& buffer_sequence) + { + return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0; + } + + static void validate(const std::array& buffer_sequence) + { + buffer_sequence[0].data(); + buffer_sequence[1].data(); + } + + static Buffer first(const std::array& buffer_sequence) + { + return Buffer(buffer_sequence[0].size() != 0 + ? buffer_sequence[0] : buffer_sequence[1]); + } + +private: + native_buffer_type buffers_[2]; + std::size_t total_buffer_size_; +}; + +#endif // defined(ASIO_HAS_STD_ARRAY) + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/buffer_sequence_adapter.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP diff --git a/tools/sdk/include/asio/asio/detail/buffered_stream_storage.hpp b/tools/sdk/include/asio/asio/detail/buffered_stream_storage.hpp new file mode 100644 index 00000000..c5eb081d --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/buffered_stream_storage.hpp @@ -0,0 +1,126 @@ +// +// detail/buffered_stream_storage.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP +#define ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/buffer.hpp" +#include "asio/detail/assert.hpp" +#include +#include +#include + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class buffered_stream_storage +{ +public: + // The type of the bytes stored in the buffer. + typedef unsigned char byte_type; + + // The type used for offsets into the buffer. + typedef std::size_t size_type; + + // Constructor. + explicit buffered_stream_storage(std::size_t buffer_capacity) + : begin_offset_(0), + end_offset_(0), + buffer_(buffer_capacity) + { + } + + /// Clear the buffer. + void clear() + { + begin_offset_ = 0; + end_offset_ = 0; + } + + // Return a pointer to the beginning of the unread data. + mutable_buffer data() + { + return asio::buffer(buffer_) + begin_offset_; + } + + // Return a pointer to the beginning of the unread data. + const_buffer data() const + { + return asio::buffer(buffer_) + begin_offset_; + } + + // Is there no unread data in the buffer. + bool empty() const + { + return begin_offset_ == end_offset_; + } + + // Return the amount of unread data the is in the buffer. + size_type size() const + { + return end_offset_ - begin_offset_; + } + + // Resize the buffer to the specified length. + void resize(size_type length) + { + ASIO_ASSERT(length <= capacity()); + if (begin_offset_ + length <= capacity()) + { + end_offset_ = begin_offset_ + length; + } + else + { + using namespace std; // For memmove. + memmove(&buffer_[0], &buffer_[0] + begin_offset_, size()); + end_offset_ = length; + begin_offset_ = 0; + } + } + + // Return the maximum size for data in the buffer. + size_type capacity() const + { + return buffer_.size(); + } + + // Consume multiple bytes from the beginning of the buffer. + void consume(size_type count) + { + ASIO_ASSERT(begin_offset_ + count <= end_offset_); + begin_offset_ += count; + if (empty()) + clear(); + } + +private: + // The offset to the beginning of the unread data. + size_type begin_offset_; + + // The offset to the end of the unread data. + size_type end_offset_; + + // The data in the buffer. + std::vector buffer_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP diff --git a/tools/sdk/include/asio/asio/detail/call_stack.hpp b/tools/sdk/include/asio/asio/detail/call_stack.hpp new file mode 100644 index 00000000..5725a10a --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/call_stack.hpp @@ -0,0 +1,125 @@ +// +// detail/call_stack.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_CALL_STACK_HPP +#define ASIO_DETAIL_CALL_STACK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/tss_ptr.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Helper class to determine whether or not the current thread is inside an +// invocation of io_context::run() for a specified io_context object. +template +class call_stack +{ +public: + // Context class automatically pushes the key/value pair on to the stack. + class context + : private noncopyable + { + public: + // Push the key on to the stack. + explicit context(Key* k) + : key_(k), + next_(call_stack::top_) + { + value_ = reinterpret_cast(this); + call_stack::top_ = this; + } + + // Push the key/value pair on to the stack. + context(Key* k, Value& v) + : key_(k), + value_(&v), + next_(call_stack::top_) + { + call_stack::top_ = this; + } + + // Pop the key/value pair from the stack. + ~context() + { + call_stack::top_ = next_; + } + + // Find the next context with the same key. + Value* next_by_key() const + { + context* elem = next_; + while (elem) + { + if (elem->key_ == key_) + return elem->value_; + elem = elem->next_; + } + return 0; + } + + private: + friend class call_stack; + + // The key associated with the context. + Key* key_; + + // The value associated with the context. + Value* value_; + + // The next element in the stack. + context* next_; + }; + + friend class context; + + // Determine whether the specified owner is on the stack. Returns address of + // key if present, 0 otherwise. + static Value* contains(Key* k) + { + context* elem = top_; + while (elem) + { + if (elem->key_ == k) + return elem->value_; + elem = elem->next_; + } + return 0; + } + + // Obtain the value at the top of the stack. + static Value* top() + { + context* elem = top_; + return elem ? elem->value_ : 0; + } + +private: + // The top of the stack of calls for the current thread. + static tss_ptr top_; +}; + +template +tss_ptr::context> +call_stack::top_; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_CALL_STACK_HPP diff --git a/tools/sdk/include/asio/asio/detail/chrono.hpp b/tools/sdk/include/asio/asio/detail/chrono.hpp new file mode 100644 index 00000000..8f56beed --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/chrono.hpp @@ -0,0 +1,66 @@ +// +// detail/chrono.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_CHRONO_HPP +#define ASIO_DETAIL_CHRONO_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_STD_CHRONO) +# include +#elif defined(ASIO_HAS_BOOST_CHRONO) +# include +#endif // defined(ASIO_HAS_BOOST_CHRONO) + +namespace asio { +namespace chrono { + +#if defined(ASIO_HAS_STD_CHRONO) +using std::chrono::duration; +using std::chrono::time_point; +using std::chrono::duration_cast; +using std::chrono::nanoseconds; +using std::chrono::microseconds; +using std::chrono::milliseconds; +using std::chrono::seconds; +using std::chrono::minutes; +using std::chrono::hours; +using std::chrono::time_point_cast; +#if defined(ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK) +typedef std::chrono::monotonic_clock steady_clock; +#else // defined(ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK) +using std::chrono::steady_clock; +#endif // defined(ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK) +using std::chrono::system_clock; +using std::chrono::high_resolution_clock; +#elif defined(ASIO_HAS_BOOST_CHRONO) +using boost::chrono::duration; +using boost::chrono::time_point; +using boost::chrono::duration_cast; +using boost::chrono::nanoseconds; +using boost::chrono::microseconds; +using boost::chrono::milliseconds; +using boost::chrono::seconds; +using boost::chrono::minutes; +using boost::chrono::hours; +using boost::chrono::time_point_cast; +using boost::chrono::system_clock; +using boost::chrono::steady_clock; +using boost::chrono::high_resolution_clock; +#endif // defined(ASIO_HAS_BOOST_CHRONO) + +} // namespace chrono +} // namespace asio + +#endif // ASIO_DETAIL_CHRONO_HPP diff --git a/tools/sdk/include/asio/asio/detail/chrono_time_traits.hpp b/tools/sdk/include/asio/asio/detail/chrono_time_traits.hpp new file mode 100644 index 00000000..d1528f70 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/chrono_time_traits.hpp @@ -0,0 +1,190 @@ +// +// detail/chrono_time_traits.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP +#define ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/cstdint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Helper template to compute the greatest common divisor. +template +struct gcd { enum { value = gcd::value }; }; + +template +struct gcd { enum { value = v1 }; }; + +// Adapts std::chrono clocks for use with a deadline timer. +template +struct chrono_time_traits +{ + // The clock type. + typedef Clock clock_type; + + // The duration type of the clock. + typedef typename clock_type::duration duration_type; + + // The time point type of the clock. + typedef typename clock_type::time_point time_type; + + // The period of the clock. + typedef typename duration_type::period period_type; + + // Get the current time. + static time_type now() + { + return clock_type::now(); + } + + // Add a duration to a time. + static time_type add(const time_type& t, const duration_type& d) + { + const time_type epoch; + if (t >= epoch) + { + if ((time_type::max)() - t < d) + return (time_type::max)(); + } + else // t < epoch + { + if (-(t - (time_type::min)()) > d) + return (time_type::min)(); + } + + return t + d; + } + + // Subtract one time from another. + static duration_type subtract(const time_type& t1, const time_type& t2) + { + const time_type epoch; + if (t1 >= epoch) + { + if (t2 >= epoch) + { + return t1 - t2; + } + else if (t2 == (time_type::min)()) + { + return (duration_type::max)(); + } + else if ((time_type::max)() - t1 < epoch - t2) + { + return (duration_type::max)(); + } + else + { + return t1 - t2; + } + } + else // t1 < epoch + { + if (t2 < epoch) + { + return t1 - t2; + } + else if (t1 == (time_type::min)()) + { + return (duration_type::min)(); + } + else if ((time_type::max)() - t2 < epoch - t1) + { + return (duration_type::min)(); + } + else + { + return -(t2 - t1); + } + } + } + + // Test whether one time is less than another. + static bool less_than(const time_type& t1, const time_type& t2) + { + return t1 < t2; + } + + // Implement just enough of the posix_time::time_duration interface to supply + // what the timer_queue requires. + class posix_time_duration + { + public: + explicit posix_time_duration(const duration_type& d) + : d_(d) + { + } + + int64_t ticks() const + { + return d_.count(); + } + + int64_t total_seconds() const + { + return duration_cast<1, 1>(); + } + + int64_t total_milliseconds() const + { + return duration_cast<1, 1000>(); + } + + int64_t total_microseconds() const + { + return duration_cast<1, 1000000>(); + } + + private: + template + int64_t duration_cast() const + { + const int64_t num1 = period_type::num / gcd::value; + const int64_t num2 = Num / gcd::value; + + const int64_t den1 = period_type::den / gcd::value; + const int64_t den2 = Den / gcd::value; + + const int64_t num = num1 * den2; + const int64_t den = num2 * den1; + + if (num == 1 && den == 1) + return ticks(); + else if (num != 1 && den == 1) + return ticks() * num; + else if (num == 1 && period_type::den != 1) + return ticks() / den; + else + return ticks() * num / den; + } + + duration_type d_; + }; + + // Convert to POSIX duration type. + static posix_time_duration to_posix_duration(const duration_type& d) + { + return posix_time_duration(WaitTraits::to_wait_duration(d)); + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP diff --git a/tools/sdk/include/asio/asio/detail/completion_handler.hpp b/tools/sdk/include/asio/asio/detail/completion_handler.hpp new file mode 100644 index 00000000..58a2e6db --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/completion_handler.hpp @@ -0,0 +1,83 @@ +// +// detail/completion_handler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_COMPLETION_HANDLER_HPP +#define ASIO_DETAIL_COMPLETION_HANDLER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_work.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/operation.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class completion_handler : public operation +{ +public: + ASIO_DEFINE_HANDLER_PTR(completion_handler); + + completion_handler(Handler& h) + : operation(&completion_handler::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(h)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + completion_handler* h(static_cast(base)); + ptr p = { asio::detail::addressof(h->handler_), h, h }; + handler_work w(h->handler_); + + ASIO_HANDLER_COMPLETION((*h)); + + // 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. + Handler handler(ASIO_MOVE_CAST(Handler)(h->handler_)); + p.h = asio::detail::addressof(handler); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN(()); + w.complete(handler, handler); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_COMPLETION_HANDLER_HPP diff --git a/tools/sdk/include/asio/asio/detail/concurrency_hint.hpp b/tools/sdk/include/asio/asio/detail/concurrency_hint.hpp new file mode 100644 index 00000000..229124d3 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/concurrency_hint.hpp @@ -0,0 +1,94 @@ +// +// detail/concurrency_hint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_CONCURRENCY_HINT_HPP +#define ASIO_DETAIL_CONCURRENCY_HINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/noncopyable.hpp" + +// The concurrency hint ID and mask are used to identify when a "well-known" +// concurrency hint value has been passed to the io_context. +#define ASIO_CONCURRENCY_HINT_ID 0xA5100000u +#define ASIO_CONCURRENCY_HINT_ID_MASK 0xFFFF0000u + +// If set, this bit indicates that the scheduler should perform locking. +#define ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER 0x1u + +// If set, this bit indicates that the reactor should perform locking when +// managing descriptor registrations. +#define ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION 0x2u + +// If set, this bit indicates that the reactor should perform locking for I/O. +#define ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_IO 0x4u + +// Helper macro to determine if we have a special concurrency hint. +#define ASIO_CONCURRENCY_HINT_IS_SPECIAL(hint) \ + ((static_cast(hint) \ + & ASIO_CONCURRENCY_HINT_ID_MASK) \ + == ASIO_CONCURRENCY_HINT_ID) + +// Helper macro to determine if locking is enabled for a given facility. +#define ASIO_CONCURRENCY_HINT_IS_LOCKING(facility, hint) \ + (((static_cast(hint) \ + & (ASIO_CONCURRENCY_HINT_ID_MASK \ + | ASIO_CONCURRENCY_HINT_LOCKING_ ## facility)) \ + ^ ASIO_CONCURRENCY_HINT_ID) != 0) + +// This special concurrency hint disables locking in both the scheduler and +// reactor I/O. This hint has the following restrictions: +// +// - Care must be taken to ensure that all operations on the io_context and any +// of its associated I/O objects (such as sockets and timers) occur in only +// one thread at a time. +// +// - Asynchronous resolve operations fail with operation_not_supported. +// +// - If a signal_set is used with the io_context, signal_set objects cannot be +// used with any other io_context in the program. +#define ASIO_CONCURRENCY_HINT_UNSAFE \ + static_cast(ASIO_CONCURRENCY_HINT_ID) + +// This special concurrency hint disables locking in the reactor I/O. This hint +// has the following restrictions: +// +// - Care must be taken to ensure that run functions on the io_context, and all +// operations on the io_context's associated I/O objects (such as sockets and +// timers), occur in only one thread at a time. +#define ASIO_CONCURRENCY_HINT_UNSAFE_IO \ + static_cast(ASIO_CONCURRENCY_HINT_ID \ + | ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER \ + | ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION) + +// The special concurrency hint provides full thread safety. +#define ASIO_CONCURRENCY_HINT_SAFE \ + static_cast(ASIO_CONCURRENCY_HINT_ID \ + | ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER \ + | ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION \ + | ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_IO) + +// This #define may be overridden at compile time to specify a program-wide +// default concurrency hint, used by the zero-argument io_context constructor. +#if !defined(ASIO_CONCURRENCY_HINT_DEFAULT) +# define ASIO_CONCURRENCY_HINT_DEFAULT -1 +#endif // !defined(ASIO_CONCURRENCY_HINT_DEFAULT) + +// This #define may be overridden at compile time to specify a program-wide +// concurrency hint, used by the one-argument io_context constructor when +// passed a value of 1. +#if !defined(ASIO_CONCURRENCY_HINT_1) +# define ASIO_CONCURRENCY_HINT_1 1 +#endif // !defined(ASIO_CONCURRENCY_HINT_DEFAULT) + +#endif // ASIO_DETAIL_CONCURRENCY_HINT_HPP diff --git a/tools/sdk/include/asio/asio/detail/conditionally_enabled_event.hpp b/tools/sdk/include/asio/asio/detail/conditionally_enabled_event.hpp new file mode 100644 index 00000000..0fda401e --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/conditionally_enabled_event.hpp @@ -0,0 +1,112 @@ +// +// detail/conditionally_enabled_event.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP +#define ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/conditionally_enabled_mutex.hpp" +#include "asio/detail/event.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/null_event.hpp" +#include "asio/detail/scoped_lock.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Mutex adapter used to conditionally enable or disable locking. +class conditionally_enabled_event + : private noncopyable +{ +public: + // Constructor. + conditionally_enabled_event() + { + } + + // Destructor. + ~conditionally_enabled_event() + { + } + + // Signal the event. (Retained for backward compatibility.) + void signal(conditionally_enabled_mutex::scoped_lock& lock) + { + if (lock.mutex_.enabled_) + event_.signal(lock); + } + + // Signal all waiters. + void signal_all(conditionally_enabled_mutex::scoped_lock& lock) + { + if (lock.mutex_.enabled_) + event_.signal_all(lock); + } + + // Unlock the mutex and signal one waiter. + void unlock_and_signal_one( + conditionally_enabled_mutex::scoped_lock& lock) + { + if (lock.mutex_.enabled_) + event_.unlock_and_signal_one(lock); + } + + // If there's a waiter, unlock the mutex and signal it. + bool maybe_unlock_and_signal_one( + conditionally_enabled_mutex::scoped_lock& lock) + { + if (lock.mutex_.enabled_) + return event_.maybe_unlock_and_signal_one(lock); + else + return false; + } + + // Reset the event. + void clear(conditionally_enabled_mutex::scoped_lock& lock) + { + if (lock.mutex_.enabled_) + event_.clear(lock); + } + + // Wait for the event to become signalled. + void wait(conditionally_enabled_mutex::scoped_lock& lock) + { + if (lock.mutex_.enabled_) + event_.wait(lock); + else + null_event().wait(lock); + } + + // Timed wait for the event to become signalled. + bool wait_for_usec( + conditionally_enabled_mutex::scoped_lock& lock, long usec) + { + if (lock.mutex_.enabled_) + return event_.wait_for_usec(lock, usec); + else + return null_event().wait_for_usec(lock, usec); + } + +private: + asio::detail::event event_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP diff --git a/tools/sdk/include/asio/asio/detail/conditionally_enabled_mutex.hpp b/tools/sdk/include/asio/asio/detail/conditionally_enabled_mutex.hpp new file mode 100644 index 00000000..2872db98 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/conditionally_enabled_mutex.hpp @@ -0,0 +1,149 @@ +// +// detail/conditionally_enabled_mutex.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP +#define ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/scoped_lock.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Mutex adapter used to conditionally enable or disable locking. +class conditionally_enabled_mutex + : private noncopyable +{ +public: + // Helper class to lock and unlock a mutex automatically. + class scoped_lock + : private noncopyable + { + public: + // Tag type used to distinguish constructors. + enum adopt_lock_t { adopt_lock }; + + // Constructor adopts a lock that is already held. + scoped_lock(conditionally_enabled_mutex& m, adopt_lock_t) + : mutex_(m), + locked_(m.enabled_) + { + } + + // Constructor acquires the lock. + explicit scoped_lock(conditionally_enabled_mutex& m) + : mutex_(m) + { + if (m.enabled_) + { + mutex_.mutex_.lock(); + locked_ = true; + } + else + locked_ = false; + } + + // Destructor releases the lock. + ~scoped_lock() + { + if (locked_) + mutex_.mutex_.unlock(); + } + + // Explicitly acquire the lock. + void lock() + { + if (mutex_.enabled_ && !locked_) + { + mutex_.mutex_.lock(); + locked_ = true; + } + } + + // Explicitly release the lock. + void unlock() + { + if (locked_) + { + mutex_.unlock(); + locked_ = false; + } + } + + // Test whether the lock is held. + bool locked() const + { + return locked_; + } + + // Get the underlying mutex. + asio::detail::mutex& mutex() + { + return mutex_.mutex_; + } + + private: + friend class conditionally_enabled_event; + conditionally_enabled_mutex& mutex_; + bool locked_; + }; + + // Constructor. + explicit conditionally_enabled_mutex(bool enabled) + : enabled_(enabled) + { + } + + // Destructor. + ~conditionally_enabled_mutex() + { + } + + // Determine whether locking is enabled. + bool enabled() const + { + return enabled_; + } + + // Lock the mutex. + void lock() + { + if (enabled_) + mutex_.lock(); + } + + // Unlock the mutex. + void unlock() + { + if (enabled_) + mutex_.unlock(); + } + +private: + friend class scoped_lock; + friend class conditionally_enabled_event; + asio::detail::mutex mutex_; + const bool enabled_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP diff --git a/tools/sdk/include/asio/asio/detail/config.hpp b/tools/sdk/include/asio/asio/detail/config.hpp new file mode 100644 index 00000000..949d67f2 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/config.hpp @@ -0,0 +1,1441 @@ +// +// detail/config.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_CONFIG_HPP +#define ASIO_DETAIL_CONFIG_HPP + +#if defined(ESP_PLATFORM) +# include "esp_asio_config.h" +#endif // defined(ESP_PLATFORM) + +#if defined(ASIO_STANDALONE) +# define ASIO_DISABLE_BOOST_ARRAY 1 +# define ASIO_DISABLE_BOOST_ASSERT 1 +# define ASIO_DISABLE_BOOST_BIND 1 +# define ASIO_DISABLE_BOOST_CHRONO 1 +# define ASIO_DISABLE_BOOST_DATE_TIME 1 +# define ASIO_DISABLE_BOOST_LIMITS 1 +# define ASIO_DISABLE_BOOST_REGEX 1 +# define ASIO_DISABLE_BOOST_STATIC_CONSTANT 1 +# define ASIO_DISABLE_BOOST_THROW_EXCEPTION 1 +# define ASIO_DISABLE_BOOST_WORKAROUND 1 +#else // defined(ASIO_STANDALONE) +# include +# include +# define ASIO_HAS_BOOST_CONFIG 1 +#endif // defined(ASIO_STANDALONE) + +// Default to a header-only implementation. The user must specifically request +// separate compilation by defining either ASIO_SEPARATE_COMPILATION or +// ASIO_DYN_LINK (as a DLL/shared library implies separate compilation). +#if !defined(ASIO_HEADER_ONLY) +# if !defined(ASIO_SEPARATE_COMPILATION) +# if !defined(ASIO_DYN_LINK) +# define ASIO_HEADER_ONLY 1 +# endif // !defined(ASIO_DYN_LINK) +# endif // !defined(ASIO_SEPARATE_COMPILATION) +#endif // !defined(ASIO_HEADER_ONLY) + +#if defined(ASIO_HEADER_ONLY) +# define ASIO_DECL inline +#else // defined(ASIO_HEADER_ONLY) +# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__) +// We need to import/export our code only if the user has specifically asked +// for it by defining ASIO_DYN_LINK. +# if defined(ASIO_DYN_LINK) +// Export if this is our own source, otherwise import. +# if defined(ASIO_SOURCE) +# define ASIO_DECL __declspec(dllexport) +# else // defined(ASIO_SOURCE) +# define ASIO_DECL __declspec(dllimport) +# endif // defined(ASIO_SOURCE) +# endif // defined(ASIO_DYN_LINK) +# endif // defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__) +#endif // defined(ASIO_HEADER_ONLY) + +// If ASIO_DECL isn't defined yet define it now. +#if !defined(ASIO_DECL) +# define ASIO_DECL +#endif // !defined(ASIO_DECL) + +// Microsoft Visual C++ detection. +#if !defined(ASIO_MSVC) +# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC) +# define ASIO_MSVC BOOST_MSVC +# elif defined(_MSC_VER) && (defined(__INTELLISENSE__) \ + || (!defined(__MWERKS__) && !defined(__EDG_VERSION__))) +# define ASIO_MSVC _MSC_VER +# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC) +#endif // !defined(ASIO_MSVC) +#if defined(ASIO_MSVC) +# include // Needed for _HAS_CXX17. +#endif // defined(ASIO_MSVC) + +// Clang / libc++ detection. +#if defined(__clang__) +# if (__cplusplus >= 201103) +# if __has_include(<__config>) +# include <__config> +# if defined(_LIBCPP_VERSION) +# define ASIO_HAS_CLANG_LIBCXX 1 +# endif // defined(_LIBCPP_VERSION) +# endif // __has_include(<__config>) +# endif // (__cplusplus >= 201103) +#endif // defined(__clang__) + +// Android platform detection. +#if defined(__ANDROID__) +# include +#endif // defined(__ANDROID__) + +// Support move construction and assignment on compilers known to allow it. +#if !defined(ASIO_HAS_MOVE) +# if !defined(ASIO_DISABLE_MOVE) +# if defined(__clang__) +# if __has_feature(__cxx_rvalue_references__) +# define ASIO_HAS_MOVE 1 +# endif // __has_feature(__cxx_rvalue_references__) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_MOVE 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_MOVE 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_MOVE) +#endif // !defined(ASIO_HAS_MOVE) + +// If ASIO_MOVE_CAST isn't defined, and move support is available, define +// ASIO_MOVE_ARG and ASIO_MOVE_CAST to take advantage of rvalue +// references and perfect forwarding. +#if defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST) +# define ASIO_MOVE_ARG(type) type&& +# define ASIO_MOVE_ARG2(type1, type2) type1, type2&& +# define ASIO_MOVE_CAST(type) static_cast +# define ASIO_MOVE_CAST2(type1, type2) static_cast +#endif // defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST) + +// If ASIO_MOVE_CAST still isn't defined, default to a C++03-compatible +// implementation. Note that older g++ and MSVC versions don't like it when you +// pass a non-member function through a const reference, so for most compilers +// we'll play it safe and stick with the old approach of passing the handler by +// value. +#if !defined(ASIO_MOVE_CAST) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4) +# define ASIO_MOVE_ARG(type) const type& +# else // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4) +# define ASIO_MOVE_ARG(type) type +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4) +# elif defined(ASIO_MSVC) +# if (_MSC_VER >= 1400) +# define ASIO_MOVE_ARG(type) const type& +# else // (_MSC_VER >= 1400) +# define ASIO_MOVE_ARG(type) type +# endif // (_MSC_VER >= 1400) +# else +# define ASIO_MOVE_ARG(type) type +# endif +# define ASIO_MOVE_CAST(type) static_cast +# define ASIO_MOVE_CAST2(type1, type2) static_cast +#endif // !defined(ASIO_MOVE_CAST) + +// Support variadic templates on compilers known to allow it. +#if !defined(ASIO_HAS_VARIADIC_TEMPLATES) +# if !defined(ASIO_DISABLE_VARIADIC_TEMPLATES) +# if defined(__clang__) +# if __has_feature(__cxx_variadic_templates__) +# define ASIO_HAS_VARIADIC_TEMPLATES 1 +# endif // __has_feature(__cxx_variadic_templates__) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_VARIADIC_TEMPLATES 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1900) +# define ASIO_HAS_VARIADIC_TEMPLATES 1 +# endif // (_MSC_VER >= 1900) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_VARIADIC_TEMPLATES) +#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) + +// Support deleted functions on compilers known to allow it. +#if !defined(ASIO_DELETED) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_DELETED = delete +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(__clang__) +# if __has_feature(__cxx_deleted_functions__) +# define ASIO_DELETED = delete +# endif // __has_feature(__cxx_deleted_functions__) +# endif // defined(__clang__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1900) +# define ASIO_DELETED = delete +# endif // (_MSC_VER >= 1900) +# endif // defined(ASIO_MSVC) +# if !defined(ASIO_DELETED) +# define ASIO_DELETED +# endif // !defined(ASIO_DELETED) +#endif // !defined(ASIO_DELETED) + +// Support constexpr on compilers known to allow it. +#if !defined(ASIO_HAS_CONSTEXPR) +# if !defined(ASIO_DISABLE_CONSTEXPR) +# if defined(__clang__) +# if __has_feature(__cxx_constexpr__) +# define ASIO_HAS_CONSTEXPR 1 +# endif // __has_feature(__cxx_constexr__) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_CONSTEXPR 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1900) +# define ASIO_HAS_CONSTEXPR 1 +# endif // (_MSC_VER >= 1900) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_CONSTEXPR) +#endif // !defined(ASIO_HAS_CONSTEXPR) +#if !defined(ASIO_CONSTEXPR) +# if defined(ASIO_HAS_CONSTEXPR) +# define ASIO_CONSTEXPR constexpr +# else // defined(ASIO_HAS_CONSTEXPR) +# define ASIO_CONSTEXPR +# endif // defined(ASIO_HAS_CONSTEXPR) +#endif // !defined(ASIO_CONSTEXPR) + +// Support noexcept on compilers known to allow it. +#if !defined(ASIO_NOEXCEPT) +# if !defined(ASIO_DISABLE_NOEXCEPT) +# if (BOOST_VERSION >= 105300) +# define ASIO_NOEXCEPT BOOST_NOEXCEPT +# define ASIO_NOEXCEPT_OR_NOTHROW BOOST_NOEXCEPT_OR_NOTHROW +# elif defined(__clang__) +# if __has_feature(__cxx_noexcept__) +# define ASIO_NOEXCEPT noexcept(true) +# define ASIO_NOEXCEPT_OR_NOTHROW noexcept(true) +# endif // __has_feature(__cxx_noexcept__) +# elif defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_NOEXCEPT noexcept(true) +# define ASIO_NOEXCEPT_OR_NOTHROW noexcept(true) +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# elif defined(ASIO_MSVC) +# if (_MSC_VER >= 1900) +# define ASIO_NOEXCEPT noexcept(true) +# define ASIO_NOEXCEPT_OR_NOTHROW noexcept(true) +# endif // (_MSC_VER >= 1900) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_NOEXCEPT) +# if !defined(ASIO_NOEXCEPT) +# define ASIO_NOEXCEPT +# endif // !defined(ASIO_NOEXCEPT) +# if !defined(ASIO_NOEXCEPT_OR_NOTHROW) +# define ASIO_NOEXCEPT_OR_NOTHROW throw() +# endif // !defined(ASIO_NOEXCEPT_OR_NOTHROW) +#endif // !defined(ASIO_NOEXCEPT) + +// Support automatic type deduction on compilers known to support it. +#if !defined(ASIO_HAS_DECLTYPE) +# if !defined(ASIO_DISABLE_DECLTYPE) +# if defined(__clang__) +# if __has_feature(__cxx_decltype__) +# define ASIO_HAS_DECLTYPE 1 +# endif // __has_feature(__cxx_decltype__) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_DECLTYPE 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_DECLTYPE 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_DECLTYPE) +#endif // !defined(ASIO_HAS_DECLTYPE) + +// Support alias templates on compilers known to allow it. +#if !defined(ASIO_HAS_ALIAS_TEMPLATES) +# if !defined(ASIO_DISABLE_ALIAS_TEMPLATES) +# if defined(__clang__) +# if __has_feature(__cxx_alias_templates__) +# define ASIO_HAS_ALIAS_TEMPLATES 1 +# endif // __has_feature(__cxx_alias_templates__) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_ALIAS_TEMPLATES 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1900) +# define ASIO_HAS_ALIAS_TEMPLATES 1 +# endif // (_MSC_VER >= 1900) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_ALIAS_TEMPLATES) +#endif // !defined(ASIO_HAS_ALIAS_TEMPLATES) + +// Standard library support for system errors. +#if !defined(ASIO_HAS_STD_SYSTEM_ERROR) +# if !defined(ASIO_DISABLE_STD_SYSTEM_ERROR) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_STD_SYSTEM_ERROR 1 +# elif (__cplusplus >= 201103) +# if __has_include() +# define ASIO_HAS_STD_SYSTEM_ERROR 1 +# endif // __has_include() +# endif // (__cplusplus >= 201103) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_STD_SYSTEM_ERROR 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_STD_SYSTEM_ERROR 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_SYSTEM_ERROR) +#endif // !defined(ASIO_HAS_STD_SYSTEM_ERROR) + +// Compliant C++11 compilers put noexcept specifiers on error_category members. +#if !defined(ASIO_ERROR_CATEGORY_NOEXCEPT) +# if (BOOST_VERSION >= 105300) +# define ASIO_ERROR_CATEGORY_NOEXCEPT BOOST_NOEXCEPT +# elif defined(__clang__) +# if __has_feature(__cxx_noexcept__) +# define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true) +# endif // __has_feature(__cxx_noexcept__) +# elif defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true) +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# elif defined(ASIO_MSVC) +# if (_MSC_VER >= 1900) +# define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true) +# endif // (_MSC_VER >= 1900) +# endif // defined(ASIO_MSVC) +# if !defined(ASIO_ERROR_CATEGORY_NOEXCEPT) +# define ASIO_ERROR_CATEGORY_NOEXCEPT +# endif // !defined(ASIO_ERROR_CATEGORY_NOEXCEPT) +#endif // !defined(ASIO_ERROR_CATEGORY_NOEXCEPT) + +// Standard library support for arrays. +#if !defined(ASIO_HAS_STD_ARRAY) +# if !defined(ASIO_DISABLE_STD_ARRAY) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_STD_ARRAY 1 +# elif (__cplusplus >= 201103) +# if __has_include() +# define ASIO_HAS_STD_ARRAY 1 +# endif // __has_include() +# endif // (__cplusplus >= 201103) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_STD_ARRAY 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1600) +# define ASIO_HAS_STD_ARRAY 1 +# endif // (_MSC_VER >= 1600) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_ARRAY) +#endif // !defined(ASIO_HAS_STD_ARRAY) + +// Standard library support for shared_ptr and weak_ptr. +#if !defined(ASIO_HAS_STD_SHARED_PTR) +# if !defined(ASIO_DISABLE_STD_SHARED_PTR) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_STD_SHARED_PTR 1 +# elif (__cplusplus >= 201103) +# define ASIO_HAS_STD_SHARED_PTR 1 +# endif // (__cplusplus >= 201103) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_STD_SHARED_PTR 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1600) +# define ASIO_HAS_STD_SHARED_PTR 1 +# endif // (_MSC_VER >= 1600) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_SHARED_PTR) +#endif // !defined(ASIO_HAS_STD_SHARED_PTR) + +// Standard library support for allocator_arg_t. +#if !defined(ASIO_HAS_STD_ALLOCATOR_ARG) +# if !defined(ASIO_DISABLE_STD_ALLOCATOR_ARG) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_STD_ALLOCATOR_ARG 1 +# elif (__cplusplus >= 201103) +# define ASIO_HAS_STD_ALLOCATOR_ARG 1 +# endif // (__cplusplus >= 201103) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_STD_ALLOCATOR_ARG 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1600) +# define ASIO_HAS_STD_ALLOCATOR_ARG 1 +# endif // (_MSC_VER >= 1600) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_ALLOCATOR_ARG) +#endif // !defined(ASIO_HAS_STD_ALLOCATOR_ARG) + +// Standard library support for atomic operations. +#if !defined(ASIO_HAS_STD_ATOMIC) +# if !defined(ASIO_DISABLE_STD_ATOMIC) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_STD_ATOMIC 1 +# elif (__cplusplus >= 201103) +# if __has_include() +# define ASIO_HAS_STD_ATOMIC 1 +# endif // __has_include() +# endif // (__cplusplus >= 201103) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_STD_ATOMIC 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_STD_ATOMIC 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_ATOMIC) +#endif // !defined(ASIO_HAS_STD_ATOMIC) + +// Standard library support for chrono. Some standard libraries (such as the +// libstdc++ shipped with gcc 4.6) provide monotonic_clock as per early C++0x +// drafts, rather than the eventually standardised name of steady_clock. +#if !defined(ASIO_HAS_STD_CHRONO) +# if !defined(ASIO_DISABLE_STD_CHRONO) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_STD_CHRONO 1 +# elif (__cplusplus >= 201103) +# if __has_include() +# define ASIO_HAS_STD_CHRONO 1 +# endif // __has_include() +# endif // (__cplusplus >= 201103) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_STD_CHRONO 1 +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ == 6)) +# define ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK 1 +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ == 6)) +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_STD_CHRONO 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_CHRONO) +#endif // !defined(ASIO_HAS_STD_CHRONO) + +// Boost support for chrono. +#if !defined(ASIO_HAS_BOOST_CHRONO) +# if !defined(ASIO_DISABLE_BOOST_CHRONO) +# if (BOOST_VERSION >= 104700) +# define ASIO_HAS_BOOST_CHRONO 1 +# endif // (BOOST_VERSION >= 104700) +# endif // !defined(ASIO_DISABLE_BOOST_CHRONO) +#endif // !defined(ASIO_HAS_BOOST_CHRONO) + +// Some form of chrono library is available. +#if !defined(ASIO_HAS_CHRONO) +# if defined(ASIO_HAS_STD_CHRONO) \ + || defined(ASIO_HAS_BOOST_CHRONO) +# define ASIO_HAS_CHRONO 1 +# endif // defined(ASIO_HAS_STD_CHRONO) + // || defined(ASIO_HAS_BOOST_CHRONO) +#endif // !defined(ASIO_HAS_CHRONO) + +// Boost support for the DateTime library. +#if !defined(ASIO_HAS_BOOST_DATE_TIME) +# if !defined(ASIO_DISABLE_BOOST_DATE_TIME) +# define ASIO_HAS_BOOST_DATE_TIME 1 +# endif // !defined(ASIO_DISABLE_BOOST_DATE_TIME) +#endif // !defined(ASIO_HAS_BOOST_DATE_TIME) + +// Standard library support for addressof. +#if !defined(ASIO_HAS_STD_ADDRESSOF) +# if !defined(ASIO_DISABLE_STD_ADDRESSOF) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_STD_ADDRESSOF 1 +# elif (__cplusplus >= 201103) +# define ASIO_HAS_STD_ADDRESSOF 1 +# endif // (__cplusplus >= 201103) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_STD_ADDRESSOF 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_STD_ADDRESSOF 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_ADDRESSOF) +#endif // !defined(ASIO_HAS_STD_ADDRESSOF) + +// Standard library support for the function class. +#if !defined(ASIO_HAS_STD_FUNCTION) +# if !defined(ASIO_DISABLE_STD_FUNCTION) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_STD_FUNCTION 1 +# elif (__cplusplus >= 201103) +# define ASIO_HAS_STD_FUNCTION 1 +# endif // (__cplusplus >= 201103) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_STD_FUNCTION 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_STD_FUNCTION 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_FUNCTION) +#endif // !defined(ASIO_HAS_STD_FUNCTION) + +// Standard library support for type traits. +#if !defined(ASIO_HAS_STD_TYPE_TRAITS) +# if !defined(ASIO_DISABLE_STD_TYPE_TRAITS) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_STD_TYPE_TRAITS 1 +# elif (__cplusplus >= 201103) +# if __has_include() +# define ASIO_HAS_STD_TYPE_TRAITS 1 +# endif // __has_include() +# endif // (__cplusplus >= 201103) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_STD_TYPE_TRAITS 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_STD_TYPE_TRAITS 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_TYPE_TRAITS) +#endif // !defined(ASIO_HAS_STD_TYPE_TRAITS) + +// Standard library support for the nullptr_t type. +#if !defined(ASIO_HAS_NULLPTR) +# if !defined(ASIO_DISABLE_NULLPTR) +# if defined(__clang__) +# if __has_feature(__cxx_nullptr__) +# define ASIO_HAS_NULLPTR 1 +# endif // __has_feature(__cxx_rvalue_references__) +# elif defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_NULLPTR 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_NULLPTR 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_NULLPTR) +#endif // !defined(ASIO_HAS_NULLPTR) + +// Standard library support for the C++11 allocator additions. +#if !defined(ASIO_HAS_CXX11_ALLOCATORS) +# if !defined(ASIO_DISABLE_CXX11_ALLOCATORS) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_CXX11_ALLOCATORS 1 +# elif (__cplusplus >= 201103) +# define ASIO_HAS_CXX11_ALLOCATORS 1 +# endif // (__cplusplus >= 201103) +# elif defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_CXX11_ALLOCATORS 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1800) +# define ASIO_HAS_CXX11_ALLOCATORS 1 +# endif // (_MSC_VER >= 1800) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_CXX11_ALLOCATORS) +#endif // !defined(ASIO_HAS_CXX11_ALLOCATORS) + +// Standard library support for the cstdint header. +#if !defined(ASIO_HAS_CSTDINT) +# if !defined(ASIO_DISABLE_CSTDINT) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_CSTDINT 1 +# elif (__cplusplus >= 201103) +# define ASIO_HAS_CSTDINT 1 +# endif // (__cplusplus >= 201103) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_CSTDINT 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_CSTDINT 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_CSTDINT) +#endif // !defined(ASIO_HAS_CSTDINT) + +// Standard library support for the thread class. +#if !defined(ASIO_HAS_STD_THREAD) +# if !defined(ASIO_DISABLE_STD_THREAD) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_STD_THREAD 1 +# elif (__cplusplus >= 201103) +# if __has_include() +# define ASIO_HAS_STD_THREAD 1 +# endif // __has_include() +# endif // (__cplusplus >= 201103) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_STD_THREAD 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_STD_THREAD 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_THREAD) +#endif // !defined(ASIO_HAS_STD_THREAD) + +// Standard library support for the mutex and condition variable classes. +#if !defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) +# if !defined(ASIO_DISABLE_STD_MUTEX_AND_CONDVAR) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1 +# elif (__cplusplus >= 201103) +# if __has_include() +# define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1 +# endif // __has_include() +# endif // (__cplusplus >= 201103) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_MUTEX_AND_CONDVAR) +#endif // !defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) + +// Standard library support for the call_once function. +#if !defined(ASIO_HAS_STD_CALL_ONCE) +# if !defined(ASIO_DISABLE_STD_CALL_ONCE) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_STD_CALL_ONCE 1 +# elif (__cplusplus >= 201103) +# if __has_include() +# define ASIO_HAS_STD_CALL_ONCE 1 +# endif // __has_include() +# endif // (__cplusplus >= 201103) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_STD_CALL_ONCE 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_STD_CALL_ONCE 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_CALL_ONCE) +#endif // !defined(ASIO_HAS_STD_CALL_ONCE) + +// Standard library support for futures. +#if !defined(ASIO_HAS_STD_FUTURE) +# if !defined(ASIO_DISABLE_STD_FUTURE) +# if defined(__clang__) +# if defined(ASIO_HAS_CLANG_LIBCXX) +# define ASIO_HAS_STD_FUTURE 1 +# elif (__cplusplus >= 201103) +# if __has_include() +# define ASIO_HAS_STD_FUTURE 1 +# endif // __has_include() +# endif // (__cplusplus >= 201103) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# if defined(_GLIBCXX_HAS_GTHREADS) +# define ASIO_HAS_STD_FUTURE 1 +# endif // defined(_GLIBCXX_HAS_GTHREADS) +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_STD_FUTURE 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_FUTURE) +#endif // !defined(ASIO_HAS_STD_FUTURE) + +// Standard library support for std::string_view. +#if !defined(ASIO_HAS_STD_STRING_VIEW) +# if !defined(ASIO_DISABLE_STD_STRING_VIEW) +# if defined(__clang__) +# if (__cplusplus >= 201703) +# if __has_include() +# define ASIO_HAS_STD_STRING_VIEW 1 +# endif // __has_include() +# endif // (__cplusplus >= 201703) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if (__GNUC__ >= 7) +# if (__cplusplus >= 201703) +# define ASIO_HAS_STD_STRING_VIEW 1 +# endif // (__cplusplus >= 201703) +# endif // (__GNUC__ >= 7) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1910 && _HAS_CXX17) +# define ASIO_HAS_STD_STRING_VIEW +# endif // (_MSC_VER >= 1910 && _HAS_CXX17) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_STRING_VIEW) +#endif // !defined(ASIO_HAS_STD_STRING_VIEW) + +// Standard library support for std::experimental::string_view. +#if !defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) +# if !defined(ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW) +# if defined(__clang__) +# if (__cplusplus >= 201402) +# if __has_include() +# define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1 +# endif // __has_include() +# endif // (__cplusplus >= 201402) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4) +# if (__cplusplus >= 201402) +# define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1 +# endif // (__cplusplus >= 201402) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# endif // !defined(ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW) +#endif // !defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) + +// Standard library has a string_view that we can use. +#if !defined(ASIO_HAS_STRING_VIEW) +# if !defined(ASIO_DISABLE_STRING_VIEW) +# if defined(ASIO_HAS_STD_STRING_VIEW) +# define ASIO_HAS_STRING_VIEW 1 +# elif defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) +# define ASIO_HAS_STRING_VIEW 1 +# endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) +# endif // !defined(ASIO_DISABLE_STRING_VIEW) +#endif // !defined(ASIO_HAS_STRING_VIEW) + +// Standard library support for iostream move construction and assignment. +#if !defined(ASIO_HAS_STD_IOSTREAM_MOVE) +# if !defined(ASIO_DISABLE_STD_IOSTREAM_MOVE) +# if defined(__GNUC__) +# if (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ASIO_HAS_STD_IOSTREAM_MOVE 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_STD_IOSTREAM_MOVE 1 +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_IOSTREAM_MOVE) +#endif // !defined(ASIO_HAS_STD_IOSTREAM_MOVE) + +// Standard library has invoke_result (which supersedes result_of). +#if !defined(ASIO_HAS_STD_INVOKE_RESULT) +# if !defined(ASIO_DISABLE_STD_INVOKE_RESULT) +# if defined(ASIO_MSVC) +# if (_MSC_VER >= 1910 && _HAS_CXX17) +# define ASIO_HAS_STD_INVOKE_RESULT 1 +# endif // (_MSC_VER >= 1910 && _HAS_CXX17) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_STD_INVOKE_RESULT) +#endif // !defined(ASIO_HAS_STD_INVOKE_RESULT) + +// Windows App target. Windows but with a limited API. +#if !defined(ASIO_WINDOWS_APP) +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603) +# include +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) \ + && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# define ASIO_WINDOWS_APP 1 +# endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) + // && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603) +#endif // !defined(ASIO_WINDOWS_APP) + +// Legacy WinRT target. Windows App is preferred. +#if !defined(ASIO_WINDOWS_RUNTIME) +# if !defined(ASIO_WINDOWS_APP) +# if defined(__cplusplus_winrt) +# include +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) \ + && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# define ASIO_WINDOWS_RUNTIME 1 +# endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) + // && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# endif // defined(__cplusplus_winrt) +# endif // !defined(ASIO_WINDOWS_APP) +#endif // !defined(ASIO_WINDOWS_RUNTIME) + +// Windows target. Excludes WinRT but includes Windows App targets. +#if !defined(ASIO_WINDOWS) +# if !defined(ASIO_WINDOWS_RUNTIME) +# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_WINDOWS) +# define ASIO_WINDOWS 1 +# elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) +# define ASIO_WINDOWS 1 +# elif defined(ASIO_WINDOWS_APP) +# define ASIO_WINDOWS 1 +# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_WINDOWS) +# endif // !defined(ASIO_WINDOWS_RUNTIME) +#endif // !defined(ASIO_WINDOWS) + +// Windows: target OS version. +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) +# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS) +# if defined(_MSC_VER) || defined(__BORLANDC__) +# pragma message( \ + "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\ + "- add -D_WIN32_WINNT=0x0501 to the compiler command line; or\n"\ + "- add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.\n"\ + "Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).") +# else // defined(_MSC_VER) || defined(__BORLANDC__) +# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. +# warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line. +# warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target). +# endif // defined(_MSC_VER) || defined(__BORLANDC__) +# define _WIN32_WINNT 0x0501 +# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS) +# if defined(_MSC_VER) +# if defined(_WIN32) && !defined(WIN32) +# if !defined(_WINSOCK2API_) +# define WIN32 // Needed for correct types in winsock2.h +# else // !defined(_WINSOCK2API_) +# error Please define the macro WIN32 in your compiler options +# endif // !defined(_WINSOCK2API_) +# endif // defined(_WIN32) && !defined(WIN32) +# endif // defined(_MSC_VER) +# if defined(__BORLANDC__) +# if defined(__WIN32__) && !defined(WIN32) +# if !defined(_WINSOCK2API_) +# define WIN32 // Needed for correct types in winsock2.h +# else // !defined(_WINSOCK2API_) +# error Please define the macro WIN32 in your compiler options +# endif // !defined(_WINSOCK2API_) +# endif // defined(__WIN32__) && !defined(WIN32) +# endif // defined(__BORLANDC__) +# if defined(__CYGWIN__) +# if !defined(__USE_W32_SOCKETS) +# error You must add -D__USE_W32_SOCKETS to your compiler options. +# endif // !defined(__USE_W32_SOCKETS) +# endif // defined(__CYGWIN__) +#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) + +// Windows: minimise header inclusion. +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) +# if !defined(ASIO_NO_WIN32_LEAN_AND_MEAN) +# if !defined(WIN32_LEAN_AND_MEAN) +# define WIN32_LEAN_AND_MEAN +# endif // !defined(WIN32_LEAN_AND_MEAN) +# endif // !defined(ASIO_NO_WIN32_LEAN_AND_MEAN) +#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) + +// Windows: suppress definition of "min" and "max" macros. +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) +# if !defined(ASIO_NO_NOMINMAX) +# if !defined(NOMINMAX) +# define NOMINMAX 1 +# endif // !defined(NOMINMAX) +# endif // !defined(ASIO_NO_NOMINMAX) +#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) + +// Windows: IO Completion Ports. +#if !defined(ASIO_HAS_IOCP) +# if defined(ASIO_WINDOWS) || defined(__CYGWIN__) +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400) +# if !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP) +# if !defined(ASIO_DISABLE_IOCP) +# define ASIO_HAS_IOCP 1 +# endif // !defined(ASIO_DISABLE_IOCP) +# endif // !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP) +# endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400) +# endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) +#endif // !defined(ASIO_HAS_IOCP) + +// On POSIX (and POSIX-like) platforms we need to include unistd.h in order to +// get access to the various platform feature macros, e.g. to be able to test +// for threads support. +#if !defined(ASIO_HAS_UNISTD_H) +# if !defined(ASIO_HAS_BOOST_CONFIG) +# if defined(unix) \ + || defined(__unix) \ + || defined(_XOPEN_SOURCE) \ + || defined(_POSIX_SOURCE) \ + || (defined(__MACH__) && defined(__APPLE__)) \ + || defined(__FreeBSD__) \ + || defined(__NetBSD__) \ + || defined(__OpenBSD__) \ + || defined(__linux__) +# define ASIO_HAS_UNISTD_H 1 +# endif +# endif // !defined(ASIO_HAS_BOOST_CONFIG) +#endif // !defined(ASIO_HAS_UNISTD_H) +#if defined(ASIO_HAS_UNISTD_H) +# include +#endif // defined(ASIO_HAS_UNISTD_H) + +// Linux: epoll, eventfd and timerfd. +#if defined(__linux__) +# include +# if !defined(ASIO_HAS_EPOLL) +# if !defined(ASIO_DISABLE_EPOLL) +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45) +# define ASIO_HAS_EPOLL 1 +# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45) +# endif // !defined(ASIO_DISABLE_EPOLL) +# endif // !defined(ASIO_HAS_EPOLL) +# if !defined(ASIO_HAS_EVENTFD) +# if !defined(ASIO_DISABLE_EVENTFD) +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +# define ASIO_HAS_EVENTFD 1 +# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +# endif // !defined(ASIO_DISABLE_EVENTFD) +# endif // !defined(ASIO_HAS_EVENTFD) +# if !defined(ASIO_HAS_TIMERFD) +# if defined(ASIO_HAS_EPOLL) +# if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) +# define ASIO_HAS_TIMERFD 1 +# endif // (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) +# endif // defined(ASIO_HAS_EPOLL) +# endif // !defined(ASIO_HAS_TIMERFD) +#endif // defined(__linux__) + +// Mac OS X, FreeBSD, NetBSD, OpenBSD: kqueue. +#if (defined(__MACH__) && defined(__APPLE__)) \ + || defined(__FreeBSD__) \ + || defined(__NetBSD__) \ + || defined(__OpenBSD__) +# if !defined(ASIO_HAS_KQUEUE) +# if !defined(ASIO_DISABLE_KQUEUE) +# define ASIO_HAS_KQUEUE 1 +# endif // !defined(ASIO_DISABLE_KQUEUE) +# endif // !defined(ASIO_HAS_KQUEUE) +#endif // (defined(__MACH__) && defined(__APPLE__)) + // || defined(__FreeBSD__) + // || defined(__NetBSD__) + // || defined(__OpenBSD__) + +// Solaris: /dev/poll. +#if defined(__sun) +# if !defined(ASIO_HAS_DEV_POLL) +# if !defined(ASIO_DISABLE_DEV_POLL) +# define ASIO_HAS_DEV_POLL 1 +# endif // !defined(ASIO_DISABLE_DEV_POLL) +# endif // !defined(ASIO_HAS_DEV_POLL) +#endif // defined(__sun) + +// Serial ports. +#if !defined(ASIO_HAS_SERIAL_PORT) +# if defined(ASIO_HAS_IOCP) \ + || !defined(ASIO_WINDOWS) \ + && !defined(ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) +# if !defined(__SYMBIAN32__) +# if !defined(ASIO_DISABLE_SERIAL_PORT) +# define ASIO_HAS_SERIAL_PORT 1 +# endif // !defined(ASIO_DISABLE_SERIAL_PORT) +# endif // !defined(__SYMBIAN32__) +# endif // defined(ASIO_HAS_IOCP) + // || !defined(ASIO_WINDOWS) + // && !defined(ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) +#endif // !defined(ASIO_HAS_SERIAL_PORT) + +// Windows: stream handles. +#if !defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) +# if !defined(ASIO_DISABLE_WINDOWS_STREAM_HANDLE) +# if defined(ASIO_HAS_IOCP) +# define ASIO_HAS_WINDOWS_STREAM_HANDLE 1 +# endif // defined(ASIO_HAS_IOCP) +# endif // !defined(ASIO_DISABLE_WINDOWS_STREAM_HANDLE) +#endif // !defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) + +// Windows: random access handles. +#if !defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) +# if !defined(ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE) +# if defined(ASIO_HAS_IOCP) +# define ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE 1 +# endif // defined(ASIO_HAS_IOCP) +# endif // !defined(ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE) +#endif // !defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + +// Windows: object handles. +#if !defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) +# if !defined(ASIO_DISABLE_WINDOWS_OBJECT_HANDLE) +# if defined(ASIO_WINDOWS) || defined(__CYGWIN__) +# if !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP) +# define ASIO_HAS_WINDOWS_OBJECT_HANDLE 1 +# endif // !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP) +# endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) +# endif // !defined(ASIO_DISABLE_WINDOWS_OBJECT_HANDLE) +#endif // !defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) + +// Windows: OVERLAPPED wrapper. +#if !defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) +# if !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR) +# if defined(ASIO_HAS_IOCP) +# define ASIO_HAS_WINDOWS_OVERLAPPED_PTR 1 +# endif // defined(ASIO_HAS_IOCP) +# endif // !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR) +#endif // !defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) + +// POSIX: stream-oriented file descriptors. +#if !defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) +# if !defined(ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR) +# if !defined(ASIO_WINDOWS) \ + && !defined(ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) +# define ASIO_HAS_POSIX_STREAM_DESCRIPTOR 1 +# endif // !defined(ASIO_WINDOWS) + // && !defined(ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) +# endif // !defined(ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR) +#endif // !defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) + +// UNIX domain sockets. +#if !defined(ASIO_HAS_LOCAL_SOCKETS) +# if !defined(ASIO_DISABLE_LOCAL_SOCKETS) +# if !defined(ASIO_WINDOWS) \ + && !defined(ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) +# define ASIO_HAS_LOCAL_SOCKETS 1 +# endif // !defined(ASIO_WINDOWS) + // && !defined(ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) +# endif // !defined(ASIO_DISABLE_LOCAL_SOCKETS) +#endif // !defined(ASIO_HAS_LOCAL_SOCKETS) + +// Can use sigaction() instead of signal(). +#if !defined(ASIO_HAS_SIGACTION) +# if !defined(ASIO_DISABLE_SIGACTION) +# if !defined(ASIO_WINDOWS) \ + && !defined(ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) +# define ASIO_HAS_SIGACTION 1 +# endif // !defined(ASIO_WINDOWS) + // && !defined(ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) +# endif // !defined(ASIO_DISABLE_SIGACTION) +#endif // !defined(ASIO_HAS_SIGACTION) + +// Can use signal(). +#if !defined(ASIO_HAS_SIGNAL) +# if !defined(ASIO_DISABLE_SIGNAL) +# if !defined(UNDER_CE) +# define ASIO_HAS_SIGNAL 1 +# endif // !defined(UNDER_CE) +# endif // !defined(ASIO_DISABLE_SIGNAL) +#endif // !defined(ASIO_HAS_SIGNAL) + +// Can use getaddrinfo() and getnameinfo(). +#if !defined(ASIO_HAS_GETADDRINFO) +# if !defined(ASIO_DISABLE_GETADDRINFO) +# if defined(ASIO_WINDOWS) || defined(__CYGWIN__) +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) +# define ASIO_HAS_GETADDRINFO 1 +# elif defined(UNDER_CE) +# define ASIO_HAS_GETADDRINFO 1 +# endif // defined(UNDER_CE) +# elif defined(__MACH__) && defined(__APPLE__) +# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) +# if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050) +# define ASIO_HAS_GETADDRINFO 1 +# endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050) +# else // defined(__MAC_OS_X_VERSION_MIN_REQUIRED) +# define ASIO_HAS_GETADDRINFO 1 +# endif // defined(__MAC_OS_X_VERSION_MIN_REQUIRED) +# else // defined(__MACH__) && defined(__APPLE__) +# define ASIO_HAS_GETADDRINFO 1 +# endif // defined(__MACH__) && defined(__APPLE__) +# endif // !defined(ASIO_DISABLE_GETADDRINFO) +#endif // !defined(ASIO_HAS_GETADDRINFO) + +// Whether standard iostreams are disabled. +#if !defined(ASIO_NO_IOSTREAM) +# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_IOSTREAM) +# define ASIO_NO_IOSTREAM 1 +# endif // !defined(BOOST_NO_IOSTREAM) +#endif // !defined(ASIO_NO_IOSTREAM) + +// Whether exception handling is disabled. +#if !defined(ASIO_NO_EXCEPTIONS) +# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_EXCEPTIONS) +# define ASIO_NO_EXCEPTIONS 1 +# endif // !defined(BOOST_NO_EXCEPTIONS) +#endif // !defined(ASIO_NO_EXCEPTIONS) + +// Whether the typeid operator is supported. +#if !defined(ASIO_NO_TYPEID) +# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_TYPEID) +# define ASIO_NO_TYPEID 1 +# endif // !defined(BOOST_NO_TYPEID) +#endif // !defined(ASIO_NO_TYPEID) + +// Threads. +#if !defined(ASIO_HAS_THREADS) +# if !defined(ASIO_DISABLE_THREADS) +# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS) +# define ASIO_HAS_THREADS 1 +# elif defined(__GNUC__) && !defined(__MINGW32__) \ + && !defined(linux) && !defined(__linux) && !defined(__linux__) +# define ASIO_HAS_THREADS 1 +# elif defined(_MT) || defined(__MT__) +# define ASIO_HAS_THREADS 1 +# elif defined(_REENTRANT) +# define ASIO_HAS_THREADS 1 +# elif defined(__APPLE__) +# define ASIO_HAS_THREADS 1 +# elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0) +# define ASIO_HAS_THREADS 1 +# elif defined(_PTHREADS) +# define ASIO_HAS_THREADS 1 +# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS) +# endif // !defined(ASIO_DISABLE_THREADS) +#endif // !defined(ASIO_HAS_THREADS) + +// POSIX threads. +#if !defined(ASIO_HAS_PTHREADS) +# if defined(ASIO_HAS_THREADS) +# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS) +# define ASIO_HAS_PTHREADS 1 +# elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0) +# define ASIO_HAS_PTHREADS 1 +# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS) +# endif // defined(ASIO_HAS_THREADS) +#endif // !defined(ASIO_HAS_PTHREADS) + +// Helper to prevent macro expansion. +#define ASIO_PREVENT_MACRO_SUBSTITUTION + +// Helper to define in-class constants. +#if !defined(ASIO_STATIC_CONSTANT) +# if !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT) +# define ASIO_STATIC_CONSTANT(type, assignment) \ + BOOST_STATIC_CONSTANT(type, assignment) +# else // !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT) +# define ASIO_STATIC_CONSTANT(type, assignment) \ + static const type assignment +# endif // !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT) +#endif // !defined(ASIO_STATIC_CONSTANT) + +// Boost array library. +#if !defined(ASIO_HAS_BOOST_ARRAY) +# if !defined(ASIO_DISABLE_BOOST_ARRAY) +# define ASIO_HAS_BOOST_ARRAY 1 +# endif // !defined(ASIO_DISABLE_BOOST_ARRAY) +#endif // !defined(ASIO_HAS_BOOST_ARRAY) + +// Boost assert macro. +#if !defined(ASIO_HAS_BOOST_ASSERT) +# if !defined(ASIO_DISABLE_BOOST_ASSERT) +# define ASIO_HAS_BOOST_ASSERT 1 +# endif // !defined(ASIO_DISABLE_BOOST_ASSERT) +#endif // !defined(ASIO_HAS_BOOST_ASSERT) + +// Boost limits header. +#if !defined(ASIO_HAS_BOOST_LIMITS) +# if !defined(ASIO_DISABLE_BOOST_LIMITS) +# define ASIO_HAS_BOOST_LIMITS 1 +# endif // !defined(ASIO_DISABLE_BOOST_LIMITS) +#endif // !defined(ASIO_HAS_BOOST_LIMITS) + +// Boost throw_exception function. +#if !defined(ASIO_HAS_BOOST_THROW_EXCEPTION) +# if !defined(ASIO_DISABLE_BOOST_THROW_EXCEPTION) +# define ASIO_HAS_BOOST_THROW_EXCEPTION 1 +# endif // !defined(ASIO_DISABLE_BOOST_THROW_EXCEPTION) +#endif // !defined(ASIO_HAS_BOOST_THROW_EXCEPTION) + +// Boost regex library. +#if !defined(ASIO_HAS_BOOST_REGEX) +# if !defined(ASIO_DISABLE_BOOST_REGEX) +# define ASIO_HAS_BOOST_REGEX 1 +# endif // !defined(ASIO_DISABLE_BOOST_REGEX) +#endif // !defined(ASIO_HAS_BOOST_REGEX) + +// Boost bind function. +#if !defined(ASIO_HAS_BOOST_BIND) +# if !defined(ASIO_DISABLE_BOOST_BIND) +# define ASIO_HAS_BOOST_BIND 1 +# endif // !defined(ASIO_DISABLE_BOOST_BIND) +#endif // !defined(ASIO_HAS_BOOST_BIND) + +// Boost's BOOST_WORKAROUND macro. +#if !defined(ASIO_HAS_BOOST_WORKAROUND) +# if !defined(ASIO_DISABLE_BOOST_WORKAROUND) +# define ASIO_HAS_BOOST_WORKAROUND 1 +# endif // !defined(ASIO_DISABLE_BOOST_WORKAROUND) +#endif // !defined(ASIO_HAS_BOOST_WORKAROUND) + +// Microsoft Visual C++'s secure C runtime library. +#if !defined(ASIO_HAS_SECURE_RTL) +# if !defined(ASIO_DISABLE_SECURE_RTL) +# if defined(ASIO_MSVC) \ + && (ASIO_MSVC >= 1400) \ + && !defined(UNDER_CE) +# define ASIO_HAS_SECURE_RTL 1 +# endif // defined(ASIO_MSVC) + // && (ASIO_MSVC >= 1400) + // && !defined(UNDER_CE) +# endif // !defined(ASIO_DISABLE_SECURE_RTL) +#endif // !defined(ASIO_HAS_SECURE_RTL) + +// Handler hooking. Disabled for ancient Borland C++ and gcc compilers. +#if !defined(ASIO_HAS_HANDLER_HOOKS) +# if !defined(ASIO_DISABLE_HANDLER_HOOKS) +# if defined(__GNUC__) +# if (__GNUC__ >= 3) +# define ASIO_HAS_HANDLER_HOOKS 1 +# endif // (__GNUC__ >= 3) +# elif !defined(__BORLANDC__) +# define ASIO_HAS_HANDLER_HOOKS 1 +# endif // !defined(__BORLANDC__) +# endif // !defined(ASIO_DISABLE_HANDLER_HOOKS) +#endif // !defined(ASIO_HAS_HANDLER_HOOKS) + +// Support for the __thread keyword extension. +#if !defined(ASIO_DISABLE_THREAD_KEYWORD_EXTENSION) +# if defined(__linux__) +# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +# if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3) +# if !defined(__INTEL_COMPILER) && !defined(__ICL) \ + && !(defined(__clang__) && defined(__ANDROID__)) +# define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1 +# define ASIO_THREAD_KEYWORD __thread +# elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100) +# define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1 +# endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100) + // && !(defined(__clang__) && defined(__ANDROID__)) +# endif // ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3) +# endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +# endif // defined(__linux__) +# if defined(ASIO_MSVC) && defined(ASIO_WINDOWS_RUNTIME) +# if (_MSC_VER >= 1700) +# define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1 +# define ASIO_THREAD_KEYWORD __declspec(thread) +# endif // (_MSC_VER >= 1700) +# endif // defined(ASIO_MSVC) && defined(ASIO_WINDOWS_RUNTIME) +#endif // !defined(ASIO_DISABLE_THREAD_KEYWORD_EXTENSION) +#if !defined(ASIO_THREAD_KEYWORD) +# define ASIO_THREAD_KEYWORD __thread +#endif // !defined(ASIO_THREAD_KEYWORD) + +// Support for POSIX ssize_t typedef. +#if !defined(ASIO_DISABLE_SSIZE_T) +# if defined(__linux__) \ + || (defined(__MACH__) && defined(__APPLE__)) +# define ASIO_HAS_SSIZE_T 1 +# endif // defined(__linux__) + // || (defined(__MACH__) && defined(__APPLE__)) +#endif // !defined(ASIO_DISABLE_SSIZE_T) + +// Helper macros to manage the transition away from the old services-based API. +#if defined(ASIO_ENABLE_OLD_SERVICES) +# define ASIO_SVC_TPARAM , typename Service +# define ASIO_SVC_TPARAM_DEF1(d1) , typename Service d1 +# define ASIO_SVC_TPARAM_DEF2(d1, d2) , typename Service d1, d2 +# define ASIO_SVC_TARG , Service +# define ASIO_SVC_T Service +# define ASIO_SVC_TPARAM1 , typename Service1 +# define ASIO_SVC_TPARAM1_DEF1(d1) , typename Service1 d1 +# define ASIO_SVC_TPARAM1_DEF2(d1, d2) , typename Service1 d1, d2 +# define ASIO_SVC_TARG1 , Service1 +# define ASIO_SVC_T1 Service1 +# define ASIO_SVC_ACCESS public +#else // defined(ASIO_ENABLE_OLD_SERVICES) +# define ASIO_SVC_TPARAM +# define ASIO_SVC_TPARAM_DEF1(d1) +# define ASIO_SVC_TPARAM_DEF2(d1, d2) +# define ASIO_SVC_TARG +// ASIO_SVC_T is defined at each point of use. +# define ASIO_SVC_TPARAM1 +# define ASIO_SVC_TPARAM1_DEF1(d1) +# define ASIO_SVC_TPARAM1_DEF2(d1, d2) +# define ASIO_SVC_TARG1 +// ASIO_SVC_T1 is defined at each point of use. +# define ASIO_SVC_ACCESS protected +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +// Helper macros to manage transition away from error_code return values. +#if defined(ASIO_NO_DEPRECATED) +# define ASIO_SYNC_OP_VOID void +# define ASIO_SYNC_OP_VOID_RETURN(e) return +#else // defined(ASIO_NO_DEPRECATED) +# define ASIO_SYNC_OP_VOID asio::error_code +# define ASIO_SYNC_OP_VOID_RETURN(e) return e +#endif // defined(ASIO_NO_DEPRECATED) + +// Newer gcc, clang need special treatment to suppress unused typedef warnings. +#if defined(__clang__) +# if defined(__apple_build_version__) +# if (__clang_major__ >= 7) +# define ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) +# endif // (__clang_major__ >= 7) +# elif ((__clang_major__ == 3) && (__clang_minor__ >= 6)) \ + || (__clang_major__ > 3) +# define ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) +# endif // ((__clang_major__ == 3) && (__clang_minor__ >= 6)) + // || (__clang_major__ > 3) +#elif defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) +# define ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) +#endif // defined(__GNUC__) +#if !defined(ASIO_UNUSED_TYPEDEF) +# define ASIO_UNUSED_TYPEDEF +#endif // !defined(ASIO_UNUSED_TYPEDEF) + +// Some versions of gcc generate spurious warnings about unused variables. +#if defined(__GNUC__) +# if (__GNUC__ >= 4) +# define ASIO_UNUSED_VARIABLE __attribute__((__unused__)) +# endif // (__GNUC__ >= 4) +#endif // defined(__GNUC__) +#if !defined(ASIO_UNUSED_VARIABLE) +# define ASIO_UNUSED_VARIABLE +#endif // !defined(ASIO_UNUSED_VARIABLE) + +// Support co_await on compilers known to allow it. +#if !defined(ASIO_HAS_CO_AWAIT) +# if !defined(ASIO_DISABLE_CO_AWAIT) +# if defined(ASIO_MSVC) +# if (_MSC_FULL_VER >= 190023506) +# if defined(_RESUMABLE_FUNCTIONS_SUPPORTED) +# define ASIO_HAS_CO_AWAIT 1 +# endif // defined(_RESUMABLE_FUNCTIONS_SUPPORTED) +# endif // (_MSC_FULL_VER >= 190023506) +# endif // defined(ASIO_MSVC) +# endif // !defined(ASIO_DISABLE_CO_AWAIT) +# if defined(__clang__) +# if (__cpp_coroutines >= 201703) +# if __has_include() +# define ASIO_HAS_CO_AWAIT 1 +# endif // __has_include() +# endif // (__cpp_coroutines >= 201703) +# endif // defined(__clang__) +#endif // !defined(ASIO_HAS_CO_AWAIT) + +#endif // ASIO_DETAIL_CONFIG_HPP diff --git a/tools/sdk/include/asio/asio/detail/consuming_buffers.hpp b/tools/sdk/include/asio/asio/detail/consuming_buffers.hpp new file mode 100644 index 00000000..8127ae75 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/consuming_buffers.hpp @@ -0,0 +1,414 @@ +// +// detail/consuming_buffers.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_CONSUMING_BUFFERS_HPP +#define ASIO_DETAIL_CONSUMING_BUFFERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/buffer.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/limits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Helper template to determine the maximum number of prepared buffers. +template +struct prepared_buffers_max +{ + enum { value = buffer_sequence_adapter_base::max_buffers }; +}; + +template +struct prepared_buffers_max > +{ + enum { value = N }; +}; + +#if defined(ASIO_HAS_STD_ARRAY) + +template +struct prepared_buffers_max > +{ + enum { value = N }; +}; + +#endif // defined(ASIO_HAS_STD_ARRAY) + +// A buffer sequence used to represent a subsequence of the buffers. +template +struct prepared_buffers +{ + typedef Buffer value_type; + typedef const Buffer* const_iterator; + + enum { max_buffers = MaxBuffers < 16 ? MaxBuffers : 16 }; + + prepared_buffers() : count(0) {} + const_iterator begin() const { return elems; } + const_iterator end() const { return elems + count; } + + Buffer elems[max_buffers]; + std::size_t count; +}; + +// A proxy for a sub-range in a list of buffers. +template +class consuming_buffers +{ +public: + typedef prepared_buffers::value> + prepared_buffers_type; + + // Construct to represent the entire list of buffers. + explicit consuming_buffers(const Buffers& buffers) + : buffers_(buffers), + total_consumed_(0), + next_elem_(0), + next_elem_offset_(0) + { + using asio::buffer_size; + total_size_ = buffer_size(buffers); + } + + // Determine if we are at the end of the buffers. + bool empty() const + { + return total_consumed_ >= total_size_; + } + + // Get the buffer for a single transfer, with a size. + prepared_buffers_type prepare(std::size_t max_size) + { + prepared_buffers_type result; + + Buffer_Iterator next = asio::buffer_sequence_begin(buffers_); + Buffer_Iterator end = asio::buffer_sequence_end(buffers_); + + std::advance(next, next_elem_); + std::size_t elem_offset = next_elem_offset_; + while (next != end && max_size > 0 && (result.count) < result.max_buffers) + { + Buffer next_buf = Buffer(*next) + elem_offset; + result.elems[result.count] = asio::buffer(next_buf, max_size); + max_size -= result.elems[result.count].size(); + elem_offset = 0; + if (result.elems[result.count].size() > 0) + ++result.count; + ++next; + } + + return result; + } + + // Consume the specified number of bytes from the buffers. + void consume(std::size_t size) + { + total_consumed_ += size; + + Buffer_Iterator next = asio::buffer_sequence_begin(buffers_); + Buffer_Iterator end = asio::buffer_sequence_end(buffers_); + + std::advance(next, next_elem_); + while (next != end && size > 0) + { + Buffer next_buf = Buffer(*next) + next_elem_offset_; + if (size < next_buf.size()) + { + next_elem_offset_ += size; + size = 0; + } + else + { + size -= next_buf.size(); + next_elem_offset_ = 0; + ++next_elem_; + ++next; + } + } + } + + // Get the total number of bytes consumed from the buffers. + std::size_t total_consumed() const + { + return total_consumed_; + } + +private: + Buffers buffers_; + std::size_t total_size_; + std::size_t total_consumed_; + std::size_t next_elem_; + std::size_t next_elem_offset_; +}; + +// Base class of all consuming_buffers specialisations for single buffers. +template +class consuming_single_buffer +{ +public: + // Construct to represent the entire list of buffers. + template + explicit consuming_single_buffer(const Buffer1& buffer) + : buffer_(buffer), + total_consumed_(0) + { + } + + // Determine if we are at the end of the buffers. + bool empty() const + { + return total_consumed_ >= buffer_.size(); + } + + // Get the buffer for a single transfer, with a size. + Buffer prepare(std::size_t max_size) + { + return asio::buffer(buffer_ + total_consumed_, max_size); + } + + // Consume the specified number of bytes from the buffers. + void consume(std::size_t size) + { + total_consumed_ += size; + } + + // Get the total number of bytes consumed from the buffers. + std::size_t total_consumed() const + { + return total_consumed_; + } + +private: + Buffer buffer_; + std::size_t total_consumed_; +}; + +template <> +class consuming_buffers + : public consuming_single_buffer +{ +public: + explicit consuming_buffers(const mutable_buffer& buffer) + : consuming_single_buffer(buffer) + { + } +}; + +template <> +class consuming_buffers + : public consuming_single_buffer +{ +public: + explicit consuming_buffers(const mutable_buffer& buffer) + : consuming_single_buffer(buffer) + { + } +}; + +template <> +class consuming_buffers + : public consuming_single_buffer +{ +public: + explicit consuming_buffers(const const_buffer& buffer) + : consuming_single_buffer(buffer) + { + } +}; + +#if !defined(ASIO_NO_DEPRECATED) + +template <> +class consuming_buffers + : public consuming_single_buffer +{ +public: + explicit consuming_buffers(const mutable_buffers_1& buffer) + : consuming_single_buffer(buffer) + { + } +}; + +template <> +class consuming_buffers + : public consuming_single_buffer +{ +public: + explicit consuming_buffers(const mutable_buffers_1& buffer) + : consuming_single_buffer(buffer) + { + } +}; + +template <> +class consuming_buffers + : public consuming_single_buffer +{ +public: + explicit consuming_buffers(const const_buffers_1& buffer) + : consuming_single_buffer(buffer) + { + } +}; + +#endif // !defined(ASIO_NO_DEPRECATED) + +template +class consuming_buffers, + typename boost::array::const_iterator> +{ +public: + // Construct to represent the entire list of buffers. + explicit consuming_buffers(const boost::array& buffers) + : buffers_(buffers), + total_consumed_(0) + { + } + + // Determine if we are at the end of the buffers. + bool empty() const + { + return total_consumed_ >= + Buffer(buffers_[0]).size() + Buffer(buffers_[1]).size(); + } + + // Get the buffer for a single transfer, with a size. + boost::array prepare(std::size_t max_size) + { + boost::array result = {{ + Buffer(buffers_[0]), Buffer(buffers_[1]) }}; + std::size_t buffer0_size = result[0].size(); + result[0] = asio::buffer(result[0] + total_consumed_, max_size); + result[1] = asio::buffer( + result[1] + (total_consumed_ < buffer0_size + ? 0 : total_consumed_ - buffer0_size), + max_size - result[0].size()); + return result; + } + + // Consume the specified number of bytes from the buffers. + void consume(std::size_t size) + { + total_consumed_ += size; + } + + // Get the total number of bytes consumed from the buffers. + std::size_t total_consumed() const + { + return total_consumed_; + } + +private: + boost::array buffers_; + std::size_t total_consumed_; +}; + +#if defined(ASIO_HAS_STD_ARRAY) + +template +class consuming_buffers, + typename std::array::const_iterator> +{ +public: + // Construct to represent the entire list of buffers. + explicit consuming_buffers(const std::array& buffers) + : buffers_(buffers), + total_consumed_(0) + { + } + + // Determine if we are at the end of the buffers. + bool empty() const + { + return total_consumed_ >= + Buffer(buffers_[0]).size() + Buffer(buffers_[1]).size(); + } + + // Get the buffer for a single transfer, with a size. + std::array prepare(std::size_t max_size) + { + std::array result = {{ + Buffer(buffers_[0]), Buffer(buffers_[1]) }}; + std::size_t buffer0_size = result[0].size(); + result[0] = asio::buffer(result[0] + total_consumed_, max_size); + result[1] = asio::buffer( + result[1] + (total_consumed_ < buffer0_size + ? 0 : total_consumed_ - buffer0_size), + max_size - result[0].size()); + return result; + } + + // Consume the specified number of bytes from the buffers. + void consume(std::size_t size) + { + total_consumed_ += size; + } + + // Get the total number of bytes consumed from the buffers. + std::size_t total_consumed() const + { + return total_consumed_; + } + +private: + std::array buffers_; + std::size_t total_consumed_; +}; + +#endif // defined(ASIO_HAS_STD_ARRAY) + +// Specialisation for null_buffers to ensure that the null_buffers type is +// always passed through to the underlying read or write operation. +template +class consuming_buffers + : public asio::null_buffers +{ +public: + consuming_buffers(const null_buffers&) + { + // No-op. + } + + bool empty() + { + return false; + } + + null_buffers prepare(std::size_t) + { + return null_buffers(); + } + + void consume(std::size_t) + { + // No-op. + } + + std::size_t total_consumed() const + { + return 0; + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_CONSUMING_BUFFERS_HPP diff --git a/tools/sdk/include/asio/asio/detail/cstddef.hpp b/tools/sdk/include/asio/asio/detail/cstddef.hpp new file mode 100644 index 00000000..3912da40 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/cstddef.hpp @@ -0,0 +1,31 @@ +// +// detail/cstddef.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_CSTDDEF_HPP +#define ASIO_DETAIL_CSTDDEF_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include + +namespace asio { + +#if defined(ASIO_HAS_NULLPTR) +using std::nullptr_t; +#else // defined(ASIO_HAS_NULLPTR) +struct nullptr_t {}; +#endif // defined(ASIO_HAS_NULLPTR) + +} // namespace asio + +#endif // ASIO_DETAIL_CSTDDEF_HPP diff --git a/tools/sdk/include/asio/asio/detail/cstdint.hpp b/tools/sdk/include/asio/asio/detail/cstdint.hpp new file mode 100644 index 00000000..62342b2d --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/cstdint.hpp @@ -0,0 +1,60 @@ +// +// detail/cstdint.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_CSTDINT_HPP +#define ASIO_DETAIL_CSTDINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_CSTDINT) +# include +#else // defined(ASIO_HAS_CSTDINT) +# include +#endif // defined(ASIO_HAS_CSTDINT) + +namespace asio { + +#if defined(ASIO_HAS_CSTDINT) +using std::int16_t; +using std::int_least16_t; +using std::uint16_t; +using std::uint_least16_t; +using std::int32_t; +using std::int_least32_t; +using std::uint32_t; +using std::uint_least32_t; +using std::int64_t; +using std::int_least64_t; +using std::uint64_t; +using std::uint_least64_t; +using std::uintmax_t; +#else // defined(ASIO_HAS_CSTDINT) +using boost::int16_t; +using boost::int_least16_t; +using boost::uint16_t; +using boost::uint_least16_t; +using boost::int32_t; +using boost::int_least32_t; +using boost::uint32_t; +using boost::uint_least32_t; +using boost::int64_t; +using boost::int_least64_t; +using boost::uint64_t; +using boost::uint_least64_t; +using boost::uintmax_t; +#endif // defined(ASIO_HAS_CSTDINT) + +} // namespace asio + +#endif // ASIO_DETAIL_CSTDINT_HPP diff --git a/tools/sdk/include/asio/asio/detail/date_time_fwd.hpp b/tools/sdk/include/asio/asio/detail/date_time_fwd.hpp new file mode 100644 index 00000000..a159562e --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/date_time_fwd.hpp @@ -0,0 +1,34 @@ +// +// detail/date_time_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_DATE_TIME_FWD_HPP +#define ASIO_DETAIL_DATE_TIME_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +namespace boost { +namespace date_time { + +template +class base_time; + +} // namespace date_time +namespace posix_time { + +class ptime; + +} // namespace posix_time +} // namespace boost + +#endif // ASIO_DETAIL_DATE_TIME_FWD_HPP diff --git a/tools/sdk/include/asio/asio/detail/deadline_timer_service.hpp b/tools/sdk/include/asio/asio/detail/deadline_timer_service.hpp new file mode 100644 index 00000000..f58a6e0e --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/deadline_timer_service.hpp @@ -0,0 +1,278 @@ +// +// detail/deadline_timer_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP +#define ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/timer_queue.hpp" +#include "asio/detail/timer_queue_ptime.hpp" +#include "asio/detail/timer_scheduler.hpp" +#include "asio/detail/wait_handler.hpp" +#include "asio/detail/wait_op.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) +# include +# include +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class deadline_timer_service + : public service_base > +{ +public: + // The time type. + typedef typename Time_Traits::time_type time_type; + + // The duration type. + typedef typename Time_Traits::duration_type duration_type; + + // The implementation type of the timer. This type is dependent on the + // underlying implementation of the timer service. + struct implementation_type + : private asio::detail::noncopyable + { + time_type expiry; + bool might_have_pending_waits; + typename timer_queue::per_timer_data timer_data; + }; + + // Constructor. + deadline_timer_service(asio::io_context& io_context) + : service_base >(io_context), + scheduler_(asio::use_service(io_context)) + { + scheduler_.init_task(); + scheduler_.add_timer_queue(timer_queue_); + } + + // Destructor. + ~deadline_timer_service() + { + scheduler_.remove_timer_queue(timer_queue_); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown() + { + } + + // Construct a new timer implementation. + void construct(implementation_type& impl) + { + impl.expiry = time_type(); + impl.might_have_pending_waits = false; + } + + // Destroy a timer implementation. + void destroy(implementation_type& impl) + { + asio::error_code ec; + cancel(impl, ec); + } + + // Move-construct a new serial port implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + scheduler_.move_timer(timer_queue_, impl.timer_data, other_impl.timer_data); + + impl.expiry = other_impl.expiry; + other_impl.expiry = time_type(); + + impl.might_have_pending_waits = other_impl.might_have_pending_waits; + other_impl.might_have_pending_waits = false; + } + + // Move-assign from another serial port implementation. + void move_assign(implementation_type& impl, + deadline_timer_service& other_service, + implementation_type& other_impl) + { + if (this != &other_service) + if (impl.might_have_pending_waits) + scheduler_.cancel_timer(timer_queue_, impl.timer_data); + + other_service.scheduler_.move_timer(other_service.timer_queue_, + impl.timer_data, other_impl.timer_data); + + impl.expiry = other_impl.expiry; + other_impl.expiry = time_type(); + + impl.might_have_pending_waits = other_impl.might_have_pending_waits; + other_impl.might_have_pending_waits = false; + } + + // Cancel any asynchronous wait operations associated with the timer. + std::size_t cancel(implementation_type& impl, asio::error_code& ec) + { + if (!impl.might_have_pending_waits) + { + ec = asio::error_code(); + return 0; + } + + ASIO_HANDLER_OPERATION((scheduler_.context(), + "deadline_timer", &impl, 0, "cancel")); + + std::size_t count = scheduler_.cancel_timer(timer_queue_, impl.timer_data); + impl.might_have_pending_waits = false; + ec = asio::error_code(); + return count; + } + + // Cancels one asynchronous wait operation associated with the timer. + std::size_t cancel_one(implementation_type& impl, + asio::error_code& ec) + { + if (!impl.might_have_pending_waits) + { + ec = asio::error_code(); + return 0; + } + + ASIO_HANDLER_OPERATION((scheduler_.context(), + "deadline_timer", &impl, 0, "cancel_one")); + + std::size_t count = scheduler_.cancel_timer( + timer_queue_, impl.timer_data, 1); + if (count == 0) + impl.might_have_pending_waits = false; + ec = asio::error_code(); + return count; + } + + // Get the expiry time for the timer as an absolute time. + time_type expiry(const implementation_type& impl) const + { + return impl.expiry; + } + + // Get the expiry time for the timer as an absolute time. + time_type expires_at(const implementation_type& impl) const + { + return impl.expiry; + } + + // Get the expiry time for the timer relative to now. + duration_type expires_from_now(const implementation_type& impl) const + { + return Time_Traits::subtract(this->expiry(impl), Time_Traits::now()); + } + + // Set the expiry time for the timer as an absolute time. + std::size_t expires_at(implementation_type& impl, + const time_type& expiry_time, asio::error_code& ec) + { + std::size_t count = cancel(impl, ec); + impl.expiry = expiry_time; + ec = asio::error_code(); + return count; + } + + // Set the expiry time for the timer relative to now. + std::size_t expires_after(implementation_type& impl, + const duration_type& expiry_time, asio::error_code& ec) + { + return expires_at(impl, + Time_Traits::add(Time_Traits::now(), expiry_time), ec); + } + + // Set the expiry time for the timer relative to now. + std::size_t expires_from_now(implementation_type& impl, + const duration_type& expiry_time, asio::error_code& ec) + { + return expires_at(impl, + Time_Traits::add(Time_Traits::now(), expiry_time), ec); + } + + // Perform a blocking wait on the timer. + void wait(implementation_type& impl, asio::error_code& ec) + { + time_type now = Time_Traits::now(); + ec = asio::error_code(); + while (Time_Traits::less_than(now, impl.expiry) && !ec) + { + this->do_wait(Time_Traits::to_posix_duration( + Time_Traits::subtract(impl.expiry, now)), ec); + now = Time_Traits::now(); + } + } + + // Start an asynchronous wait on the timer. + template + void async_wait(implementation_type& impl, Handler& handler) + { + // Allocate and construct an operation to wrap the handler. + typedef wait_handler op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + impl.might_have_pending_waits = true; + + ASIO_HANDLER_CREATION((scheduler_.context(), + *p.p, "deadline_timer", &impl, 0, "async_wait")); + + scheduler_.schedule_timer(timer_queue_, impl.expiry, impl.timer_data, p.p); + p.v = p.p = 0; + } + +private: + // Helper function to wait given a duration type. The duration type should + // either be of type boost::posix_time::time_duration, or implement the + // required subset of its interface. + template + void do_wait(const Duration& timeout, asio::error_code& ec) + { +#if defined(ASIO_WINDOWS_RUNTIME) + std::this_thread::sleep_for( + std::chrono::seconds(timeout.total_seconds()) + + std::chrono::microseconds(timeout.total_microseconds())); + ec = asio::error_code(); +#else // defined(ASIO_WINDOWS_RUNTIME) + ::timeval tv; + tv.tv_sec = timeout.total_seconds(); + tv.tv_usec = timeout.total_microseconds() % 1000000; + socket_ops::select(0, 0, 0, 0, &tv, ec); +#endif // defined(ASIO_WINDOWS_RUNTIME) + } + + // The queue of timers. + timer_queue timer_queue_; + + // The object that schedules and executes timers. Usually a reactor. + timer_scheduler& scheduler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/dependent_type.hpp b/tools/sdk/include/asio/asio/detail/dependent_type.hpp new file mode 100644 index 00000000..85b41c89 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/dependent_type.hpp @@ -0,0 +1,36 @@ +// +// detail/dependent_type.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_DEPENDENT_TYPE_HPP +#define ASIO_DETAIL_DEPENDENT_TYPE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +struct dependent_type +{ + typedef T type; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_DEPENDENT_TYPE_HPP diff --git a/tools/sdk/include/asio/asio/detail/descriptor_ops.hpp b/tools/sdk/include/asio/asio/detail/descriptor_ops.hpp new file mode 100644 index 00000000..9c0560aa --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/descriptor_ops.hpp @@ -0,0 +1,121 @@ +// +// detail/descriptor_ops.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_DESCRIPTOR_OPS_HPP +#define ASIO_DETAIL_DESCRIPTOR_OPS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_WINDOWS) \ + && !defined(ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) + +#include +#include "asio/error.hpp" +#include "asio/error_code.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { +namespace descriptor_ops { + +// Descriptor state bits. +enum +{ + // The user wants a non-blocking descriptor. + user_set_non_blocking = 1, + + // The descriptor has been set non-blocking. + internal_non_blocking = 2, + + // Helper "state" used to determine whether the descriptor is non-blocking. + non_blocking = user_set_non_blocking | internal_non_blocking, + + // The descriptor may have been dup()-ed. + possible_dup = 4 +}; + +typedef unsigned char state_type; + +template +inline ReturnType error_wrapper(ReturnType return_value, + asio::error_code& ec) +{ + ec = asio::error_code(errno, + asio::error::get_system_category()); + return return_value; +} + +ASIO_DECL int open(const char* path, int flags, + asio::error_code& ec); + +ASIO_DECL int close(int d, state_type& state, + asio::error_code& ec); + +ASIO_DECL bool set_user_non_blocking(int d, + state_type& state, bool value, asio::error_code& ec); + +ASIO_DECL bool set_internal_non_blocking(int d, + state_type& state, bool value, asio::error_code& ec); + +typedef iovec buf; + +ASIO_DECL std::size_t sync_read(int d, state_type state, buf* bufs, + std::size_t count, bool all_empty, asio::error_code& ec); + +ASIO_DECL bool non_blocking_read(int d, buf* bufs, std::size_t count, + asio::error_code& ec, std::size_t& bytes_transferred); + +ASIO_DECL std::size_t sync_write(int d, state_type state, + const buf* bufs, std::size_t count, bool all_empty, + asio::error_code& ec); + +ASIO_DECL bool non_blocking_write(int d, + const buf* bufs, std::size_t count, + asio::error_code& ec, std::size_t& bytes_transferred); + +ASIO_DECL int ioctl(int d, state_type& state, long cmd, + ioctl_arg_type* arg, asio::error_code& ec); + +ASIO_DECL int fcntl(int d, int cmd, asio::error_code& ec); + +ASIO_DECL int fcntl(int d, int cmd, + long arg, asio::error_code& ec); + +ASIO_DECL int poll_read(int d, + state_type state, asio::error_code& ec); + +ASIO_DECL int poll_write(int d, + state_type state, asio::error_code& ec); + +ASIO_DECL int poll_error(int d, + state_type state, asio::error_code& ec); + +} // namespace descriptor_ops +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/descriptor_ops.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // !defined(ASIO_WINDOWS) + // && !defined(ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) + +#endif // ASIO_DETAIL_DESCRIPTOR_OPS_HPP diff --git a/tools/sdk/include/asio/asio/detail/descriptor_read_op.hpp b/tools/sdk/include/asio/asio/detail/descriptor_read_op.hpp new file mode 100644 index 00000000..6db4bfb9 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/descriptor_read_op.hpp @@ -0,0 +1,128 @@ +// +// detail/descriptor_read_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP +#define ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/descriptor_ops.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_work.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactor_op.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class descriptor_read_op_base : public reactor_op +{ +public: + descriptor_read_op_base(int descriptor, + const MutableBufferSequence& buffers, func_type complete_func) + : reactor_op(&descriptor_read_op_base::do_perform, complete_func), + descriptor_(descriptor), + buffers_(buffers) + { + } + + static status do_perform(reactor_op* base) + { + descriptor_read_op_base* o(static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + status result = descriptor_ops::non_blocking_read(o->descriptor_, + bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_) + ? done : not_done; + + ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_read", + o->ec_, o->bytes_transferred_)); + + return result; + } + +private: + int descriptor_; + MutableBufferSequence buffers_; +}; + +template +class descriptor_read_op + : public descriptor_read_op_base +{ +public: + ASIO_DEFINE_HANDLER_PTR(descriptor_read_op); + + descriptor_read_op(int descriptor, + const MutableBufferSequence& buffers, Handler& handler) + : descriptor_read_op_base( + descriptor, buffers, &descriptor_read_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + descriptor_read_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + 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::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) + +#endif // ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/descriptor_write_op.hpp b/tools/sdk/include/asio/asio/detail/descriptor_write_op.hpp new file mode 100644 index 00000000..a9ec2a97 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/descriptor_write_op.hpp @@ -0,0 +1,128 @@ +// +// detail/descriptor_write_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_DESCRIPTOR_WRITE_OP_HPP +#define ASIO_DETAIL_DESCRIPTOR_WRITE_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/descriptor_ops.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_work.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactor_op.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class descriptor_write_op_base : public reactor_op +{ +public: + descriptor_write_op_base(int descriptor, + const ConstBufferSequence& buffers, func_type complete_func) + : reactor_op(&descriptor_write_op_base::do_perform, complete_func), + descriptor_(descriptor), + buffers_(buffers) + { + } + + static status do_perform(reactor_op* base) + { + descriptor_write_op_base* o(static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + status result = descriptor_ops::non_blocking_write(o->descriptor_, + bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_) + ? done : not_done; + + ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_write", + o->ec_, o->bytes_transferred_)); + + return result; + } + +private: + int descriptor_; + ConstBufferSequence buffers_; +}; + +template +class descriptor_write_op + : public descriptor_write_op_base +{ +public: + ASIO_DEFINE_HANDLER_PTR(descriptor_write_op); + + descriptor_write_op(int descriptor, + const ConstBufferSequence& buffers, Handler& handler) + : descriptor_write_op_base( + descriptor, buffers, &descriptor_write_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + descriptor_write_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + 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::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) + +#endif // ASIO_DETAIL_DESCRIPTOR_WRITE_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/dev_poll_reactor.hpp b/tools/sdk/include/asio/asio/detail/dev_poll_reactor.hpp new file mode 100644 index 00000000..e9e4e29e --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/dev_poll_reactor.hpp @@ -0,0 +1,218 @@ +// +// detail/dev_poll_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_DEV_POLL_REACTOR_HPP +#define ASIO_DETAIL_DEV_POLL_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_DEV_POLL) + +#include +#include +#include +#include "asio/detail/hash_map.hpp" +#include "asio/detail/limits.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/reactor_op_queue.hpp" +#include "asio/detail/select_interrupter.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/timer_queue_base.hpp" +#include "asio/detail/timer_queue_set.hpp" +#include "asio/detail/wait_op.hpp" +#include "asio/execution_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class dev_poll_reactor + : public execution_context_service_base +{ +public: + enum op_types { read_op = 0, write_op = 1, + connect_op = 1, except_op = 2, max_ops = 3 }; + + // Per-descriptor data. + struct per_descriptor_data + { + }; + + // Constructor. + ASIO_DECL dev_poll_reactor(asio::execution_context& ctx); + + // Destructor. + ASIO_DECL ~dev_poll_reactor(); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Recreate internal descriptors following a fork. + ASIO_DECL void notify_fork( + asio::execution_context::fork_event fork_ev); + + // Initialise the task. + ASIO_DECL void init_task(); + + // Register a socket with the reactor. Returns 0 on success, system error + // code on failure. + ASIO_DECL int register_descriptor(socket_type, per_descriptor_data&); + + // Register a descriptor with an associated single operation. Returns 0 on + // success, system error code on failure. + ASIO_DECL int register_internal_descriptor( + int op_type, socket_type descriptor, + per_descriptor_data& descriptor_data, reactor_op* op); + + // Move descriptor registration from one descriptor_data object to another. + ASIO_DECL void move_descriptor(socket_type descriptor, + per_descriptor_data& target_descriptor_data, + per_descriptor_data& source_descriptor_data); + + // Post a reactor operation for immediate completion. + void post_immediate_completion(reactor_op* op, bool is_continuation) + { + scheduler_.post_immediate_completion(op, is_continuation); + } + + // Start a new operation. The reactor operation will be performed when the + // given descriptor is flagged as ready, or an error has occurred. + ASIO_DECL void start_op(int op_type, socket_type descriptor, + per_descriptor_data&, reactor_op* op, + bool is_continuation, bool allow_speculative); + + // Cancel all operations associated with the given descriptor. The + // handlers associated with the descriptor will be invoked with the + // operation_aborted error. + ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&); + + // Cancel any operations that are running against the descriptor and remove + // its registration from the reactor. The reactor resources associated with + // the descriptor must be released by calling cleanup_descriptor_data. + ASIO_DECL void deregister_descriptor(socket_type descriptor, + per_descriptor_data&, bool closing); + + // Remove the descriptor's registration from the reactor. The reactor + // resources associated with the descriptor must be released by calling + // cleanup_descriptor_data. + ASIO_DECL void deregister_internal_descriptor( + socket_type descriptor, per_descriptor_data&); + + // Perform any post-deregistration cleanup tasks associated with the + // descriptor data. + ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&); + + // Add a new timer queue to the reactor. + template + void add_timer_queue(timer_queue& queue); + + // Remove a timer queue from the reactor. + template + void remove_timer_queue(timer_queue& queue); + + // Schedule a new operation in the given timer queue to expire at the + // specified absolute time. + template + void schedule_timer(timer_queue& queue, + const typename Time_Traits::time_type& time, + typename timer_queue::per_timer_data& timer, wait_op* op); + + // Cancel the timer operations associated with the given token. Returns the + // number of operations that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& queue, + typename timer_queue::per_timer_data& timer, + std::size_t max_cancelled = (std::numeric_limits::max)()); + + // Move the timer operations associated with the given timer. + template + void move_timer(timer_queue& queue, + typename timer_queue::per_timer_data& target, + typename timer_queue::per_timer_data& source); + + // Run /dev/poll once until interrupted or events are ready to be dispatched. + ASIO_DECL void run(long usec, op_queue& ops); + + // Interrupt the select loop. + ASIO_DECL void interrupt(); + +private: + // Create the /dev/poll file descriptor. Throws an exception if the descriptor + // cannot be created. + ASIO_DECL static int do_dev_poll_create(); + + // Helper function to add a new timer queue. + ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); + + // Helper function to remove a timer queue. + ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); + + // Get the timeout value for the /dev/poll DP_POLL operation. The timeout + // value is returned as a number of milliseconds. A return value of -1 + // indicates that the poll should block indefinitely. + ASIO_DECL int get_timeout(int msec); + + // Cancel all operations associated with the given descriptor. The do_cancel + // function of the handler objects will be invoked. This function does not + // acquire the dev_poll_reactor's mutex. + ASIO_DECL void cancel_ops_unlocked(socket_type descriptor, + const asio::error_code& ec); + + // Add a pending event entry for the given descriptor. + ASIO_DECL ::pollfd& add_pending_event_change(int descriptor); + + // The scheduler implementation used to post completions. + scheduler& scheduler_; + + // Mutex to protect access to internal data. + asio::detail::mutex mutex_; + + // The /dev/poll file descriptor. + int dev_poll_fd_; + + // Vector of /dev/poll events waiting to be written to the descriptor. + std::vector< ::pollfd> pending_event_changes_; + + // Hash map to associate a descriptor with a pending event change index. + hash_map pending_event_change_index_; + + // The interrupter is used to break a blocking DP_POLL operation. + select_interrupter interrupter_; + + // The queues of read, write and except operations. + reactor_op_queue op_queue_[max_ops]; + + // The timer queues. + timer_queue_set timer_queues_; + + // Whether the service has been shut down. + bool shutdown_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/impl/dev_poll_reactor.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/dev_poll_reactor.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_DEV_POLL) + +#endif // ASIO_DETAIL_DEV_POLL_REACTOR_HPP diff --git a/tools/sdk/include/asio/asio/detail/epoll_reactor.hpp b/tools/sdk/include/asio/asio/detail/epoll_reactor.hpp new file mode 100644 index 00000000..5f581099 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/epoll_reactor.hpp @@ -0,0 +1,266 @@ +// +// detail/epoll_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_EPOLL_REACTOR_HPP +#define ASIO_DETAIL_EPOLL_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_EPOLL) + +#include "asio/detail/atomic_count.hpp" +#include "asio/detail/conditionally_enabled_mutex.hpp" +#include "asio/detail/limits.hpp" +#include "asio/detail/object_pool.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/select_interrupter.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/timer_queue_base.hpp" +#include "asio/detail/timer_queue_set.hpp" +#include "asio/detail/wait_op.hpp" +#include "asio/execution_context.hpp" + +#if defined(ASIO_HAS_TIMERFD) +# include +#endif // defined(ASIO_HAS_TIMERFD) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class epoll_reactor + : public execution_context_service_base +{ +private: + // The mutex type used by this reactor. + typedef conditionally_enabled_mutex mutex; + +public: + enum op_types { read_op = 0, write_op = 1, + connect_op = 1, except_op = 2, max_ops = 3 }; + + // Per-descriptor queues. + class descriptor_state : operation + { + friend class epoll_reactor; + friend class object_pool_access; + + descriptor_state* next_; + descriptor_state* prev_; + + mutex mutex_; + epoll_reactor* reactor_; + int descriptor_; + uint32_t registered_events_; + op_queue op_queue_[max_ops]; + bool try_speculative_[max_ops]; + bool shutdown_; + + ASIO_DECL descriptor_state(bool locking); + void set_ready_events(uint32_t events) { task_result_ = events; } + void add_ready_events(uint32_t events) { task_result_ |= events; } + ASIO_DECL operation* perform_io(uint32_t events); + ASIO_DECL static void do_complete( + void* owner, operation* base, + const asio::error_code& ec, std::size_t bytes_transferred); + }; + + // Per-descriptor data. + typedef descriptor_state* per_descriptor_data; + + // Constructor. + ASIO_DECL epoll_reactor(asio::execution_context& ctx); + + // Destructor. + ASIO_DECL ~epoll_reactor(); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Recreate internal descriptors following a fork. + ASIO_DECL void notify_fork( + asio::execution_context::fork_event fork_ev); + + // Initialise the task. + ASIO_DECL void init_task(); + + // Register a socket with the reactor. Returns 0 on success, system error + // code on failure. + ASIO_DECL int register_descriptor(socket_type descriptor, + per_descriptor_data& descriptor_data); + + // Register a descriptor with an associated single operation. Returns 0 on + // success, system error code on failure. + ASIO_DECL int register_internal_descriptor( + int op_type, socket_type descriptor, + per_descriptor_data& descriptor_data, reactor_op* op); + + // Move descriptor registration from one descriptor_data object to another. + ASIO_DECL void move_descriptor(socket_type descriptor, + per_descriptor_data& target_descriptor_data, + per_descriptor_data& source_descriptor_data); + + // Post a reactor operation for immediate completion. + void post_immediate_completion(reactor_op* op, bool is_continuation) + { + scheduler_.post_immediate_completion(op, is_continuation); + } + + // Start a new operation. The reactor operation will be performed when the + // given descriptor is flagged as ready, or an error has occurred. + ASIO_DECL void start_op(int op_type, socket_type descriptor, + per_descriptor_data& descriptor_data, reactor_op* op, + bool is_continuation, bool allow_speculative); + + // Cancel all operations associated with the given descriptor. The + // handlers associated with the descriptor will be invoked with the + // operation_aborted error. + ASIO_DECL void cancel_ops(socket_type descriptor, + per_descriptor_data& descriptor_data); + + // Cancel any operations that are running against the descriptor and remove + // its registration from the reactor. The reactor resources associated with + // the descriptor must be released by calling cleanup_descriptor_data. + ASIO_DECL void deregister_descriptor(socket_type descriptor, + per_descriptor_data& descriptor_data, bool closing); + + // Remove the descriptor's registration from the reactor. The reactor + // resources associated with the descriptor must be released by calling + // cleanup_descriptor_data. + ASIO_DECL void deregister_internal_descriptor( + socket_type descriptor, per_descriptor_data& descriptor_data); + + // Perform any post-deregistration cleanup tasks associated with the + // descriptor data. + ASIO_DECL void cleanup_descriptor_data( + per_descriptor_data& descriptor_data); + + // Add a new timer queue to the reactor. + template + void add_timer_queue(timer_queue& timer_queue); + + // Remove a timer queue from the reactor. + template + void remove_timer_queue(timer_queue& timer_queue); + + // Schedule a new operation in the given timer queue to expire at the + // specified absolute time. + template + void schedule_timer(timer_queue& queue, + const typename Time_Traits::time_type& time, + typename timer_queue::per_timer_data& timer, wait_op* op); + + // Cancel the timer operations associated with the given token. Returns the + // number of operations that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& queue, + typename timer_queue::per_timer_data& timer, + std::size_t max_cancelled = (std::numeric_limits::max)()); + + // Move the timer operations associated with the given timer. + template + void move_timer(timer_queue& queue, + typename timer_queue::per_timer_data& target, + typename timer_queue::per_timer_data& source); + + // Run epoll once until interrupted or events are ready to be dispatched. + ASIO_DECL void run(long usec, op_queue& ops); + + // Interrupt the select loop. + ASIO_DECL void interrupt(); + +private: + // The hint to pass to epoll_create to size its data structures. + enum { epoll_size = 20000 }; + + // Create the epoll file descriptor. Throws an exception if the descriptor + // cannot be created. + ASIO_DECL static int do_epoll_create(); + + // Create the timerfd file descriptor. Does not throw. + ASIO_DECL static int do_timerfd_create(); + + // Allocate a new descriptor state object. + ASIO_DECL descriptor_state* allocate_descriptor_state(); + + // Free an existing descriptor state object. + ASIO_DECL void free_descriptor_state(descriptor_state* s); + + // Helper function to add a new timer queue. + ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); + + // Helper function to remove a timer queue. + ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); + + // Called to recalculate and update the timeout. + ASIO_DECL void update_timeout(); + + // Get the timeout value for the epoll_wait call. The timeout value is + // returned as a number of milliseconds. A return value of -1 indicates + // that epoll_wait should block indefinitely. + ASIO_DECL int get_timeout(int msec); + +#if defined(ASIO_HAS_TIMERFD) + // Get the timeout value for the timer descriptor. The return value is the + // flag argument to be used when calling timerfd_settime. + ASIO_DECL int get_timeout(itimerspec& ts); +#endif // defined(ASIO_HAS_TIMERFD) + + // The scheduler implementation used to post completions. + scheduler& scheduler_; + + // Mutex to protect access to internal data. + mutex mutex_; + + // The interrupter is used to break a blocking epoll_wait call. + select_interrupter interrupter_; + + // The epoll file descriptor. + int epoll_fd_; + + // The timer file descriptor. + int timer_fd_; + + // The timer queues. + timer_queue_set timer_queues_; + + // Whether the service has been shut down. + bool shutdown_; + + // Mutex to protect access to the registered descriptors. + mutex registered_descriptors_mutex_; + + // Keep track of all registered descriptors. + object_pool registered_descriptors_; + + // Helper class to do post-perform_io cleanup. + struct perform_io_cleanup_on_block_exit; + friend struct perform_io_cleanup_on_block_exit; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/impl/epoll_reactor.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/epoll_reactor.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_EPOLL) + +#endif // ASIO_DETAIL_EPOLL_REACTOR_HPP diff --git a/tools/sdk/include/asio/asio/detail/event.hpp b/tools/sdk/include/asio/asio/detail/event.hpp new file mode 100644 index 00000000..da8fa770 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/event.hpp @@ -0,0 +1,48 @@ +// +// detail/event.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_EVENT_HPP +#define ASIO_DETAIL_EVENT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_THREADS) +# include "asio/detail/null_event.hpp" +#elif defined(ASIO_WINDOWS) +# include "asio/detail/win_event.hpp" +#elif defined(ASIO_HAS_PTHREADS) +# include "asio/detail/posix_event.hpp" +#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) +# include "asio/detail/std_event.hpp" +#else +# error Only Windows, POSIX and std::condition_variable are supported! +#endif + +namespace asio { +namespace detail { + +#if !defined(ASIO_HAS_THREADS) +typedef null_event event; +#elif defined(ASIO_WINDOWS) +typedef win_event event; +#elif defined(ASIO_HAS_PTHREADS) +typedef posix_event event; +#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) +typedef std_event event; +#endif + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_EVENT_HPP diff --git a/tools/sdk/include/asio/asio/detail/eventfd_select_interrupter.hpp b/tools/sdk/include/asio/asio/detail/eventfd_select_interrupter.hpp new file mode 100644 index 00000000..f6e594b6 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/eventfd_select_interrupter.hpp @@ -0,0 +1,83 @@ +// +// detail/eventfd_select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com) +// +// 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 ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP +#define ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_EVENTFD) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class eventfd_select_interrupter +{ +public: + // Constructor. + ASIO_DECL eventfd_select_interrupter(); + + // Destructor. + ASIO_DECL ~eventfd_select_interrupter(); + + // Recreate the interrupter's descriptors. Used after a fork. + ASIO_DECL void recreate(); + + // Interrupt the select call. + ASIO_DECL void interrupt(); + + // Reset the select interrupt. Returns true if the call was interrupted. + ASIO_DECL bool reset(); + + // Get the read descriptor to be passed to select. + int read_descriptor() const + { + return read_descriptor_; + } + +private: + // Open the descriptors. Throws on error. + ASIO_DECL void open_descriptors(); + + // Close the descriptors. + ASIO_DECL void close_descriptors(); + + // The read end of a connection used to interrupt the select call. This file + // descriptor is passed to select such that when it is time to stop, a single + // 64bit value will be written on the other end of the connection and this + // descriptor will become readable. + int read_descriptor_; + + // The write end of a connection used to interrupt the select call. A single + // 64bit non-zero value may be written to this to wake up the select which is + // waiting for the other end to become readable. This descriptor will only + // differ from the read descriptor when a pipe is used. + int write_descriptor_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/eventfd_select_interrupter.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_EVENTFD) + +#endif // ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP diff --git a/tools/sdk/include/asio/asio/detail/executor_op.hpp b/tools/sdk/include/asio/asio/detail/executor_op.hpp new file mode 100644 index 00000000..2d5c7e8b --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/executor_op.hpp @@ -0,0 +1,84 @@ +// +// detail/executor_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_EXECUTOR_OP_HPP +#define ASIO_DETAIL_EXECUTOR_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/scheduler_operation.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class executor_op : public Operation +{ +public: + ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(executor_op); + + template + executor_op(ASIO_MOVE_ARG(H) h, const Alloc& allocator) + : Operation(&executor_op::do_complete), + handler_(ASIO_MOVE_CAST(H)(h)), + allocator_(allocator) + { + } + + static void do_complete(void* owner, Operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + executor_op* o(static_cast(base)); + Alloc allocator(o->allocator_); + ptr p = { detail::addressof(allocator), o, o }; + + 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. + Handler handler(ASIO_MOVE_CAST(Handler)(o->handler_)); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN(()); + asio_handler_invoke_helpers::invoke(handler, handler); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; + Alloc allocator_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_EXECUTOR_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/fd_set_adapter.hpp b/tools/sdk/include/asio/asio/detail/fd_set_adapter.hpp new file mode 100644 index 00000000..fd373dae --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/fd_set_adapter.hpp @@ -0,0 +1,39 @@ +// +// detail/fd_set_adapter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_FD_SET_ADAPTER_HPP +#define ASIO_DETAIL_FD_SET_ADAPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/detail/posix_fd_set_adapter.hpp" +#include "asio/detail/win_fd_set_adapter.hpp" + +namespace asio { +namespace detail { + +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) +typedef win_fd_set_adapter fd_set_adapter; +#else +typedef posix_fd_set_adapter fd_set_adapter; +#endif + +} // namespace detail +} // namespace asio + +#endif // !defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_FD_SET_ADAPTER_HPP diff --git a/tools/sdk/include/asio/asio/detail/fenced_block.hpp b/tools/sdk/include/asio/asio/detail/fenced_block.hpp new file mode 100644 index 00000000..dc34bd9f --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/fenced_block.hpp @@ -0,0 +1,80 @@ +// +// detail/fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_FENCED_BLOCK_HPP +#define ASIO_DETAIL_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_THREADS) \ + || defined(ASIO_DISABLE_FENCED_BLOCK) +# include "asio/detail/null_fenced_block.hpp" +#elif defined(ASIO_HAS_STD_ATOMIC) +# include "asio/detail/std_fenced_block.hpp" +#elif defined(__MACH__) && defined(__APPLE__) +# include "asio/detail/macos_fenced_block.hpp" +#elif defined(__sun) +# include "asio/detail/solaris_fenced_block.hpp" +#elif defined(__GNUC__) && defined(__arm__) \ + && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) +# include "asio/detail/gcc_arm_fenced_block.hpp" +#elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__)) +# include "asio/detail/gcc_hppa_fenced_block.hpp" +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +# include "asio/detail/gcc_x86_fenced_block.hpp" +#elif defined(__GNUC__) \ + && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \ + && !defined(__INTEL_COMPILER) && !defined(__ICL) \ + && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) +# include "asio/detail/gcc_sync_fenced_block.hpp" +#elif defined(ASIO_WINDOWS) && !defined(UNDER_CE) +# include "asio/detail/win_fenced_block.hpp" +#else +# include "asio/detail/null_fenced_block.hpp" +#endif + +namespace asio { +namespace detail { + +#if !defined(ASIO_HAS_THREADS) \ + || defined(ASIO_DISABLE_FENCED_BLOCK) +typedef null_fenced_block fenced_block; +#elif defined(ASIO_HAS_STD_ATOMIC) +typedef std_fenced_block fenced_block; +#elif defined(__MACH__) && defined(__APPLE__) +typedef macos_fenced_block fenced_block; +#elif defined(__sun) +typedef solaris_fenced_block fenced_block; +#elif defined(__GNUC__) && defined(__arm__) \ + && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) +typedef gcc_arm_fenced_block fenced_block; +#elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__)) +typedef gcc_hppa_fenced_block fenced_block; +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +typedef gcc_x86_fenced_block fenced_block; +#elif defined(__GNUC__) \ + && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \ + && !defined(__INTEL_COMPILER) && !defined(__ICL) \ + && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) +typedef gcc_sync_fenced_block fenced_block; +#elif defined(ASIO_WINDOWS) && !defined(UNDER_CE) +typedef win_fenced_block fenced_block; +#else +typedef null_fenced_block fenced_block; +#endif + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_FENCED_BLOCK_HPP diff --git a/tools/sdk/include/asio/asio/detail/functional.hpp b/tools/sdk/include/asio/asio/detail/functional.hpp new file mode 100644 index 00000000..a37e9e63 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/functional.hpp @@ -0,0 +1,38 @@ +// +// detail/functional.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_FUNCTIONAL_HPP +#define ASIO_DETAIL_FUNCTIONAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include + +#if !defined(ASIO_HAS_STD_FUNCTION) +# include +#endif // !defined(ASIO_HAS_STD_FUNCTION) + +namespace asio { +namespace detail { + +#if defined(ASIO_HAS_STD_FUNCTION) +using std::function; +#else // defined(ASIO_HAS_STD_FUNCTION) +using boost::function; +#endif // defined(ASIO_HAS_STD_FUNCTION) + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_FUNCTIONAL_HPP diff --git a/tools/sdk/include/asio/asio/detail/gcc_arm_fenced_block.hpp b/tools/sdk/include/asio/asio/detail/gcc_arm_fenced_block.hpp new file mode 100644 index 00000000..7919a551 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/gcc_arm_fenced_block.hpp @@ -0,0 +1,91 @@ +// +// detail/gcc_arm_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP +#define ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(__GNUC__) && defined(__arm__) + +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class gcc_arm_fenced_block + : private noncopyable +{ +public: + enum half_t { half }; + enum full_t { full }; + + // Constructor for a half fenced block. + explicit gcc_arm_fenced_block(half_t) + { + } + + // Constructor for a full fenced block. + explicit gcc_arm_fenced_block(full_t) + { + barrier(); + } + + // Destructor. + ~gcc_arm_fenced_block() + { + barrier(); + } + +private: + static void barrier() + { +#if defined(__ARM_ARCH_4__) \ + || defined(__ARM_ARCH_4T__) \ + || defined(__ARM_ARCH_5__) \ + || defined(__ARM_ARCH_5E__) \ + || defined(__ARM_ARCH_5T__) \ + || defined(__ARM_ARCH_5TE__) \ + || defined(__ARM_ARCH_5TEJ__) \ + || defined(__ARM_ARCH_6__) \ + || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6T2__) +# if defined(__thumb__) + // This is just a placeholder and almost certainly not sufficient. + __asm__ __volatile__ ("" : : : "memory"); +# else // defined(__thumb__) + int a = 0, b = 0; + __asm__ __volatile__ ("swp %0, %1, [%2]" + : "=&r"(a) : "r"(1), "r"(&b) : "memory", "cc"); +# endif // defined(__thumb__) +#else + // ARMv7 and later. + __asm__ __volatile__ ("dmb" : : : "memory"); +#endif + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(__GNUC__) && defined(__arm__) + +#endif // ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP diff --git a/tools/sdk/include/asio/asio/detail/gcc_hppa_fenced_block.hpp b/tools/sdk/include/asio/asio/detail/gcc_hppa_fenced_block.hpp new file mode 100644 index 00000000..d3957ce3 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/gcc_hppa_fenced_block.hpp @@ -0,0 +1,68 @@ +// +// detail/gcc_hppa_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP +#define ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(__GNUC__) && (defined(__hppa) || defined(__hppa__)) + +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class gcc_hppa_fenced_block + : private noncopyable +{ +public: + enum half_t { half }; + enum full_t { full }; + + // Constructor for a half fenced block. + explicit gcc_hppa_fenced_block(half_t) + { + } + + // Constructor for a full fenced block. + explicit gcc_hppa_fenced_block(full_t) + { + barrier(); + } + + // Destructor. + ~gcc_hppa_fenced_block() + { + barrier(); + } + +private: + static void barrier() + { + // This is just a placeholder and almost certainly not sufficient. + __asm__ __volatile__ ("" : : : "memory"); + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(__GNUC__) && (defined(__hppa) || defined(__hppa__)) + +#endif // ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP diff --git a/tools/sdk/include/asio/asio/detail/gcc_sync_fenced_block.hpp b/tools/sdk/include/asio/asio/detail/gcc_sync_fenced_block.hpp new file mode 100644 index 00000000..90d176f1 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/gcc_sync_fenced_block.hpp @@ -0,0 +1,65 @@ +// +// detail/gcc_sync_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP +#define ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(__GNUC__) \ + && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \ + && !defined(__INTEL_COMPILER) && !defined(__ICL) \ + && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) + +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class gcc_sync_fenced_block + : private noncopyable +{ +public: + enum half_or_full_t { half, full }; + + // Constructor. + explicit gcc_sync_fenced_block(half_or_full_t) + : value_(0) + { + __sync_lock_test_and_set(&value_, 1); + } + + // Destructor. + ~gcc_sync_fenced_block() + { + __sync_lock_release(&value_); + } + +private: + int value_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(__GNUC__) + // && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) + // && !defined(__INTEL_COMPILER) && !defined(__ICL) + // && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) + +#endif // ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP diff --git a/tools/sdk/include/asio/asio/detail/gcc_x86_fenced_block.hpp b/tools/sdk/include/asio/asio/detail/gcc_x86_fenced_block.hpp new file mode 100644 index 00000000..1366def7 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/gcc_x86_fenced_block.hpp @@ -0,0 +1,99 @@ +// +// detail/gcc_x86_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP +#define ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class gcc_x86_fenced_block + : private noncopyable +{ +public: + enum half_t { half }; + enum full_t { full }; + + // Constructor for a half fenced block. + explicit gcc_x86_fenced_block(half_t) + { + } + + // Constructor for a full fenced block. + explicit gcc_x86_fenced_block(full_t) + { + lbarrier(); + } + + // Destructor. + ~gcc_x86_fenced_block() + { + sbarrier(); + } + +private: + static int barrier() + { + int r = 0, m = 1; + __asm__ __volatile__ ( + "xchgl %0, %1" : + "=r"(r), "=m"(m) : + "0"(1), "m"(m) : + "memory", "cc"); + return r; + } + + static void lbarrier() + { +#if defined(__SSE2__) +# if (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) + __builtin_ia32_lfence(); +# else // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) + __asm__ __volatile__ ("lfence" ::: "memory"); +# endif // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) +#else // defined(__SSE2__) + barrier(); +#endif // defined(__SSE2__) + } + + static void sbarrier() + { +#if defined(__SSE2__) +# if (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) + __builtin_ia32_sfence(); +# else // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) + __asm__ __volatile__ ("sfence" ::: "memory"); +# endif // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) +#else // defined(__SSE2__) + barrier(); +#endif // defined(__SSE2__) + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + +#endif // ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP diff --git a/tools/sdk/include/asio/asio/detail/global.hpp b/tools/sdk/include/asio/asio/detail/global.hpp new file mode 100644 index 00000000..085ac643 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/global.hpp @@ -0,0 +1,52 @@ +// +// detail/global.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_GLOBAL_HPP +#define ASIO_DETAIL_GLOBAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_THREADS) +# include "asio/detail/null_global.hpp" +#elif defined(ASIO_WINDOWS) +# include "asio/detail/win_global.hpp" +#elif defined(ASIO_HAS_PTHREADS) +# include "asio/detail/posix_global.hpp" +#elif defined(ASIO_HAS_STD_CALL_ONCE) +# include "asio/detail/std_global.hpp" +#else +# error Only Windows, POSIX and std::call_once are supported! +#endif + +namespace asio { +namespace detail { + +template +inline T& global() +{ +#if !defined(ASIO_HAS_THREADS) + return null_global(); +#elif defined(ASIO_WINDOWS) + return win_global(); +#elif defined(ASIO_HAS_PTHREADS) + return posix_global(); +#elif defined(ASIO_HAS_STD_CALL_ONCE) + return std_global(); +#endif +} + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_GLOBAL_HPP diff --git a/tools/sdk/include/asio/asio/detail/handler_alloc_helpers.hpp b/tools/sdk/include/asio/asio/detail/handler_alloc_helpers.hpp new file mode 100644 index 00000000..afefb4d1 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/handler_alloc_helpers.hpp @@ -0,0 +1,235 @@ +// +// detail/handler_alloc_helpers.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP +#define ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/recycling_allocator.hpp" +#include "asio/associated_allocator.hpp" +#include "asio/handler_alloc_hook.hpp" + +#include "asio/detail/push_options.hpp" + +// Calls to asio_handler_allocate and asio_handler_deallocate must be made from +// a namespace that does not contain any overloads of these functions. The +// asio_handler_alloc_helpers namespace is defined here for that purpose. +namespace asio_handler_alloc_helpers { + +template +inline void* allocate(std::size_t s, Handler& h) +{ +#if !defined(ASIO_HAS_HANDLER_HOOKS) + return ::operator new(s); +#else + using asio::asio_handler_allocate; + return asio_handler_allocate(s, asio::detail::addressof(h)); +#endif +} + +template +inline void deallocate(void* p, std::size_t s, Handler& h) +{ +#if !defined(ASIO_HAS_HANDLER_HOOKS) + ::operator delete(p); +#else + using asio::asio_handler_deallocate; + asio_handler_deallocate(p, s, asio::detail::addressof(h)); +#endif +} + +} // namespace asio_handler_alloc_helpers + +namespace asio { +namespace detail { + +template +class hook_allocator +{ +public: + typedef T value_type; + + template + struct rebind + { + typedef hook_allocator other; + }; + + explicit hook_allocator(Handler& h) + : handler_(h) + { + } + + template + hook_allocator(const hook_allocator& a) + : handler_(a.handler_) + { + } + + T* allocate(std::size_t n) + { + return static_cast( + asio_handler_alloc_helpers::allocate(sizeof(T) * n, handler_)); + } + + void deallocate(T* p, std::size_t n) + { + asio_handler_alloc_helpers::deallocate(p, sizeof(T) * n, handler_); + } + +//private: + Handler& handler_; +}; + +template +class hook_allocator +{ +public: + typedef void value_type; + + template + struct rebind + { + typedef hook_allocator other; + }; + + explicit hook_allocator(Handler& h) + : handler_(h) + { + } + + template + hook_allocator(const hook_allocator& a) + : handler_(a.handler_) + { + } + +//private: + Handler& handler_; +}; + +template +struct get_hook_allocator +{ + typedef Allocator type; + + static type get(Handler&, const Allocator& a) + { + return a; + } +}; + +template +struct get_hook_allocator > +{ + typedef hook_allocator type; + + static type get(Handler& handler, const std::allocator&) + { + return type(handler); + } +}; + +} // namespace detail +} // namespace asio + +#define ASIO_DEFINE_HANDLER_PTR(op) \ + struct ptr \ + { \ + Handler* h; \ + op* v; \ + op* p; \ + ~ptr() \ + { \ + reset(); \ + } \ + static op* allocate(Handler& handler) \ + { \ + typedef typename ::asio::associated_allocator< \ + Handler>::type associated_allocator_type; \ + typedef typename ::asio::detail::get_hook_allocator< \ + Handler, associated_allocator_type>::type hook_allocator_type; \ + ASIO_REBIND_ALLOC(hook_allocator_type, op) a( \ + ::asio::detail::get_hook_allocator< \ + Handler, associated_allocator_type>::get( \ + handler, ::asio::get_associated_allocator(handler))); \ + return a.allocate(1); \ + } \ + void reset() \ + { \ + if (p) \ + { \ + p->~op(); \ + p = 0; \ + } \ + if (v) \ + { \ + typedef typename ::asio::associated_allocator< \ + Handler>::type associated_allocator_type; \ + typedef typename ::asio::detail::get_hook_allocator< \ + Handler, associated_allocator_type>::type hook_allocator_type; \ + ASIO_REBIND_ALLOC(hook_allocator_type, op) a( \ + ::asio::detail::get_hook_allocator< \ + Handler, associated_allocator_type>::get( \ + *h, ::asio::get_associated_allocator(*h))); \ + a.deallocate(static_cast(v), 1); \ + v = 0; \ + } \ + } \ + } \ + /**/ + +#define ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(op) \ + struct ptr \ + { \ + const Alloc* a; \ + void* v; \ + op* p; \ + ~ptr() \ + { \ + reset(); \ + } \ + static op* allocate(const Alloc& a) \ + { \ + typedef typename ::asio::detail::get_recycling_allocator< \ + Alloc>::type recycling_allocator_type; \ + ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \ + ::asio::detail::get_recycling_allocator::get(a)); \ + return a1.allocate(1); \ + } \ + void reset() \ + { \ + if (p) \ + { \ + p->~op(); \ + p = 0; \ + } \ + if (v) \ + { \ + typedef typename ::asio::detail::get_recycling_allocator< \ + Alloc>::type recycling_allocator_type; \ + ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \ + ::asio::detail::get_recycling_allocator::get(*a)); \ + a1.deallocate(static_cast(v), 1); \ + v = 0; \ + } \ + } \ + } \ + /**/ + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP diff --git a/tools/sdk/include/asio/asio/detail/handler_cont_helpers.hpp b/tools/sdk/include/asio/asio/detail/handler_cont_helpers.hpp new file mode 100644 index 00000000..110ba944 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/handler_cont_helpers.hpp @@ -0,0 +1,45 @@ +// +// detail/handler_cont_helpers.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_HANDLER_CONT_HELPERS_HPP +#define ASIO_DETAIL_HANDLER_CONT_HELPERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/memory.hpp" +#include "asio/handler_continuation_hook.hpp" + +#include "asio/detail/push_options.hpp" + +// Calls to asio_handler_is_continuation must be made from a namespace that +// does not contain overloads of this function. This namespace is defined here +// for that purpose. +namespace asio_handler_cont_helpers { + +template +inline bool is_continuation(Context& context) +{ +#if !defined(ASIO_HAS_HANDLER_HOOKS) + return false; +#else + using asio::asio_handler_is_continuation; + return asio_handler_is_continuation( + asio::detail::addressof(context)); +#endif +} + +} // namespace asio_handler_cont_helpers + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_HANDLER_CONT_HELPERS_HPP diff --git a/tools/sdk/include/asio/asio/detail/handler_invoke_helpers.hpp b/tools/sdk/include/asio/asio/detail/handler_invoke_helpers.hpp new file mode 100644 index 00000000..4c65c4c5 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/handler_invoke_helpers.hpp @@ -0,0 +1,57 @@ +// +// detail/handler_invoke_helpers.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP +#define ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/memory.hpp" +#include "asio/handler_invoke_hook.hpp" + +#include "asio/detail/push_options.hpp" + +// Calls to asio_handler_invoke must be made from a namespace that does not +// contain overloads of this function. The asio_handler_invoke_helpers +// namespace is defined here for that purpose. +namespace asio_handler_invoke_helpers { + +template +inline void invoke(Function& function, Context& context) +{ +#if !defined(ASIO_HAS_HANDLER_HOOKS) + Function tmp(function); + tmp(); +#else + using asio::asio_handler_invoke; + asio_handler_invoke(function, asio::detail::addressof(context)); +#endif +} + +template +inline void invoke(const Function& function, Context& context) +{ +#if !defined(ASIO_HAS_HANDLER_HOOKS) + Function tmp(function); + tmp(); +#else + using asio::asio_handler_invoke; + asio_handler_invoke(function, asio::detail::addressof(context)); +#endif +} + +} // namespace asio_handler_invoke_helpers + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP diff --git a/tools/sdk/include/asio/asio/detail/handler_tracking.hpp b/tools/sdk/include/asio/asio/detail/handler_tracking.hpp new file mode 100644 index 00000000..83f820ec --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/handler_tracking.hpp @@ -0,0 +1,238 @@ +// +// detail/handler_tracking.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_HANDLER_TRACKING_HPP +#define ASIO_DETAIL_HANDLER_TRACKING_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +namespace asio { + +class execution_context; + +} // namespace asio + +#if defined(ASIO_CUSTOM_HANDLER_TRACKING) +# include ASIO_CUSTOM_HANDLER_TRACKING +#elif defined(ASIO_ENABLE_HANDLER_TRACKING) +# include "asio/error_code.hpp" +# include "asio/detail/cstdint.hpp" +# include "asio/detail/static_mutex.hpp" +# include "asio/detail/tss_ptr.hpp" +#endif // defined(ASIO_ENABLE_HANDLER_TRACKING) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +#if defined(ASIO_CUSTOM_HANDLER_TRACKING) + +// The user-specified header must define the following macros: +// - ASIO_INHERIT_TRACKED_HANDLER +// - ASIO_ALSO_INHERIT_TRACKED_HANDLER +// - ASIO_HANDLER_TRACKING_INIT +// - ASIO_HANDLER_CREATION(args) +// - ASIO_HANDLER_COMPLETION(args) +// - ASIO_HANDLER_INVOCATION_BEGIN(args) +// - ASIO_HANDLER_INVOCATION_END +// - ASIO_HANDLER_OPERATION(args) +// - ASIO_HANDLER_REACTOR_REGISTRATION(args) +// - ASIO_HANDLER_REACTOR_DEREGISTRATION(args) +// - ASIO_HANDLER_REACTOR_READ_EVENT +// - ASIO_HANDLER_REACTOR_WRITE_EVENT +// - ASIO_HANDLER_REACTOR_ERROR_EVENT +// - ASIO_HANDLER_REACTOR_EVENTS(args) +// - ASIO_HANDLER_REACTOR_OPERATION(args) + +# if !defined(ASIO_ENABLE_HANDLER_TRACKING) +# define ASIO_ENABLE_HANDLER_TRACKING 1 +# endif /// !defined(ASIO_ENABLE_HANDLER_TRACKING) + +#elif defined(ASIO_ENABLE_HANDLER_TRACKING) + +class handler_tracking +{ +public: + class completion; + + // Base class for objects containing tracked handlers. + class tracked_handler + { + private: + // Only the handler_tracking class will have access to the id. + friend class handler_tracking; + friend class completion; + uint64_t id_; + + protected: + // Constructor initialises with no id. + tracked_handler() : id_(0) {} + + // Prevent deletion through this type. + ~tracked_handler() {} + }; + + // Initialise the tracking system. + ASIO_DECL static void init(); + + // Record the creation of a tracked handler. + ASIO_DECL static void creation( + execution_context& context, tracked_handler& h, + const char* object_type, void* object, + uintmax_t native_handle, const char* op_name); + + class completion + { + public: + // Constructor records that handler is to be invoked with no arguments. + ASIO_DECL explicit completion(const tracked_handler& h); + + // Destructor records only when an exception is thrown from the handler, or + // if the memory is being freed without the handler having been invoked. + ASIO_DECL ~completion(); + + // Records that handler is to be invoked with no arguments. + ASIO_DECL void invocation_begin(); + + // Records that handler is to be invoked with one arguments. + ASIO_DECL void invocation_begin(const asio::error_code& ec); + + // Constructor records that handler is to be invoked with two arguments. + ASIO_DECL void invocation_begin( + const asio::error_code& ec, std::size_t bytes_transferred); + + // Constructor records that handler is to be invoked with two arguments. + ASIO_DECL void invocation_begin( + const asio::error_code& ec, int signal_number); + + // Constructor records that handler is to be invoked with two arguments. + ASIO_DECL void invocation_begin( + const asio::error_code& ec, const char* arg); + + // Record that handler invocation has ended. + ASIO_DECL void invocation_end(); + + private: + friend class handler_tracking; + uint64_t id_; + bool invoked_; + completion* next_; + }; + + // Record an operation that is not directly associated with a handler. + ASIO_DECL static void operation(execution_context& context, + const char* object_type, void* object, + uintmax_t native_handle, const char* op_name); + + // Record that a descriptor has been registered with the reactor. + ASIO_DECL static void reactor_registration(execution_context& context, + uintmax_t native_handle, uintmax_t registration); + + // Record that a descriptor has been deregistered from the reactor. + ASIO_DECL static void reactor_deregistration(execution_context& context, + uintmax_t native_handle, uintmax_t registration); + + // Record a reactor-based operation that is associated with a handler. + ASIO_DECL static void reactor_events(execution_context& context, + uintmax_t registration, unsigned events); + + // Record a reactor-based operation that is associated with a handler. + ASIO_DECL static void reactor_operation( + const tracked_handler& h, const char* op_name, + const asio::error_code& ec); + + // Record a reactor-based operation that is associated with a handler. + ASIO_DECL static void reactor_operation( + const tracked_handler& h, const char* op_name, + const asio::error_code& ec, std::size_t bytes_transferred); + + // Write a line of output. + ASIO_DECL static void write_line(const char* format, ...); + +private: + struct tracking_state; + ASIO_DECL static tracking_state* get_state(); +}; + +# define ASIO_INHERIT_TRACKED_HANDLER \ + : public asio::detail::handler_tracking::tracked_handler + +# define ASIO_ALSO_INHERIT_TRACKED_HANDLER \ + , public asio::detail::handler_tracking::tracked_handler + +# define ASIO_HANDLER_TRACKING_INIT \ + asio::detail::handler_tracking::init() + +# define ASIO_HANDLER_CREATION(args) \ + asio::detail::handler_tracking::creation args + +# define ASIO_HANDLER_COMPLETION(args) \ + asio::detail::handler_tracking::completion tracked_completion args + +# define ASIO_HANDLER_INVOCATION_BEGIN(args) \ + tracked_completion.invocation_begin args + +# define ASIO_HANDLER_INVOCATION_END \ + tracked_completion.invocation_end() + +# define ASIO_HANDLER_OPERATION(args) \ + asio::detail::handler_tracking::operation args + +# define ASIO_HANDLER_REACTOR_REGISTRATION(args) \ + asio::detail::handler_tracking::reactor_registration args + +# define ASIO_HANDLER_REACTOR_DEREGISTRATION(args) \ + asio::detail::handler_tracking::reactor_deregistration args + +# define ASIO_HANDLER_REACTOR_READ_EVENT 1 +# define ASIO_HANDLER_REACTOR_WRITE_EVENT 2 +# define ASIO_HANDLER_REACTOR_ERROR_EVENT 4 + +# define ASIO_HANDLER_REACTOR_EVENTS(args) \ + asio::detail::handler_tracking::reactor_events args + +# define ASIO_HANDLER_REACTOR_OPERATION(args) \ + asio::detail::handler_tracking::reactor_operation args + +#else // defined(ASIO_ENABLE_HANDLER_TRACKING) + +# define ASIO_INHERIT_TRACKED_HANDLER +# define ASIO_ALSO_INHERIT_TRACKED_HANDLER +# define ASIO_HANDLER_TRACKING_INIT (void)0 +# define ASIO_HANDLER_CREATION(args) (void)0 +# define ASIO_HANDLER_COMPLETION(args) (void)0 +# define ASIO_HANDLER_INVOCATION_BEGIN(args) (void)0 +# define ASIO_HANDLER_INVOCATION_END (void)0 +# define ASIO_HANDLER_OPERATION(args) (void)0 +# define ASIO_HANDLER_REACTOR_REGISTRATION(args) (void)0 +# define ASIO_HANDLER_REACTOR_DEREGISTRATION(args) (void)0 +# define ASIO_HANDLER_REACTOR_READ_EVENT 0 +# define ASIO_HANDLER_REACTOR_WRITE_EVENT 0 +# define ASIO_HANDLER_REACTOR_ERROR_EVENT 0 +# define ASIO_HANDLER_REACTOR_EVENTS(args) (void)0 +# define ASIO_HANDLER_REACTOR_OPERATION(args) (void)0 + +#endif // defined(ASIO_ENABLE_HANDLER_TRACKING) + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/handler_tracking.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_DETAIL_HANDLER_TRACKING_HPP diff --git a/tools/sdk/include/asio/asio/detail/handler_type_requirements.hpp b/tools/sdk/include/asio/asio/detail/handler_type_requirements.hpp new file mode 100644 index 00000000..9181bc51 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/handler_type_requirements.hpp @@ -0,0 +1,556 @@ +// +// detail/handler_type_requirements.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_HPP +#define ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +// 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(ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) +# if !defined(__GNUC__) || (__GNUC__ >= 4) +# define ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 +# endif // !defined(__GNUC__) || (__GNUC__ >= 4) +#endif // !defined(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(ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define 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(ASIO_MSVC) +# if (_MSC_VER >= 1600) +# define ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 +# endif // (_MSC_VER >= 1600) +# endif // defined(ASIO_MSVC) +# if defined(__clang__) +# if __has_feature(__cxx_static_assert__) +# define ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 +# endif // __has_feature(cxx_static_assert) +# endif // defined(__clang__) +#endif // !defined(ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) + +#if defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) +# include "asio/async_result.hpp" +#endif // defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) + +namespace asio { +namespace detail { + +#if defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) + +# if defined(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(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(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(ASIO_MOVE_CAST(Handler)(h))), + ((h)(*a1, ASIO_MOVE_CAST(Arg2)(*a2))), + char(0)); + +template +char (&two_arg_move_handler_test(Handler, ...))[2]; + +# define ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ + static_assert(expr, msg); + +# else // defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) + +# define ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) + +# endif // defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) + +template T& lvref(); +template T& lvref(T); +template const T& clvref(); +template const T& clvref(T); +#if defined(ASIO_HAS_MOVE) +template T rvref(); +template T rvref(T); +#else // defined(ASIO_HAS_MOVE) +template const T& rvref(); +template const T& rvref(T); +#endif // defined(ASIO_HAS_MOVE) +template char argbyv(T); + +template +struct handler_type_requirements +{ +}; + +#define ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef ASIO_HANDLER_TYPE(handler_type, \ + void()) asio_true_handler_type; \ + \ + ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(asio::detail::zero_arg_copyable_handler_test( \ + asio::detail::clvref< \ + asio_true_handler_type>(), 0)) == 1, \ + "CompletionHandler type requirements not met") \ + \ + typedef asio::detail::handler_type_requirements< \ + sizeof( \ + asio::detail::argbyv( \ + asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + asio::detail::lvref< \ + asio_true_handler_type>()(), \ + char(0))> ASIO_UNUSED_TYPEDEF + +#define ASIO_READ_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef ASIO_HANDLER_TYPE(handler_type, \ + void(asio::error_code, std::size_t)) \ + asio_true_handler_type; \ + \ + ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(asio::detail::two_arg_handler_test( \ + asio::detail::rvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "ReadHandler type requirements not met") \ + \ + typedef asio::detail::handler_type_requirements< \ + sizeof( \ + asio::detail::argbyv( \ + asio::detail::rvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + asio::detail::lvref< \ + asio_true_handler_type>()( \ + asio::detail::lvref(), \ + asio::detail::lvref()), \ + char(0))> ASIO_UNUSED_TYPEDEF + +#define ASIO_WRITE_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef ASIO_HANDLER_TYPE(handler_type, \ + void(asio::error_code, std::size_t)) \ + asio_true_handler_type; \ + \ + ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(asio::detail::two_arg_handler_test( \ + asio::detail::rvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "WriteHandler type requirements not met") \ + \ + typedef asio::detail::handler_type_requirements< \ + sizeof( \ + asio::detail::argbyv( \ + asio::detail::rvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + asio::detail::lvref< \ + asio_true_handler_type>()( \ + asio::detail::lvref(), \ + asio::detail::lvref()), \ + char(0))> ASIO_UNUSED_TYPEDEF + +#define ASIO_ACCEPT_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef ASIO_HANDLER_TYPE(handler_type, \ + void(asio::error_code)) \ + asio_true_handler_type; \ + \ + ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(asio::detail::one_arg_handler_test( \ + asio::detail::rvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "AcceptHandler type requirements not met") \ + \ + typedef asio::detail::handler_type_requirements< \ + sizeof( \ + asio::detail::argbyv( \ + asio::detail::rvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + asio::detail::lvref< \ + asio_true_handler_type>()( \ + asio::detail::lvref()), \ + char(0))> ASIO_UNUSED_TYPEDEF + +#define ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ + handler_type, handler, socket_type) \ + \ + typedef ASIO_HANDLER_TYPE(handler_type, \ + void(asio::error_code, socket_type)) \ + asio_true_handler_type; \ + \ + ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(asio::detail::two_arg_move_handler_test( \ + asio::detail::rvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "MoveAcceptHandler type requirements not met") \ + \ + typedef asio::detail::handler_type_requirements< \ + sizeof( \ + asio::detail::argbyv( \ + asio::detail::rvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + asio::detail::lvref< \ + asio_true_handler_type>()( \ + asio::detail::lvref(), \ + asio::detail::rvref()), \ + char(0))> ASIO_UNUSED_TYPEDEF + +#define ASIO_CONNECT_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef ASIO_HANDLER_TYPE(handler_type, \ + void(asio::error_code)) \ + asio_true_handler_type; \ + \ + ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(asio::detail::one_arg_handler_test( \ + asio::detail::rvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "ConnectHandler type requirements not met") \ + \ + typedef asio::detail::handler_type_requirements< \ + sizeof( \ + asio::detail::argbyv( \ + asio::detail::rvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + asio::detail::lvref< \ + asio_true_handler_type>()( \ + asio::detail::lvref()), \ + char(0))> ASIO_UNUSED_TYPEDEF + +#define ASIO_RANGE_CONNECT_HANDLER_CHECK( \ + handler_type, handler, endpoint_type) \ + \ + typedef ASIO_HANDLER_TYPE(handler_type, \ + void(asio::error_code, endpoint_type)) \ + asio_true_handler_type; \ + \ + ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(asio::detail::two_arg_handler_test( \ + asio::detail::rvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "RangeConnectHandler type requirements not met") \ + \ + typedef asio::detail::handler_type_requirements< \ + sizeof( \ + asio::detail::argbyv( \ + asio::detail::rvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + asio::detail::lvref< \ + asio_true_handler_type>()( \ + asio::detail::lvref(), \ + asio::detail::lvref()), \ + char(0))> ASIO_UNUSED_TYPEDEF + +#define ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ + handler_type, handler, iter_type) \ + \ + typedef ASIO_HANDLER_TYPE(handler_type, \ + void(asio::error_code, iter_type)) \ + asio_true_handler_type; \ + \ + ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(asio::detail::two_arg_handler_test( \ + asio::detail::rvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "IteratorConnectHandler type requirements not met") \ + \ + typedef asio::detail::handler_type_requirements< \ + sizeof( \ + asio::detail::argbyv( \ + asio::detail::rvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + asio::detail::lvref< \ + asio_true_handler_type>()( \ + asio::detail::lvref(), \ + asio::detail::lvref()), \ + char(0))> ASIO_UNUSED_TYPEDEF + +#define ASIO_RESOLVE_HANDLER_CHECK( \ + handler_type, handler, range_type) \ + \ + typedef ASIO_HANDLER_TYPE(handler_type, \ + void(asio::error_code, range_type)) \ + asio_true_handler_type; \ + \ + ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(asio::detail::two_arg_handler_test( \ + asio::detail::rvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "ResolveHandler type requirements not met") \ + \ + typedef asio::detail::handler_type_requirements< \ + sizeof( \ + asio::detail::argbyv( \ + asio::detail::rvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + asio::detail::lvref< \ + asio_true_handler_type>()( \ + asio::detail::lvref(), \ + asio::detail::lvref()), \ + char(0))> ASIO_UNUSED_TYPEDEF + +#define ASIO_WAIT_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef ASIO_HANDLER_TYPE(handler_type, \ + void(asio::error_code)) \ + asio_true_handler_type; \ + \ + ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(asio::detail::one_arg_handler_test( \ + asio::detail::rvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "WaitHandler type requirements not met") \ + \ + typedef asio::detail::handler_type_requirements< \ + sizeof( \ + asio::detail::argbyv( \ + asio::detail::rvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + asio::detail::lvref< \ + asio_true_handler_type>()( \ + asio::detail::lvref()), \ + char(0))> ASIO_UNUSED_TYPEDEF + +#define ASIO_SIGNAL_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef ASIO_HANDLER_TYPE(handler_type, \ + void(asio::error_code, int)) \ + asio_true_handler_type; \ + \ + ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(asio::detail::two_arg_handler_test( \ + asio::detail::rvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "SignalHandler type requirements not met") \ + \ + typedef asio::detail::handler_type_requirements< \ + sizeof( \ + asio::detail::argbyv( \ + asio::detail::rvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + asio::detail::lvref< \ + asio_true_handler_type>()( \ + asio::detail::lvref(), \ + asio::detail::lvref()), \ + char(0))> ASIO_UNUSED_TYPEDEF + +#define ASIO_HANDSHAKE_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef ASIO_HANDLER_TYPE(handler_type, \ + void(asio::error_code)) \ + asio_true_handler_type; \ + \ + ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(asio::detail::one_arg_handler_test( \ + asio::detail::rvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "HandshakeHandler type requirements not met") \ + \ + typedef asio::detail::handler_type_requirements< \ + sizeof( \ + asio::detail::argbyv( \ + asio::detail::rvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + asio::detail::lvref< \ + asio_true_handler_type>()( \ + asio::detail::lvref()), \ + char(0))> ASIO_UNUSED_TYPEDEF + +#define ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef ASIO_HANDLER_TYPE(handler_type, \ + void(asio::error_code, std::size_t)) \ + asio_true_handler_type; \ + \ + ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(asio::detail::two_arg_handler_test( \ + asio::detail::rvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "BufferedHandshakeHandler type requirements not met") \ + \ + typedef asio::detail::handler_type_requirements< \ + sizeof( \ + asio::detail::argbyv( \ + asio::detail::rvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + asio::detail::lvref< \ + asio_true_handler_type>()( \ + asio::detail::lvref(), \ + asio::detail::lvref()), \ + char(0))> ASIO_UNUSED_TYPEDEF + +#define ASIO_SHUTDOWN_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef ASIO_HANDLER_TYPE(handler_type, \ + void(asio::error_code)) \ + asio_true_handler_type; \ + \ + ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(asio::detail::one_arg_handler_test( \ + asio::detail::rvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "ShutdownHandler type requirements not met") \ + \ + typedef asio::detail::handler_type_requirements< \ + sizeof( \ + asio::detail::argbyv( \ + asio::detail::rvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + asio::detail::lvref< \ + asio_true_handler_type>()( \ + asio::detail::lvref()), \ + char(0))> ASIO_UNUSED_TYPEDEF + +#else // !defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) + +#define ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int ASIO_UNUSED_TYPEDEF + +#define ASIO_READ_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int ASIO_UNUSED_TYPEDEF + +#define ASIO_WRITE_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int ASIO_UNUSED_TYPEDEF + +#define ASIO_ACCEPT_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int ASIO_UNUSED_TYPEDEF + +#define ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ + handler_type, handler, socket_type) \ + typedef int ASIO_UNUSED_TYPEDEF + +#define ASIO_CONNECT_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int ASIO_UNUSED_TYPEDEF + +#define ASIO_RANGE_CONNECT_HANDLER_CHECK( \ + handler_type, handler, iter_type) \ + typedef int ASIO_UNUSED_TYPEDEF + +#define ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ + handler_type, handler, iter_type) \ + typedef int ASIO_UNUSED_TYPEDEF + +#define ASIO_RESOLVE_HANDLER_CHECK( \ + handler_type, handler, iter_type) \ + typedef int ASIO_UNUSED_TYPEDEF + +#define ASIO_WAIT_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int ASIO_UNUSED_TYPEDEF + +#define ASIO_SIGNAL_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int ASIO_UNUSED_TYPEDEF + +#define ASIO_HANDSHAKE_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int ASIO_UNUSED_TYPEDEF + +#define ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int ASIO_UNUSED_TYPEDEF + +#define ASIO_SHUTDOWN_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int ASIO_UNUSED_TYPEDEF + +#endif // !defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_HPP diff --git a/tools/sdk/include/asio/asio/detail/handler_work.hpp b/tools/sdk/include/asio/asio/detail/handler_work.hpp new file mode 100644 index 00000000..cce5c4b6 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/handler_work.hpp @@ -0,0 +1,95 @@ +// +// detail/handler_work.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_HANDLER_WORK_HPP +#define ASIO_DETAIL_HANDLER_WORK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/associated_executor.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// A helper class template to allow completion handlers to be dispatched +// through either the new executors framework or the old invocaton hook. The +// primary template uses the new executors framework. +template ::type> +class handler_work +{ +public: + explicit handler_work(Handler& handler) ASIO_NOEXCEPT + : executor_(associated_executor::get(handler)) + { + } + + static void start(Handler& handler) ASIO_NOEXCEPT + { + Executor ex(associated_executor::get(handler)); + ex.on_work_started(); + } + + ~handler_work() + { + executor_.on_work_finished(); + } + + template + void complete(Function& function, Handler& handler) + { + executor_.dispatch(ASIO_MOVE_CAST(Function)(function), + associated_allocator::get(handler)); + } + +private: + // Disallow copying and assignment. + handler_work(const handler_work&); + handler_work& operator=(const handler_work&); + + typename associated_executor::type executor_; +}; + +// This specialisation dispatches a handler through the old invocation hook. +// The specialisation is not strictly required for correctness, as the +// system_executor will dispatch through the hook anyway. However, by doing +// this we avoid an extra copy of the handler. +template +class handler_work +{ +public: + explicit handler_work(Handler&) ASIO_NOEXCEPT {} + static void start(Handler&) ASIO_NOEXCEPT {} + ~handler_work() {} + + template + void complete(Function& function, Handler& handler) + { + asio_handler_invoke_helpers::invoke(function, handler); + } + +private: + // Disallow copying and assignment. + handler_work(const handler_work&); + handler_work& operator=(const handler_work&); +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_HANDLER_WORK_HPP diff --git a/tools/sdk/include/asio/asio/detail/hash_map.hpp b/tools/sdk/include/asio/asio/detail/hash_map.hpp new file mode 100644 index 00000000..e70970d6 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/hash_map.hpp @@ -0,0 +1,331 @@ +// +// detail/hash_map.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_HASH_MAP_HPP +#define ASIO_DETAIL_HASH_MAP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include +#include "asio/detail/assert.hpp" +#include "asio/detail/noncopyable.hpp" + +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) +# include "asio/detail/socket_types.hpp" +#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +inline std::size_t calculate_hash_value(int i) +{ + return static_cast(i); +} + +inline std::size_t calculate_hash_value(void* p) +{ + return reinterpret_cast(p) + + (reinterpret_cast(p) >> 3); +} + +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) +inline std::size_t calculate_hash_value(SOCKET s) +{ + return static_cast(s); +} +#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) + +// Note: assumes K and V are POD types. +template +class hash_map + : private noncopyable +{ +public: + // The type of a value in the map. + typedef std::pair value_type; + + // The type of a non-const iterator over the hash map. + typedef typename std::list::iterator iterator; + + // The type of a const iterator over the hash map. + typedef typename std::list::const_iterator const_iterator; + + // Constructor. + hash_map() + : size_(0), + buckets_(0), + num_buckets_(0) + { + } + + // Destructor. + ~hash_map() + { + delete[] buckets_; + } + + // Get an iterator for the beginning of the map. + iterator begin() + { + return values_.begin(); + } + + // Get an iterator for the beginning of the map. + const_iterator begin() const + { + return values_.begin(); + } + + // Get an iterator for the end of the map. + iterator end() + { + return values_.end(); + } + + // Get an iterator for the end of the map. + const_iterator end() const + { + return values_.end(); + } + + // Check whether the map is empty. + bool empty() const + { + return values_.empty(); + } + + // Find an entry in the map. + iterator find(const K& k) + { + if (num_buckets_) + { + size_t bucket = calculate_hash_value(k) % num_buckets_; + iterator it = buckets_[bucket].first; + if (it == values_.end()) + return values_.end(); + iterator end_it = buckets_[bucket].last; + ++end_it; + while (it != end_it) + { + if (it->first == k) + return it; + ++it; + } + } + return values_.end(); + } + + // Find an entry in the map. + const_iterator find(const K& k) const + { + if (num_buckets_) + { + size_t bucket = calculate_hash_value(k) % num_buckets_; + const_iterator it = buckets_[bucket].first; + if (it == values_.end()) + return it; + const_iterator end_it = buckets_[bucket].last; + ++end_it; + while (it != end_it) + { + if (it->first == k) + return it; + ++it; + } + } + return values_.end(); + } + + // Insert a new entry into the map. + std::pair insert(const value_type& v) + { + if (size_ + 1 >= num_buckets_) + rehash(hash_size(size_ + 1)); + size_t bucket = calculate_hash_value(v.first) % num_buckets_; + iterator it = buckets_[bucket].first; + if (it == values_.end()) + { + buckets_[bucket].first = buckets_[bucket].last = + values_insert(values_.end(), v); + ++size_; + return std::pair(buckets_[bucket].last, true); + } + iterator end_it = buckets_[bucket].last; + ++end_it; + while (it != end_it) + { + if (it->first == v.first) + return std::pair(it, false); + ++it; + } + buckets_[bucket].last = values_insert(end_it, v); + ++size_; + return std::pair(buckets_[bucket].last, true); + } + + // Erase an entry from the map. + void erase(iterator it) + { + ASIO_ASSERT(it != values_.end()); + ASIO_ASSERT(num_buckets_ != 0); + + size_t bucket = calculate_hash_value(it->first) % num_buckets_; + bool is_first = (it == buckets_[bucket].first); + bool is_last = (it == buckets_[bucket].last); + if (is_first && is_last) + buckets_[bucket].first = buckets_[bucket].last = values_.end(); + else if (is_first) + ++buckets_[bucket].first; + else if (is_last) + --buckets_[bucket].last; + + values_erase(it); + --size_; + } + + // Erase a key from the map. + void erase(const K& k) + { + iterator it = find(k); + if (it != values_.end()) + erase(it); + } + + // Remove all entries from the map. + void clear() + { + // Clear the values. + values_.clear(); + size_ = 0; + + // Initialise all buckets to empty. + iterator end_it = values_.end(); + for (size_t i = 0; i < num_buckets_; ++i) + buckets_[i].first = buckets_[i].last = end_it; + } + +private: + // Calculate the hash size for the specified number of elements. + static std::size_t hash_size(std::size_t num_elems) + { + static std::size_t sizes[] = + { +#if defined(ASIO_HASH_MAP_BUCKETS) + ASIO_HASH_MAP_BUCKETS +#else // ASIO_HASH_MAP_BUCKETS + 3, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, + 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, + 12582917, 25165843 +#endif // ASIO_HASH_MAP_BUCKETS + }; + const std::size_t nth_size = sizeof(sizes) / sizeof(std::size_t) - 1; + for (std::size_t i = 0; i < nth_size; ++i) + if (num_elems < sizes[i]) + return sizes[i]; + return sizes[nth_size]; + } + + // Re-initialise the hash from the values already contained in the list. + void rehash(std::size_t num_buckets) + { + if (num_buckets == num_buckets_) + return; + ASIO_ASSERT(num_buckets != 0); + + iterator end_iter = values_.end(); + + // Update number of buckets and initialise all buckets to empty. + bucket_type* tmp = new bucket_type[num_buckets]; + delete[] buckets_; + buckets_ = tmp; + num_buckets_ = num_buckets; + for (std::size_t i = 0; i < num_buckets_; ++i) + buckets_[i].first = buckets_[i].last = end_iter; + + // Put all values back into the hash. + iterator iter = values_.begin(); + while (iter != end_iter) + { + std::size_t bucket = calculate_hash_value(iter->first) % num_buckets_; + if (buckets_[bucket].last == end_iter) + { + buckets_[bucket].first = buckets_[bucket].last = iter++; + } + else if (++buckets_[bucket].last == iter) + { + ++iter; + } + else + { + values_.splice(buckets_[bucket].last, values_, iter++); + --buckets_[bucket].last; + } + } + } + + // Insert an element into the values list by splicing from the spares list, + // if a spare is available, and otherwise by inserting a new element. + iterator values_insert(iterator it, const value_type& v) + { + if (spares_.empty()) + { + return values_.insert(it, v); + } + else + { + spares_.front() = v; + values_.splice(it, spares_, spares_.begin()); + return --it; + } + } + + // Erase an element from the values list by splicing it to the spares list. + void values_erase(iterator it) + { + *it = value_type(); + spares_.splice(spares_.begin(), values_, it); + } + + // The number of elements in the hash. + std::size_t size_; + + // The list of all values in the hash map. + std::list values_; + + // The list of spare nodes waiting to be recycled. Assumes that POD types only + // are stored in the hash map. + std::list spares_; + + // The type for a bucket in the hash table. + struct bucket_type + { + iterator first; + iterator last; + }; + + // The buckets in the hash. + bucket_type* buckets_; + + // The number of buckets in the hash. + std::size_t num_buckets_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_HASH_MAP_HPP diff --git a/tools/sdk/include/asio/asio/detail/impl/dev_poll_reactor.hpp b/tools/sdk/include/asio/asio/detail/impl/dev_poll_reactor.hpp new file mode 100644 index 00000000..4cd8aafe --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/impl/dev_poll_reactor.hpp @@ -0,0 +1,91 @@ +// +// detail/impl/dev_poll_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_HPP +#define ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_DEV_POLL) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +void dev_poll_reactor::add_timer_queue(timer_queue& queue) +{ + do_add_timer_queue(queue); +} + +template +void dev_poll_reactor::remove_timer_queue(timer_queue& queue) +{ + do_remove_timer_queue(queue); +} + +template +void dev_poll_reactor::schedule_timer(timer_queue& queue, + const typename Time_Traits::time_type& time, + typename timer_queue::per_timer_data& timer, wait_op* op) +{ + asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + { + scheduler_.post_immediate_completion(op, false); + return; + } + + bool earliest = queue.enqueue_timer(time, timer, op); + scheduler_.work_started(); + if (earliest) + interrupter_.interrupt(); +} + +template +std::size_t dev_poll_reactor::cancel_timer(timer_queue& queue, + typename timer_queue::per_timer_data& timer, + std::size_t max_cancelled) +{ + asio::detail::mutex::scoped_lock lock(mutex_); + op_queue ops; + std::size_t n = queue.cancel_timer(timer, ops, max_cancelled); + lock.unlock(); + scheduler_.post_deferred_completions(ops); + return n; +} + +template +void dev_poll_reactor::move_timer(timer_queue& queue, + typename timer_queue::per_timer_data& target, + typename timer_queue::per_timer_data& source) +{ + asio::detail::mutex::scoped_lock lock(mutex_); + op_queue ops; + queue.cancel_timer(target, ops); + queue.move_timer(target, source); + lock.unlock(); + scheduler_.post_deferred_completions(ops); +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_DEV_POLL) + +#endif // ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_HPP diff --git a/tools/sdk/include/asio/asio/detail/impl/epoll_reactor.hpp b/tools/sdk/include/asio/asio/detail/impl/epoll_reactor.hpp new file mode 100644 index 00000000..f990059d --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/impl/epoll_reactor.hpp @@ -0,0 +1,89 @@ +// +// detail/impl/epoll_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_IMPL_EPOLL_REACTOR_HPP +#define ASIO_DETAIL_IMPL_EPOLL_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if defined(ASIO_HAS_EPOLL) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +void epoll_reactor::add_timer_queue(timer_queue& queue) +{ + do_add_timer_queue(queue); +} + +template +void epoll_reactor::remove_timer_queue(timer_queue& queue) +{ + do_remove_timer_queue(queue); +} + +template +void epoll_reactor::schedule_timer(timer_queue& queue, + const typename Time_Traits::time_type& time, + typename timer_queue::per_timer_data& timer, wait_op* op) +{ + mutex::scoped_lock lock(mutex_); + + if (shutdown_) + { + scheduler_.post_immediate_completion(op, false); + return; + } + + bool earliest = queue.enqueue_timer(time, timer, op); + scheduler_.work_started(); + if (earliest) + update_timeout(); +} + +template +std::size_t epoll_reactor::cancel_timer(timer_queue& queue, + typename timer_queue::per_timer_data& timer, + std::size_t max_cancelled) +{ + mutex::scoped_lock lock(mutex_); + op_queue ops; + std::size_t n = queue.cancel_timer(timer, ops, max_cancelled); + lock.unlock(); + scheduler_.post_deferred_completions(ops); + return n; +} + +template +void epoll_reactor::move_timer(timer_queue& queue, + typename timer_queue::per_timer_data& target, + typename timer_queue::per_timer_data& source) +{ + mutex::scoped_lock lock(mutex_); + op_queue ops; + queue.cancel_timer(target, ops); + queue.move_timer(target, source); + lock.unlock(); + scheduler_.post_deferred_completions(ops); +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_EPOLL) + +#endif // ASIO_DETAIL_IMPL_EPOLL_REACTOR_HPP diff --git a/tools/sdk/include/asio/asio/detail/impl/kqueue_reactor.hpp b/tools/sdk/include/asio/asio/detail/impl/kqueue_reactor.hpp new file mode 100644 index 00000000..136d1678 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/impl/kqueue_reactor.hpp @@ -0,0 +1,93 @@ +// +// detail/impl/kqueue_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) +// +// 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 ASIO_DETAIL_IMPL_KQUEUE_REACTOR_HPP +#define ASIO_DETAIL_IMPL_KQUEUE_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_KQUEUE) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +void kqueue_reactor::add_timer_queue(timer_queue& queue) +{ + do_add_timer_queue(queue); +} + +// Remove a timer queue from the reactor. +template +void kqueue_reactor::remove_timer_queue(timer_queue& queue) +{ + do_remove_timer_queue(queue); +} + +template +void kqueue_reactor::schedule_timer(timer_queue& queue, + const typename Time_Traits::time_type& time, + typename timer_queue::per_timer_data& timer, wait_op* op) +{ + mutex::scoped_lock lock(mutex_); + + if (shutdown_) + { + scheduler_.post_immediate_completion(op, false); + return; + } + + bool earliest = queue.enqueue_timer(time, timer, op); + scheduler_.work_started(); + if (earliest) + interrupt(); +} + +template +std::size_t kqueue_reactor::cancel_timer(timer_queue& queue, + typename timer_queue::per_timer_data& timer, + std::size_t max_cancelled) +{ + mutex::scoped_lock lock(mutex_); + op_queue ops; + std::size_t n = queue.cancel_timer(timer, ops, max_cancelled); + lock.unlock(); + scheduler_.post_deferred_completions(ops); + return n; +} + +template +void kqueue_reactor::move_timer(timer_queue& queue, + typename timer_queue::per_timer_data& target, + typename timer_queue::per_timer_data& source) +{ + mutex::scoped_lock lock(mutex_); + op_queue ops; + queue.cancel_timer(target, ops); + queue.move_timer(target, source); + lock.unlock(); + scheduler_.post_deferred_completions(ops); +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_KQUEUE) + +#endif // ASIO_DETAIL_IMPL_KQUEUE_REACTOR_HPP diff --git a/tools/sdk/include/asio/asio/detail/impl/select_reactor.hpp b/tools/sdk/include/asio/asio/detail/impl/select_reactor.hpp new file mode 100644 index 00000000..04a04d49 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/impl/select_reactor.hpp @@ -0,0 +1,100 @@ +// +// detail/impl/select_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_IMPL_SELECT_REACTOR_HPP +#define ASIO_DETAIL_IMPL_SELECT_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) \ + || (!defined(ASIO_HAS_DEV_POLL) \ + && !defined(ASIO_HAS_EPOLL) \ + && !defined(ASIO_HAS_KQUEUE) \ + && !defined(ASIO_WINDOWS_RUNTIME)) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +void select_reactor::add_timer_queue(timer_queue& queue) +{ + do_add_timer_queue(queue); +} + +// Remove a timer queue from the reactor. +template +void select_reactor::remove_timer_queue(timer_queue& queue) +{ + do_remove_timer_queue(queue); +} + +template +void select_reactor::schedule_timer(timer_queue& queue, + const typename Time_Traits::time_type& time, + typename timer_queue::per_timer_data& timer, wait_op* op) +{ + asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + { + scheduler_.post_immediate_completion(op, false); + return; + } + + bool earliest = queue.enqueue_timer(time, timer, op); + scheduler_.work_started(); + if (earliest) + interrupter_.interrupt(); +} + +template +std::size_t select_reactor::cancel_timer(timer_queue& queue, + typename timer_queue::per_timer_data& timer, + std::size_t max_cancelled) +{ + asio::detail::mutex::scoped_lock lock(mutex_); + op_queue ops; + std::size_t n = queue.cancel_timer(timer, ops, max_cancelled); + lock.unlock(); + scheduler_.post_deferred_completions(ops); + return n; +} + +template +void select_reactor::move_timer(timer_queue& queue, + typename timer_queue::per_timer_data& target, + typename timer_queue::per_timer_data& source) +{ + asio::detail::mutex::scoped_lock lock(mutex_); + op_queue ops; + queue.cancel_timer(target, ops); + queue.move_timer(target, source); + lock.unlock(); + scheduler_.post_deferred_completions(ops); +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + // || (!defined(ASIO_HAS_DEV_POLL) + // && !defined(ASIO_HAS_EPOLL) + // && !defined(ASIO_HAS_KQUEUE) + // && !defined(ASIO_WINDOWS_RUNTIME)) + +#endif // ASIO_DETAIL_IMPL_SELECT_REACTOR_HPP diff --git a/tools/sdk/include/asio/asio/detail/impl/service_registry.hpp b/tools/sdk/include/asio/asio/detail/impl/service_registry.hpp new file mode 100644 index 00000000..d4db5899 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/impl/service_registry.hpp @@ -0,0 +1,94 @@ +// +// detail/impl/service_registry.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_IMPL_SERVICE_REGISTRY_HPP +#define ASIO_DETAIL_IMPL_SERVICE_REGISTRY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +Service& service_registry::use_service() +{ + execution_context::service::key key; + init_key(key, 0); + factory_type factory = &service_registry::create; + return *static_cast(do_use_service(key, factory, &owner_)); +} + +template +Service& service_registry::use_service(io_context& owner) +{ + execution_context::service::key key; + init_key(key, 0); + factory_type factory = &service_registry::create; + return *static_cast(do_use_service(key, factory, &owner)); +} + +template +void service_registry::add_service(Service* new_service) +{ + execution_context::service::key key; + init_key(key, 0); + return do_add_service(key, new_service); +} + +template +bool service_registry::has_service() const +{ + execution_context::service::key key; + init_key(key, 0); + return do_has_service(key); +} + +template +inline void service_registry::init_key( + execution_context::service::key& key, ...) +{ + init_key_from_id(key, Service::id); +} + +#if !defined(ASIO_NO_TYPEID) +template +void service_registry::init_key(execution_context::service::key& key, + typename enable_if< + is_base_of::value>::type*) +{ + key.type_info_ = &typeid(typeid_wrapper); + key.id_ = 0; +} + +template +void service_registry::init_key_from_id(execution_context::service::key& key, + const service_id& /*id*/) +{ + key.type_info_ = &typeid(typeid_wrapper); + key.id_ = 0; +} +#endif // !defined(ASIO_NO_TYPEID) + +template +execution_context::service* service_registry::create(void* owner) +{ + return new Service(*static_cast(owner)); +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_IMPL_SERVICE_REGISTRY_HPP diff --git a/tools/sdk/include/asio/asio/detail/impl/strand_executor_service.hpp b/tools/sdk/include/asio/asio/detail/impl/strand_executor_service.hpp new file mode 100644 index 00000000..0e18ca05 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/impl/strand_executor_service.hpp @@ -0,0 +1,179 @@ +// +// detail/impl/strand_executor_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_IMPL_STRAND_EXECUTOR_SERVICE_HPP +#define ASIO_DETAIL_IMPL_STRAND_EXECUTOR_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/call_stack.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/recycling_allocator.hpp" +#include "asio/executor_work_guard.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class strand_executor_service::invoker +{ +public: + invoker(const implementation_type& impl, Executor& ex) + : impl_(impl), + work_(ex) + { + } + + invoker(const invoker& other) + : impl_(other.impl_), + work_(other.work_) + { + } + +#if defined(ASIO_HAS_MOVE) + invoker(invoker&& other) + : impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_)), + work_(ASIO_MOVE_CAST(executor_work_guard)(other.work_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + struct on_invoker_exit + { + invoker* this_; + + ~on_invoker_exit() + { + this_->impl_->mutex_->lock(); + this_->impl_->ready_queue_.push(this_->impl_->waiting_queue_); + bool more_handlers = this_->impl_->locked_ = + !this_->impl_->ready_queue_.empty(); + this_->impl_->mutex_->unlock(); + + if (more_handlers) + { + Executor ex(this_->work_.get_executor()); + recycling_allocator allocator; + ex.post(ASIO_MOVE_CAST(invoker)(*this_), allocator); + } + } + }; + + void operator()() + { + // Indicate that this strand is executing on the current thread. + call_stack::context ctx(impl_.get()); + + // Ensure the next handler, if any, is scheduled on block exit. + on_invoker_exit on_exit = { this }; + (void)on_exit; + + // Run all ready handlers. No lock is required since the ready queue is + // accessed only within the strand. + asio::error_code ec; + while (scheduler_operation* o = impl_->ready_queue_.front()) + { + impl_->ready_queue_.pop(); + o->complete(impl_.get(), ec, 0); + } + } + +private: + implementation_type impl_; + executor_work_guard work_; +}; + +template +void strand_executor_service::dispatch(const implementation_type& impl, + Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a) +{ + typedef typename decay::type function_type; + + // If we are already in the strand then the function can run immediately. + if (call_stack::contains(impl.get())) + { + // Make a local, non-const copy of the function. + function_type tmp(ASIO_MOVE_CAST(Function)(function)); + + fenced_block b(fenced_block::full); + asio_handler_invoke_helpers::invoke(tmp, tmp); + return; + } + + // Allocate and construct an operation to wrap the function. + typedef executor_op op; + typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; + p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(function), a); + + ASIO_HANDLER_CREATION((impl->service_->context(), *p.p, + "strand_executor", impl.get(), 0, "dispatch")); + + // Add the function to the strand and schedule the strand if required. + bool first = enqueue(impl, p.p); + p.v = p.p = 0; + if (first) + ex.dispatch(invoker(impl, ex), a); +} + +// Request invocation of the given function and return immediately. +template +void strand_executor_service::post(const implementation_type& impl, + Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a) +{ + typedef typename decay::type function_type; + + // Allocate and construct an operation to wrap the function. + typedef executor_op op; + typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; + p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(function), a); + + ASIO_HANDLER_CREATION((impl->service_->context(), *p.p, + "strand_executor", impl.get(), 0, "post")); + + // Add the function to the strand and schedule the strand if required. + bool first = enqueue(impl, p.p); + p.v = p.p = 0; + if (first) + ex.post(invoker(impl, ex), a); +} + +// Request invocation of the given function and return immediately. +template +void strand_executor_service::defer(const implementation_type& impl, + Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a) +{ + typedef typename decay::type function_type; + + // Allocate and construct an operation to wrap the function. + typedef executor_op op; + typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; + p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(function), a); + + ASIO_HANDLER_CREATION((impl->service_->context(), *p.p, + "strand_executor", impl.get(), 0, "defer")); + + // Add the function to the strand and schedule the strand if required. + bool first = enqueue(impl, p.p); + p.v = p.p = 0; + if (first) + ex.defer(invoker(impl, ex), a); +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_IMPL_STRAND_EXECUTOR_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/impl/strand_service.hpp b/tools/sdk/include/asio/asio/detail/impl/strand_service.hpp new file mode 100644 index 00000000..da5b7169 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/impl/strand_service.hpp @@ -0,0 +1,118 @@ +// +// detail/impl/strand_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP +#define ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/call_stack.hpp" +#include "asio/detail/completion_handler.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +inline strand_service::strand_impl::strand_impl() + : operation(&strand_service::do_complete), + locked_(false) +{ +} + +struct strand_service::on_dispatch_exit +{ + io_context_impl* io_context_; + strand_impl* impl_; + + ~on_dispatch_exit() + { + impl_->mutex_.lock(); + impl_->ready_queue_.push(impl_->waiting_queue_); + bool more_handlers = impl_->locked_ = !impl_->ready_queue_.empty(); + impl_->mutex_.unlock(); + + if (more_handlers) + io_context_->post_immediate_completion(impl_, false); + } +}; + +template +void strand_service::dispatch(strand_service::implementation_type& impl, + Handler& handler) +{ + // If we are already in the strand then the handler can run immediately. + if (call_stack::contains(impl)) + { + fenced_block b(fenced_block::full); + asio_handler_invoke_helpers::invoke(handler, handler); + return; + } + + // Allocate and construct an operation to wrap the handler. + typedef completion_handler op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + ASIO_HANDLER_CREATION((this->context(), + *p.p, "strand", impl, 0, "dispatch")); + + bool dispatch_immediately = do_dispatch(impl, p.p); + operation* o = p.p; + p.v = p.p = 0; + + if (dispatch_immediately) + { + // Indicate that this strand is executing on the current thread. + call_stack::context ctx(impl); + + // Ensure the next handler, if any, is scheduled on block exit. + on_dispatch_exit on_exit = { &io_context_, impl }; + (void)on_exit; + + completion_handler::do_complete( + &io_context_, o, asio::error_code(), 0); + } +} + +// Request the io_context to invoke the given handler and return immediately. +template +void strand_service::post(strand_service::implementation_type& impl, + Handler& handler) +{ + bool is_continuation = + asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef completion_handler op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + ASIO_HANDLER_CREATION((this->context(), + *p.p, "strand", impl, 0, "post")); + + do_post(impl, p.p, is_continuation); + p.v = p.p = 0; +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/impl/win_iocp_io_context.hpp b/tools/sdk/include/asio/asio/detail/impl/win_iocp_io_context.hpp new file mode 100644 index 00000000..44887d7c --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/impl/win_iocp_io_context.hpp @@ -0,0 +1,103 @@ +// +// detail/impl/win_iocp_io_context.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_IMPL_WIN_IOCP_IO_CONTEXT_HPP +#define ASIO_DETAIL_IMPL_WIN_IOCP_IO_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/completion_handler.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +void win_iocp_io_context::add_timer_queue( + timer_queue& queue) +{ + do_add_timer_queue(queue); +} + +template +void win_iocp_io_context::remove_timer_queue( + timer_queue& queue) +{ + do_remove_timer_queue(queue); +} + +template +void win_iocp_io_context::schedule_timer(timer_queue& queue, + const typename Time_Traits::time_type& time, + typename timer_queue::per_timer_data& timer, wait_op* op) +{ + // If the service has been shut down we silently discard the timer. + if (::InterlockedExchangeAdd(&shutdown_, 0) != 0) + { + post_immediate_completion(op, false); + return; + } + + mutex::scoped_lock lock(dispatch_mutex_); + + bool earliest = queue.enqueue_timer(time, timer, op); + work_started(); + if (earliest) + update_timeout(); +} + +template +std::size_t win_iocp_io_context::cancel_timer(timer_queue& queue, + typename timer_queue::per_timer_data& timer, + std::size_t max_cancelled) +{ + // If the service has been shut down we silently ignore the cancellation. + if (::InterlockedExchangeAdd(&shutdown_, 0) != 0) + return 0; + + mutex::scoped_lock lock(dispatch_mutex_); + op_queue ops; + std::size_t n = queue.cancel_timer(timer, ops, max_cancelled); + post_deferred_completions(ops); + return n; +} + +template +void win_iocp_io_context::move_timer(timer_queue& queue, + typename timer_queue::per_timer_data& to, + typename timer_queue::per_timer_data& from) +{ + asio::detail::mutex::scoped_lock lock(dispatch_mutex_); + op_queue ops; + queue.cancel_timer(to, ops); + queue.move_timer(to, from); + lock.unlock(); + post_deferred_completions(ops); +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_IMPL_WIN_IOCP_IO_CONTEXT_HPP diff --git a/tools/sdk/include/asio/asio/detail/impl/winrt_timer_scheduler.hpp b/tools/sdk/include/asio/asio/detail/impl/winrt_timer_scheduler.hpp new file mode 100644 index 00000000..856378fe --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/impl/winrt_timer_scheduler.hpp @@ -0,0 +1,92 @@ +// +// detail/impl/winrt_timer_scheduler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_HPP +#define ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +void winrt_timer_scheduler::add_timer_queue(timer_queue& queue) +{ + do_add_timer_queue(queue); +} + +// Remove a timer queue from the reactor. +template +void winrt_timer_scheduler::remove_timer_queue(timer_queue& queue) +{ + do_remove_timer_queue(queue); +} + +template +void winrt_timer_scheduler::schedule_timer(timer_queue& queue, + const typename Time_Traits::time_type& time, + typename timer_queue::per_timer_data& timer, wait_op* op) +{ + asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + { + io_context_.post_immediate_completion(op, false); + return; + } + + bool earliest = queue.enqueue_timer(time, timer, op); + io_context_.work_started(); + if (earliest) + event_.signal(lock); +} + +template +std::size_t winrt_timer_scheduler::cancel_timer(timer_queue& queue, + typename timer_queue::per_timer_data& timer, + std::size_t max_cancelled) +{ + asio::detail::mutex::scoped_lock lock(mutex_); + op_queue ops; + std::size_t n = queue.cancel_timer(timer, ops, max_cancelled); + lock.unlock(); + io_context_.post_deferred_completions(ops); + return n; +} + +template +void winrt_timer_scheduler::move_timer(timer_queue& queue, + typename timer_queue::per_timer_data& to, + typename timer_queue::per_timer_data& from) +{ + asio::detail::mutex::scoped_lock lock(mutex_); + op_queue ops; + queue.cancel_timer(to, ops); + queue.move_timer(to, from); + lock.unlock(); + scheduler_.post_deferred_completions(ops); +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_HPP diff --git a/tools/sdk/include/asio/asio/detail/io_control.hpp b/tools/sdk/include/asio/asio/detail/io_control.hpp new file mode 100644 index 00000000..12f35e09 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/io_control.hpp @@ -0,0 +1,84 @@ +// +// detail/io_control.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_IO_CONTROL_HPP +#define ASIO_DETAIL_IO_CONTROL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { +namespace io_control { + +// I/O control command for getting number of bytes available. +class bytes_readable +{ +public: + // Default constructor. + bytes_readable() + : value_(0) + { + } + + // Construct with a specific command value. + bytes_readable(std::size_t value) + : value_(static_cast(value)) + { + } + + // Get the name of the IO control command. + int name() const + { + return static_cast(ASIO_OS_DEF(FIONREAD)); + } + + // Set the value of the I/O control command. + void set(std::size_t value) + { + value_ = static_cast(value); + } + + // Get the current value of the I/O control command. + std::size_t get() const + { + return static_cast(value_); + } + + // Get the address of the command data. + detail::ioctl_arg_type* data() + { + return &value_; + } + + // Get the address of the command data. + const detail::ioctl_arg_type* data() const + { + return &value_; + } + +private: + detail::ioctl_arg_type value_; +}; + +} // namespace io_control +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_IO_CONTROL_HPP diff --git a/tools/sdk/include/asio/asio/detail/is_buffer_sequence.hpp b/tools/sdk/include/asio/asio/detail/is_buffer_sequence.hpp new file mode 100644 index 00000000..42ad0ebe --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/is_buffer_sequence.hpp @@ -0,0 +1,239 @@ +// +// detail/is_buffer_sequence.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_IS_BUFFER_SEQUENCE_HPP +#define ASIO_DETAIL_IS_BUFFER_SEQUENCE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/type_traits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +class mutable_buffer; +class const_buffer; + +namespace detail { + +struct buffer_sequence_memfns_base +{ + void begin(); + void end(); + void size(); + void max_size(); + void capacity(); + void data(); + void prepare(); + void commit(); + void consume(); +}; + +template +struct buffer_sequence_memfns_derived + : T, buffer_sequence_memfns_base +{ +}; + +template +struct buffer_sequence_memfns_check +{ +}; + +template +char (&begin_memfn_helper(...))[2]; + +template +char begin_memfn_helper( + buffer_sequence_memfns_check< + void (buffer_sequence_memfns_base::*)(), + &buffer_sequence_memfns_derived::begin>*); + +template +char (&end_memfn_helper(...))[2]; + +template +char end_memfn_helper( + buffer_sequence_memfns_check< + void (buffer_sequence_memfns_base::*)(), + &buffer_sequence_memfns_derived::end>*); + +template +char (&size_memfn_helper(...))[2]; + +template +char size_memfn_helper( + buffer_sequence_memfns_check< + void (buffer_sequence_memfns_base::*)(), + &buffer_sequence_memfns_derived::size>*); + +template +char (&max_size_memfn_helper(...))[2]; + +template +char max_size_memfn_helper( + buffer_sequence_memfns_check< + void (buffer_sequence_memfns_base::*)(), + &buffer_sequence_memfns_derived::max_size>*); + +template +char (&capacity_memfn_helper(...))[2]; + +template +char capacity_memfn_helper( + buffer_sequence_memfns_check< + void (buffer_sequence_memfns_base::*)(), + &buffer_sequence_memfns_derived::capacity>*); + +template +char (&data_memfn_helper(...))[2]; + +template +char data_memfn_helper( + buffer_sequence_memfns_check< + void (buffer_sequence_memfns_base::*)(), + &buffer_sequence_memfns_derived::data>*); + +template +char (&prepare_memfn_helper(...))[2]; + +template +char prepare_memfn_helper( + buffer_sequence_memfns_check< + void (buffer_sequence_memfns_base::*)(), + &buffer_sequence_memfns_derived::prepare>*); + +template +char (&commit_memfn_helper(...))[2]; + +template +char commit_memfn_helper( + buffer_sequence_memfns_check< + void (buffer_sequence_memfns_base::*)(), + &buffer_sequence_memfns_derived::commit>*); + +template +char (&consume_memfn_helper(...))[2]; + +template +char consume_memfn_helper( + buffer_sequence_memfns_check< + void (buffer_sequence_memfns_base::*)(), + &buffer_sequence_memfns_derived::consume>*); + +template +char (&buffer_element_type_helper(...))[2]; + +#if defined(ASIO_HAS_DECL_TYPE) + +template +char buffer_element_type_helper(T* t, + typename enable_if::value>::type*); + +#else // defined(ASIO_HAS_DECL_TYPE) + +template +char buffer_element_type_helper( + typename T::const_iterator*, + typename enable_if::value>::type*); + +#endif // defined(ASIO_HAS_DECL_TYPE) + +template +char (&const_buffers_type_typedef_helper(...))[2]; + +template +char const_buffers_type_typedef_helper( + typename T::const_buffers_type*); + +template +char (&mutable_buffers_type_typedef_helper(...))[2]; + +template +char mutable_buffers_type_typedef_helper( + typename T::mutable_buffers_type*); + +template +struct is_buffer_sequence_class + : integral_constant(0)) != 1 && + sizeof(end_memfn_helper(0)) != 1 && + sizeof(buffer_element_type_helper(0, 0)) == 1> +{ +}; + +template +struct is_buffer_sequence + : conditional::value, + is_buffer_sequence_class, + false_type>::type +{ +}; + +template <> +struct is_buffer_sequence + : true_type +{ +}; + +template <> +struct is_buffer_sequence + : true_type +{ +}; + +template <> +struct is_buffer_sequence + : true_type +{ +}; + +template <> +struct is_buffer_sequence + : false_type +{ +}; + +template +struct is_dynamic_buffer_class + : integral_constant(0)) != 1 && + sizeof(max_size_memfn_helper(0)) != 1 && + sizeof(capacity_memfn_helper(0)) != 1 && + sizeof(data_memfn_helper(0)) != 1 && + sizeof(consume_memfn_helper(0)) != 1 && + sizeof(prepare_memfn_helper(0)) != 1 && + sizeof(commit_memfn_helper(0)) != 1 && + sizeof(const_buffers_type_typedef_helper(0)) == 1 && + sizeof(mutable_buffers_type_typedef_helper(0)) == 1> +{ +}; + +template +struct is_dynamic_buffer + : conditional::value, + is_dynamic_buffer_class, + false_type>::type +{ +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_IS_BUFFER_SEQUENCE_HPP diff --git a/tools/sdk/include/asio/asio/detail/is_executor.hpp b/tools/sdk/include/asio/asio/detail/is_executor.hpp new file mode 100644 index 00000000..4584dd04 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/is_executor.hpp @@ -0,0 +1,126 @@ +// +// detail/is_executor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_IS_EXECUTOR_HPP +#define ASIO_DETAIL_IS_EXECUTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/type_traits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +struct executor_memfns_base +{ + void context(); + void on_work_started(); + void on_work_finished(); + void dispatch(); + void post(); + void defer(); +}; + +template +struct executor_memfns_derived + : T, executor_memfns_base +{ +}; + +template +struct executor_memfns_check +{ +}; + +template +char (&context_memfn_helper(...))[2]; + +template +char context_memfn_helper( + executor_memfns_check< + void (executor_memfns_base::*)(), + &executor_memfns_derived::context>*); + +template +char (&on_work_started_memfn_helper(...))[2]; + +template +char on_work_started_memfn_helper( + executor_memfns_check< + void (executor_memfns_base::*)(), + &executor_memfns_derived::on_work_started>*); + +template +char (&on_work_finished_memfn_helper(...))[2]; + +template +char on_work_finished_memfn_helper( + executor_memfns_check< + void (executor_memfns_base::*)(), + &executor_memfns_derived::on_work_finished>*); + +template +char (&dispatch_memfn_helper(...))[2]; + +template +char dispatch_memfn_helper( + executor_memfns_check< + void (executor_memfns_base::*)(), + &executor_memfns_derived::dispatch>*); + +template +char (&post_memfn_helper(...))[2]; + +template +char post_memfn_helper( + executor_memfns_check< + void (executor_memfns_base::*)(), + &executor_memfns_derived::post>*); + +template +char (&defer_memfn_helper(...))[2]; + +template +char defer_memfn_helper( + executor_memfns_check< + void (executor_memfns_base::*)(), + &executor_memfns_derived::defer>*); + +template +struct is_executor_class + : integral_constant(0)) != 1 && + sizeof(on_work_started_memfn_helper(0)) != 1 && + sizeof(on_work_finished_memfn_helper(0)) != 1 && + sizeof(dispatch_memfn_helper(0)) != 1 && + sizeof(post_memfn_helper(0)) != 1 && + sizeof(defer_memfn_helper(0)) != 1> +{ +}; + +template +struct is_executor + : conditional::value, + is_executor_class, + false_type>::type +{ +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_IS_EXECUTOR_HPP diff --git a/tools/sdk/include/asio/asio/detail/keyword_tss_ptr.hpp b/tools/sdk/include/asio/asio/detail/keyword_tss_ptr.hpp new file mode 100644 index 00000000..2ae651ab --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/keyword_tss_ptr.hpp @@ -0,0 +1,70 @@ +// +// detail/keyword_tss_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_KEYWORD_TSS_PTR_HPP +#define ASIO_DETAIL_KEYWORD_TSS_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_THREAD_KEYWORD_EXTENSION) + +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class keyword_tss_ptr + : private noncopyable +{ +public: + // Constructor. + keyword_tss_ptr() + { + } + + // Destructor. + ~keyword_tss_ptr() + { + } + + // Get the value. + operator T*() const + { + return value_; + } + + // Set the value. + void operator=(T* value) + { + value_ = value; + } + +private: + static ASIO_THREAD_KEYWORD T* value_; +}; + +template +ASIO_THREAD_KEYWORD T* keyword_tss_ptr::value_; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_THREAD_KEYWORD_EXTENSION) + +#endif // ASIO_DETAIL_KEYWORD_TSS_PTR_HPP diff --git a/tools/sdk/include/asio/asio/detail/kqueue_reactor.hpp b/tools/sdk/include/asio/asio/detail/kqueue_reactor.hpp new file mode 100644 index 00000000..43cb9f93 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/kqueue_reactor.hpp @@ -0,0 +1,242 @@ +// +// detail/kqueue_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) +// +// 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 ASIO_DETAIL_KQUEUE_REACTOR_HPP +#define ASIO_DETAIL_KQUEUE_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_KQUEUE) + +#include +#include +#include +#include +#include "asio/detail/limits.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/object_pool.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/select_interrupter.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/timer_queue_base.hpp" +#include "asio/detail/timer_queue_set.hpp" +#include "asio/detail/wait_op.hpp" +#include "asio/error.hpp" +#include "asio/execution_context.hpp" + +// Older versions of Mac OS X may not define EV_OOBAND. +#if !defined(EV_OOBAND) +# define EV_OOBAND EV_FLAG1 +#endif // !defined(EV_OOBAND) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class scheduler; + +class kqueue_reactor + : public execution_context_service_base +{ +private: + // The mutex type used by this reactor. + typedef conditionally_enabled_mutex mutex; + +public: + enum op_types { read_op = 0, write_op = 1, + connect_op = 1, except_op = 2, max_ops = 3 }; + + // Per-descriptor queues. + struct descriptor_state + { + descriptor_state(bool locking) : mutex_(locking) {} + + friend class kqueue_reactor; + friend class object_pool_access; + + descriptor_state* next_; + descriptor_state* prev_; + + mutex mutex_; + int descriptor_; + int num_kevents_; // 1 == read only, 2 == read and write + op_queue op_queue_[max_ops]; + bool shutdown_; + }; + + // Per-descriptor data. + typedef descriptor_state* per_descriptor_data; + + // Constructor. + ASIO_DECL kqueue_reactor(asio::execution_context& ctx); + + // Destructor. + ASIO_DECL ~kqueue_reactor(); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Recreate internal descriptors following a fork. + ASIO_DECL void notify_fork( + asio::execution_context::fork_event fork_ev); + + // Initialise the task. + ASIO_DECL void init_task(); + + // Register a socket with the reactor. Returns 0 on success, system error + // code on failure. + ASIO_DECL int register_descriptor(socket_type descriptor, + per_descriptor_data& descriptor_data); + + // Register a descriptor with an associated single operation. Returns 0 on + // success, system error code on failure. + ASIO_DECL int register_internal_descriptor( + int op_type, socket_type descriptor, + per_descriptor_data& descriptor_data, reactor_op* op); + + // Move descriptor registration from one descriptor_data object to another. + ASIO_DECL void move_descriptor(socket_type descriptor, + per_descriptor_data& target_descriptor_data, + per_descriptor_data& source_descriptor_data); + + // Post a reactor operation for immediate completion. + void post_immediate_completion(reactor_op* op, bool is_continuation) + { + scheduler_.post_immediate_completion(op, is_continuation); + } + + // Start a new operation. The reactor operation will be performed when the + // given descriptor is flagged as ready, or an error has occurred. + ASIO_DECL void start_op(int op_type, socket_type descriptor, + per_descriptor_data& descriptor_data, reactor_op* op, + bool is_continuation, bool allow_speculative); + + // Cancel all operations associated with the given descriptor. The + // handlers associated with the descriptor will be invoked with the + // operation_aborted error. + ASIO_DECL void cancel_ops(socket_type descriptor, + per_descriptor_data& descriptor_data); + + // Cancel any operations that are running against the descriptor and remove + // its registration from the reactor. The reactor resources associated with + // the descriptor must be released by calling cleanup_descriptor_data. + ASIO_DECL void deregister_descriptor(socket_type descriptor, + per_descriptor_data& descriptor_data, bool closing); + + // Remove the descriptor's registration from the reactor. The reactor + // resources associated with the descriptor must be released by calling + // cleanup_descriptor_data. + ASIO_DECL void deregister_internal_descriptor( + socket_type descriptor, per_descriptor_data& descriptor_data); + + // Perform any post-deregistration cleanup tasks associated with the + // descriptor data. + ASIO_DECL void cleanup_descriptor_data( + per_descriptor_data& descriptor_data); + + // Add a new timer queue to the reactor. + template + void add_timer_queue(timer_queue& queue); + + // Remove a timer queue from the reactor. + template + void remove_timer_queue(timer_queue& queue); + + // Schedule a new operation in the given timer queue to expire at the + // specified absolute time. + template + void schedule_timer(timer_queue& queue, + const typename Time_Traits::time_type& time, + typename timer_queue::per_timer_data& timer, wait_op* op); + + // Cancel the timer operations associated with the given token. Returns the + // number of operations that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& queue, + typename timer_queue::per_timer_data& timer, + std::size_t max_cancelled = (std::numeric_limits::max)()); + + // Move the timer operations associated with the given timer. + template + void move_timer(timer_queue& queue, + typename timer_queue::per_timer_data& target, + typename timer_queue::per_timer_data& source); + + // Run the kqueue loop. + ASIO_DECL void run(long usec, op_queue& ops); + + // Interrupt the kqueue loop. + ASIO_DECL void interrupt(); + +private: + // Create the kqueue file descriptor. Throws an exception if the descriptor + // cannot be created. + ASIO_DECL static int do_kqueue_create(); + + // Allocate a new descriptor state object. + ASIO_DECL descriptor_state* allocate_descriptor_state(); + + // Free an existing descriptor state object. + ASIO_DECL void free_descriptor_state(descriptor_state* s); + + // Helper function to add a new timer queue. + ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); + + // Helper function to remove a timer queue. + ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); + + // Get the timeout value for the kevent call. + ASIO_DECL timespec* get_timeout(long usec, timespec& ts); + + // The scheduler used to post completions. + scheduler& scheduler_; + + // Mutex to protect access to internal data. + mutex mutex_; + + // The kqueue file descriptor. + int kqueue_fd_; + + // The interrupter is used to break a blocking kevent call. + select_interrupter interrupter_; + + // The timer queues. + timer_queue_set timer_queues_; + + // Whether the service has been shut down. + bool shutdown_; + + // Mutex to protect access to the registered descriptors. + mutex registered_descriptors_mutex_; + + // Keep track of all registered descriptors. + object_pool registered_descriptors_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/impl/kqueue_reactor.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/kqueue_reactor.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_KQUEUE) + +#endif // ASIO_DETAIL_KQUEUE_REACTOR_HPP diff --git a/tools/sdk/include/asio/asio/detail/limits.hpp b/tools/sdk/include/asio/asio/detail/limits.hpp new file mode 100644 index 00000000..d32470d2 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/limits.hpp @@ -0,0 +1,26 @@ +// +// detail/limits.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_LIMITS_HPP +#define ASIO_DETAIL_LIMITS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_BOOST_LIMITS) +# include +#else // defined(ASIO_HAS_BOOST_LIMITS) +# include +#endif // defined(ASIO_HAS_BOOST_LIMITS) + +#endif // ASIO_DETAIL_LIMITS_HPP diff --git a/tools/sdk/include/asio/asio/detail/local_free_on_block_exit.hpp b/tools/sdk/include/asio/asio/detail/local_free_on_block_exit.hpp new file mode 100644 index 00000000..eba6b777 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/local_free_on_block_exit.hpp @@ -0,0 +1,59 @@ +// +// detail/local_free_on_block_exit.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP +#define ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) +#if !defined(ASIO_WINDOWS_APP) + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class local_free_on_block_exit + : private noncopyable +{ +public: + // Constructor blocks all signals for the calling thread. + explicit local_free_on_block_exit(void* p) + : p_(p) + { + } + + // Destructor restores the previous signal mask. + ~local_free_on_block_exit() + { + ::LocalFree(p_); + } + +private: + void* p_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_WINDOWS_APP) +#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) + +#endif // ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP diff --git a/tools/sdk/include/asio/asio/detail/macos_fenced_block.hpp b/tools/sdk/include/asio/asio/detail/macos_fenced_block.hpp new file mode 100644 index 00000000..bbac270a --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/macos_fenced_block.hpp @@ -0,0 +1,62 @@ +// +// detail/macos_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP +#define ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(__MACH__) && defined(__APPLE__) + +#include +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class macos_fenced_block + : private noncopyable +{ +public: + enum half_t { half }; + enum full_t { full }; + + // Constructor for a half fenced block. + explicit macos_fenced_block(half_t) + { + } + + // Constructor for a full fenced block. + explicit macos_fenced_block(full_t) + { + OSMemoryBarrier(); + } + + // Destructor. + ~macos_fenced_block() + { + OSMemoryBarrier(); + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(__MACH__) && defined(__APPLE__) + +#endif // ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP diff --git a/tools/sdk/include/asio/asio/detail/memory.hpp b/tools/sdk/include/asio/asio/detail/memory.hpp new file mode 100644 index 00000000..b1ec4975 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/memory.hpp @@ -0,0 +1,70 @@ +// +// detail/memory.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_MEMORY_HPP +#define ASIO_DETAIL_MEMORY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include + +#if !defined(ASIO_HAS_STD_SHARED_PTR) +# include +# include +#endif // !defined(ASIO_HAS_STD_SHARED_PTR) + +#if !defined(ASIO_HAS_STD_ADDRESSOF) +# include +#endif // !defined(ASIO_HAS_STD_ADDRESSOF) + +namespace asio { +namespace detail { + +#if defined(ASIO_HAS_STD_SHARED_PTR) +using std::shared_ptr; +using std::weak_ptr; +#else // defined(ASIO_HAS_STD_SHARED_PTR) +using boost::shared_ptr; +using boost::weak_ptr; +#endif // defined(ASIO_HAS_STD_SHARED_PTR) + +#if defined(ASIO_HAS_STD_ADDRESSOF) +using std::addressof; +#else // defined(ASIO_HAS_STD_ADDRESSOF) +using boost::addressof; +#endif // defined(ASIO_HAS_STD_ADDRESSOF) + +} // namespace detail + +#if defined(ASIO_HAS_CXX11_ALLOCATORS) +using std::allocator_arg_t; +# define ASIO_USES_ALLOCATOR(t) \ + namespace std { \ + template \ + struct uses_allocator : true_type {}; \ + } \ + /**/ +# define ASIO_REBIND_ALLOC(alloc, t) \ + typename std::allocator_traits::template rebind_alloc + /**/ +#else // defined(ASIO_HAS_CXX11_ALLOCATORS) +struct allocator_arg_t {}; +# define ASIO_USES_ALLOCATOR(t) +# define ASIO_REBIND_ALLOC(alloc, t) \ + typename alloc::template rebind::other + /**/ +#endif // defined(ASIO_HAS_CXX11_ALLOCATORS) + +} // namespace asio + +#endif // ASIO_DETAIL_MEMORY_HPP diff --git a/tools/sdk/include/asio/asio/detail/mutex.hpp b/tools/sdk/include/asio/asio/detail/mutex.hpp new file mode 100644 index 00000000..2f8f0b13 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/mutex.hpp @@ -0,0 +1,48 @@ +// +// detail/mutex.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_MUTEX_HPP +#define ASIO_DETAIL_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_THREADS) +# include "asio/detail/null_mutex.hpp" +#elif defined(ASIO_WINDOWS) +# include "asio/detail/win_mutex.hpp" +#elif defined(ASIO_HAS_PTHREADS) +# include "asio/detail/posix_mutex.hpp" +#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) +# include "asio/detail/std_mutex.hpp" +#else +# error Only Windows, POSIX and std::mutex are supported! +#endif + +namespace asio { +namespace detail { + +#if !defined(ASIO_HAS_THREADS) +typedef null_mutex mutex; +#elif defined(ASIO_WINDOWS) +typedef win_mutex mutex; +#elif defined(ASIO_HAS_PTHREADS) +typedef posix_mutex mutex; +#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) +typedef std_mutex mutex; +#endif + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_MUTEX_HPP diff --git a/tools/sdk/include/asio/asio/detail/noncopyable.hpp b/tools/sdk/include/asio/asio/detail/noncopyable.hpp new file mode 100644 index 00000000..0c038e11 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/noncopyable.hpp @@ -0,0 +1,43 @@ +// +// detail/noncopyable.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_NONCOPYABLE_HPP +#define ASIO_DETAIL_NONCOPYABLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class noncopyable +{ +protected: + noncopyable() {} + ~noncopyable() {} +private: + noncopyable(const noncopyable&); + const noncopyable& operator=(const noncopyable&); +}; + +} // namespace detail + +using asio::detail::noncopyable; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_NONCOPYABLE_HPP diff --git a/tools/sdk/include/asio/asio/detail/null_event.hpp b/tools/sdk/include/asio/asio/detail/null_event.hpp new file mode 100644 index 00000000..5686a41e --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/null_event.hpp @@ -0,0 +1,100 @@ +// +// detail/null_event.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_NULL_EVENT_HPP +#define ASIO_DETAIL_NULL_EVENT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class null_event + : private noncopyable +{ +public: + // Constructor. + null_event() + { + } + + // Destructor. + ~null_event() + { + } + + // Signal the event. (Retained for backward compatibility.) + template + void signal(Lock&) + { + } + + // Signal all waiters. + template + void signal_all(Lock&) + { + } + + // Unlock the mutex and signal one waiter. + template + void unlock_and_signal_one(Lock&) + { + } + + // If there's a waiter, unlock the mutex and signal it. + template + bool maybe_unlock_and_signal_one(Lock&) + { + return false; + } + + // Reset the event. + template + void clear(Lock&) + { + } + + // Wait for the event to become signalled. + template + void wait(Lock&) + { + do_wait(); + } + + // Timed wait for the event to become signalled. + template + bool wait_for_usec(Lock&, long usec) + { + do_wait_for_usec(usec); + return true; + } + +private: + ASIO_DECL static void do_wait(); + ASIO_DECL static void do_wait_for_usec(long usec); +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/null_event.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_DETAIL_NULL_EVENT_HPP diff --git a/tools/sdk/include/asio/asio/detail/null_fenced_block.hpp b/tools/sdk/include/asio/asio/detail/null_fenced_block.hpp new file mode 100644 index 00000000..0275326b --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/null_fenced_block.hpp @@ -0,0 +1,47 @@ +// +// detail/null_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_NULL_FENCED_BLOCK_HPP +#define ASIO_DETAIL_NULL_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class null_fenced_block + : private noncopyable +{ +public: + enum half_or_full_t { half, full }; + + // Constructor. + explicit null_fenced_block(half_or_full_t) + { + } + + // Destructor. + ~null_fenced_block() + { + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_NULL_FENCED_BLOCK_HPP diff --git a/tools/sdk/include/asio/asio/detail/null_global.hpp b/tools/sdk/include/asio/asio/detail/null_global.hpp new file mode 100644 index 00000000..727dd3f4 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/null_global.hpp @@ -0,0 +1,59 @@ +// +// detail/null_global.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_NULL_GLOBAL_HPP +#define ASIO_DETAIL_NULL_GLOBAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +struct null_global_impl +{ + null_global_impl() + : ptr_(0) + { + } + + // Destructor automatically cleans up the global. + ~null_global_impl() + { + delete ptr_; + } + + static null_global_impl instance_; + T* ptr_; +}; + +template +null_global_impl null_global_impl::instance_; + +template +T& null_global() +{ + if (null_global_impl::instance_.ptr_ == 0) + null_global_impl::instance_.ptr_ = new T; + return *null_global_impl::instance_.ptr_; +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_NULL_GLOBAL_HPP diff --git a/tools/sdk/include/asio/asio/detail/null_mutex.hpp b/tools/sdk/include/asio/asio/detail/null_mutex.hpp new file mode 100644 index 00000000..afe3fc03 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/null_mutex.hpp @@ -0,0 +1,64 @@ +// +// detail/null_mutex.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_NULL_MUTEX_HPP +#define ASIO_DETAIL_NULL_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_THREADS) + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/scoped_lock.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class null_mutex + : private noncopyable +{ +public: + typedef asio::detail::scoped_lock scoped_lock; + + // Constructor. + null_mutex() + { + } + + // Destructor. + ~null_mutex() + { + } + + // Lock the mutex. + void lock() + { + } + + // Unlock the mutex. + void unlock() + { + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_HAS_THREADS) + +#endif // ASIO_DETAIL_NULL_MUTEX_HPP diff --git a/tools/sdk/include/asio/asio/detail/null_reactor.hpp b/tools/sdk/include/asio/asio/detail/null_reactor.hpp new file mode 100644 index 00000000..ca3c5fde --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/null_reactor.hpp @@ -0,0 +1,68 @@ +// +// detail/null_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_NULL_REACTOR_HPP +#define ASIO_DETAIL_NULL_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) || defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/detail/scheduler_operation.hpp" +#include "asio/execution_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class null_reactor + : public execution_context_service_base +{ +public: + // Constructor. + null_reactor(asio::execution_context& ctx) + : execution_context_service_base(ctx) + { + } + + // Destructor. + ~null_reactor() + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown() + { + } + + // No-op because should never be called. + void run(long /*usec*/, op_queue& /*ops*/) + { + } + + // No-op. + void interrupt() + { + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) || defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_NULL_REACTOR_HPP diff --git a/tools/sdk/include/asio/asio/detail/null_signal_blocker.hpp b/tools/sdk/include/asio/asio/detail/null_signal_blocker.hpp new file mode 100644 index 00000000..edfe8205 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/null_signal_blocker.hpp @@ -0,0 +1,69 @@ +// +// detail/null_signal_blocker.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_NULL_SIGNAL_BLOCKER_HPP +#define ASIO_DETAIL_NULL_SIGNAL_BLOCKER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_THREADS) \ + || defined(ASIO_WINDOWS) \ + || defined(ASIO_WINDOWS_RUNTIME) \ + || defined(__CYGWIN__) \ + || defined(__SYMBIAN32__) + +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class null_signal_blocker + : private noncopyable +{ +public: + // Constructor blocks all signals for the calling thread. + null_signal_blocker() + { + } + + // Destructor restores the previous signal mask. + ~null_signal_blocker() + { + } + + // Block all signals for the calling thread. + void block() + { + } + + // Restore the previous signal mask. + void unblock() + { + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_HAS_THREADS) + // || defined(ASIO_WINDOWS) + // || defined(ASIO_WINDOWS_RUNTIME) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) + +#endif // ASIO_DETAIL_NULL_SIGNAL_BLOCKER_HPP diff --git a/tools/sdk/include/asio/asio/detail/null_socket_service.hpp b/tools/sdk/include/asio/asio/detail/null_socket_service.hpp new file mode 100644 index 00000000..109c6c7b --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/null_socket_service.hpp @@ -0,0 +1,508 @@ +// +// detail/null_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_NULL_SOCKET_SERVICE_HPP +#define ASIO_DETAIL_NULL_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/buffer.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/socket_base.hpp" +#include "asio/detail/bind_handler.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class null_socket_service : + public service_base > +{ +public: + // The protocol type. + typedef Protocol protocol_type; + + // The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + // The native type of a socket. + typedef int native_handle_type; + + // The implementation type of the socket. + struct implementation_type + { + }; + + // Constructor. + null_socket_service(asio::io_context& io_context) + : service_base >(io_context), + io_context_(io_context) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown() + { + } + + // Construct a new socket implementation. + void construct(implementation_type&) + { + } + + // Move-construct a new socket implementation. + void move_construct(implementation_type&, implementation_type&) + { + } + + // Move-assign from another socket implementation. + void move_assign(implementation_type&, + null_socket_service&, implementation_type&) + { + } + + // Move-construct a new socket implementation from another protocol type. + template + void converting_move_construct(implementation_type&, + null_socket_service&, + typename null_socket_service::implementation_type&) + { + } + + // Destroy a socket implementation. + void destroy(implementation_type&) + { + } + + // Open a new socket implementation. + asio::error_code open(implementation_type&, + const protocol_type&, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Assign a native socket to a socket implementation. + asio::error_code assign(implementation_type&, const protocol_type&, + const native_handle_type&, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Determine whether the socket is open. + bool is_open(const implementation_type&) const + { + return false; + } + + // Destroy a socket implementation. + asio::error_code close(implementation_type&, + asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Release ownership of the socket. + native_handle_type release(implementation_type&, + asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return 0; + } + + // Get the native socket representation. + native_handle_type native_handle(implementation_type&) + { + return 0; + } + + // Cancel all operations associated with the socket. + asio::error_code cancel(implementation_type&, + asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Determine whether the socket is at the out-of-band data mark. + bool at_mark(const implementation_type&, + asio::error_code& ec) const + { + ec = asio::error::operation_not_supported; + return false; + } + + // Determine the number of bytes available for reading. + std::size_t available(const implementation_type&, + asio::error_code& ec) const + { + ec = asio::error::operation_not_supported; + return 0; + } + + // Place the socket into the state where it will listen for new connections. + asio::error_code listen(implementation_type&, + int, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Perform an IO control command on the socket. + template + asio::error_code io_control(implementation_type&, + IO_Control_Command&, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Gets the non-blocking mode of the socket. + bool non_blocking(const implementation_type&) const + { + return false; + } + + // Sets the non-blocking mode of the socket. + asio::error_code non_blocking(implementation_type&, + bool, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Gets the non-blocking mode of the native socket implementation. + bool native_non_blocking(const implementation_type&) const + { + return false; + } + + // Sets the non-blocking mode of the native socket implementation. + asio::error_code native_non_blocking(implementation_type&, + bool, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Disable sends or receives on the socket. + asio::error_code shutdown(implementation_type&, + socket_base::shutdown_type, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Bind the socket to the specified local endpoint. + asio::error_code bind(implementation_type&, + const endpoint_type&, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Set a socket option. + template + asio::error_code set_option(implementation_type&, + const Option&, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Set a socket option. + template + asio::error_code get_option(const implementation_type&, + Option&, asio::error_code& ec) const + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Get the local endpoint. + endpoint_type local_endpoint(const implementation_type&, + asio::error_code& ec) const + { + ec = asio::error::operation_not_supported; + return endpoint_type(); + } + + // Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type&, + asio::error_code& ec) const + { + ec = asio::error::operation_not_supported; + return endpoint_type(); + } + + // Send the given data to the peer. + template + std::size_t send(implementation_type&, const ConstBufferSequence&, + socket_base::message_flags, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return 0; + } + + // Wait until data can be sent without blocking. + std::size_t send(implementation_type&, const null_buffers&, + socket_base::message_flags, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return 0; + } + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_send(implementation_type&, const ConstBufferSequence&, + socket_base::message_flags, Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + const std::size_t bytes_transferred = 0; + io_context_.post(detail::bind_handler(handler, ec, bytes_transferred)); + } + + // Start an asynchronous wait until data can be sent without blocking. + template + void async_send(implementation_type&, const null_buffers&, + socket_base::message_flags, Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + const std::size_t bytes_transferred = 0; + io_context_.post(detail::bind_handler(handler, ec, bytes_transferred)); + } + + // Receive some data from the peer. Returns the number of bytes received. + template + std::size_t receive(implementation_type&, const MutableBufferSequence&, + socket_base::message_flags, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return 0; + } + + // Wait until data can be received without blocking. + std::size_t receive(implementation_type&, const null_buffers&, + socket_base::message_flags, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + 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(implementation_type&, const MutableBufferSequence&, + socket_base::message_flags, Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + const std::size_t bytes_transferred = 0; + io_context_.post(detail::bind_handler(handler, ec, bytes_transferred)); + } + + // Wait until data can be received without blocking. + template + void async_receive(implementation_type&, const null_buffers&, + socket_base::message_flags, Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + const std::size_t bytes_transferred = 0; + io_context_.post(detail::bind_handler(handler, ec, bytes_transferred)); + } + + // Receive some data with associated flags. Returns the number of bytes + // received. + template + std::size_t receive_with_flags(implementation_type&, + const MutableBufferSequence&, socket_base::message_flags, + socket_base::message_flags&, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return 0; + } + + // Wait until data can be received without blocking. + std::size_t receive_with_flags(implementation_type&, + const null_buffers&, socket_base::message_flags, + socket_base::message_flags&, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + 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(implementation_type&, + const MutableBufferSequence&, socket_base::message_flags, + socket_base::message_flags&, Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + const std::size_t bytes_transferred = 0; + io_context_.post(detail::bind_handler(handler, ec, bytes_transferred)); + } + + // Wait until data can be received without blocking. + template + void async_receive_with_flags(implementation_type&, + const null_buffers&, socket_base::message_flags, + socket_base::message_flags&, Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + const std::size_t bytes_transferred = 0; + io_context_.post(detail::bind_handler(handler, ec, bytes_transferred)); + } + + // Send a datagram to the specified endpoint. Returns the number of bytes + // sent. + template + std::size_t send_to(implementation_type&, const ConstBufferSequence&, + const endpoint_type&, socket_base::message_flags, + asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return 0; + } + + // Wait until data can be sent without blocking. + std::size_t send_to(implementation_type&, const null_buffers&, + const endpoint_type&, socket_base::message_flags, + asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + 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&, const ConstBufferSequence&, + const endpoint_type&, socket_base::message_flags, + Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + const std::size_t bytes_transferred = 0; + io_context_.post(detail::bind_handler(handler, ec, bytes_transferred)); + } + + // Start an asynchronous wait until data can be sent without blocking. + template + void async_send_to(implementation_type&, const null_buffers&, + const endpoint_type&, socket_base::message_flags, Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + const std::size_t bytes_transferred = 0; + io_context_.post(detail::bind_handler(handler, ec, bytes_transferred)); + } + + // Receive a datagram with the endpoint of the sender. Returns the number of + // bytes received. + template + std::size_t receive_from(implementation_type&, const MutableBufferSequence&, + endpoint_type&, socket_base::message_flags, + asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return 0; + } + + // Wait until data can be received without blocking. + std::size_t receive_from(implementation_type&, const null_buffers&, + endpoint_type&, socket_base::message_flags, + asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + 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&, + const MutableBufferSequence&, endpoint_type&, + socket_base::message_flags, Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + const std::size_t bytes_transferred = 0; + io_context_.post(detail::bind_handler(handler, ec, bytes_transferred)); + } + + // Wait until data can be received without blocking. + template + void async_receive_from(implementation_type&, + const null_buffers&, endpoint_type&, + socket_base::message_flags, Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + const std::size_t bytes_transferred = 0; + io_context_.post(detail::bind_handler(handler, ec, bytes_transferred)); + } + + // Accept a new connection. + template + asio::error_code accept(implementation_type&, + Socket&, endpoint_type*, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + 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&, Socket&, + endpoint_type*, Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + io_context_.post(detail::bind_handler(handler, ec)); + } + + // Connect the socket to the specified endpoint. + asio::error_code connect(implementation_type&, + const endpoint_type&, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Start an asynchronous connect. + template + void async_connect(implementation_type&, + const endpoint_type&, Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + io_context_.post(detail::bind_handler(handler, ec)); + } + +private: + asio::io_context& io_context_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_NULL_SOCKET_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/null_static_mutex.hpp b/tools/sdk/include/asio/asio/detail/null_static_mutex.hpp new file mode 100644 index 00000000..36ec04f7 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/null_static_mutex.hpp @@ -0,0 +1,60 @@ +// +// detail/null_static_mutex.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_NULL_STATIC_MUTEX_HPP +#define ASIO_DETAIL_NULL_STATIC_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_THREADS) + +#include "asio/detail/scoped_lock.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +struct null_static_mutex +{ + typedef asio::detail::scoped_lock scoped_lock; + + // Initialise the mutex. + void init() + { + } + + // Lock the mutex. + void lock() + { + } + + // Unlock the mutex. + void unlock() + { + } + + int unused_; +}; + +#define ASIO_NULL_STATIC_MUTEX_INIT { 0 } + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_HAS_THREADS) + +#endif // ASIO_DETAIL_NULL_STATIC_MUTEX_HPP diff --git a/tools/sdk/include/asio/asio/detail/null_thread.hpp b/tools/sdk/include/asio/asio/detail/null_thread.hpp new file mode 100644 index 00000000..7291ba38 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/null_thread.hpp @@ -0,0 +1,67 @@ +// +// detail/null_thread.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_NULL_THREAD_HPP +#define ASIO_DETAIL_NULL_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_THREADS) + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class null_thread + : private noncopyable +{ +public: + // Constructor. + template + null_thread(Function, unsigned int = 0) + { + asio::detail::throw_error( + asio::error::operation_not_supported, "thread"); + } + + // Destructor. + ~null_thread() + { + } + + // Wait for the thread to exit. + void join() + { + } + + // Get number of CPUs. + static std::size_t hardware_concurrency() + { + return 1; + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_HAS_THREADS) + +#endif // ASIO_DETAIL_NULL_THREAD_HPP diff --git a/tools/sdk/include/asio/asio/detail/null_tss_ptr.hpp b/tools/sdk/include/asio/asio/detail/null_tss_ptr.hpp new file mode 100644 index 00000000..323967d6 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/null_tss_ptr.hpp @@ -0,0 +1,68 @@ +// +// detail/null_tss_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_NULL_TSS_PTR_HPP +#define ASIO_DETAIL_NULL_TSS_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_THREADS) + +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class null_tss_ptr + : private noncopyable +{ +public: + // Constructor. + null_tss_ptr() + : value_(0) + { + } + + // Destructor. + ~null_tss_ptr() + { + } + + // Get the value. + operator T*() const + { + return value_; + } + + // Set the value. + void operator=(T* value) + { + value_ = value; + } + +private: + T* value_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_HAS_THREADS) + +#endif // ASIO_DETAIL_NULL_TSS_PTR_HPP diff --git a/tools/sdk/include/asio/asio/detail/object_pool.hpp b/tools/sdk/include/asio/asio/detail/object_pool.hpp new file mode 100644 index 00000000..e1a3c548 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/object_pool.hpp @@ -0,0 +1,171 @@ +// +// detail/object_pool.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_OBJECT_POOL_HPP +#define ASIO_DETAIL_OBJECT_POOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class object_pool; + +class object_pool_access +{ +public: + template + static Object* create() + { + return new Object; + } + + template + static Object* create(Arg arg) + { + return new Object(arg); + } + + template + static void destroy(Object* o) + { + delete o; + } + + template + static Object*& next(Object* o) + { + return o->next_; + } + + template + static Object*& prev(Object* o) + { + return o->prev_; + } +}; + +template +class object_pool + : private noncopyable +{ +public: + // Constructor. + object_pool() + : live_list_(0), + free_list_(0) + { + } + + // Destructor destroys all objects. + ~object_pool() + { + destroy_list(live_list_); + destroy_list(free_list_); + } + + // Get the object at the start of the live list. + Object* first() + { + return live_list_; + } + + // Allocate a new object. + Object* alloc() + { + Object* o = free_list_; + if (o) + free_list_ = object_pool_access::next(free_list_); + else + o = object_pool_access::create(); + + object_pool_access::next(o) = live_list_; + object_pool_access::prev(o) = 0; + if (live_list_) + object_pool_access::prev(live_list_) = o; + live_list_ = o; + + return o; + } + + // Allocate a new object with an argument. + template + Object* alloc(Arg arg) + { + Object* o = free_list_; + if (o) + free_list_ = object_pool_access::next(free_list_); + else + o = object_pool_access::create(arg); + + object_pool_access::next(o) = live_list_; + object_pool_access::prev(o) = 0; + if (live_list_) + object_pool_access::prev(live_list_) = o; + live_list_ = o; + + return o; + } + + // Free an object. Moves it to the free list. No destructors are run. + void free(Object* o) + { + if (live_list_ == o) + live_list_ = object_pool_access::next(o); + + if (object_pool_access::prev(o)) + { + object_pool_access::next(object_pool_access::prev(o)) + = object_pool_access::next(o); + } + + if (object_pool_access::next(o)) + { + object_pool_access::prev(object_pool_access::next(o)) + = object_pool_access::prev(o); + } + + object_pool_access::next(o) = free_list_; + object_pool_access::prev(o) = 0; + free_list_ = o; + } + +private: + // Helper function to destroy all elements in a list. + void destroy_list(Object* list) + { + while (list) + { + Object* o = list; + list = object_pool_access::next(o); + object_pool_access::destroy(o); + } + } + + // The list of live objects. + Object* live_list_; + + // The free list. + Object* free_list_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_OBJECT_POOL_HPP diff --git a/tools/sdk/include/asio/asio/detail/old_win_sdk_compat.hpp b/tools/sdk/include/asio/asio/detail/old_win_sdk_compat.hpp new file mode 100644 index 00000000..bfb109e7 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/old_win_sdk_compat.hpp @@ -0,0 +1,214 @@ +// +// detail/old_win_sdk_compat.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP +#define ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) + +// Guess whether we are building against on old Platform SDK. +#if !defined(IN6ADDR_ANY_INIT) +#define ASIO_HAS_OLD_WIN_SDK 1 +#endif // !defined(IN6ADDR_ANY_INIT) + +#if defined(ASIO_HAS_OLD_WIN_SDK) + +// Emulation of types that are missing from old Platform SDKs. +// +// N.B. this emulation is also used if building for a Windows 2000 target with +// a recent (i.e. Vista or later) SDK, as the SDK does not provide IPv6 support +// in that case. + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +enum +{ + sockaddr_storage_maxsize = 128, // Maximum size. + sockaddr_storage_alignsize = (sizeof(__int64)), // Desired alignment. + sockaddr_storage_pad1size = (sockaddr_storage_alignsize - sizeof(short)), + sockaddr_storage_pad2size = (sockaddr_storage_maxsize - + (sizeof(short) + sockaddr_storage_pad1size + sockaddr_storage_alignsize)) +}; + +struct sockaddr_storage_emulation +{ + short ss_family; + char __ss_pad1[sockaddr_storage_pad1size]; + __int64 __ss_align; + char __ss_pad2[sockaddr_storage_pad2size]; +}; + +struct in6_addr_emulation +{ + union + { + u_char Byte[16]; + u_short Word[8]; + } u; +}; + +#if !defined(s6_addr) +# define _S6_un u +# define _S6_u8 Byte +# define s6_addr _S6_un._S6_u8 +#endif // !defined(s6_addr) + +struct sockaddr_in6_emulation +{ + short sin6_family; + u_short sin6_port; + u_long sin6_flowinfo; + in6_addr_emulation sin6_addr; + u_long sin6_scope_id; +}; + +struct ipv6_mreq_emulation +{ + in6_addr_emulation ipv6mr_multiaddr; + unsigned int ipv6mr_interface; +}; + +struct addrinfo_emulation +{ + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + size_t ai_addrlen; + char* ai_canonname; + sockaddr* ai_addr; + addrinfo_emulation* ai_next; +}; + +#if !defined(AI_PASSIVE) +# define AI_PASSIVE 0x1 +#endif + +#if !defined(AI_CANONNAME) +# define AI_CANONNAME 0x2 +#endif + +#if !defined(AI_NUMERICHOST) +# define AI_NUMERICHOST 0x4 +#endif + +#if !defined(EAI_AGAIN) +# define EAI_AGAIN WSATRY_AGAIN +#endif + +#if !defined(EAI_BADFLAGS) +# define EAI_BADFLAGS WSAEINVAL +#endif + +#if !defined(EAI_FAIL) +# define EAI_FAIL WSANO_RECOVERY +#endif + +#if !defined(EAI_FAMILY) +# define EAI_FAMILY WSAEAFNOSUPPORT +#endif + +#if !defined(EAI_MEMORY) +# define EAI_MEMORY WSA_NOT_ENOUGH_MEMORY +#endif + +#if !defined(EAI_NODATA) +# define EAI_NODATA WSANO_DATA +#endif + +#if !defined(EAI_NONAME) +# define EAI_NONAME WSAHOST_NOT_FOUND +#endif + +#if !defined(EAI_SERVICE) +# define EAI_SERVICE WSATYPE_NOT_FOUND +#endif + +#if !defined(EAI_SOCKTYPE) +# define EAI_SOCKTYPE WSAESOCKTNOSUPPORT +#endif + +#if !defined(NI_NOFQDN) +# define NI_NOFQDN 0x01 +#endif + +#if !defined(NI_NUMERICHOST) +# define NI_NUMERICHOST 0x02 +#endif + +#if !defined(NI_NAMEREQD) +# define NI_NAMEREQD 0x04 +#endif + +#if !defined(NI_NUMERICSERV) +# define NI_NUMERICSERV 0x08 +#endif + +#if !defined(NI_DGRAM) +# define NI_DGRAM 0x10 +#endif + +#if !defined(IPPROTO_IPV6) +# define IPPROTO_IPV6 41 +#endif + +#if !defined(IPV6_UNICAST_HOPS) +# define IPV6_UNICAST_HOPS 4 +#endif + +#if !defined(IPV6_MULTICAST_IF) +# define IPV6_MULTICAST_IF 9 +#endif + +#if !defined(IPV6_MULTICAST_HOPS) +# define IPV6_MULTICAST_HOPS 10 +#endif + +#if !defined(IPV6_MULTICAST_LOOP) +# define IPV6_MULTICAST_LOOP 11 +#endif + +#if !defined(IPV6_JOIN_GROUP) +# define IPV6_JOIN_GROUP 12 +#endif + +#if !defined(IPV6_LEAVE_GROUP) +# define IPV6_LEAVE_GROUP 13 +#endif + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_OLD_WIN_SDK) + +// Even newer Platform SDKs that support IPv6 may not define IPV6_V6ONLY. +#if !defined(IPV6_V6ONLY) +# define IPV6_V6ONLY 27 +#endif + +// Some SDKs (e.g. Windows CE) don't define IPPROTO_ICMPV6. +#if !defined(IPPROTO_ICMPV6) +# define IPPROTO_ICMPV6 58 +#endif + +#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) + +#endif // ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP diff --git a/tools/sdk/include/asio/asio/detail/op_queue.hpp b/tools/sdk/include/asio/asio/detail/op_queue.hpp new file mode 100644 index 00000000..6219f797 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/op_queue.hpp @@ -0,0 +1,162 @@ +// +// detail/op_queue.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_OP_QUEUE_HPP +#define ASIO_DETAIL_OP_QUEUE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class op_queue; + +class op_queue_access +{ +public: + template + static Operation* next(Operation* o) + { + return static_cast(o->next_); + } + + template + static void next(Operation1*& o1, Operation2* o2) + { + o1->next_ = o2; + } + + template + static void destroy(Operation* o) + { + o->destroy(); + } + + template + static Operation*& front(op_queue& q) + { + return q.front_; + } + + template + static Operation*& back(op_queue& q) + { + return q.back_; + } +}; + +template +class op_queue + : private noncopyable +{ +public: + // Constructor. + op_queue() + : front_(0), + back_(0) + { + } + + // Destructor destroys all operations. + ~op_queue() + { + while (Operation* op = front_) + { + pop(); + op_queue_access::destroy(op); + } + } + + // Get the operation at the front of the queue. + Operation* front() + { + return front_; + } + + // Pop an operation from the front of the queue. + void pop() + { + if (front_) + { + Operation* tmp = front_; + front_ = op_queue_access::next(front_); + if (front_ == 0) + back_ = 0; + op_queue_access::next(tmp, static_cast(0)); + } + } + + // Push an operation on to the back of the queue. + void push(Operation* h) + { + op_queue_access::next(h, static_cast(0)); + if (back_) + { + op_queue_access::next(back_, h); + back_ = h; + } + else + { + front_ = back_ = h; + } + } + + // Push all operations from another queue on to the back of the queue. The + // source queue may contain operations of a derived type. + template + void push(op_queue& q) + { + if (Operation* other_front = op_queue_access::front(q)) + { + if (back_) + op_queue_access::next(back_, other_front); + else + front_ = other_front; + back_ = op_queue_access::back(q); + op_queue_access::front(q) = 0; + op_queue_access::back(q) = 0; + } + } + + // Whether the queue is empty. + bool empty() const + { + return front_ == 0; + } + + // Test whether an operation is already enqueued. + bool is_enqueued(Operation* o) const + { + return op_queue_access::next(o) != 0 || back_ == o; + } + +private: + friend class op_queue_access; + + // The front of the queue. + Operation* front_; + + // The back of the queue. + Operation* back_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_OP_QUEUE_HPP diff --git a/tools/sdk/include/asio/asio/detail/operation.hpp b/tools/sdk/include/asio/asio/detail/operation.hpp new file mode 100644 index 00000000..811e54d4 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/operation.hpp @@ -0,0 +1,38 @@ +// +// detail/operation.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_OPERATION_HPP +#define ASIO_DETAIL_OPERATION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_operation.hpp" +#else +# include "asio/detail/scheduler_operation.hpp" +#endif + +namespace asio { +namespace detail { + +#if defined(ASIO_HAS_IOCP) +typedef win_iocp_operation operation; +#else +typedef scheduler_operation operation; +#endif + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_OPERATION_HPP diff --git a/tools/sdk/include/asio/asio/detail/pipe_select_interrupter.hpp b/tools/sdk/include/asio/asio/detail/pipe_select_interrupter.hpp new file mode 100644 index 00000000..55d7db49 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/pipe_select_interrupter.hpp @@ -0,0 +1,89 @@ +// +// detail/pipe_select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP +#define ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_WINDOWS) +#if !defined(ASIO_WINDOWS_RUNTIME) +#if !defined(__CYGWIN__) +#if !defined(__SYMBIAN32__) +#if !defined(ASIO_HAS_EVENTFD) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class pipe_select_interrupter +{ +public: + // Constructor. + ASIO_DECL pipe_select_interrupter(); + + // Destructor. + ASIO_DECL ~pipe_select_interrupter(); + + // Recreate the interrupter's descriptors. Used after a fork. + ASIO_DECL void recreate(); + + // Interrupt the select call. + ASIO_DECL void interrupt(); + + // Reset the select interrupt. Returns true if the call was interrupted. + ASIO_DECL bool reset(); + + // Get the read descriptor to be passed to select. + int read_descriptor() const + { + return read_descriptor_; + } + +private: + // Open the descriptors. Throws on error. + ASIO_DECL void open_descriptors(); + + // Close the descriptors. + ASIO_DECL void close_descriptors(); + + // The read end of a connection used to interrupt the select call. This file + // descriptor is passed to select such that when it is time to stop, a single + // byte will be written on the other end of the connection and this + // descriptor will become readable. + int read_descriptor_; + + // The write end of a connection used to interrupt the select call. A single + // byte may be written to this to wake up the select which is waiting for the + // other end to become readable. + int write_descriptor_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/pipe_select_interrupter.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // !defined(ASIO_HAS_EVENTFD) +#endif // !defined(__SYMBIAN32__) +#endif // !defined(__CYGWIN__) +#endif // !defined(ASIO_WINDOWS_RUNTIME) +#endif // !defined(ASIO_WINDOWS) + +#endif // ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP diff --git a/tools/sdk/include/asio/asio/detail/pop_options.hpp b/tools/sdk/include/asio/asio/detail/pop_options.hpp new file mode 100644 index 00000000..1045612b --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/pop_options.hpp @@ -0,0 +1,135 @@ +// +// detail/pop_options.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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) +// + +// No header guard + +#if defined(__COMO__) + +// Comeau C++ + +#elif defined(__DMC__) + +// Digital Mars C++ + +#elif defined(__INTEL_COMPILER) || defined(__ICL) \ + || defined(__ICC) || defined(__ECC) + +// Intel C++ + +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) + +#elif defined(__clang__) + +// Clang + +# if defined(__OBJC__) +# if !defined(__APPLE_CC__) || (__APPLE_CC__ <= 1) +# if defined(ASIO_OBJC_WORKAROUND) +# undef Protocol +# undef id +# undef ASIO_OBJC_WORKAROUND +# endif +# endif +# endif + +# if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) +# pragma GCC visibility pop +# endif // !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) + +#elif defined(__GNUC__) + +// GNU C++ + +# if defined(__MINGW32__) || defined(__CYGWIN__) +# pragma pack (pop) +# endif + +# if defined(__OBJC__) +# if !defined(__APPLE_CC__) || (__APPLE_CC__ <= 1) +# if defined(ASIO_OBJC_WORKAROUND) +# undef Protocol +# undef id +# undef ASIO_OBJC_WORKAROUND +# endif +# endif +# endif + +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) + +# if (__GNUC__ >= 7) +# pragma GCC diagnostic pop +# endif // (__GNUC__ >= 7) + +#elif defined(__KCC) + +// Kai C++ + +#elif defined(__sgi) + +// SGI MIPSpro C++ + +#elif defined(__DECCXX) + +// Compaq Tru64 Unix cxx + +#elif defined(__ghs) + +// Greenhills C++ + +#elif defined(__BORLANDC__) + +// Borland C++ + +# pragma option pop +# pragma nopushoptwarn +# pragma nopackwarning + +#elif defined(__MWERKS__) + +// Metrowerks CodeWarrior + +#elif defined(__SUNPRO_CC) + +// Sun Workshop Compiler C++ + +#elif defined(__HP_aCC) + +// HP aCC + +#elif defined(__MRC__) || defined(__SC__) + +// MPW MrCpp or SCpp + +#elif defined(__IBMCPP__) + +// IBM Visual Age + +#elif defined(_MSC_VER) + +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for example) +// also #define _MSC_VER + +# pragma warning (pop) +# pragma pack (pop) + +# if defined(__cplusplus_cli) || defined(__cplusplus_winrt) +# if defined(ASIO_CLR_WORKAROUND) +# undef generic +# undef ASIO_CLR_WORKAROUND +# endif +# endif + +#endif diff --git a/tools/sdk/include/asio/asio/detail/posix_event.hpp b/tools/sdk/include/asio/asio/detail/posix_event.hpp new file mode 100644 index 00000000..121065ef --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/posix_event.hpp @@ -0,0 +1,162 @@ +// +// detail/posix_event.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_POSIX_EVENT_HPP +#define ASIO_DETAIL_POSIX_EVENT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_PTHREADS) + +#include +#include "asio/detail/assert.hpp" +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class posix_event + : private noncopyable +{ +public: + // Constructor. + ASIO_DECL posix_event(); + + // Destructor. + ~posix_event() + { + ::pthread_cond_destroy(&cond_); + } + + // Signal the event. (Retained for backward compatibility.) + template + void signal(Lock& lock) + { + this->signal_all(lock); + } + + // Signal all waiters. + template + void signal_all(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + (void)lock; + state_ |= 1; + ::pthread_cond_broadcast(&cond_); // Ignore EINVAL. + } + + // Unlock the mutex and signal one waiter. + template + void unlock_and_signal_one(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + state_ |= 1; + bool have_waiters = (state_ > 1); + lock.unlock(); + if (have_waiters) + ::pthread_cond_signal(&cond_); // Ignore EINVAL. + } + + // If there's a waiter, unlock the mutex and signal it. + template + bool maybe_unlock_and_signal_one(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + state_ |= 1; + if (state_ > 1) + { + lock.unlock(); + ::pthread_cond_signal(&cond_); // Ignore EINVAL. + return true; + } + return false; + } + + // Reset the event. + template + void clear(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + (void)lock; + state_ &= ~std::size_t(1); + } + + // Wait for the event to become signalled. + template + void wait(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + while ((state_ & 1) == 0) + { + state_ += 2; + ::pthread_cond_wait(&cond_, &lock.mutex().mutex_); // Ignore EINVAL. + state_ -= 2; + } + } + + // Timed wait for the event to become signalled. + template + bool wait_for_usec(Lock& lock, long usec) + { + ASIO_ASSERT(lock.locked()); + if ((state_ & 1) == 0) + { + state_ += 2; + timespec ts; +#if (defined(__MACH__) && defined(__APPLE__)) \ + || (defined(__ANDROID__) && (__ANDROID_API__ < 21) \ + && defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)) + ts.tv_sec = usec / 1000000; + ts.tv_nsec = (usec % 1000000) * 1000; + ::pthread_cond_timedwait_relative_np( + &cond_, &lock.mutex().mutex_, &ts); // Ignore EINVAL. +#else // (defined(__MACH__) && defined(__APPLE__)) + // || (defined(__ANDROID__) && (__ANDROID_API__ < 21) + // && defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)) + if (::clock_gettime(CLOCK_MONOTONIC, &ts) == 0) + { + ts.tv_sec += usec / 1000000; + ts.tv_nsec = (usec % 1000000) * 1000; + ts.tv_sec += ts.tv_nsec / 1000000000; + ts.tv_nsec = ts.tv_nsec % 1000000000; + ::pthread_cond_timedwait(&cond_, + &lock.mutex().mutex_, &ts); // Ignore EINVAL. + } +#endif // (defined(__MACH__) && defined(__APPLE__)) + // || (defined(__ANDROID__) && (__ANDROID_API__ < 21) + // && defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)) + state_ -= 2; + } + return (state_ & 1) != 0; + } + +private: + ::pthread_cond_t cond_; + std::size_t state_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/posix_event.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_PTHREADS) + +#endif // ASIO_DETAIL_POSIX_EVENT_HPP diff --git a/tools/sdk/include/asio/asio/detail/posix_fd_set_adapter.hpp b/tools/sdk/include/asio/asio/detail/posix_fd_set_adapter.hpp new file mode 100644 index 00000000..95042d66 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/posix_fd_set_adapter.hpp @@ -0,0 +1,118 @@ +// +// detail/posix_fd_set_adapter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP +#define ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_WINDOWS) \ + && !defined(__CYGWIN__) \ + && !defined(ASIO_WINDOWS_RUNTIME) + +#include +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/reactor_op_queue.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Adapts the FD_SET type to meet the Descriptor_Set concept's requirements. +class posix_fd_set_adapter : noncopyable +{ +public: + posix_fd_set_adapter() + : max_descriptor_(invalid_socket) + { + using namespace std; // Needed for memset on Solaris. + FD_ZERO(&fd_set_); + } + + void reset() + { + using namespace std; // Needed for memset on Solaris. + FD_ZERO(&fd_set_); + } + + bool set(socket_type descriptor) + { + if (descriptor < (socket_type)FD_SETSIZE) + { + if (max_descriptor_ == invalid_socket || descriptor > max_descriptor_) + max_descriptor_ = descriptor; + FD_SET(descriptor, &fd_set_); + return true; + } + return false; + } + + void set(reactor_op_queue& operations, op_queue& ops) + { + reactor_op_queue::iterator i = operations.begin(); + while (i != operations.end()) + { + reactor_op_queue::iterator op_iter = i++; + if (!set(op_iter->first)) + { + asio::error_code ec(error::fd_set_failure); + operations.cancel_operations(op_iter, ops, ec); + } + } + } + + bool is_set(socket_type descriptor) const + { + return FD_ISSET(descriptor, &fd_set_) != 0; + } + + operator fd_set*() + { + return &fd_set_; + } + + socket_type max_descriptor() const + { + return max_descriptor_; + } + + void perform(reactor_op_queue& operations, + op_queue& ops) const + { + reactor_op_queue::iterator i = operations.begin(); + while (i != operations.end()) + { + reactor_op_queue::iterator op_iter = i++; + if (is_set(op_iter->first)) + operations.perform_operations(op_iter, ops); + } + } + +private: + mutable fd_set fd_set_; + socket_type max_descriptor_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_WINDOWS) + // && !defined(__CYGWIN__) + // && !defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP diff --git a/tools/sdk/include/asio/asio/detail/posix_global.hpp b/tools/sdk/include/asio/asio/detail/posix_global.hpp new file mode 100644 index 00000000..7ee0a715 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/posix_global.hpp @@ -0,0 +1,80 @@ +// +// detail/posix_global.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_POSIX_GLOBAL_HPP +#define ASIO_DETAIL_POSIX_GLOBAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_PTHREADS) + +#include +#include + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +struct posix_global_impl +{ + // Helper function to perform initialisation. + static void do_init() + { + instance_.static_ptr_ = instance_.ptr_ = new T; + } + + // Destructor automatically cleans up the global. + ~posix_global_impl() + { + delete static_ptr_; + } + + static ::pthread_once_t init_once_; + static T* static_ptr_; + static posix_global_impl instance_; + T* ptr_; +}; + +template +::pthread_once_t posix_global_impl::init_once_ = PTHREAD_ONCE_INIT; + +template +T* posix_global_impl::static_ptr_ = 0; + +template +posix_global_impl posix_global_impl::instance_; + +template +T& posix_global() +{ + int result = ::pthread_once( + &posix_global_impl::init_once_, + &posix_global_impl::do_init); + + if (result != 0) + std::terminate(); + + return *posix_global_impl::instance_.ptr_; +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_PTHREADS) + +#endif // ASIO_DETAIL_POSIX_GLOBAL_HPP diff --git a/tools/sdk/include/asio/asio/detail/posix_mutex.hpp b/tools/sdk/include/asio/asio/detail/posix_mutex.hpp new file mode 100644 index 00000000..c0d9fc9b --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/posix_mutex.hpp @@ -0,0 +1,76 @@ +// +// detail/posix_mutex.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_POSIX_MUTEX_HPP +#define ASIO_DETAIL_POSIX_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_PTHREADS) + +#include +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/scoped_lock.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class posix_event; + +class posix_mutex + : private noncopyable +{ +public: + typedef asio::detail::scoped_lock scoped_lock; + + // Constructor. + ASIO_DECL posix_mutex(); + + // Destructor. + ~posix_mutex() + { + ::pthread_mutex_destroy(&mutex_); // Ignore EBUSY. + } + + // Lock the mutex. + void lock() + { + (void)::pthread_mutex_lock(&mutex_); // Ignore EINVAL. + } + + // Unlock the mutex. + void unlock() + { + (void)::pthread_mutex_unlock(&mutex_); // Ignore EINVAL. + } + +private: + friend class posix_event; + ::pthread_mutex_t mutex_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/posix_mutex.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_PTHREADS) + +#endif // ASIO_DETAIL_POSIX_MUTEX_HPP diff --git a/tools/sdk/include/asio/asio/detail/posix_signal_blocker.hpp b/tools/sdk/include/asio/asio/detail/posix_signal_blocker.hpp new file mode 100644 index 00000000..fab5eb12 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/posix_signal_blocker.hpp @@ -0,0 +1,85 @@ +// +// detail/posix_signal_blocker.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_POSIX_SIGNAL_BLOCKER_HPP +#define ASIO_DETAIL_POSIX_SIGNAL_BLOCKER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_PTHREADS) + +#include +#include +#include +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class posix_signal_blocker + : private noncopyable +{ +public: + // Constructor blocks all signals for the calling thread. + posix_signal_blocker() + : blocked_(false) + { + sigset_t new_mask; + sigfillset(&new_mask); + blocked_ = (pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask_) == 0); + } + + // Destructor restores the previous signal mask. + ~posix_signal_blocker() + { + if (blocked_) + pthread_sigmask(SIG_SETMASK, &old_mask_, 0); + } + + // Block all signals for the calling thread. + void block() + { + if (!blocked_) + { + sigset_t new_mask; + sigfillset(&new_mask); + blocked_ = (pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask_) == 0); + } + } + + // Restore the previous signal mask. + void unblock() + { + if (blocked_) + blocked_ = (pthread_sigmask(SIG_SETMASK, &old_mask_, 0) != 0); + } + +private: + // Have signals been blocked. + bool blocked_; + + // The previous signal mask. + sigset_t old_mask_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_PTHREADS) + +#endif // ASIO_DETAIL_POSIX_SIGNAL_BLOCKER_HPP diff --git a/tools/sdk/include/asio/asio/detail/posix_static_mutex.hpp b/tools/sdk/include/asio/asio/detail/posix_static_mutex.hpp new file mode 100644 index 00000000..59b86c18 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/posix_static_mutex.hpp @@ -0,0 +1,64 @@ +// +// detail/posix_static_mutex.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_POSIX_STATIC_MUTEX_HPP +#define ASIO_DETAIL_POSIX_STATIC_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_PTHREADS) + +#include +#include "asio/detail/scoped_lock.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +struct posix_static_mutex +{ + typedef asio::detail::scoped_lock scoped_lock; + + // Initialise the mutex. + void init() + { + // Nothing to do. + } + + // Lock the mutex. + void lock() + { + (void)::pthread_mutex_lock(&mutex_); // Ignore EINVAL. + } + + // Unlock the mutex. + void unlock() + { + (void)::pthread_mutex_unlock(&mutex_); // Ignore EINVAL. + } + + ::pthread_mutex_t mutex_; +}; + +#define ASIO_POSIX_STATIC_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER } + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_PTHREADS) + +#endif // ASIO_DETAIL_POSIX_STATIC_MUTEX_HPP diff --git a/tools/sdk/include/asio/asio/detail/posix_thread.hpp b/tools/sdk/include/asio/asio/detail/posix_thread.hpp new file mode 100644 index 00000000..1817af28 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/posix_thread.hpp @@ -0,0 +1,109 @@ +// +// detail/posix_thread.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_POSIX_THREAD_HPP +#define ASIO_DETAIL_POSIX_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_PTHREADS) + +#include +#include +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +extern "C" +{ + ASIO_DECL void* asio_detail_posix_thread_function(void* arg); +} + +class posix_thread + : private noncopyable +{ +public: + // Constructor. + template + posix_thread(Function f, unsigned int = 0) + : joined_(false) + { + start_thread(new func(f)); + } + + // Destructor. + ASIO_DECL ~posix_thread(); + + // Wait for the thread to exit. + ASIO_DECL void join(); + + // Get number of CPUs. + ASIO_DECL static std::size_t hardware_concurrency(); + +private: + friend void* asio_detail_posix_thread_function(void* arg); + + class func_base + { + public: + virtual ~func_base() {} + virtual void run() = 0; + }; + + struct auto_func_base_ptr + { + func_base* ptr; + ~auto_func_base_ptr() { delete ptr; } + }; + + template + class func + : public func_base + { + public: + func(Function f) + : f_(f) + { + } + + virtual void run() + { + f_(); + } + + private: + Function f_; + }; + + ASIO_DECL void start_thread(func_base* arg); + + ::pthread_t thread_; + bool joined_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/posix_thread.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_PTHREADS) + +#endif // ASIO_DETAIL_POSIX_THREAD_HPP diff --git a/tools/sdk/include/asio/asio/detail/posix_tss_ptr.hpp b/tools/sdk/include/asio/asio/detail/posix_tss_ptr.hpp new file mode 100644 index 00000000..a3096b43 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/posix_tss_ptr.hpp @@ -0,0 +1,79 @@ +// +// detail/posix_tss_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_POSIX_TSS_PTR_HPP +#define ASIO_DETAIL_POSIX_TSS_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_PTHREADS) + +#include +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Helper function to create thread-specific storage. +ASIO_DECL void posix_tss_ptr_create(pthread_key_t& key); + +template +class posix_tss_ptr + : private noncopyable +{ +public: + // Constructor. + posix_tss_ptr() + { + posix_tss_ptr_create(tss_key_); + } + + // Destructor. + ~posix_tss_ptr() + { + ::pthread_key_delete(tss_key_); + } + + // Get the value. + operator T*() const + { + return static_cast(::pthread_getspecific(tss_key_)); + } + + // Set the value. + void operator=(T* value) + { + ::pthread_setspecific(tss_key_, value); + } + +private: + // Thread-specific storage to allow unlocked access to determine whether a + // thread is a member of the pool. + pthread_key_t tss_key_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/posix_tss_ptr.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_PTHREADS) + +#endif // ASIO_DETAIL_POSIX_TSS_PTR_HPP diff --git a/tools/sdk/include/asio/asio/detail/push_options.hpp b/tools/sdk/include/asio/asio/detail/push_options.hpp new file mode 100644 index 00000000..0a3e9798 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/push_options.hpp @@ -0,0 +1,175 @@ +// +// detail/push_options.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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) +// + +// No header guard + +#if defined(__COMO__) + +// Comeau C++ + +#elif defined(__DMC__) + +// Digital Mars C++ + +#elif defined(__INTEL_COMPILER) || defined(__ICL) \ + || defined(__ICC) || defined(__ECC) + +// Intel C++ + +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) + +#elif defined(__clang__) + +// Clang + +# if defined(__OBJC__) +# if !defined(__APPLE_CC__) || (__APPLE_CC__ <= 1) +# if !defined(ASIO_DISABLE_OBJC_WORKAROUND) +# if !defined(Protocol) && !defined(id) +# define Protocol cpp_Protocol +# define id cpp_id +# define ASIO_OBJC_WORKAROUND +# endif +# endif +# endif +# endif + +# if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) +# pragma GCC visibility push (default) +# endif // !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) + +#elif defined(__GNUC__) + +// GNU C++ + +# if defined(__MINGW32__) || defined(__CYGWIN__) +# pragma pack (push, 8) +# endif + +# if defined(__OBJC__) +# if !defined(__APPLE_CC__) || (__APPLE_CC__ <= 1) +# if !defined(ASIO_DISABLE_OBJC_WORKAROUND) +# if !defined(Protocol) && !defined(id) +# define Protocol cpp_Protocol +# define id cpp_id +# define ASIO_OBJC_WORKAROUND +# endif +# endif +# endif +# endif + +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) + +# if (__GNUC__ >= 7) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +# endif // (__GNUC__ >= 7) + +#elif defined(__KCC) + +// Kai C++ + +#elif defined(__sgi) + +// SGI MIPSpro C++ + +#elif defined(__DECCXX) + +// Compaq Tru64 Unix cxx + +#elif defined(__ghs) + +// Greenhills C++ + +#elif defined(__BORLANDC__) + +// Borland C++ + +# pragma option push -a8 -b -Ve- -Vx- -w-inl -vi- +# pragma nopushoptwarn +# pragma nopackwarning +# if !defined(__MT__) +# error Multithreaded RTL must be selected. +# endif // !defined(__MT__) + +#elif defined(__MWERKS__) + +// Metrowerks CodeWarrior + +#elif defined(__SUNPRO_CC) + +// Sun Workshop Compiler C++ + +#elif defined(__HP_aCC) + +// HP aCC + +#elif defined(__MRC__) || defined(__SC__) + +// MPW MrCpp or SCpp + +#elif defined(__IBMCPP__) + +// IBM Visual Age + +#elif defined(_MSC_VER) + +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for example) +// also #define _MSC_VER + +# pragma warning (disable:4103) +# pragma warning (push) +# pragma warning (disable:4127) +# pragma warning (disable:4180) +# pragma warning (disable:4244) +# pragma warning (disable:4355) +# pragma warning (disable:4510) +# pragma warning (disable:4512) +# pragma warning (disable:4610) +# pragma warning (disable:4675) +# if (_MSC_VER < 1600) +// Visual Studio 2008 generates spurious warnings about unused parameters. +# pragma warning (disable:4100) +# endif // (_MSC_VER < 1600) +# if defined(_M_IX86) && defined(_Wp64) +// The /Wp64 option is broken. If you want to check 64 bit portability, use a +// 64 bit compiler! +# pragma warning (disable:4311) +# pragma warning (disable:4312) +# endif // defined(_M_IX86) && defined(_Wp64) +# pragma pack (push, 8) +// Note that if the /Og optimisation flag is enabled with MSVC6, the compiler +// has a tendency to incorrectly optimise away some calls to member template +// functions, even though those functions contain code that should not be +// optimised away! Therefore we will always disable this optimisation option +// for the MSVC6 compiler. +# if (_MSC_VER < 1300) +# pragma optimize ("g", off) +# endif +# if !defined(_MT) +# error Multithreaded RTL must be selected. +# endif // !defined(_MT) + +# if defined(__cplusplus_cli) || defined(__cplusplus_winrt) +# if !defined(ASIO_DISABLE_CLR_WORKAROUND) +# if !defined(generic) +# define generic cpp_generic +# define ASIO_CLR_WORKAROUND +# endif +# endif +# endif + +#endif diff --git a/tools/sdk/include/asio/asio/detail/reactive_descriptor_service.hpp b/tools/sdk/include/asio/asio/detail/reactive_descriptor_service.hpp new file mode 100644 index 00000000..e8668639 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactive_descriptor_service.hpp @@ -0,0 +1,388 @@ +// +// detail/reactive_descriptor_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTIVE_DESCRIPTOR_SERVICE_HPP +#define ASIO_DETAIL_REACTIVE_DESCRIPTOR_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_WINDOWS) \ + && !defined(ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) + +#include "asio/buffer.hpp" +#include "asio/io_context.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/descriptor_ops.hpp" +#include "asio/detail/descriptor_read_op.hpp" +#include "asio/detail/descriptor_write_op.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/reactive_null_buffers_op.hpp" +#include "asio/detail/reactive_wait_op.hpp" +#include "asio/detail/reactor.hpp" +#include "asio/posix/descriptor_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class reactive_descriptor_service : + public service_base +{ +public: + // The native type of a descriptor. + typedef int native_handle_type; + + // The implementation type of the descriptor. + class implementation_type + : private asio::detail::noncopyable + { + public: + // Default constructor. + implementation_type() + : descriptor_(-1), + state_(0) + { + } + + private: + // Only this service will have access to the internal values. + friend class reactive_descriptor_service; + + // The native descriptor representation. + int descriptor_; + + // The current state of the descriptor. + descriptor_ops::state_type state_; + + // Per-descriptor data used by the reactor. + reactor::per_descriptor_data reactor_data_; + }; + + // Constructor. + ASIO_DECL reactive_descriptor_service( + asio::io_context& io_context); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Construct a new descriptor implementation. + ASIO_DECL void construct(implementation_type& impl); + + // Move-construct a new descriptor implementation. + ASIO_DECL void move_construct(implementation_type& impl, + implementation_type& other_impl); + + // Move-assign from another descriptor implementation. + ASIO_DECL void move_assign(implementation_type& impl, + reactive_descriptor_service& other_service, + implementation_type& other_impl); + + // Destroy a descriptor implementation. + ASIO_DECL void destroy(implementation_type& impl); + + // Assign a native descriptor to a descriptor implementation. + ASIO_DECL asio::error_code assign(implementation_type& impl, + const native_handle_type& native_descriptor, + asio::error_code& ec); + + // Determine whether the descriptor is open. + bool is_open(const implementation_type& impl) const + { + return impl.descriptor_ != -1; + } + + // Destroy a descriptor implementation. + ASIO_DECL asio::error_code close(implementation_type& impl, + asio::error_code& ec); + + // Get the native descriptor representation. + native_handle_type native_handle(const implementation_type& impl) const + { + return impl.descriptor_; + } + + // Release ownership of the native descriptor representation. + ASIO_DECL native_handle_type release(implementation_type& impl); + + // Cancel all operations associated with the descriptor. + ASIO_DECL asio::error_code cancel(implementation_type& impl, + asio::error_code& ec); + + // Perform an IO control command on the descriptor. + template + asio::error_code io_control(implementation_type& impl, + IO_Control_Command& command, asio::error_code& ec) + { + descriptor_ops::ioctl(impl.descriptor_, impl.state_, + command.name(), static_cast(command.data()), ec); + return ec; + } + + // Gets the non-blocking mode of the descriptor. + bool non_blocking(const implementation_type& impl) const + { + return (impl.state_ & descriptor_ops::user_set_non_blocking) != 0; + } + + // Sets the non-blocking mode of the descriptor. + asio::error_code non_blocking(implementation_type& impl, + bool mode, asio::error_code& ec) + { + descriptor_ops::set_user_non_blocking( + impl.descriptor_, impl.state_, mode, ec); + return ec; + } + + // Gets the non-blocking mode of the native descriptor implementation. + bool native_non_blocking(const implementation_type& impl) const + { + return (impl.state_ & descriptor_ops::internal_non_blocking) != 0; + } + + // Sets the non-blocking mode of the native descriptor implementation. + asio::error_code native_non_blocking(implementation_type& impl, + bool mode, asio::error_code& ec) + { + descriptor_ops::set_internal_non_blocking( + impl.descriptor_, impl.state_, mode, ec); + return ec; + } + + // Wait for the descriptor to become ready to read, ready to write, or to have + // pending error conditions. + asio::error_code wait(implementation_type& impl, + posix::descriptor_base::wait_type w, asio::error_code& ec) + { + switch (w) + { + case posix::descriptor_base::wait_read: + descriptor_ops::poll_read(impl.descriptor_, impl.state_, ec); + break; + case posix::descriptor_base::wait_write: + descriptor_ops::poll_write(impl.descriptor_, impl.state_, ec); + break; + case posix::descriptor_base::wait_error: + descriptor_ops::poll_error(impl.descriptor_, impl.state_, ec); + break; + default: + ec = asio::error::invalid_argument; + break; + } + + return ec; + } + + // Asynchronously wait for the descriptor to become ready to read, ready to + // write, or to have pending error conditions. + template + void async_wait(implementation_type& impl, + posix::descriptor_base::wait_type w, Handler& handler) + { + bool is_continuation = + 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 = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor", + &impl, impl.descriptor_, "async_wait")); + + int op_type; + switch (w) + { + case posix::descriptor_base::wait_read: + op_type = reactor::read_op; + break; + case posix::descriptor_base::wait_write: + op_type = reactor::write_op; + break; + case posix::descriptor_base::wait_error: + op_type = reactor::except_op; + break; + default: + p.p->ec_ = 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; + } + + // Write some data to the descriptor. + template + size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + buffer_sequence_adapter bufs(buffers); + + return descriptor_ops::sync_write(impl.descriptor_, impl.state_, + bufs.buffers(), bufs.count(), bufs.all_empty(), ec); + } + + // Wait until data can be written without blocking. + size_t write_some(implementation_type& impl, + const null_buffers&, asio::error_code& ec) + { + // Wait for descriptor to become ready. + descriptor_ops::poll_write(impl.descriptor_, impl.state_, ec); + + return 0; + } + + // Start an asynchronous write. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, Handler& handler) + { + bool is_continuation = + asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef descriptor_write_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.descriptor_, buffers, handler); + + ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor", + &impl, impl.descriptor_, "async_write_some")); + + start_op(impl, reactor::write_op, p.p, is_continuation, true, + buffer_sequence_adapter::all_empty(buffers)); + p.v = p.p = 0; + } + + // Start an asynchronous wait until data can be written without blocking. + template + void async_write_some(implementation_type& impl, + const null_buffers&, Handler& handler) + { + bool is_continuation = + 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 = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor", + &impl, impl.descriptor_, "async_write_some(null_buffers)")); + + start_op(impl, reactor::write_op, p.p, is_continuation, false, false); + p.v = p.p = 0; + } + + // Read some data from the stream. Returns the number of bytes read. + template + size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + buffer_sequence_adapter bufs(buffers); + + return descriptor_ops::sync_read(impl.descriptor_, impl.state_, + bufs.buffers(), bufs.count(), bufs.all_empty(), ec); + } + + // Wait until data can be read without blocking. + size_t read_some(implementation_type& impl, + const null_buffers&, asio::error_code& ec) + { + // Wait for descriptor to become ready. + descriptor_ops::poll_read(impl.descriptor_, impl.state_, ec); + + return 0; + } + + // Start an asynchronous read. The buffer for the data being read must be + // valid for the lifetime of the asynchronous operation. + template + void async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, Handler& handler) + { + bool is_continuation = + asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef descriptor_read_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.descriptor_, buffers, handler); + + ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor", + &impl, impl.descriptor_, "async_read_some")); + + start_op(impl, reactor::read_op, p.p, is_continuation, true, + buffer_sequence_adapter::all_empty(buffers)); + p.v = p.p = 0; + } + + // Wait until data can be read without blocking. + template + void async_read_some(implementation_type& impl, + const null_buffers&, Handler& handler) + { + bool is_continuation = + 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 = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor", + &impl, impl.descriptor_, "async_read_some(null_buffers)")); + + start_op(impl, reactor::read_op, p.p, is_continuation, false, false); + p.v = p.p = 0; + } + +private: + // Start the asynchronous operation. + ASIO_DECL void start_op(implementation_type& impl, int op_type, + reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); + + // The selector that performs event demultiplexing for the service. + reactor& reactor_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/reactive_descriptor_service.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // !defined(ASIO_WINDOWS) + // && !defined(ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) + +#endif // ASIO_DETAIL_REACTIVE_DESCRIPTOR_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactive_null_buffers_op.hpp b/tools/sdk/include/asio/asio/detail/reactive_null_buffers_op.hpp new file mode 100644 index 00000000..74082692 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactive_null_buffers_op.hpp @@ -0,0 +1,90 @@ +// +// detail/reactive_null_buffers_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTIVE_NULL_BUFFERS_OP_HPP +#define ASIO_DETAIL_REACTIVE_NULL_BUFFERS_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactor_op.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class reactive_null_buffers_op : public reactor_op +{ +public: + ASIO_DEFINE_HANDLER_PTR(reactive_null_buffers_op); + + reactive_null_buffers_op(Handler& handler) + : reactor_op(&reactive_null_buffers_op::do_perform, + &reactive_null_buffers_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static status do_perform(reactor_op*) + { + return done; + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_null_buffers_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + 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::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTIVE_NULL_BUFFERS_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactive_serial_port_service.hpp b/tools/sdk/include/asio/asio/detail/reactive_serial_port_service.hpp new file mode 100644 index 00000000..6fddd9f1 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactive_serial_port_service.hpp @@ -0,0 +1,236 @@ +// +// detail/reactive_serial_port_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// 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 ASIO_DETAIL_REACTIVE_SERIAL_PORT_SERVICE_HPP +#define ASIO_DETAIL_REACTIVE_SERIAL_PORT_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_SERIAL_PORT) +#if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) + +#include +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/serial_port_base.hpp" +#include "asio/detail/descriptor_ops.hpp" +#include "asio/detail/reactive_descriptor_service.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Extend reactive_descriptor_service to provide serial port support. +class reactive_serial_port_service : + public service_base +{ +public: + // The native type of a serial port. + typedef reactive_descriptor_service::native_handle_type native_handle_type; + + // The implementation type of the serial port. + typedef reactive_descriptor_service::implementation_type implementation_type; + + ASIO_DECL reactive_serial_port_service( + asio::io_context& io_context); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Construct a new serial port implementation. + void construct(implementation_type& impl) + { + descriptor_service_.construct(impl); + } + + // Move-construct a new serial port implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + descriptor_service_.move_construct(impl, other_impl); + } + + // Move-assign from another serial port implementation. + void move_assign(implementation_type& impl, + reactive_serial_port_service& other_service, + implementation_type& other_impl) + { + descriptor_service_.move_assign(impl, + other_service.descriptor_service_, other_impl); + } + + // Destroy a serial port implementation. + void destroy(implementation_type& impl) + { + descriptor_service_.destroy(impl); + } + + // Open the serial port using the specified device name. + ASIO_DECL asio::error_code open(implementation_type& impl, + const std::string& device, asio::error_code& ec); + + // Assign a native descriptor to a serial port implementation. + asio::error_code assign(implementation_type& impl, + const native_handle_type& native_descriptor, + asio::error_code& ec) + { + return descriptor_service_.assign(impl, native_descriptor, ec); + } + + // Determine whether the serial port is open. + bool is_open(const implementation_type& impl) const + { + return descriptor_service_.is_open(impl); + } + + // Destroy a serial port implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + return descriptor_service_.close(impl, ec); + } + + // Get the native serial port representation. + native_handle_type native_handle(implementation_type& impl) + { + return descriptor_service_.native_handle(impl); + } + + // Cancel all operations associated with the serial port. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + return descriptor_service_.cancel(impl, ec); + } + + // Set an option on the serial port. + template + asio::error_code set_option(implementation_type& impl, + const SettableSerialPortOption& option, asio::error_code& ec) + { + return do_set_option(impl, + &reactive_serial_port_service::store_option, + &option, ec); + } + + // Get an option from the serial port. + template + asio::error_code get_option(const implementation_type& impl, + GettableSerialPortOption& option, asio::error_code& ec) const + { + return do_get_option(impl, + &reactive_serial_port_service::load_option, + &option, ec); + } + + // Send a break sequence to the serial port. + asio::error_code send_break(implementation_type& impl, + asio::error_code& ec) + { + errno = 0; + descriptor_ops::error_wrapper(::tcsendbreak( + descriptor_service_.native_handle(impl), 0), ec); + return ec; + } + + // Write the given data. Returns the number of bytes sent. + template + size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return descriptor_service_.write_some(impl, buffers, ec); + } + + // Start an asynchronous write. The data being written must be valid for the + // lifetime of the asynchronous operation. + template + void async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, Handler& handler) + { + descriptor_service_.async_write_some(impl, buffers, handler); + } + + // Read some data. Returns the number of bytes received. + template + size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return descriptor_service_.read_some(impl, buffers, ec); + } + + // Start an asynchronous read. The buffer for the data being received must be + // valid for the lifetime of the asynchronous operation. + template + void async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, Handler& handler) + { + descriptor_service_.async_read_some(impl, buffers, handler); + } + +private: + // Function pointer type for storing a serial port option. + typedef asio::error_code (*store_function_type)( + const void*, termios&, asio::error_code&); + + // Helper function template to store a serial port option. + template + static asio::error_code store_option(const void* option, + termios& storage, asio::error_code& ec) + { + static_cast(option)->store(storage, ec); + return ec; + } + + // Helper function to set a serial port option. + ASIO_DECL asio::error_code do_set_option( + implementation_type& impl, store_function_type store, + const void* option, asio::error_code& ec); + + // Function pointer type for loading a serial port option. + typedef asio::error_code (*load_function_type)( + void*, const termios&, asio::error_code&); + + // Helper function template to load a serial port option. + template + static asio::error_code load_option(void* option, + const termios& storage, asio::error_code& ec) + { + static_cast(option)->load(storage, ec); + return ec; + } + + // Helper function to get a serial port option. + ASIO_DECL asio::error_code do_get_option( + const implementation_type& impl, load_function_type load, + void* option, asio::error_code& ec) const; + + // The implementation used for initiating asynchronous operations. + reactive_descriptor_service descriptor_service_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/reactive_serial_port_service.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) +#endif // defined(ASIO_HAS_SERIAL_PORT) + +#endif // ASIO_DETAIL_REACTIVE_SERIAL_PORT_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactive_socket_accept_op.hpp b/tools/sdk/include/asio/asio/detail/reactive_socket_accept_op.hpp new file mode 100644 index 00000000..4a98f047 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactive_socket_accept_op.hpp @@ -0,0 +1,217 @@ +// +// detail/reactive_socket_accept_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP +#define ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/socket_holder.hpp" +#include "asio/detail/socket_ops.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class reactive_socket_accept_op_base : public reactor_op +{ +public: + reactive_socket_accept_op_base(socket_type socket, + socket_ops::state_type state, Socket& peer, const Protocol& protocol, + typename Protocol::endpoint* peer_endpoint, func_type complete_func) + : reactor_op(&reactive_socket_accept_op_base::do_perform, complete_func), + socket_(socket), + state_(state), + peer_(peer), + protocol_(protocol), + peer_endpoint_(peer_endpoint), + addrlen_(peer_endpoint ? peer_endpoint->capacity() : 0) + { + } + + static status do_perform(reactor_op* base) + { + reactive_socket_accept_op_base* o( + static_cast(base)); + + socket_type new_socket = invalid_socket; + status result = socket_ops::non_blocking_accept(o->socket_, + o->state_, o->peer_endpoint_ ? o->peer_endpoint_->data() : 0, + o->peer_endpoint_ ? &o->addrlen_ : 0, o->ec_, new_socket) + ? done : not_done; + o->new_socket_.reset(new_socket); + + ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_accept", o->ec_)); + + return result; + } + + void do_assign() + { + if (new_socket_.get() != invalid_socket) + { + if (peer_endpoint_) + peer_endpoint_->resize(addrlen_); + peer_.assign(protocol_, new_socket_.get(), ec_); + if (!ec_) + new_socket_.release(); + } + } + +private: + socket_type socket_; + socket_ops::state_type state_; + socket_holder new_socket_; + Socket& peer_; + Protocol protocol_; + typename Protocol::endpoint* peer_endpoint_; + std::size_t addrlen_; +}; + +template +class reactive_socket_accept_op : + public reactive_socket_accept_op_base +{ +public: + ASIO_DEFINE_HANDLER_PTR(reactive_socket_accept_op); + + reactive_socket_accept_op(socket_type socket, + socket_ops::state_type state, Socket& peer, const Protocol& protocol, + typename Protocol::endpoint* peer_endpoint, Handler& handler) + : reactive_socket_accept_op_base(socket, state, peer, + protocol, peer_endpoint, &reactive_socket_accept_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_accept_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + // On success, assign new connection to peer socket object. + if (owner) + o->do_assign(); + + 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::binder1 + handler(o->handler_, o->ec_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +#if defined(ASIO_HAS_MOVE) + +template +class reactive_socket_move_accept_op : + private Protocol::socket, + public reactive_socket_accept_op_base +{ +public: + ASIO_DEFINE_HANDLER_PTR(reactive_socket_move_accept_op); + + reactive_socket_move_accept_op(io_context& ioc, socket_type socket, + socket_ops::state_type state, const Protocol& protocol, + typename Protocol::endpoint* peer_endpoint, Handler& handler) + : Protocol::socket(ioc), + reactive_socket_accept_op_base( + socket, state, *this, protocol, peer_endpoint, + &reactive_socket_move_accept_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_move_accept_op* o( + static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + // On success, assign new connection to peer socket object. + if (owner) + o->do_assign(); + + 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::move_binder2 + handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_, + ASIO_MOVE_CAST(typename Protocol::socket)(*o)); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "...")); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +#endif // defined(ASIO_HAS_MOVE) + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactive_socket_connect_op.hpp b/tools/sdk/include/asio/asio/detail/reactive_socket_connect_op.hpp new file mode 100644 index 00000000..76164b2a --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactive_socket_connect_op.hpp @@ -0,0 +1,113 @@ +// +// detail/reactive_socket_connect_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP +#define ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/socket_ops.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class reactive_socket_connect_op_base : public reactor_op +{ +public: + reactive_socket_connect_op_base(socket_type socket, func_type complete_func) + : reactor_op(&reactive_socket_connect_op_base::do_perform, complete_func), + socket_(socket) + { + } + + static status do_perform(reactor_op* base) + { + reactive_socket_connect_op_base* o( + static_cast(base)); + + status result = socket_ops::non_blocking_connect( + o->socket_, o->ec_) ? done : not_done; + + ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_connect", o->ec_)); + + return result; + } + +private: + socket_type socket_; +}; + +template +class reactive_socket_connect_op : public reactive_socket_connect_op_base +{ +public: + ASIO_DEFINE_HANDLER_PTR(reactive_socket_connect_op); + + reactive_socket_connect_op(socket_type socket, Handler& handler) + : reactive_socket_connect_op_base(socket, + &reactive_socket_connect_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_connect_op* o + (static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + 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::binder1 + handler(o->handler_, o->ec_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactive_socket_recv_op.hpp b/tools/sdk/include/asio/asio/detail/reactive_socket_recv_op.hpp new file mode 100644 index 00000000..04bd266f --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactive_socket_recv_op.hpp @@ -0,0 +1,135 @@ +// +// detail/reactive_socket_recv_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_HPP +#define ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/socket_ops.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class reactive_socket_recv_op_base : public reactor_op +{ +public: + reactive_socket_recv_op_base(socket_type socket, + socket_ops::state_type state, const MutableBufferSequence& buffers, + socket_base::message_flags flags, func_type complete_func) + : reactor_op(&reactive_socket_recv_op_base::do_perform, complete_func), + socket_(socket), + state_(state), + buffers_(buffers), + flags_(flags) + { + } + + static status do_perform(reactor_op* base) + { + reactive_socket_recv_op_base* 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; + + 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 : + public reactive_socket_recv_op_base +{ +public: + ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op); + + reactive_socket_recv_op(socket_type socket, + socket_ops::state_type state, const MutableBufferSequence& buffers, + socket_base::message_flags flags, Handler& handler) + : reactive_socket_recv_op_base(socket, state, + buffers, flags, &reactive_socket_recv_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_recv_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + 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::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactive_socket_recvfrom_op.hpp b/tools/sdk/include/asio/asio/detail/reactive_socket_recvfrom_op.hpp new file mode 100644 index 00000000..3d4fa4ca --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactive_socket_recvfrom_op.hpp @@ -0,0 +1,138 @@ +// +// detail/reactive_socket_recvfrom_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_HPP +#define ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/socket_ops.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class reactive_socket_recvfrom_op_base : public reactor_op +{ +public: + reactive_socket_recvfrom_op_base(socket_type socket, int protocol_type, + const MutableBufferSequence& buffers, Endpoint& endpoint, + socket_base::message_flags flags, func_type complete_func) + : reactor_op(&reactive_socket_recvfrom_op_base::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* 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_) ? done : not_done; + + if (result && !o->ec_) + o->sender_endpoint_.resize(addr_len); + + 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 : + public reactive_socket_recvfrom_op_base +{ +public: + ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op); + + reactive_socket_recvfrom_op(socket_type socket, int protocol_type, + const MutableBufferSequence& buffers, Endpoint& endpoint, + socket_base::message_flags flags, Handler& handler) + : reactive_socket_recvfrom_op_base( + socket, protocol_type, buffers, endpoint, flags, + &reactive_socket_recvfrom_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_recvfrom_op* o( + static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + 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::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactive_socket_recvmsg_op.hpp b/tools/sdk/include/asio/asio/detail/reactive_socket_recvmsg_op.hpp new file mode 100644 index 00000000..f4732747 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactive_socket_recvmsg_op.hpp @@ -0,0 +1,132 @@ +// +// detail/reactive_socket_recvmsg_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_HPP +#define ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/socket_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class reactive_socket_recvmsg_op_base : public reactor_op +{ +public: + reactive_socket_recvmsg_op_base(socket_type socket, + const MutableBufferSequence& buffers, socket_base::message_flags in_flags, + socket_base::message_flags& out_flags, func_type complete_func) + : reactor_op(&reactive_socket_recvmsg_op_base::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* 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; + + 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 : + public reactive_socket_recvmsg_op_base +{ +public: + ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op); + + reactive_socket_recvmsg_op(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(socket, buffers, + in_flags, out_flags, &reactive_socket_recvmsg_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_recvmsg_op* o( + static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + 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::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactive_socket_send_op.hpp b/tools/sdk/include/asio/asio/detail/reactive_socket_send_op.hpp new file mode 100644 index 00000000..bd550d9c --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactive_socket_send_op.hpp @@ -0,0 +1,134 @@ +// +// detail/reactive_socket_send_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTIVE_SOCKET_SEND_OP_HPP +#define ASIO_DETAIL_REACTIVE_SOCKET_SEND_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/socket_ops.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class reactive_socket_send_op_base : public reactor_op +{ +public: + reactive_socket_send_op_base(socket_type socket, + socket_ops::state_type state, const ConstBufferSequence& buffers, + socket_base::message_flags flags, func_type complete_func) + : reactor_op(&reactive_socket_send_op_base::do_perform, complete_func), + socket_(socket), + state_(state), + buffers_(buffers), + flags_(flags) + { + } + + static status do_perform(reactor_op* base) + { + reactive_socket_send_op_base* o( + static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + status result = socket_ops::non_blocking_send(o->socket_, + bufs.buffers(), bufs.count(), o->flags_, + o->ec_, o->bytes_transferred_) ? done : not_done; + + if (result == done) + if ((o->state_ & socket_ops::stream_oriented) != 0) + if (o->bytes_transferred_ < bufs.total_size()) + result = done_and_exhausted; + + ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_send", + o->ec_, o->bytes_transferred_)); + + return result; + } + +private: + socket_type socket_; + socket_ops::state_type state_; + ConstBufferSequence buffers_; + socket_base::message_flags flags_; +}; + +template +class reactive_socket_send_op : + public reactive_socket_send_op_base +{ +public: + ASIO_DEFINE_HANDLER_PTR(reactive_socket_send_op); + + reactive_socket_send_op(socket_type socket, + socket_ops::state_type state, const ConstBufferSequence& buffers, + socket_base::message_flags flags, Handler& handler) + : reactive_socket_send_op_base(socket, + state, buffers, flags, &reactive_socket_send_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_send_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + 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::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTIVE_SOCKET_SEND_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactive_socket_sendto_op.hpp b/tools/sdk/include/asio/asio/detail/reactive_socket_sendto_op.hpp new file mode 100644 index 00000000..c97554d7 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactive_socket_sendto_op.hpp @@ -0,0 +1,130 @@ +// +// detail/reactive_socket_sendto_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTIVE_SOCKET_SENDTO_OP_HPP +#define ASIO_DETAIL_REACTIVE_SOCKET_SENDTO_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/socket_ops.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class reactive_socket_sendto_op_base : public reactor_op +{ +public: + reactive_socket_sendto_op_base(socket_type socket, + const ConstBufferSequence& buffers, const Endpoint& endpoint, + socket_base::message_flags flags, func_type complete_func) + : reactor_op(&reactive_socket_sendto_op_base::do_perform, complete_func), + socket_(socket), + buffers_(buffers), + destination_(endpoint), + flags_(flags) + { + } + + static status do_perform(reactor_op* base) + { + reactive_socket_sendto_op_base* o( + static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + status result = socket_ops::non_blocking_sendto(o->socket_, + bufs.buffers(), bufs.count(), o->flags_, + o->destination_.data(), o->destination_.size(), + o->ec_, o->bytes_transferred_) ? done : not_done; + + ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_sendto", + o->ec_, o->bytes_transferred_)); + + return result; + } + +private: + socket_type socket_; + ConstBufferSequence buffers_; + Endpoint destination_; + socket_base::message_flags flags_; +}; + +template +class reactive_socket_sendto_op : + public reactive_socket_sendto_op_base +{ +public: + ASIO_DEFINE_HANDLER_PTR(reactive_socket_sendto_op); + + reactive_socket_sendto_op(socket_type socket, + const ConstBufferSequence& buffers, const Endpoint& endpoint, + socket_base::message_flags flags, Handler& handler) + : reactive_socket_sendto_op_base(socket, + buffers, endpoint, flags, &reactive_socket_sendto_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_sendto_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + 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::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTIVE_SOCKET_SENDTO_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactive_socket_service.hpp b/tools/sdk/include/asio/asio/detail/reactive_socket_service.hpp new file mode 100644 index 00000000..15a4fdb5 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactive_socket_service.hpp @@ -0,0 +1,526 @@ +// +// detail/reactive_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP +#define ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_IOCP) + +#include "asio/buffer.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/socket_base.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/reactive_null_buffers_op.hpp" +#include "asio/detail/reactive_socket_accept_op.hpp" +#include "asio/detail/reactive_socket_connect_op.hpp" +#include "asio/detail/reactive_socket_recvfrom_op.hpp" +#include "asio/detail/reactive_socket_sendto_op.hpp" +#include "asio/detail/reactive_socket_service_base.hpp" +#include "asio/detail/reactor.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/socket_holder.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class reactive_socket_service : + public service_base >, + public reactive_socket_service_base +{ +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::base_implementation_type + { + // Default constructor. + implementation_type() + : protocol_(endpoint_type().protocol()) + { + } + + // The protocol associated with the socket. + protocol_type protocol_; + }; + + // Constructor. + reactive_socket_service(asio::io_context& io_context) + : service_base >(io_context), + reactive_socket_service_base(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& 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&, + typename reactive_socket_service< + 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. + asio::error_code open(implementation_type& impl, + const protocol_type& protocol, asio::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. + asio::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_handle_type& native_socket, + asio::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. + asio::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); + return ec; + } + + // Set a socket option. + template + asio::error_code set_option(implementation_type& impl, + const Option& option, asio::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 + asio::error_code get_option(const implementation_type& impl, + Option& option, asio::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, + asio::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, + asio::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. + asio::error_code shutdown(base_implementation_type& impl, + socket_base::shutdown_type what, asio::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, + asio::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, + asio::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 = + 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 = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler); + + 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 = + 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 = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + 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, + asio::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, + asio::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 = + asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_recvfrom_op op; + typename op::ptr p = { 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); + + 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 = + 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 = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + 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 + asio::error_code accept(implementation_type& impl, + Socket& peer, endpoint_type* peer_endpoint, asio::error_code& ec) + { + // We cannot accept a socket that is already open. + if (peer.is_open()) + { + ec = 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(ASIO_HAS_MOVE) + // Accept a new connection. + typename Protocol::socket accept(implementation_type& impl, + io_context* peer_io_context, endpoint_type* peer_endpoint, + asio::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(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 = + 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 = { 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); + + 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(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, + asio::io_context* peer_io_context, + endpoint_type* peer_endpoint, Handler& handler) + { + bool is_continuation = + 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 = { 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); + + 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(ASIO_HAS_MOVE) + + // Connect the socket to the specified endpoint. + asio::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, asio::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 = + 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 = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.socket_, handler); + + 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 + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactive_socket_service_base.hpp b/tools/sdk/include/asio/asio/detail/reactive_socket_service_base.hpp new file mode 100644 index 00000000..ccd497e8 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactive_socket_service_base.hpp @@ -0,0 +1,511 @@ +// +// detail/reactive_socket_service_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_HPP +#define ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_IOCP) \ + && !defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/buffer.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/socket_base.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactive_null_buffers_op.hpp" +#include "asio/detail/reactive_socket_recv_op.hpp" +#include "asio/detail/reactive_socket_recvmsg_op.hpp" +#include "asio/detail/reactive_socket_send_op.hpp" +#include "asio/detail/reactive_wait_op.hpp" +#include "asio/detail/reactor.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/socket_holder.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class reactive_socket_service_base +{ +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. + ASIO_DECL reactive_socket_service_base( + asio::io_context& io_context); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void base_shutdown(); + + // Construct a new socket implementation. + ASIO_DECL void construct(base_implementation_type& impl); + + // Move-construct a new socket implementation. + ASIO_DECL void base_move_construct(base_implementation_type& impl, + base_implementation_type& other_impl); + + // Move-assign from another socket implementation. + ASIO_DECL void base_move_assign(base_implementation_type& impl, + reactive_socket_service_base& other_service, + base_implementation_type& other_impl); + + // Destroy a socket implementation. + 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. + ASIO_DECL asio::error_code close( + base_implementation_type& impl, asio::error_code& ec); + + // Release ownership of the socket. + ASIO_DECL socket_type release( + base_implementation_type& impl, asio::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. + ASIO_DECL asio::error_code cancel( + base_implementation_type& impl, asio::error_code& ec); + + // Determine whether the socket is at the out-of-band data mark. + bool at_mark(const base_implementation_type& impl, + asio::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, + asio::error_code& ec) const + { + return socket_ops::available(impl.socket_, ec); + } + + // Place the socket into the state where it will listen for new connections. + asio::error_code listen(base_implementation_type& impl, + int backlog, asio::error_code& ec) + { + socket_ops::listen(impl.socket_, backlog, ec); + return ec; + } + + // Perform an IO control command on the socket. + template + asio::error_code io_control(base_implementation_type& impl, + IO_Control_Command& command, asio::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. + asio::error_code non_blocking(base_implementation_type& impl, + bool mode, asio::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. + asio::error_code native_non_blocking(base_implementation_type& impl, + bool mode, asio::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. + asio::error_code wait(base_implementation_type& impl, + socket_base::wait_type w, asio::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 = 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 = + 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 = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + 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_ = 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, asio::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, asio::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 = + 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 = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); + + 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 = + 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 = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + 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, asio::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, asio::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 = + asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_recv_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); + + 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 = + 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 = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + 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, asio::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, asio::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 = + asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_recvmsg_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler); + + 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 = + 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 = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + 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. + ASIO_DECL asio::error_code do_open( + base_implementation_type& impl, int af, + int type, int protocol, asio::error_code& ec); + + // Assign a native socket to a socket implementation. + ASIO_DECL asio::error_code do_assign( + base_implementation_type& impl, int type, + const native_handle_type& native_socket, asio::error_code& ec); + + // Start the asynchronous read or write operation. + 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. + 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. + 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 + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/reactive_socket_service_base.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // !defined(ASIO_HAS_IOCP) + // && !defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactive_wait_op.hpp b/tools/sdk/include/asio/asio/detail/reactive_wait_op.hpp new file mode 100644 index 00000000..616d8b11 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactive_wait_op.hpp @@ -0,0 +1,90 @@ +// +// detail/reactive_wait_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTIVE_WAIT_OP_HPP +#define ASIO_DETAIL_REACTIVE_WAIT_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactor_op.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class reactive_wait_op : public reactor_op +{ +public: + ASIO_DEFINE_HANDLER_PTR(reactive_wait_op); + + reactive_wait_op(Handler& handler) + : reactor_op(&reactive_wait_op::do_perform, + &reactive_wait_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static status do_perform(reactor_op*) + { + return done; + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_wait_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + 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::binder1 + handler(o->handler_, o->ec_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTIVE_WAIT_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactor.hpp b/tools/sdk/include/asio/asio/detail/reactor.hpp new file mode 100644 index 00000000..47502764 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactor.hpp @@ -0,0 +1,32 @@ +// +// detail/reactor.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTOR_HPP +#define ASIO_DETAIL_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/reactor_fwd.hpp" + +#if defined(ASIO_HAS_EPOLL) +# include "asio/detail/epoll_reactor.hpp" +#elif defined(ASIO_HAS_KQUEUE) +# include "asio/detail/kqueue_reactor.hpp" +#elif defined(ASIO_HAS_DEV_POLL) +# include "asio/detail/dev_poll_reactor.hpp" +#elif defined(ASIO_HAS_IOCP) || defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/null_reactor.hpp" +#else +# include "asio/detail/select_reactor.hpp" +#endif + +#endif // ASIO_DETAIL_REACTOR_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactor_fwd.hpp b/tools/sdk/include/asio/asio/detail/reactor_fwd.hpp new file mode 100644 index 00000000..a4555c3d --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactor_fwd.hpp @@ -0,0 +1,40 @@ +// +// detail/reactor_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTOR_FWD_HPP +#define ASIO_DETAIL_REACTOR_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +namespace asio { +namespace detail { + +#if defined(ASIO_HAS_IOCP) || defined(ASIO_WINDOWS_RUNTIME) +typedef class null_reactor reactor; +#elif defined(ASIO_HAS_IOCP) +typedef class select_reactor reactor; +#elif defined(ASIO_HAS_EPOLL) +typedef class epoll_reactor reactor; +#elif defined(ASIO_HAS_KQUEUE) +typedef class kqueue_reactor reactor; +#elif defined(ASIO_HAS_DEV_POLL) +typedef class dev_poll_reactor reactor; +#else +typedef class select_reactor reactor; +#endif + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_REACTOR_FWD_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactor_op.hpp b/tools/sdk/include/asio/asio/detail/reactor_op.hpp new file mode 100644 index 00000000..faad1a77 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactor_op.hpp @@ -0,0 +1,65 @@ +// +// detail/reactor_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTOR_OP_HPP +#define ASIO_DETAIL_REACTOR_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/operation.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class reactor_op + : public operation +{ +public: + // The error code to be passed to the completion handler. + asio::error_code ec_; + + // The number of bytes transferred, to be passed to the completion handler. + std::size_t bytes_transferred_; + + // Status returned by perform function. May be used to decide whether it is + // worth performing more operations on the descriptor immediately. + enum status { not_done, done, done_and_exhausted }; + + // Perform the operation. Returns true if it is finished. + status perform() + { + return perform_func_(this); + } + +protected: + typedef status (*perform_func_type)(reactor_op*); + + reactor_op(perform_func_type perform_func, func_type complete_func) + : operation(complete_func), + bytes_transferred_(0), + perform_func_(perform_func) + { + } + +private: + perform_func_type perform_func_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTOR_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/reactor_op_queue.hpp b/tools/sdk/include/asio/asio/detail/reactor_op_queue.hpp new file mode 100644 index 00000000..898f31d1 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/reactor_op_queue.hpp @@ -0,0 +1,168 @@ +// +// detail/reactor_op_queue.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REACTOR_OP_QUEUE_HPP +#define ASIO_DETAIL_REACTOR_OP_QUEUE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/hash_map.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class reactor_op_queue + : private noncopyable +{ +public: + typedef Descriptor key_type; + + struct mapped_type : op_queue + { + mapped_type() {} + mapped_type(const mapped_type&) {} + void operator=(const mapped_type&) {} + }; + + typedef typename hash_map::value_type value_type; + typedef typename hash_map::iterator iterator; + + // Constructor. + reactor_op_queue() + : operations_() + { + } + + // Obtain iterators to all registered descriptors. + iterator begin() { return operations_.begin(); } + iterator end() { return operations_.end(); } + + // Add a new operation to the queue. Returns true if this is the only + // operation for the given descriptor, in which case the reactor's event + // demultiplexing function call may need to be interrupted and restarted. + bool enqueue_operation(Descriptor descriptor, reactor_op* op) + { + std::pair entry = + operations_.insert(value_type(descriptor, mapped_type())); + entry.first->second.push(op); + return entry.second; + } + + // Cancel all operations associated with the descriptor identified by the + // supplied iterator. Any operations pending for the descriptor will be + // cancelled. Returns true if any operations were cancelled, in which case + // the reactor's event demultiplexing function may need to be interrupted and + // restarted. + bool cancel_operations(iterator i, op_queue& ops, + const asio::error_code& ec = + asio::error::operation_aborted) + { + if (i != operations_.end()) + { + while (reactor_op* op = i->second.front()) + { + op->ec_ = ec; + i->second.pop(); + ops.push(op); + } + operations_.erase(i); + return true; + } + + return false; + } + + // Cancel all operations associated with the descriptor. Any operations + // pending for the descriptor will be cancelled. Returns true if any + // operations were cancelled, in which case the reactor's event + // demultiplexing function may need to be interrupted and restarted. + bool cancel_operations(Descriptor descriptor, op_queue& ops, + const asio::error_code& ec = + asio::error::operation_aborted) + { + return this->cancel_operations(operations_.find(descriptor), ops, ec); + } + + // Whether there are no operations in the queue. + bool empty() const + { + return operations_.empty(); + } + + // Determine whether there are any operations associated with the descriptor. + bool has_operation(Descriptor descriptor) const + { + return operations_.find(descriptor) != operations_.end(); + } + + // Perform the operations corresponding to the descriptor identified by the + // supplied iterator. Returns true if there are still unfinished operations + // queued for the descriptor. + bool perform_operations(iterator i, op_queue& ops) + { + if (i != operations_.end()) + { + while (reactor_op* op = i->second.front()) + { + if (op->perform()) + { + i->second.pop(); + ops.push(op); + } + else + { + return true; + } + } + operations_.erase(i); + } + return false; + } + + // Perform the operations corresponding to the descriptor. Returns true if + // there are still unfinished operations queued for the descriptor. + bool perform_operations(Descriptor descriptor, op_queue& ops) + { + return this->perform_operations(operations_.find(descriptor), ops); + } + + // Get all operations owned by the queue. + void get_all_operations(op_queue& ops) + { + iterator i = operations_.begin(); + while (i != operations_.end()) + { + iterator op_iter = i++; + ops.push(op_iter->second); + operations_.erase(op_iter); + } + } + +private: + // The operations that are currently executing asynchronously. + hash_map operations_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTOR_OP_QUEUE_HPP diff --git a/tools/sdk/include/asio/asio/detail/recycling_allocator.hpp b/tools/sdk/include/asio/asio/detail/recycling_allocator.hpp new file mode 100644 index 00000000..964af1da --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/recycling_allocator.hpp @@ -0,0 +1,104 @@ +// +// detail/recycling_allocator.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_RECYCLING_ALLOCATOR_HPP +#define ASIO_DETAIL_RECYCLING_ALLOCATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/thread_context.hpp" +#include "asio/detail/thread_info_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class recycling_allocator +{ +public: + typedef T value_type; + + template + struct rebind + { + typedef recycling_allocator other; + }; + + recycling_allocator() + { + } + + template + recycling_allocator(const recycling_allocator&) + { + } + + T* allocate(std::size_t n) + { + typedef thread_context::thread_call_stack call_stack; + void* p = thread_info_base::allocate(call_stack::top(), sizeof(T) * n); + return static_cast(p); + } + + void deallocate(T* p, std::size_t n) + { + typedef thread_context::thread_call_stack call_stack; + thread_info_base::deallocate(call_stack::top(), p, sizeof(T) * n); + } +}; + +template <> +class recycling_allocator +{ +public: + typedef void value_type; + + template + struct rebind + { + typedef recycling_allocator other; + }; + + recycling_allocator() + { + } + + template + recycling_allocator(const recycling_allocator&) + { + } +}; + +template +struct get_recycling_allocator +{ + typedef Allocator type; + static type get(const Allocator& a) { return a; } +}; + +template +struct get_recycling_allocator > +{ + typedef recycling_allocator type; + static type get(const std::allocator&) { return type(); } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_RECYCLING_ALLOCATOR_HPP diff --git a/tools/sdk/include/asio/asio/detail/regex_fwd.hpp b/tools/sdk/include/asio/asio/detail/regex_fwd.hpp new file mode 100644 index 00000000..dcf7d06e --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/regex_fwd.hpp @@ -0,0 +1,35 @@ +// +// detail/regex_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_REGEX_FWD_HPP +#define ASIO_DETAIL_REGEX_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if defined(ASIO_HAS_BOOST_REGEX) + +#include +#include + +namespace boost { + +template +struct sub_match; + +template +class match_results; + +} // namespace boost + +#endif // defined(ASIO_HAS_BOOST_REGEX) + +#endif // ASIO_DETAIL_REGEX_FWD_HPP diff --git a/tools/sdk/include/asio/asio/detail/resolve_endpoint_op.hpp b/tools/sdk/include/asio/asio/detail/resolve_endpoint_op.hpp new file mode 100644 index 00000000..8eee2f98 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/resolve_endpoint_op.hpp @@ -0,0 +1,122 @@ +// +// detail/resolve_endpoint_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP +#define ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/ip/basic_resolver_results.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/resolve_op.hpp" +#include "asio/detail/socket_ops.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class resolve_endpoint_op : public resolve_op +{ +public: + ASIO_DEFINE_HANDLER_PTR(resolve_endpoint_op); + + typedef typename Protocol::endpoint endpoint_type; + typedef asio::ip::basic_resolver_results results_type; + + resolve_endpoint_op(socket_ops::weak_cancel_token_type cancel_token, + const endpoint_type& endpoint, io_context_impl& ioc, Handler& handler) + : resolve_op(&resolve_endpoint_op::do_complete), + cancel_token_(cancel_token), + endpoint_(endpoint), + io_context_impl_(ioc), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the operation object. + resolve_endpoint_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + if (owner && owner != &o->io_context_impl_) + { + // The operation is being run on the worker io_context. Time to perform + // the resolver operation. + + // Perform the blocking endpoint resolution operation. + char host_name[NI_MAXHOST]; + char service_name[NI_MAXSERV]; + socket_ops::background_getnameinfo(o->cancel_token_, o->endpoint_.data(), + o->endpoint_.size(), host_name, NI_MAXHOST, service_name, NI_MAXSERV, + o->endpoint_.protocol().type(), o->ec_); + o->results_ = results_type::create(o->endpoint_, host_name, service_name); + + // Pass operation back to main io_context for completion. + o->io_context_impl_.post_deferred_completion(o); + p.v = p.p = 0; + } + else + { + // The operation has been returned to the main io_context. The completion + // handler is ready to be delivered. + + 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::binder2 + handler(o->handler_, o->ec_, o->results_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "...")); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + } + +private: + socket_ops::weak_cancel_token_type cancel_token_; + endpoint_type endpoint_; + io_context_impl& io_context_impl_; + Handler handler_; + results_type results_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/resolve_op.hpp b/tools/sdk/include/asio/asio/detail/resolve_op.hpp new file mode 100644 index 00000000..a528aa82 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/resolve_op.hpp @@ -0,0 +1,45 @@ +// +// detail/resolve_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_RESOLVE_OP_HPP +#define ASIO_DETAIL_RESOLVE_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/error.hpp" +#include "asio/detail/operation.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class resolve_op : public operation +{ +public: + // The error code to be passed to the completion handler. + asio::error_code ec_; + +protected: + resolve_op(func_type complete_func) + : operation(complete_func) + { + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_RESOLVE_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/resolve_query_op.hpp b/tools/sdk/include/asio/asio/detail/resolve_query_op.hpp new file mode 100644 index 00000000..0ec5a321 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/resolve_query_op.hpp @@ -0,0 +1,134 @@ +// +// detail/resolve_query_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_RESOLVE_QUERY_OP_HPP +#define ASIO_DETAIL_RESOLVE_QUERY_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/ip/basic_resolver_results.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/resolve_op.hpp" +#include "asio/detail/socket_ops.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class resolve_query_op : public resolve_op +{ +public: + ASIO_DEFINE_HANDLER_PTR(resolve_query_op); + + typedef asio::ip::basic_resolver_query query_type; + typedef asio::ip::basic_resolver_results results_type; + + resolve_query_op(socket_ops::weak_cancel_token_type cancel_token, + const query_type& query, io_context_impl& ioc, Handler& handler) + : resolve_op(&resolve_query_op::do_complete), + cancel_token_(cancel_token), + query_(query), + io_context_impl_(ioc), + handler_(ASIO_MOVE_CAST(Handler)(handler)), + addrinfo_(0) + { + handler_work::start(handler_); + } + + ~resolve_query_op() + { + if (addrinfo_) + socket_ops::freeaddrinfo(addrinfo_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the operation object. + resolve_query_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + + if (owner && owner != &o->io_context_impl_) + { + // The operation is being run on the worker io_context. Time to perform + // the resolver operation. + + // Perform the blocking host resolution operation. + socket_ops::background_getaddrinfo(o->cancel_token_, + o->query_.host_name().c_str(), o->query_.service_name().c_str(), + o->query_.hints(), &o->addrinfo_, o->ec_); + + // Pass operation back to main io_context for completion. + o->io_context_impl_.post_deferred_completion(o); + p.v = p.p = 0; + } + else + { + // The operation has been returned to the main io_context. The completion + // handler is ready to be delivered. + + // Take ownership of the operation's outstanding work. + handler_work w(o->handler_); + + 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::binder2 + handler(o->handler_, o->ec_, results_type()); + p.h = asio::detail::addressof(handler.handler_); + if (o->addrinfo_) + { + handler.arg2_ = results_type::create(o->addrinfo_, + o->query_.host_name(), o->query_.service_name()); + } + p.reset(); + + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "...")); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + } + +private: + socket_ops::weak_cancel_token_type cancel_token_; + query_type query_; + io_context_impl& io_context_impl_; + Handler handler_; + asio::detail::addrinfo_type* addrinfo_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_RESOLVE_QUERY_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/resolver_service.hpp b/tools/sdk/include/asio/asio/detail/resolver_service.hpp new file mode 100644 index 00000000..11a94d13 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/resolver_service.hpp @@ -0,0 +1,145 @@ +// +// detail/resolver_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_RESOLVER_SERVICE_HPP +#define ASIO_DETAIL_RESOLVER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/ip/basic_resolver_results.hpp" +#include "asio/detail/concurrency_hint.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/resolve_endpoint_op.hpp" +#include "asio/detail/resolve_query_op.hpp" +#include "asio/detail/resolver_service_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class resolver_service : + public service_base >, + public resolver_service_base +{ +public: + // The implementation type of the resolver. A cancellation token is used to + // indicate to the background thread that the operation has been cancelled. + typedef socket_ops::shared_cancel_token_type implementation_type; + + // The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + // The query type. + typedef asio::ip::basic_resolver_query query_type; + + // The results type. + typedef asio::ip::basic_resolver_results results_type; + + // Constructor. + resolver_service(asio::io_context& io_context) + : service_base >(io_context), + resolver_service_base(io_context) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown() + { + this->base_shutdown(); + } + + // Perform any fork-related housekeeping. + void notify_fork(asio::io_context::fork_event fork_ev) + { + this->base_notify_fork(fork_ev); + } + + // Resolve a query to a list of entries. + results_type resolve(implementation_type&, const query_type& query, + asio::error_code& ec) + { + asio::detail::addrinfo_type* address_info = 0; + + socket_ops::getaddrinfo(query.host_name().c_str(), + query.service_name().c_str(), query.hints(), &address_info, ec); + auto_addrinfo auto_address_info(address_info); + + return ec ? results_type() : results_type::create( + address_info, query.host_name(), query.service_name()); + } + + // Asynchronously resolve a query to a list of entries. + template + void async_resolve(implementation_type& impl, + const query_type& query, Handler& handler) + { + // Allocate and construct an operation to wrap the handler. + typedef resolve_query_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl, query, io_context_impl_, handler); + + ASIO_HANDLER_CREATION((io_context_impl_.context(), + *p.p, "resolver", &impl, 0, "async_resolve")); + + start_resolve_op(p.p); + p.v = p.p = 0; + } + + // Resolve an endpoint to a list of entries. + results_type resolve(implementation_type&, + const endpoint_type& endpoint, asio::error_code& ec) + { + char host_name[NI_MAXHOST]; + char service_name[NI_MAXSERV]; + socket_ops::sync_getnameinfo(endpoint.data(), endpoint.size(), + host_name, NI_MAXHOST, service_name, NI_MAXSERV, + endpoint.protocol().type(), ec); + + return ec ? results_type() : results_type::create( + endpoint, host_name, service_name); + } + + // Asynchronously resolve an endpoint to a list of entries. + template + void async_resolve(implementation_type& impl, + const endpoint_type& endpoint, Handler& handler) + { + // Allocate and construct an operation to wrap the handler. + typedef resolve_endpoint_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl, endpoint, io_context_impl_, handler); + + ASIO_HANDLER_CREATION((io_context_impl_.context(), + *p.p, "resolver", &impl, 0, "async_resolve")); + + start_resolve_op(p.p); + p.v = p.p = 0; + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_RESOLVER_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/resolver_service_base.hpp b/tools/sdk/include/asio/asio/detail/resolver_service_base.hpp new file mode 100644 index 00000000..10a79224 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/resolver_service_base.hpp @@ -0,0 +1,140 @@ +// +// detail/resolver_service_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_RESOLVER_SERVICE_BASE_HPP +#define ASIO_DETAIL_RESOLVER_SERVICE_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/error.hpp" +#include "asio/executor_work_guard.hpp" +#include "asio/io_context.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/resolve_op.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/scoped_ptr.hpp" +#include "asio/detail/thread.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class resolver_service_base +{ +public: + // The implementation type of the resolver. A cancellation token is used to + // indicate to the background thread that the operation has been cancelled. + typedef socket_ops::shared_cancel_token_type implementation_type; + + // Constructor. + ASIO_DECL resolver_service_base(asio::io_context& io_context); + + // Destructor. + ASIO_DECL ~resolver_service_base(); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void base_shutdown(); + + // Perform any fork-related housekeeping. + ASIO_DECL void base_notify_fork( + asio::io_context::fork_event fork_ev); + + // Construct a new resolver implementation. + ASIO_DECL void construct(implementation_type& impl); + + // Destroy a resolver implementation. + ASIO_DECL void destroy(implementation_type&); + + // Move-construct a new resolver implementation. + ASIO_DECL void move_construct(implementation_type& impl, + implementation_type& other_impl); + + // Move-assign from another resolver implementation. + ASIO_DECL void move_assign(implementation_type& impl, + resolver_service_base& other_service, + implementation_type& other_impl); + + // Cancel pending asynchronous operations. + ASIO_DECL void cancel(implementation_type& impl); + +protected: + // Helper function to start an asynchronous resolve operation. + ASIO_DECL void start_resolve_op(resolve_op* op); + +#if !defined(ASIO_WINDOWS_RUNTIME) + // Helper class to perform exception-safe cleanup of addrinfo objects. + class auto_addrinfo + : private asio::detail::noncopyable + { + public: + explicit auto_addrinfo(asio::detail::addrinfo_type* ai) + : ai_(ai) + { + } + + ~auto_addrinfo() + { + if (ai_) + socket_ops::freeaddrinfo(ai_); + } + + operator asio::detail::addrinfo_type*() + { + return ai_; + } + + private: + asio::detail::addrinfo_type* ai_; + }; +#endif // !defined(ASIO_WINDOWS_RUNTIME) + + // Helper class to run the work io_context in a thread. + class work_io_context_runner; + + // Start the work thread if it's not already running. + ASIO_DECL void start_work_thread(); + + // The io_context implementation used to post completions. + io_context_impl& io_context_impl_; + +private: + // Mutex to protect access to internal data. + asio::detail::mutex mutex_; + + // Private io_context used for performing asynchronous host resolution. + asio::detail::scoped_ptr work_io_context_; + + // The work io_context implementation used to post completions. + io_context_impl& work_io_context_impl_; + + // Work for the private io_context to perform. + asio::executor_work_guard< + asio::io_context::executor_type> work_; + + // Thread used for running the work io_context's run loop. + asio::detail::scoped_ptr work_thread_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/resolver_service_base.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_DETAIL_RESOLVER_SERVICE_BASE_HPP diff --git a/tools/sdk/include/asio/asio/detail/scheduler.hpp b/tools/sdk/include/asio/asio/detail/scheduler.hpp new file mode 100644 index 00000000..10c29b7e --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/scheduler.hpp @@ -0,0 +1,213 @@ +// +// detail/scheduler.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SCHEDULER_HPP +#define ASIO_DETAIL_SCHEDULER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/error_code.hpp" +#include "asio/execution_context.hpp" +#include "asio/detail/atomic_count.hpp" +#include "asio/detail/conditionally_enabled_event.hpp" +#include "asio/detail/conditionally_enabled_mutex.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/reactor_fwd.hpp" +#include "asio/detail/scheduler_operation.hpp" +#include "asio/detail/thread_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +struct scheduler_thread_info; + +class scheduler + : public execution_context_service_base, + public thread_context +{ +public: + typedef scheduler_operation operation; + + // Constructor. Specifies the number of concurrent threads that are likely to + // run the scheduler. If set to 1 certain optimisation are performed. + ASIO_DECL scheduler(asio::execution_context& ctx, + int concurrency_hint = 0); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Initialise the task, if required. + ASIO_DECL void init_task(); + + // Run the event loop until interrupted or no more work. + ASIO_DECL std::size_t run(asio::error_code& ec); + + // Run until interrupted or one operation is performed. + ASIO_DECL std::size_t run_one(asio::error_code& ec); + + // Run until timeout, interrupted, or one operation is performed. + ASIO_DECL std::size_t wait_one( + long usec, asio::error_code& ec); + + // Poll for operations without blocking. + ASIO_DECL std::size_t poll(asio::error_code& ec); + + // Poll for one operation without blocking. + ASIO_DECL std::size_t poll_one(asio::error_code& ec); + + // Interrupt the event processing loop. + ASIO_DECL void stop(); + + // Determine whether the scheduler is stopped. + ASIO_DECL bool stopped() const; + + // Restart in preparation for a subsequent run invocation. + ASIO_DECL void restart(); + + // Notify that some work has started. + void work_started() + { + ++outstanding_work_; + } + + // Used to compensate for a forthcoming work_finished call. Must be called + // from within a scheduler-owned thread. + ASIO_DECL void compensating_work_started(); + + // Notify that some work has finished. + void work_finished() + { + if (--outstanding_work_ == 0) + stop(); + } + + // Return whether a handler can be dispatched immediately. + bool can_dispatch() + { + return thread_call_stack::contains(this) != 0; + } + + // Request invocation of the given operation and return immediately. Assumes + // that work_started() has not yet been called for the operation. + ASIO_DECL void post_immediate_completion( + operation* op, bool is_continuation); + + // Request invocation of the given operation and return immediately. Assumes + // that work_started() was previously called for the operation. + ASIO_DECL void post_deferred_completion(operation* op); + + // Request invocation of the given operations and return immediately. Assumes + // that work_started() was previously called for each operation. + ASIO_DECL void post_deferred_completions(op_queue& ops); + + // Enqueue the given operation following a failed attempt to dispatch the + // operation for immediate invocation. + ASIO_DECL void do_dispatch(operation* op); + + // Process unfinished operations as part of a shutdownoperation. Assumes that + // work_started() was previously called for the operations. + ASIO_DECL void abandon_operations(op_queue& ops); + + // Get the concurrency hint that was used to initialise the scheduler. + int concurrency_hint() const + { + return concurrency_hint_; + } + +private: + // The mutex type used by this scheduler. + typedef conditionally_enabled_mutex mutex; + + // The event type used by this scheduler. + typedef conditionally_enabled_event event; + + // Structure containing thread-specific data. + typedef scheduler_thread_info thread_info; + + // Run at most one operation. May block. + ASIO_DECL std::size_t do_run_one(mutex::scoped_lock& lock, + thread_info& this_thread, const asio::error_code& ec); + + // Run at most one operation with a timeout. May block. + ASIO_DECL std::size_t do_wait_one(mutex::scoped_lock& lock, + thread_info& this_thread, long usec, const asio::error_code& ec); + + // Poll for at most one operation. + ASIO_DECL std::size_t do_poll_one(mutex::scoped_lock& lock, + thread_info& this_thread, const asio::error_code& ec); + + // Stop the task and all idle threads. + ASIO_DECL void stop_all_threads(mutex::scoped_lock& lock); + + // Wake a single idle thread, or the task, and always unlock the mutex. + ASIO_DECL void wake_one_thread_and_unlock( + mutex::scoped_lock& lock); + + // Helper class to perform task-related operations on block exit. + struct task_cleanup; + friend struct task_cleanup; + + // Helper class to call work-related operations on block exit. + struct work_cleanup; + friend struct work_cleanup; + + // Whether to optimise for single-threaded use cases. + const bool one_thread_; + + // Mutex to protect access to internal data. + mutable mutex mutex_; + + // Event to wake up blocked threads. + event wakeup_event_; + + // The task to be run by this service. + reactor* task_; + + // Operation object to represent the position of the task in the queue. + struct task_operation : operation + { + task_operation() : operation(0) {} + } task_operation_; + + // Whether the task has been interrupted. + bool task_interrupted_; + + // The count of unfinished work. + atomic_count outstanding_work_; + + // The queue of handlers that are ready to be delivered. + op_queue op_queue_; + + // Flag to indicate that the dispatcher has been stopped. + bool stopped_; + + // Flag to indicate that the dispatcher has been shut down. + bool shutdown_; + + // The concurrency hint used to initialise the scheduler. + const int concurrency_hint_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/scheduler.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_DETAIL_SCHEDULER_HPP diff --git a/tools/sdk/include/asio/asio/detail/scheduler_operation.hpp b/tools/sdk/include/asio/asio/detail/scheduler_operation.hpp new file mode 100644 index 00000000..1c2ce02e --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/scheduler_operation.hpp @@ -0,0 +1,78 @@ +// +// detail/scheduler_operation.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SCHEDULER_OPERATION_HPP +#define ASIO_DETAIL_SCHEDULER_OPERATION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/error_code.hpp" +#include "asio/detail/handler_tracking.hpp" +#include "asio/detail/op_queue.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class scheduler; + +// Base class for all operations. A function pointer is used instead of virtual +// functions to avoid the associated overhead. +class scheduler_operation ASIO_INHERIT_TRACKED_HANDLER +{ +public: + typedef scheduler_operation operation_type; + + void complete(void* owner, const asio::error_code& ec, + std::size_t bytes_transferred) + { + func_(owner, this, ec, bytes_transferred); + } + + void destroy() + { + func_(0, this, asio::error_code(), 0); + } + +protected: + typedef void (*func_type)(void*, + scheduler_operation*, + const asio::error_code&, std::size_t); + + scheduler_operation(func_type func) + : next_(0), + func_(func), + task_result_(0) + { + } + + // Prevents deletion through this type. + ~scheduler_operation() + { + } + +private: + friend class op_queue_access; + scheduler_operation* next_; + func_type func_; +protected: + friend class scheduler; + unsigned int task_result_; // Passed into bytes transferred. +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SCHEDULER_OPERATION_HPP diff --git a/tools/sdk/include/asio/asio/detail/scheduler_thread_info.hpp b/tools/sdk/include/asio/asio/detail/scheduler_thread_info.hpp new file mode 100644 index 00000000..2ffe013b --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/scheduler_thread_info.hpp @@ -0,0 +1,40 @@ +// +// detail/scheduler_thread_info.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SCHEDULER_THREAD_INFO_HPP +#define ASIO_DETAIL_SCHEDULER_THREAD_INFO_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/op_queue.hpp" +#include "asio/detail/thread_info_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class scheduler; +class scheduler_operation; + +struct scheduler_thread_info : public thread_info_base +{ + op_queue private_op_queue; + long private_outstanding_work; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SCHEDULER_THREAD_INFO_HPP diff --git a/tools/sdk/include/asio/asio/detail/scoped_lock.hpp b/tools/sdk/include/asio/asio/detail/scoped_lock.hpp new file mode 100644 index 00000000..6cbce381 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/scoped_lock.hpp @@ -0,0 +1,101 @@ +// +// detail/scoped_lock.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SCOPED_LOCK_HPP +#define ASIO_DETAIL_SCOPED_LOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Helper class to lock and unlock a mutex automatically. +template +class scoped_lock + : private noncopyable +{ +public: + // Tag type used to distinguish constructors. + enum adopt_lock_t { adopt_lock }; + + // Constructor adopts a lock that is already held. + scoped_lock(Mutex& m, adopt_lock_t) + : mutex_(m), + locked_(true) + { + } + + // Constructor acquires the lock. + explicit scoped_lock(Mutex& m) + : mutex_(m) + { + mutex_.lock(); + locked_ = true; + } + + // Destructor releases the lock. + ~scoped_lock() + { + if (locked_) + mutex_.unlock(); + } + + // Explicitly acquire the lock. + void lock() + { + if (!locked_) + { + mutex_.lock(); + locked_ = true; + } + } + + // Explicitly release the lock. + void unlock() + { + if (locked_) + { + mutex_.unlock(); + locked_ = false; + } + } + + // Test whether the lock is held. + bool locked() const + { + return locked_; + } + + // Get the underlying mutex. + Mutex& mutex() + { + return mutex_; + } + +private: + // The underlying mutex. + Mutex& mutex_; + + // Whether the mutex is currently locked or unlocked. + bool locked_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SCOPED_LOCK_HPP diff --git a/tools/sdk/include/asio/asio/detail/scoped_ptr.hpp b/tools/sdk/include/asio/asio/detail/scoped_ptr.hpp new file mode 100644 index 00000000..3449c53b --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/scoped_ptr.hpp @@ -0,0 +1,87 @@ +// +// detail/scoped_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SCOPED_PTR_HPP +#define ASIO_DETAIL_SCOPED_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class scoped_ptr +{ +public: + // Constructor. + explicit scoped_ptr(T* p = 0) + : p_(p) + { + } + + // Destructor. + ~scoped_ptr() + { + delete p_; + } + + // Access. + T* get() + { + return p_; + } + + // Access. + T* operator->() + { + return p_; + } + + // Dereference. + T& operator*() + { + return *p_; + } + + // Reset pointer. + void reset(T* p = 0) + { + delete p_; + p_ = p; + } + + // Release ownership of the pointer. + T* release() + { + T* tmp = p_; + p_ = 0; + return tmp; + } + +private: + // Disallow copying and assignment. + scoped_ptr(const scoped_ptr&); + scoped_ptr& operator=(const scoped_ptr&); + + T* p_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SCOPED_PTR_HPP diff --git a/tools/sdk/include/asio/asio/detail/select_interrupter.hpp b/tools/sdk/include/asio/asio/detail/select_interrupter.hpp new file mode 100644 index 00000000..c5832738 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/select_interrupter.hpp @@ -0,0 +1,46 @@ +// +// detail/select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SELECT_INTERRUPTER_HPP +#define ASIO_DETAIL_SELECT_INTERRUPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_WINDOWS_RUNTIME) + +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) || defined(__SYMBIAN32__) || defined (ESP_PLATFORM) +# include "asio/detail/socket_select_interrupter.hpp" +#elif defined(ASIO_HAS_EVENTFD) +# include "asio/detail/eventfd_select_interrupter.hpp" +#else +# include "asio/detail/pipe_select_interrupter.hpp" +#endif + +namespace asio { +namespace detail { + +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) || defined(__SYMBIAN32__) || defined (ESP_PLATFORM) +typedef socket_select_interrupter select_interrupter; +#elif defined(ASIO_HAS_EVENTFD) +typedef eventfd_select_interrupter select_interrupter; +#else +typedef pipe_select_interrupter select_interrupter; +#endif + +} // namespace detail +} // namespace asio + +#endif // !defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_SELECT_INTERRUPTER_HPP diff --git a/tools/sdk/include/asio/asio/detail/select_reactor.hpp b/tools/sdk/include/asio/asio/detail/select_reactor.hpp new file mode 100644 index 00000000..09965492 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/select_reactor.hpp @@ -0,0 +1,238 @@ +// +// detail/select_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SELECT_REACTOR_HPP +#define ASIO_DETAIL_SELECT_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) \ + || (!defined(ASIO_HAS_DEV_POLL) \ + && !defined(ASIO_HAS_EPOLL) \ + && !defined(ASIO_HAS_KQUEUE) \ + && !defined(ASIO_WINDOWS_RUNTIME)) + +#include +#include "asio/detail/fd_set_adapter.hpp" +#include "asio/detail/limits.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/reactor_op_queue.hpp" +#include "asio/detail/select_interrupter.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/timer_queue_base.hpp" +#include "asio/detail/timer_queue_set.hpp" +#include "asio/detail/wait_op.hpp" +#include "asio/execution_context.hpp" + +#if defined(ASIO_HAS_IOCP) +# include "asio/detail/thread.hpp" +#endif // defined(ASIO_HAS_IOCP) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class select_reactor + : public execution_context_service_base +{ +public: +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) + enum op_types { read_op = 0, write_op = 1, except_op = 2, + max_select_ops = 3, connect_op = 3, max_ops = 4 }; +#else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) + enum op_types { read_op = 0, write_op = 1, except_op = 2, + max_select_ops = 3, connect_op = 1, max_ops = 3 }; +#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) + + // Per-descriptor data. + struct per_descriptor_data + { + }; + + // Constructor. + ASIO_DECL select_reactor(asio::execution_context& ctx); + + // Destructor. + ASIO_DECL ~select_reactor(); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Recreate internal descriptors following a fork. + ASIO_DECL void notify_fork( + asio::execution_context::fork_event fork_ev); + + // Initialise the task, but only if the reactor is not in its own thread. + ASIO_DECL void init_task(); + + // Register a socket with the reactor. Returns 0 on success, system error + // code on failure. + ASIO_DECL int register_descriptor(socket_type, per_descriptor_data&); + + // Register a descriptor with an associated single operation. Returns 0 on + // success, system error code on failure. + ASIO_DECL int register_internal_descriptor( + int op_type, socket_type descriptor, + per_descriptor_data& descriptor_data, reactor_op* op); + + // Post a reactor operation for immediate completion. + void post_immediate_completion(reactor_op* op, bool is_continuation) + { + scheduler_.post_immediate_completion(op, is_continuation); + } + + // Start a new operation. The reactor operation will be performed when the + // given descriptor is flagged as ready, or an error has occurred. + ASIO_DECL void start_op(int op_type, socket_type descriptor, + per_descriptor_data&, reactor_op* op, bool is_continuation, bool); + + // Cancel all operations associated with the given descriptor. The + // handlers associated with the descriptor will be invoked with the + // operation_aborted error. + ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&); + + // Cancel any operations that are running against the descriptor and remove + // its registration from the reactor. The reactor resources associated with + // the descriptor must be released by calling cleanup_descriptor_data. + ASIO_DECL void deregister_descriptor(socket_type descriptor, + per_descriptor_data&, bool closing); + + // Remove the descriptor's registration from the reactor. The reactor + // resources associated with the descriptor must be released by calling + // cleanup_descriptor_data. + ASIO_DECL void deregister_internal_descriptor( + socket_type descriptor, per_descriptor_data&); + + // Perform any post-deregistration cleanup tasks associated with the + // descriptor data. + ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&); + + // Move descriptor registration from one descriptor_data object to another. + ASIO_DECL void move_descriptor(socket_type descriptor, + per_descriptor_data& target_descriptor_data, + per_descriptor_data& source_descriptor_data); + + // Add a new timer queue to the reactor. + template + void add_timer_queue(timer_queue& queue); + + // Remove a timer queue from the reactor. + template + void remove_timer_queue(timer_queue& queue); + + // Schedule a new operation in the given timer queue to expire at the + // specified absolute time. + template + void schedule_timer(timer_queue& queue, + const typename Time_Traits::time_type& time, + typename timer_queue::per_timer_data& timer, wait_op* op); + + // Cancel the timer operations associated with the given token. Returns the + // number of operations that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& queue, + typename timer_queue::per_timer_data& timer, + std::size_t max_cancelled = (std::numeric_limits::max)()); + + // Move the timer operations associated with the given timer. + template + void move_timer(timer_queue& queue, + typename timer_queue::per_timer_data& target, + typename timer_queue::per_timer_data& source); + + // Run select once until interrupted or events are ready to be dispatched. + ASIO_DECL void run(long usec, op_queue& ops); + + // Interrupt the select loop. + ASIO_DECL void interrupt(); + +private: +#if defined(ASIO_HAS_IOCP) + // Run the select loop in the thread. + ASIO_DECL void run_thread(); +#endif // defined(ASIO_HAS_IOCP) + + // Helper function to add a new timer queue. + ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); + + // Helper function to remove a timer queue. + ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); + + // Get the timeout value for the select call. + ASIO_DECL timeval* get_timeout(long usec, timeval& tv); + + // Cancel all operations associated with the given descriptor. This function + // does not acquire the select_reactor's mutex. + ASIO_DECL void cancel_ops_unlocked(socket_type descriptor, + const asio::error_code& ec); + + // The scheduler implementation used to post completions. +# if defined(ASIO_HAS_IOCP) + typedef class win_iocp_io_context scheduler_type; +# else // defined(ASIO_HAS_IOCP) + typedef class scheduler scheduler_type; +# endif // defined(ASIO_HAS_IOCP) + scheduler_type& scheduler_; + + // Mutex to protect access to internal data. + asio::detail::mutex mutex_; + + // The interrupter is used to break a blocking select call. + select_interrupter interrupter_; + + // The queues of read, write and except operations. + reactor_op_queue op_queue_[max_ops]; + + // The file descriptor sets to be passed to the select system call. + fd_set_adapter fd_sets_[max_select_ops]; + + // The timer queues. + timer_queue_set timer_queues_; + +#if defined(ASIO_HAS_IOCP) + // Helper class to run the reactor loop in a thread. + class thread_function; + friend class thread_function; + + // Does the reactor loop thread need to stop. + bool stop_thread_; + + // The thread that is running the reactor loop. + asio::detail::thread* thread_; +#endif // defined(ASIO_HAS_IOCP) + + // Whether the service has been shut down. + bool shutdown_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/impl/select_reactor.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/select_reactor.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_IOCP) + // || (!defined(ASIO_HAS_DEV_POLL) + // && !defined(ASIO_HAS_EPOLL) + // && !defined(ASIO_HAS_KQUEUE) + // && !defined(ASIO_WINDOWS_RUNTIME)) + +#endif // ASIO_DETAIL_SELECT_REACTOR_HPP diff --git a/tools/sdk/include/asio/asio/detail/service_registry.hpp b/tools/sdk/include/asio/asio/detail/service_registry.hpp new file mode 100644 index 00000000..cda63072 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/service_registry.hpp @@ -0,0 +1,164 @@ +// +// detail/service_registry.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SERVICE_REGISTRY_HPP +#define ASIO_DETAIL_SERVICE_REGISTRY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/detail/mutex.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/execution_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +class io_context; + +namespace detail { + +template +class typeid_wrapper {}; + +class service_registry + : private noncopyable +{ +public: + // Constructor. + ASIO_DECL service_registry(execution_context& owner); + + // Destructor. + ASIO_DECL ~service_registry(); + + // Shutdown all services. + ASIO_DECL void shutdown_services(); + + // Destroy all services. + ASIO_DECL void destroy_services(); + + // Notify all services of a fork event. + ASIO_DECL void notify_fork(execution_context::fork_event fork_ev); + + // Get the service object corresponding to the specified service type. Will + // create a new service object automatically if no such object already + // exists. Ownership of the service object is not transferred to the caller. + template + Service& use_service(); + + // Get the service object corresponding to the specified service type. Will + // create a new service object automatically if no such object already + // exists. Ownership of the service object is not transferred to the caller. + // This overload is used for backwards compatibility with services that + // inherit from io_context::service. + template + Service& use_service(io_context& owner); + + // Add a service object. Throws on error, in which case ownership of the + // object is retained by the caller. + template + void add_service(Service* new_service); + + // Check whether a service object of the specified type already exists. + template + bool has_service() const; + +private: + // Initalise a service's key when the key_type typedef is not available. + template + static void init_key(execution_context::service::key& key, ...); + +#if !defined(ASIO_NO_TYPEID) + // Initalise a service's key when the key_type typedef is available. + template + static void init_key(execution_context::service::key& key, + typename enable_if< + is_base_of::value>::type*); +#endif // !defined(ASIO_NO_TYPEID) + + // Initialise a service's key based on its id. + ASIO_DECL static void init_key_from_id( + execution_context::service::key& key, + const execution_context::id& id); + +#if !defined(ASIO_NO_TYPEID) + // Initialise a service's key based on its id. + template + static void init_key_from_id(execution_context::service::key& key, + const service_id& /*id*/); +#endif // !defined(ASIO_NO_TYPEID) + + // Check if a service matches the given id. + ASIO_DECL static bool keys_match( + const execution_context::service::key& key1, + const execution_context::service::key& key2); + + // The type of a factory function used for creating a service instance. + typedef execution_context::service*(*factory_type)(void*); + + // Factory function for creating a service instance. + template + static execution_context::service* create(void* owner); + + // Destroy a service instance. + ASIO_DECL static void destroy(execution_context::service* service); + + // Helper class to manage service pointers. + struct auto_service_ptr; + friend struct auto_service_ptr; + struct auto_service_ptr + { + execution_context::service* ptr_; + ~auto_service_ptr() { destroy(ptr_); } + }; + + // Get the service object corresponding to the specified service key. Will + // create a new service object automatically if no such object already + // exists. Ownership of the service object is not transferred to the caller. + ASIO_DECL execution_context::service* do_use_service( + const execution_context::service::key& key, + factory_type factory, void* owner); + + // Add a service object. Throws on error, in which case ownership of the + // object is retained by the caller. + ASIO_DECL void do_add_service( + const execution_context::service::key& key, + execution_context::service* new_service); + + // Check whether a service object with the specified key already exists. + ASIO_DECL bool do_has_service( + const execution_context::service::key& key) const; + + // Mutex to protect access to internal data. + mutable asio::detail::mutex mutex_; + + // The owner of this service registry and the services it contains. + execution_context& owner_; + + // The first service in the list of contained services. + execution_context::service* first_service_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/impl/service_registry.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/service_registry.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_DETAIL_SERVICE_REGISTRY_HPP diff --git a/tools/sdk/include/asio/asio/detail/signal_blocker.hpp b/tools/sdk/include/asio/asio/detail/signal_blocker.hpp new file mode 100644 index 00000000..b6842957 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/signal_blocker.hpp @@ -0,0 +1,44 @@ +// +// detail/signal_blocker.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SIGNAL_BLOCKER_HPP +#define ASIO_DETAIL_SIGNAL_BLOCKER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_THREADS) || defined(ASIO_WINDOWS) \ + || defined(ASIO_WINDOWS_RUNTIME) \ + || defined(__CYGWIN__) || defined(__SYMBIAN32__) +# include "asio/detail/null_signal_blocker.hpp" +#elif defined(ASIO_HAS_PTHREADS) +# include "asio/detail/posix_signal_blocker.hpp" +#else +# error Only Windows and POSIX are supported! +#endif + +namespace asio { +namespace detail { + +#if !defined(ASIO_HAS_THREADS) || defined(ASIO_WINDOWS) \ + || defined(ASIO_WINDOWS_RUNTIME) \ + || defined(__CYGWIN__) || defined(__SYMBIAN32__) +typedef null_signal_blocker signal_blocker; +#elif defined(ASIO_HAS_PTHREADS) +typedef posix_signal_blocker signal_blocker; +#endif + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_SIGNAL_BLOCKER_HPP diff --git a/tools/sdk/include/asio/asio/detail/signal_handler.hpp b/tools/sdk/include/asio/asio/detail/signal_handler.hpp new file mode 100644 index 00000000..d1c99105 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/signal_handler.hpp @@ -0,0 +1,86 @@ +// +// detail/signal_handler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SIGNAL_HANDLER_HPP +#define ASIO_DETAIL_SIGNAL_HANDLER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/handler_work.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/signal_op.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class signal_handler : public signal_op +{ +public: + ASIO_DEFINE_HANDLER_PTR(signal_handler); + + signal_handler(Handler& h) + : signal_op(&signal_handler::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(h)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + signal_handler* h(static_cast(base)); + ptr p = { asio::detail::addressof(h->handler_), h, h }; + handler_work w(h->handler_); + + ASIO_HANDLER_COMPLETION((*h)); + + // 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::binder2 + handler(h->handler_, h->ec_, h->signal_number_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SIGNAL_HANDLER_HPP diff --git a/tools/sdk/include/asio/asio/detail/signal_init.hpp b/tools/sdk/include/asio/asio/detail/signal_init.hpp new file mode 100644 index 00000000..814ff519 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/signal_init.hpp @@ -0,0 +1,47 @@ +// +// detail/signal_init.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SIGNAL_INIT_HPP +#define ASIO_DETAIL_SIGNAL_INIT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) + +#include + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class signal_init +{ +public: + // Constructor. + signal_init() + { + std::signal(Signal, SIG_IGN); + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) + +#endif // ASIO_DETAIL_SIGNAL_INIT_HPP diff --git a/tools/sdk/include/asio/asio/detail/signal_op.hpp b/tools/sdk/include/asio/asio/detail/signal_op.hpp new file mode 100644 index 00000000..c4e364c1 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/signal_op.hpp @@ -0,0 +1,49 @@ +// +// detail/signal_op.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SIGNAL_OP_HPP +#define ASIO_DETAIL_SIGNAL_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/operation.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class signal_op + : public operation +{ +public: + // The error code to be passed to the completion handler. + asio::error_code ec_; + + // The signal number to be passed to the completion handler. + int signal_number_; + +protected: + signal_op(func_type func) + : operation(func), + signal_number_(0) + { + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SIGNAL_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/signal_set_service.hpp b/tools/sdk/include/asio/asio/detail/signal_set_service.hpp new file mode 100644 index 00000000..a18ab709 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/signal_set_service.hpp @@ -0,0 +1,217 @@ +// +// detail/signal_set_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SIGNAL_SET_SERVICE_HPP +#define ASIO_DETAIL_SIGNAL_SET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include +#include +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/signal_handler.hpp" +#include "asio/detail/signal_op.hpp" +#include "asio/detail/socket_types.hpp" + +#if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) +# include "asio/detail/reactor.hpp" +#endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +#if defined(NSIG) && (NSIG > 0) +enum { max_signal_number = NSIG }; +#else +enum { max_signal_number = 128 }; +#endif + +extern ASIO_DECL struct signal_state* get_signal_state(); + +extern "C" ASIO_DECL void asio_signal_handler(int signal_number); + +class signal_set_service : + public service_base +{ +public: + // Type used for tracking an individual signal registration. + class registration + { + public: + // Default constructor. + registration() + : signal_number_(0), + queue_(0), + undelivered_(0), + next_in_table_(0), + prev_in_table_(0), + next_in_set_(0) + { + } + + private: + // Only this service will have access to the internal values. + friend class signal_set_service; + + // The signal number that is registered. + int signal_number_; + + // The waiting signal handlers. + op_queue* queue_; + + // The number of undelivered signals. + std::size_t undelivered_; + + // Pointers to adjacent registrations in the registrations_ table. + registration* next_in_table_; + registration* prev_in_table_; + + // Link to next registration in the signal set. + registration* next_in_set_; + }; + + // The implementation type of the signal_set. + class implementation_type + { + public: + // Default constructor. + implementation_type() + : signals_(0) + { + } + + private: + // Only this service will have access to the internal values. + friend class signal_set_service; + + // The pending signal handlers. + op_queue queue_; + + // Linked list of registered signals. + registration* signals_; + }; + + // Constructor. + ASIO_DECL signal_set_service(asio::io_context& io_context); + + // Destructor. + ASIO_DECL ~signal_set_service(); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Perform fork-related housekeeping. + ASIO_DECL void notify_fork( + asio::io_context::fork_event fork_ev); + + // Construct a new signal_set implementation. + ASIO_DECL void construct(implementation_type& impl); + + // Destroy a signal_set implementation. + ASIO_DECL void destroy(implementation_type& impl); + + // Add a signal to a signal_set. + ASIO_DECL asio::error_code add(implementation_type& impl, + int signal_number, asio::error_code& ec); + + // Remove a signal to a signal_set. + ASIO_DECL asio::error_code remove(implementation_type& impl, + int signal_number, asio::error_code& ec); + + // Remove all signals from a signal_set. + ASIO_DECL asio::error_code clear(implementation_type& impl, + asio::error_code& ec); + + // Cancel all operations associated with the signal set. + ASIO_DECL asio::error_code cancel(implementation_type& impl, + asio::error_code& ec); + + // Start an asynchronous operation to wait for a signal to be delivered. + template + void async_wait(implementation_type& impl, Handler& handler) + { + // Allocate and construct an operation to wrap the handler. + typedef signal_handler op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + ASIO_HANDLER_CREATION((io_context_.context(), + *p.p, "signal_set", &impl, 0, "async_wait")); + + start_wait_op(impl, p.p); + p.v = p.p = 0; + } + + // Deliver notification that a particular signal occurred. + ASIO_DECL static void deliver_signal(int signal_number); + +private: + // Helper function to add a service to the global signal state. + ASIO_DECL static void add_service(signal_set_service* service); + + // Helper function to remove a service from the global signal state. + ASIO_DECL static void remove_service(signal_set_service* service); + + // Helper function to create the pipe descriptors. + ASIO_DECL static void open_descriptors(); + + // Helper function to close the pipe descriptors. + ASIO_DECL static void close_descriptors(); + + // Helper function to start a wait operation. + ASIO_DECL void start_wait_op(implementation_type& impl, signal_op* op); + + // The io_context instance used for dispatching handlers. + io_context_impl& io_context_; + +#if !defined(ASIO_WINDOWS) \ + && !defined(ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) + // The type used for registering for pipe reactor notifications. + class pipe_read_op; + + // The reactor used for waiting for pipe readiness. + reactor& reactor_; + + // The per-descriptor reactor data used for the pipe. + reactor::per_descriptor_data reactor_data_; +#endif // !defined(ASIO_WINDOWS) + // && !defined(ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) + + // A mapping from signal number to the registered signal sets. + registration* registrations_[max_signal_number]; + + // Pointers to adjacent services in linked list. + signal_set_service* next_; + signal_set_service* prev_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/signal_set_service.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_DETAIL_SIGNAL_SET_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/socket_holder.hpp b/tools/sdk/include/asio/asio/detail/socket_holder.hpp new file mode 100644 index 00000000..99b081f7 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/socket_holder.hpp @@ -0,0 +1,98 @@ +// +// detail/socket_holder.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SOCKET_HOLDER_HPP +#define ASIO_DETAIL_SOCKET_HOLDER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_ops.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Implement the resource acquisition is initialisation idiom for sockets. +class socket_holder + : private noncopyable +{ +public: + // Construct as an uninitialised socket. + socket_holder() + : socket_(invalid_socket) + { + } + + // Construct to take ownership of the specified socket. + explicit socket_holder(socket_type s) + : socket_(s) + { + } + + // Destructor. + ~socket_holder() + { + if (socket_ != invalid_socket) + { + asio::error_code ec; + socket_ops::state_type state = 0; + socket_ops::close(socket_, state, true, ec); + } + } + + // Get the underlying socket. + socket_type get() const + { + return socket_; + } + + // Reset to an uninitialised socket. + void reset() + { + if (socket_ != invalid_socket) + { + asio::error_code ec; + socket_ops::state_type state = 0; + socket_ops::close(socket_, state, true, ec); + socket_ = invalid_socket; + } + } + + // Reset to take ownership of the specified socket. + void reset(socket_type s) + { + reset(); + socket_ = s; + } + + // Release ownership of the socket. + socket_type release() + { + socket_type tmp = socket_; + socket_ = invalid_socket; + return tmp; + } + +private: + // The underlying socket. + socket_type socket_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SOCKET_HOLDER_HPP diff --git a/tools/sdk/include/asio/asio/detail/socket_ops.hpp b/tools/sdk/include/asio/asio/detail/socket_ops.hpp new file mode 100644 index 00000000..815b0d1c --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/socket_ops.hpp @@ -0,0 +1,337 @@ +// +// detail/socket_ops.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SOCKET_OPS_HPP +#define ASIO_DETAIL_SOCKET_OPS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/error_code.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { +namespace socket_ops { + +// Socket state bits. +enum +{ + // The user wants a non-blocking socket. + user_set_non_blocking = 1, + + // The socket has been set non-blocking. + internal_non_blocking = 2, + + // Helper "state" used to determine whether the socket is non-blocking. + non_blocking = user_set_non_blocking | internal_non_blocking, + + // User wants connection_aborted errors, which are disabled by default. + enable_connection_aborted = 4, + + // The user set the linger option. Needs to be checked when closing. + user_set_linger = 8, + + // The socket is stream-oriented. + stream_oriented = 16, + + // The socket is datagram-oriented. + datagram_oriented = 32, + + // The socket may have been dup()-ed. + possible_dup = 64 +}; + +typedef unsigned char state_type; + +struct noop_deleter { void operator()(void*) {} }; +typedef shared_ptr shared_cancel_token_type; +typedef weak_ptr weak_cancel_token_type; + +#if !defined(ASIO_WINDOWS_RUNTIME) + +ASIO_DECL socket_type accept(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, asio::error_code& ec); + +ASIO_DECL socket_type sync_accept(socket_type s, + state_type state, socket_addr_type* addr, + std::size_t* addrlen, asio::error_code& ec); + +#if defined(ASIO_HAS_IOCP) + +ASIO_DECL void complete_iocp_accept(socket_type s, + void* output_buffer, DWORD address_length, + socket_addr_type* addr, std::size_t* addrlen, + socket_type new_socket, asio::error_code& ec); + +#else // defined(ASIO_HAS_IOCP) + +ASIO_DECL bool non_blocking_accept(socket_type s, + state_type state, socket_addr_type* addr, std::size_t* addrlen, + asio::error_code& ec, socket_type& new_socket); + +#endif // defined(ASIO_HAS_IOCP) + +ASIO_DECL int bind(socket_type s, const socket_addr_type* addr, + std::size_t addrlen, asio::error_code& ec); + +ASIO_DECL int close(socket_type s, state_type& state, + bool destruction, asio::error_code& ec); + +ASIO_DECL bool set_user_non_blocking(socket_type s, + state_type& state, bool value, asio::error_code& ec); + +ASIO_DECL bool set_internal_non_blocking(socket_type s, + state_type& state, bool value, asio::error_code& ec); + +ASIO_DECL int shutdown(socket_type s, + int what, asio::error_code& ec); + +ASIO_DECL int connect(socket_type s, const socket_addr_type* addr, + std::size_t addrlen, asio::error_code& ec); + +ASIO_DECL void sync_connect(socket_type s, const socket_addr_type* addr, + std::size_t addrlen, asio::error_code& ec); + +#if defined(ASIO_HAS_IOCP) + +ASIO_DECL void complete_iocp_connect(socket_type s, + asio::error_code& ec); + +#endif // defined(ASIO_HAS_IOCP) + +ASIO_DECL bool non_blocking_connect(socket_type s, + asio::error_code& ec); + +ASIO_DECL int socketpair(int af, int type, int protocol, + socket_type sv[2], asio::error_code& ec); + +ASIO_DECL bool sockatmark(socket_type s, asio::error_code& ec); + +ASIO_DECL size_t available(socket_type s, asio::error_code& ec); + +ASIO_DECL int listen(socket_type s, + int backlog, asio::error_code& ec); + +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) +typedef WSABUF buf; +#else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) +typedef iovec buf; +#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) + +ASIO_DECL void init_buf(buf& b, void* data, size_t size); + +ASIO_DECL void init_buf(buf& b, const void* data, size_t size); + +ASIO_DECL signed_size_type recv(socket_type s, buf* bufs, + size_t count, int flags, asio::error_code& ec); + +ASIO_DECL size_t sync_recv(socket_type s, state_type state, buf* bufs, + size_t count, int flags, bool all_empty, asio::error_code& ec); + +#if defined(ASIO_HAS_IOCP) + +ASIO_DECL void complete_iocp_recv(state_type state, + const weak_cancel_token_type& cancel_token, bool all_empty, + asio::error_code& ec, size_t bytes_transferred); + +#else // defined(ASIO_HAS_IOCP) + +ASIO_DECL bool non_blocking_recv(socket_type s, + buf* bufs, size_t count, int flags, bool is_stream, + asio::error_code& ec, size_t& bytes_transferred); + +#endif // defined(ASIO_HAS_IOCP) + +ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, + size_t count, int flags, socket_addr_type* addr, + std::size_t* addrlen, asio::error_code& ec); + +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, asio::error_code& ec); + +#if defined(ASIO_HAS_IOCP) + +ASIO_DECL void complete_iocp_recvfrom( + const weak_cancel_token_type& cancel_token, + asio::error_code& ec); + +#else // defined(ASIO_HAS_IOCP) + +ASIO_DECL bool non_blocking_recvfrom(socket_type s, + buf* bufs, size_t count, int flags, + socket_addr_type* addr, std::size_t* addrlen, + asio::error_code& ec, size_t& bytes_transferred); + +#endif // defined(ASIO_HAS_IOCP) + +ASIO_DECL signed_size_type recvmsg(socket_type s, buf* bufs, + size_t count, int in_flags, int& out_flags, + asio::error_code& ec); + +ASIO_DECL size_t sync_recvmsg(socket_type s, state_type state, + buf* bufs, size_t count, int in_flags, int& out_flags, + asio::error_code& ec); + +#if defined(ASIO_HAS_IOCP) + +ASIO_DECL void complete_iocp_recvmsg( + const weak_cancel_token_type& cancel_token, + asio::error_code& ec); + +#else // defined(ASIO_HAS_IOCP) + +ASIO_DECL bool non_blocking_recvmsg(socket_type s, + buf* bufs, size_t count, int in_flags, int& out_flags, + asio::error_code& ec, size_t& bytes_transferred); + +#endif // defined(ASIO_HAS_IOCP) + +ASIO_DECL signed_size_type send(socket_type s, const buf* bufs, + size_t count, int flags, asio::error_code& ec); + +ASIO_DECL size_t sync_send(socket_type s, state_type state, + const buf* bufs, size_t count, int flags, + bool all_empty, asio::error_code& ec); + +#if defined(ASIO_HAS_IOCP) + +ASIO_DECL void complete_iocp_send( + const weak_cancel_token_type& cancel_token, + asio::error_code& ec); + +#else // defined(ASIO_HAS_IOCP) + +ASIO_DECL bool non_blocking_send(socket_type s, + const buf* bufs, size_t count, int flags, + asio::error_code& ec, size_t& bytes_transferred); + +#endif // defined(ASIO_HAS_IOCP) + +ASIO_DECL signed_size_type sendto(socket_type s, const buf* bufs, + size_t count, int flags, const socket_addr_type* addr, + std::size_t addrlen, asio::error_code& ec); + +ASIO_DECL size_t sync_sendto(socket_type s, state_type state, + const buf* bufs, size_t count, int flags, const socket_addr_type* addr, + std::size_t addrlen, asio::error_code& ec); + +#if !defined(ASIO_HAS_IOCP) + +ASIO_DECL bool non_blocking_sendto(socket_type s, + const buf* bufs, size_t count, int flags, + const socket_addr_type* addr, std::size_t addrlen, + asio::error_code& ec, size_t& bytes_transferred); + +#endif // !defined(ASIO_HAS_IOCP) + +ASIO_DECL socket_type socket(int af, int type, int protocol, + asio::error_code& ec); + +ASIO_DECL int setsockopt(socket_type s, state_type& state, + int level, int optname, const void* optval, + std::size_t optlen, asio::error_code& ec); + +ASIO_DECL int getsockopt(socket_type s, state_type state, + int level, int optname, void* optval, + size_t* optlen, asio::error_code& ec); + +ASIO_DECL int getpeername(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, bool cached, asio::error_code& ec); + +ASIO_DECL int getsockname(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, asio::error_code& ec); + +ASIO_DECL int ioctl(socket_type s, state_type& state, + int cmd, ioctl_arg_type* arg, asio::error_code& ec); + +ASIO_DECL int select(int nfds, fd_set* readfds, fd_set* writefds, + fd_set* exceptfds, timeval* timeout, asio::error_code& ec); + +ASIO_DECL int poll_read(socket_type s, + state_type state, int msec, asio::error_code& ec); + +ASIO_DECL int poll_write(socket_type s, + state_type state, int msec, asio::error_code& ec); + +ASIO_DECL int poll_error(socket_type s, + state_type state, int msec, asio::error_code& ec); + +ASIO_DECL int poll_connect(socket_type s, + int msec, asio::error_code& ec); + +#endif // !defined(ASIO_WINDOWS_RUNTIME) + +ASIO_DECL const char* inet_ntop(int af, const void* src, char* dest, + size_t length, unsigned long scope_id, asio::error_code& ec); + +ASIO_DECL int inet_pton(int af, const char* src, void* dest, + unsigned long* scope_id, asio::error_code& ec); + +ASIO_DECL int gethostname(char* name, + int namelen, asio::error_code& ec); + +#if !defined(ASIO_WINDOWS_RUNTIME) + +ASIO_DECL asio::error_code getaddrinfo(const char* host, + const char* service, const addrinfo_type& hints, + addrinfo_type** result, asio::error_code& ec); + +ASIO_DECL asio::error_code background_getaddrinfo( + const weak_cancel_token_type& cancel_token, const char* host, + const char* service, const addrinfo_type& hints, + addrinfo_type** result, asio::error_code& ec); + +ASIO_DECL void freeaddrinfo(addrinfo_type* ai); + +ASIO_DECL asio::error_code getnameinfo( + const socket_addr_type* addr, std::size_t addrlen, + char* host, std::size_t hostlen, char* serv, + std::size_t servlen, int flags, asio::error_code& ec); + +ASIO_DECL asio::error_code sync_getnameinfo( + const socket_addr_type* addr, std::size_t addrlen, + char* host, std::size_t hostlen, char* serv, + std::size_t servlen, int sock_type, asio::error_code& ec); + +ASIO_DECL asio::error_code background_getnameinfo( + const weak_cancel_token_type& cancel_token, + const socket_addr_type* addr, std::size_t addrlen, + char* host, std::size_t hostlen, char* serv, + std::size_t servlen, int sock_type, asio::error_code& ec); + +#endif // !defined(ASIO_WINDOWS_RUNTIME) + +ASIO_DECL u_long_type network_to_host_long(u_long_type value); + +ASIO_DECL u_long_type host_to_network_long(u_long_type value); + +ASIO_DECL u_short_type network_to_host_short(u_short_type value); + +ASIO_DECL u_short_type host_to_network_short(u_short_type value); + +} // namespace socket_ops +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/socket_ops.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/tools/sdk/include/asio/asio/detail/socket_option.hpp b/tools/sdk/include/asio/asio/detail/socket_option.hpp new file mode 100644 index 00000000..6852d569 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/socket_option.hpp @@ -0,0 +1,316 @@ +// +// detail/socket_option.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SOCKET_OPTION_HPP +#define ASIO_DETAIL_SOCKET_OPTION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_exception.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { +namespace socket_option { + +// Helper template for implementing boolean-based options. +template +class boolean +{ +public: + // Default constructor. + boolean() + : value_(0) + { + } + + // Construct with a specific option value. + explicit boolean(bool v) + : value_(v ? 1 : 0) + { + } + + // Set the current value of the boolean. + boolean& operator=(bool v) + { + value_ = v ? 1 : 0; + return *this; + } + + // Get the current value of the boolean. + bool value() const + { + return !!value_; + } + + // Convert to bool. + operator bool() const + { + return !!value_; + } + + // Test for false. + bool operator!() const + { + return !value_; + } + + // Get the level of the socket option. + template + int level(const Protocol&) const + { + return Level; + } + + // Get the name of the socket option. + template + int name(const Protocol&) const + { + return Name; + } + + // Get the address of the boolean data. + template + int* data(const Protocol&) + { + return &value_; + } + + // Get the address of the boolean data. + template + const int* data(const Protocol&) const + { + return &value_; + } + + // Get the size of the boolean data. + template + std::size_t size(const Protocol&) const + { + return sizeof(value_); + } + + // Set the size of the boolean data. + template + void resize(const Protocol&, std::size_t s) + { + // On some platforms (e.g. Windows Vista), the getsockopt function will + // return the size of a boolean socket option as one byte, even though a + // four byte integer was passed in. + switch (s) + { + case sizeof(char): + value_ = *reinterpret_cast(&value_) ? 1 : 0; + break; + case sizeof(value_): + break; + default: + { + std::length_error ex("boolean socket option resize"); + asio::detail::throw_exception(ex); + } + } + } + +private: + int value_; +}; + +// Helper template for implementing integer options. +template +class integer +{ +public: + // Default constructor. + integer() + : value_(0) + { + } + + // Construct with a specific option value. + explicit integer(int v) + : value_(v) + { + } + + // Set the value of the int option. + integer& operator=(int v) + { + value_ = v; + return *this; + } + + // Get the current value of the int option. + int value() const + { + return value_; + } + + // Get the level of the socket option. + template + int level(const Protocol&) const + { + return Level; + } + + // Get the name of the socket option. + template + int name(const Protocol&) const + { + return Name; + } + + // Get the address of the int data. + template + int* data(const Protocol&) + { + return &value_; + } + + // Get the address of the int data. + template + const int* data(const Protocol&) const + { + return &value_; + } + + // Get the size of the int data. + template + std::size_t size(const Protocol&) const + { + return sizeof(value_); + } + + // Set the size of the int data. + template + void resize(const Protocol&, std::size_t s) + { + if (s != sizeof(value_)) + { + std::length_error ex("integer socket option resize"); + asio::detail::throw_exception(ex); + } + } + +private: + int value_; +}; + +// Helper template for implementing linger options. +template +class linger +{ +public: + // Default constructor. + linger() + { + value_.l_onoff = 0; + value_.l_linger = 0; + } + + // Construct with specific option values. + linger(bool e, int t) + { + enabled(e); + timeout ASIO_PREVENT_MACRO_SUBSTITUTION(t); + } + + // Set the value for whether linger is enabled. + void enabled(bool value) + { + value_.l_onoff = value ? 1 : 0; + } + + // Get the value for whether linger is enabled. + bool enabled() const + { + return value_.l_onoff != 0; + } + + // Set the value for the linger timeout. + void timeout ASIO_PREVENT_MACRO_SUBSTITUTION(int value) + { +#if defined(WIN32) + value_.l_linger = static_cast(value); +#else + value_.l_linger = value; +#endif + } + + // Get the value for the linger timeout. + int timeout ASIO_PREVENT_MACRO_SUBSTITUTION() const + { + return static_cast(value_.l_linger); + } + + // Get the level of the socket option. + template + int level(const Protocol&) const + { + return Level; + } + + // Get the name of the socket option. + template + int name(const Protocol&) const + { + return Name; + } + + // Get the address of the linger data. + template + detail::linger_type* data(const Protocol&) + { + return &value_; + } + + // Get the address of the linger data. + template + const detail::linger_type* data(const Protocol&) const + { + return &value_; + } + + // Get the size of the linger data. + template + std::size_t size(const Protocol&) const + { + return sizeof(value_); + } + + // Set the size of the int data. + template + void resize(const Protocol&, std::size_t s) + { + if (s != sizeof(value_)) + { + std::length_error ex("linger socket option resize"); + asio::detail::throw_exception(ex); + } + } + +private: + detail::linger_type value_; +}; + +} // namespace socket_option +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SOCKET_OPTION_HPP diff --git a/tools/sdk/include/asio/asio/detail/socket_select_interrupter.hpp b/tools/sdk/include/asio/asio/detail/socket_select_interrupter.hpp new file mode 100644 index 00000000..540b2aeb --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/socket_select_interrupter.hpp @@ -0,0 +1,92 @@ +// +// detail/socket_select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SOCKET_SELECT_INTERRUPTER_HPP +#define ASIO_DETAIL_SOCKET_SELECT_INTERRUPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_WINDOWS_RUNTIME) + +#if defined(ASIO_WINDOWS) \ + || defined(__CYGWIN__) \ + || defined(__SYMBIAN32__) \ + || defined(ESP_PLATFORM) + +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class socket_select_interrupter +{ +public: + // Constructor. + ASIO_DECL socket_select_interrupter(); + + // Destructor. + ASIO_DECL ~socket_select_interrupter(); + + // Recreate the interrupter's descriptors. Used after a fork. + ASIO_DECL void recreate(); + + // Interrupt the select call. + ASIO_DECL void interrupt(); + + // Reset the select interrupt. Returns true if the call was interrupted. + ASIO_DECL bool reset(); + + // Get the read descriptor to be passed to select. + socket_type read_descriptor() const + { + return read_descriptor_; + } + +private: + // Open the descriptors. Throws on error. + ASIO_DECL void open_descriptors(); + + // Close the descriptors. + ASIO_DECL void close_descriptors(); + + // The read end of a connection used to interrupt the select call. This file + // descriptor is passed to select such that when it is time to stop, a single + // byte will be written on the other end of the connection and this + // descriptor will become readable. + socket_type read_descriptor_; + + // The write end of a connection used to interrupt the select call. A single + // byte may be written to this to wake up the select which is waiting for the + // other end to become readable. + socket_type write_descriptor_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/socket_select_interrupter.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_WINDOWS) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) + +#endif // !defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_SOCKET_SELECT_INTERRUPTER_HPP diff --git a/tools/sdk/include/asio/asio/detail/socket_types.hpp b/tools/sdk/include/asio/asio/detail/socket_types.hpp new file mode 100644 index 00000000..6f1abb20 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/socket_types.hpp @@ -0,0 +1,419 @@ +// +// detail/socket_types.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SOCKET_TYPES_HPP +#define ASIO_DETAIL_SOCKET_TYPES_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) +// Empty. +#elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) +# if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) +# error WinSock.h has already been included +# endif // defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) +# if defined(__BORLANDC__) +# include // Needed for __errno +# if !defined(_WSPIAPI_H_) +# define _WSPIAPI_H_ +# define ASIO_WSPIAPI_H_DEFINED +# endif // !defined(_WSPIAPI_H_) +# endif // defined(__BORLANDC__) +# include +# include +# if defined(WINAPI_FAMILY) +# if ((WINAPI_FAMILY & WINAPI_PARTITION_DESKTOP) != 0) +# include +# endif // ((WINAPI_FAMILY & WINAPI_PARTITION_DESKTOP) != 0) +# endif // defined(WINAPI_FAMILY) +# if !defined(ASIO_WINDOWS_APP) +# include +# endif // !defined(ASIO_WINDOWS_APP) +# if defined(ASIO_WSPIAPI_H_DEFINED) +# undef _WSPIAPI_H_ +# undef ASIO_WSPIAPI_H_DEFINED +# endif // defined(ASIO_WSPIAPI_H_DEFINED) +# if !defined(ASIO_NO_DEFAULT_LINKED_LIBS) +# if defined(UNDER_CE) +# pragma comment(lib, "ws2.lib") +# elif defined(_MSC_VER) || defined(__BORLANDC__) +# pragma comment(lib, "ws2_32.lib") +# if !defined(ASIO_WINDOWS_APP) +# pragma comment(lib, "mswsock.lib") +# endif // !defined(ASIO_WINDOWS_APP) +# endif // defined(_MSC_VER) || defined(__BORLANDC__) +# endif // !defined(ASIO_NO_DEFAULT_LINKED_LIBS) +# include "asio/detail/old_win_sdk_compat.hpp" +#else +# include +# if (defined(__MACH__) && defined(__APPLE__)) \ + || defined(__FreeBSD__) || defined(__NetBSD__) \ + || defined(__OpenBSD__) || defined(__linux__) \ + || defined(__EMSCRIPTEN__) +# include +# elif !defined(__SYMBIAN32__) +# include +# endif +# include +# include +# include +# if defined(__hpux) +# include +# endif +# if !defined(__hpux) || defined(__SELECT) +# include +# endif +# include +# include +# include +# include +# if !defined(__SYMBIAN32__) && !defined(ESP_PLATFORM) +# include +# endif +# include +# include +# include +# if defined(ESP_PLATFORM) +# include "esp_exception.h" +# endif +# include +# if defined(__sun) +# include +# include +# endif +#endif + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +#if defined(ASIO_WINDOWS_RUNTIME) +const int max_addr_v4_str_len = 256; +const int max_addr_v6_str_len = 256; +typedef unsigned __int32 u_long_type; +typedef unsigned __int16 u_short_type; +struct in4_addr_type { u_long_type s_addr; }; +struct in4_mreq_type { in4_addr_type imr_multiaddr, imr_interface; }; +struct in6_addr_type { unsigned char s6_addr[16]; }; +struct in6_mreq_type { in6_addr_type ipv6mr_multiaddr; + unsigned long ipv6mr_interface; }; +struct socket_addr_type { int sa_family; }; +struct sockaddr_in4_type { int sin_family; + in4_addr_type sin_addr; u_short_type sin_port; }; +struct sockaddr_in6_type { int sin6_family; + in6_addr_type sin6_addr; u_short_type sin6_port; + u_long_type sin6_flowinfo; u_long_type sin6_scope_id; }; +struct sockaddr_storage_type { int ss_family; + unsigned char ss_bytes[128 - sizeof(int)]; }; +struct addrinfo_type { int ai_flags; + int ai_family, ai_socktype, ai_protocol; + int ai_addrlen; const void* ai_addr; + const char* ai_canonname; addrinfo_type* ai_next; }; +struct linger_type { u_short_type l_onoff, l_linger; }; +typedef u_long_type ioctl_arg_type; +typedef int signed_size_type; +# define ASIO_OS_DEF(c) ASIO_OS_DEF_##c +# define ASIO_OS_DEF_AF_UNSPEC 0 +# define ASIO_OS_DEF_AF_INET 2 +# define ASIO_OS_DEF_AF_INET6 23 +# define ASIO_OS_DEF_SOCK_STREAM 1 +# define ASIO_OS_DEF_SOCK_DGRAM 2 +# define ASIO_OS_DEF_SOCK_RAW 3 +# define ASIO_OS_DEF_SOCK_SEQPACKET 5 +# define ASIO_OS_DEF_IPPROTO_IP 0 +# define ASIO_OS_DEF_IPPROTO_IPV6 41 +# define ASIO_OS_DEF_IPPROTO_TCP 6 +# define ASIO_OS_DEF_IPPROTO_UDP 17 +# define ASIO_OS_DEF_IPPROTO_ICMP 1 +# define ASIO_OS_DEF_IPPROTO_ICMPV6 58 +# define ASIO_OS_DEF_FIONBIO 1 +# define ASIO_OS_DEF_FIONREAD 2 +# define ASIO_OS_DEF_INADDR_ANY 0 +# define ASIO_OS_DEF_MSG_OOB 0x1 +# define ASIO_OS_DEF_MSG_PEEK 0x2 +# define ASIO_OS_DEF_MSG_DONTROUTE 0x4 +# define ASIO_OS_DEF_MSG_EOR 0 // Not supported. +# define ASIO_OS_DEF_SHUT_RD 0x0 +# define ASIO_OS_DEF_SHUT_WR 0x1 +# define ASIO_OS_DEF_SHUT_RDWR 0x2 +# define ASIO_OS_DEF_SOMAXCONN 0x7fffffff +# define ASIO_OS_DEF_SOL_SOCKET 0xffff +# define ASIO_OS_DEF_SO_BROADCAST 0x20 +# define ASIO_OS_DEF_SO_DEBUG 0x1 +# define ASIO_OS_DEF_SO_DONTROUTE 0x10 +# define ASIO_OS_DEF_SO_KEEPALIVE 0x8 +# define ASIO_OS_DEF_SO_LINGER 0x80 +# define ASIO_OS_DEF_SO_OOBINLINE 0x100 +# define ASIO_OS_DEF_SO_SNDBUF 0x1001 +# define ASIO_OS_DEF_SO_RCVBUF 0x1002 +# define ASIO_OS_DEF_SO_SNDLOWAT 0x1003 +# define ASIO_OS_DEF_SO_RCVLOWAT 0x1004 +# define ASIO_OS_DEF_SO_REUSEADDR 0x4 +# define ASIO_OS_DEF_TCP_NODELAY 0x1 +# define ASIO_OS_DEF_IP_MULTICAST_IF 2 +# define ASIO_OS_DEF_IP_MULTICAST_TTL 3 +# define ASIO_OS_DEF_IP_MULTICAST_LOOP 4 +# define ASIO_OS_DEF_IP_ADD_MEMBERSHIP 5 +# define ASIO_OS_DEF_IP_DROP_MEMBERSHIP 6 +# define ASIO_OS_DEF_IP_TTL 7 +# define ASIO_OS_DEF_IPV6_UNICAST_HOPS 4 +# define ASIO_OS_DEF_IPV6_MULTICAST_IF 9 +# define ASIO_OS_DEF_IPV6_MULTICAST_HOPS 10 +# define ASIO_OS_DEF_IPV6_MULTICAST_LOOP 11 +# define ASIO_OS_DEF_IPV6_JOIN_GROUP 12 +# define ASIO_OS_DEF_IPV6_LEAVE_GROUP 13 +# define ASIO_OS_DEF_AI_CANONNAME 0x2 +# define ASIO_OS_DEF_AI_PASSIVE 0x1 +# define ASIO_OS_DEF_AI_NUMERICHOST 0x4 +# define ASIO_OS_DEF_AI_NUMERICSERV 0x8 +# define ASIO_OS_DEF_AI_V4MAPPED 0x800 +# define ASIO_OS_DEF_AI_ALL 0x100 +# define ASIO_OS_DEF_AI_ADDRCONFIG 0x400 +#elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) +typedef SOCKET socket_type; +const SOCKET invalid_socket = INVALID_SOCKET; +const int socket_error_retval = SOCKET_ERROR; +const int max_addr_v4_str_len = 256; +const int max_addr_v6_str_len = 256; +typedef sockaddr socket_addr_type; +typedef in_addr in4_addr_type; +typedef ip_mreq in4_mreq_type; +typedef sockaddr_in sockaddr_in4_type; +# if defined(ASIO_HAS_OLD_WIN_SDK) +typedef in6_addr_emulation in6_addr_type; +typedef ipv6_mreq_emulation in6_mreq_type; +typedef sockaddr_in6_emulation sockaddr_in6_type; +typedef sockaddr_storage_emulation sockaddr_storage_type; +typedef addrinfo_emulation addrinfo_type; +# else +typedef in6_addr in6_addr_type; +typedef ipv6_mreq in6_mreq_type; +typedef sockaddr_in6 sockaddr_in6_type; +typedef sockaddr_storage sockaddr_storage_type; +typedef addrinfo addrinfo_type; +# endif +typedef ::linger linger_type; +typedef unsigned long ioctl_arg_type; +typedef u_long u_long_type; +typedef u_short u_short_type; +typedef int signed_size_type; +# define ASIO_OS_DEF(c) ASIO_OS_DEF_##c +# define ASIO_OS_DEF_AF_UNSPEC AF_UNSPEC +# define ASIO_OS_DEF_AF_INET AF_INET +# define ASIO_OS_DEF_AF_INET6 AF_INET6 +# define ASIO_OS_DEF_SOCK_STREAM SOCK_STREAM +# define ASIO_OS_DEF_SOCK_DGRAM SOCK_DGRAM +# define ASIO_OS_DEF_SOCK_RAW SOCK_RAW +# define ASIO_OS_DEF_SOCK_SEQPACKET SOCK_SEQPACKET +# define ASIO_OS_DEF_IPPROTO_IP IPPROTO_IP +# define ASIO_OS_DEF_IPPROTO_IPV6 IPPROTO_IPV6 +# define ASIO_OS_DEF_IPPROTO_TCP IPPROTO_TCP +# define ASIO_OS_DEF_IPPROTO_UDP IPPROTO_UDP +# define ASIO_OS_DEF_IPPROTO_ICMP IPPROTO_ICMP +# define ASIO_OS_DEF_IPPROTO_ICMPV6 IPPROTO_ICMPV6 +# define ASIO_OS_DEF_FIONBIO FIONBIO +# define ASIO_OS_DEF_FIONREAD FIONREAD +# define ASIO_OS_DEF_INADDR_ANY INADDR_ANY +# define ASIO_OS_DEF_MSG_OOB MSG_OOB +# define ASIO_OS_DEF_MSG_PEEK MSG_PEEK +# define ASIO_OS_DEF_MSG_DONTROUTE MSG_DONTROUTE +# define ASIO_OS_DEF_MSG_EOR 0 // Not supported on Windows. +# define ASIO_OS_DEF_SHUT_RD SD_RECEIVE +# define ASIO_OS_DEF_SHUT_WR SD_SEND +# define ASIO_OS_DEF_SHUT_RDWR SD_BOTH +# define ASIO_OS_DEF_SOMAXCONN SOMAXCONN +# define ASIO_OS_DEF_SOL_SOCKET SOL_SOCKET +# define ASIO_OS_DEF_SO_BROADCAST SO_BROADCAST +# define ASIO_OS_DEF_SO_DEBUG SO_DEBUG +# define ASIO_OS_DEF_SO_DONTROUTE SO_DONTROUTE +# define ASIO_OS_DEF_SO_KEEPALIVE SO_KEEPALIVE +# define ASIO_OS_DEF_SO_LINGER SO_LINGER +# define ASIO_OS_DEF_SO_OOBINLINE SO_OOBINLINE +# define ASIO_OS_DEF_SO_SNDBUF SO_SNDBUF +# define ASIO_OS_DEF_SO_RCVBUF SO_RCVBUF +# define ASIO_OS_DEF_SO_SNDLOWAT SO_SNDLOWAT +# define ASIO_OS_DEF_SO_RCVLOWAT SO_RCVLOWAT +# define ASIO_OS_DEF_SO_REUSEADDR SO_REUSEADDR +# define ASIO_OS_DEF_TCP_NODELAY TCP_NODELAY +# define ASIO_OS_DEF_IP_MULTICAST_IF IP_MULTICAST_IF +# define ASIO_OS_DEF_IP_MULTICAST_TTL IP_MULTICAST_TTL +# define ASIO_OS_DEF_IP_MULTICAST_LOOP IP_MULTICAST_LOOP +# define ASIO_OS_DEF_IP_ADD_MEMBERSHIP IP_ADD_MEMBERSHIP +# define ASIO_OS_DEF_IP_DROP_MEMBERSHIP IP_DROP_MEMBERSHIP +# define ASIO_OS_DEF_IP_TTL IP_TTL +# define ASIO_OS_DEF_IPV6_UNICAST_HOPS IPV6_UNICAST_HOPS +# define ASIO_OS_DEF_IPV6_MULTICAST_IF IPV6_MULTICAST_IF +# define ASIO_OS_DEF_IPV6_MULTICAST_HOPS IPV6_MULTICAST_HOPS +# define ASIO_OS_DEF_IPV6_MULTICAST_LOOP IPV6_MULTICAST_LOOP +# define ASIO_OS_DEF_IPV6_JOIN_GROUP IPV6_JOIN_GROUP +# define ASIO_OS_DEF_IPV6_LEAVE_GROUP IPV6_LEAVE_GROUP +# define ASIO_OS_DEF_AI_CANONNAME AI_CANONNAME +# define ASIO_OS_DEF_AI_PASSIVE AI_PASSIVE +# define ASIO_OS_DEF_AI_NUMERICHOST AI_NUMERICHOST +# if defined(AI_NUMERICSERV) +# define ASIO_OS_DEF_AI_NUMERICSERV AI_NUMERICSERV +# else +# define ASIO_OS_DEF_AI_NUMERICSERV 0 +# endif +# if defined(AI_V4MAPPED) +# define ASIO_OS_DEF_AI_V4MAPPED AI_V4MAPPED +# else +# define ASIO_OS_DEF_AI_V4MAPPED 0 +# endif +# if defined(AI_ALL) +# define ASIO_OS_DEF_AI_ALL AI_ALL +# else +# define ASIO_OS_DEF_AI_ALL 0 +# endif +# if defined(AI_ADDRCONFIG) +# define ASIO_OS_DEF_AI_ADDRCONFIG AI_ADDRCONFIG +# else +# define ASIO_OS_DEF_AI_ADDRCONFIG 0 +# endif +# if defined (_WIN32_WINNT) +const int max_iov_len = 64; +# else +const int max_iov_len = 16; +# endif +#else +typedef int socket_type; +const int invalid_socket = -1; +const int socket_error_retval = -1; +const int max_addr_v4_str_len = INET_ADDRSTRLEN; +#if defined(INET6_ADDRSTRLEN) +const int max_addr_v6_str_len = INET6_ADDRSTRLEN + 1 + IF_NAMESIZE; +#else // defined(INET6_ADDRSTRLEN) +const int max_addr_v6_str_len = 256; +#endif // defined(INET6_ADDRSTRLEN) +typedef sockaddr socket_addr_type; +typedef in_addr in4_addr_type; +# if defined(__hpux) +// HP-UX doesn't provide ip_mreq when _XOPEN_SOURCE_EXTENDED is defined. +struct in4_mreq_type +{ + struct in_addr imr_multiaddr; + struct in_addr imr_interface; +}; +# else +typedef ip_mreq in4_mreq_type; +# endif +typedef sockaddr_in sockaddr_in4_type; +typedef in6_addr in6_addr_type; +typedef ipv6_mreq in6_mreq_type; +typedef sockaddr_in6 sockaddr_in6_type; +typedef sockaddr_storage sockaddr_storage_type; +typedef sockaddr_un sockaddr_un_type; +typedef addrinfo addrinfo_type; +typedef ::linger linger_type; +typedef int ioctl_arg_type; +typedef uint32_t u_long_type; +typedef uint16_t u_short_type; +#if defined(ASIO_HAS_SSIZE_T) +typedef ssize_t signed_size_type; +#else // defined(ASIO_HAS_SSIZE_T) +typedef int signed_size_type; +#endif // defined(ASIO_HAS_SSIZE_T) +# define ASIO_OS_DEF(c) ASIO_OS_DEF_##c +# define ASIO_OS_DEF_AF_UNSPEC AF_UNSPEC +# define ASIO_OS_DEF_AF_INET AF_INET +# define ASIO_OS_DEF_AF_INET6 AF_INET6 +# define ASIO_OS_DEF_SOCK_STREAM SOCK_STREAM +# define ASIO_OS_DEF_SOCK_DGRAM SOCK_DGRAM +# define ASIO_OS_DEF_SOCK_RAW SOCK_RAW +# define ASIO_OS_DEF_SOCK_SEQPACKET SOCK_SEQPACKET +# define ASIO_OS_DEF_IPPROTO_IP IPPROTO_IP +# define ASIO_OS_DEF_IPPROTO_IPV6 IPPROTO_IPV6 +# define ASIO_OS_DEF_IPPROTO_TCP IPPROTO_TCP +# define ASIO_OS_DEF_IPPROTO_UDP IPPROTO_UDP +# define ASIO_OS_DEF_IPPROTO_ICMP IPPROTO_ICMP +# define ASIO_OS_DEF_IPPROTO_ICMPV6 IPPROTO_ICMPV6 +# define ASIO_OS_DEF_FIONBIO FIONBIO +# define ASIO_OS_DEF_FIONREAD FIONREAD +# define ASIO_OS_DEF_INADDR_ANY INADDR_ANY +# define ASIO_OS_DEF_MSG_OOB MSG_OOB +# define ASIO_OS_DEF_MSG_PEEK MSG_PEEK +# define ASIO_OS_DEF_MSG_DONTROUTE MSG_DONTROUTE +# define ASIO_OS_DEF_MSG_EOR MSG_EOR +# define ASIO_OS_DEF_SHUT_RD SHUT_RD +# define ASIO_OS_DEF_SHUT_WR SHUT_WR +# define ASIO_OS_DEF_SHUT_RDWR SHUT_RDWR +# define ASIO_OS_DEF_SOMAXCONN SOMAXCONN +# define ASIO_OS_DEF_SOL_SOCKET SOL_SOCKET +# define ASIO_OS_DEF_SO_BROADCAST SO_BROADCAST +# define ASIO_OS_DEF_SO_DEBUG SO_DEBUG +# define ASIO_OS_DEF_SO_DONTROUTE SO_DONTROUTE +# define ASIO_OS_DEF_SO_KEEPALIVE SO_KEEPALIVE +# define ASIO_OS_DEF_SO_LINGER SO_LINGER +# define ASIO_OS_DEF_SO_OOBINLINE SO_OOBINLINE +# define ASIO_OS_DEF_SO_SNDBUF SO_SNDBUF +# define ASIO_OS_DEF_SO_RCVBUF SO_RCVBUF +# define ASIO_OS_DEF_SO_SNDLOWAT SO_SNDLOWAT +# define ASIO_OS_DEF_SO_RCVLOWAT SO_RCVLOWAT +# define ASIO_OS_DEF_SO_REUSEADDR SO_REUSEADDR +# define ASIO_OS_DEF_TCP_NODELAY TCP_NODELAY +# define ASIO_OS_DEF_IP_MULTICAST_IF IP_MULTICAST_IF +# define ASIO_OS_DEF_IP_MULTICAST_TTL IP_MULTICAST_TTL +# define ASIO_OS_DEF_IP_MULTICAST_LOOP IP_MULTICAST_LOOP +# define ASIO_OS_DEF_IP_ADD_MEMBERSHIP IP_ADD_MEMBERSHIP +# define ASIO_OS_DEF_IP_DROP_MEMBERSHIP IP_DROP_MEMBERSHIP +# define ASIO_OS_DEF_IP_TTL IP_TTL +# define ASIO_OS_DEF_IPV6_UNICAST_HOPS IPV6_UNICAST_HOPS +# define ASIO_OS_DEF_IPV6_MULTICAST_IF IPV6_MULTICAST_IF +# define ASIO_OS_DEF_IPV6_MULTICAST_HOPS IPV6_MULTICAST_HOPS +# define ASIO_OS_DEF_IPV6_MULTICAST_LOOP IPV6_MULTICAST_LOOP +# define ASIO_OS_DEF_IPV6_JOIN_GROUP IPV6_JOIN_GROUP +# define ASIO_OS_DEF_IPV6_LEAVE_GROUP IPV6_LEAVE_GROUP +# define ASIO_OS_DEF_AI_CANONNAME AI_CANONNAME +# define ASIO_OS_DEF_AI_PASSIVE AI_PASSIVE +# define ASIO_OS_DEF_AI_NUMERICHOST AI_NUMERICHOST +# if defined(AI_NUMERICSERV) +# define ASIO_OS_DEF_AI_NUMERICSERV AI_NUMERICSERV +# else +# define ASIO_OS_DEF_AI_NUMERICSERV 0 +# endif +// Note: QNX Neutrino 6.3 defines AI_V4MAPPED, AI_ALL and AI_ADDRCONFIG but +// does not implement them. Therefore they are specifically excluded here. +# if defined(AI_V4MAPPED) && !defined(__QNXNTO__) +# define ASIO_OS_DEF_AI_V4MAPPED AI_V4MAPPED +# else +# define ASIO_OS_DEF_AI_V4MAPPED 0 +# endif +# if defined(AI_ALL) && !defined(__QNXNTO__) +# define ASIO_OS_DEF_AI_ALL AI_ALL +# else +# define ASIO_OS_DEF_AI_ALL 0 +# endif +# if defined(AI_ADDRCONFIG) && !defined(__QNXNTO__) +# define ASIO_OS_DEF_AI_ADDRCONFIG AI_ADDRCONFIG +# else +# define ASIO_OS_DEF_AI_ADDRCONFIG 0 +# endif +# if defined(IOV_MAX) +const int max_iov_len = IOV_MAX; +# else +// POSIX platforms are not required to define IOV_MAX. +const int max_iov_len = 16; +# endif +#endif +const int custom_socket_option_level = 0xA5100000; +const int enable_connection_aborted_option = 1; +const int always_fail_option = 2; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SOCKET_TYPES_HPP diff --git a/tools/sdk/include/asio/asio/detail/solaris_fenced_block.hpp b/tools/sdk/include/asio/asio/detail/solaris_fenced_block.hpp new file mode 100644 index 00000000..d48f6a37 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/solaris_fenced_block.hpp @@ -0,0 +1,62 @@ +// +// detail/solaris_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP +#define ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(__sun) + +#include +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class solaris_fenced_block + : private noncopyable +{ +public: + enum half_t { half }; + enum full_t { full }; + + // Constructor for a half fenced block. + explicit solaris_fenced_block(half_t) + { + } + + // Constructor for a full fenced block. + explicit solaris_fenced_block(full_t) + { + membar_consumer(); + } + + // Destructor. + ~solaris_fenced_block() + { + membar_producer(); + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(__sun) + +#endif // ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP diff --git a/tools/sdk/include/asio/asio/detail/static_mutex.hpp b/tools/sdk/include/asio/asio/detail/static_mutex.hpp new file mode 100644 index 00000000..8f2bc02a --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/static_mutex.hpp @@ -0,0 +1,52 @@ +// +// detail/static_mutex.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_STATIC_MUTEX_HPP +#define ASIO_DETAIL_STATIC_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_THREADS) +# include "asio/detail/null_static_mutex.hpp" +#elif defined(ASIO_WINDOWS) +# include "asio/detail/win_static_mutex.hpp" +#elif defined(ASIO_HAS_PTHREADS) +# include "asio/detail/posix_static_mutex.hpp" +#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) +# include "asio/detail/std_static_mutex.hpp" +#else +# error Only Windows and POSIX are supported! +#endif + +namespace asio { +namespace detail { + +#if !defined(ASIO_HAS_THREADS) +typedef null_static_mutex static_mutex; +# define ASIO_STATIC_MUTEX_INIT ASIO_NULL_STATIC_MUTEX_INIT +#elif defined(ASIO_WINDOWS) +typedef win_static_mutex static_mutex; +# define ASIO_STATIC_MUTEX_INIT ASIO_WIN_STATIC_MUTEX_INIT +#elif defined(ASIO_HAS_PTHREADS) +typedef posix_static_mutex static_mutex; +# define ASIO_STATIC_MUTEX_INIT ASIO_POSIX_STATIC_MUTEX_INIT +#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) +typedef std_static_mutex static_mutex; +# define ASIO_STATIC_MUTEX_INIT ASIO_STD_STATIC_MUTEX_INIT +#endif + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_STATIC_MUTEX_HPP diff --git a/tools/sdk/include/asio/asio/detail/std_event.hpp b/tools/sdk/include/asio/asio/detail/std_event.hpp new file mode 100644 index 00000000..5639ecdd --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/std_event.hpp @@ -0,0 +1,176 @@ +// +// detail/std_event.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_STD_EVENT_HPP +#define ASIO_DETAIL_STD_EVENT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) + +#include +#include +#include "asio/detail/assert.hpp" +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class std_event + : private noncopyable +{ +public: + // Constructor. + std_event() + : state_(0) + { + } + + // Destructor. + ~std_event() + { + } + + // Signal the event. (Retained for backward compatibility.) + template + void signal(Lock& lock) + { + this->signal_all(lock); + } + + // Signal all waiters. + template + void signal_all(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + (void)lock; + state_ |= 1; + cond_.notify_all(); + } + + // Unlock the mutex and signal one waiter. + template + void unlock_and_signal_one(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + state_ |= 1; + bool have_waiters = (state_ > 1); + lock.unlock(); + if (have_waiters) + cond_.notify_one(); + } + + // If there's a waiter, unlock the mutex and signal it. + template + bool maybe_unlock_and_signal_one(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + state_ |= 1; + if (state_ > 1) + { + lock.unlock(); + cond_.notify_one(); + return true; + } + return false; + } + + // Reset the event. + template + void clear(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + (void)lock; + state_ &= ~std::size_t(1); + } + + // Wait for the event to become signalled. + template + void wait(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + unique_lock_adapter u_lock(lock); + while ((state_ & 1) == 0) + { + waiter w(state_); + cond_.wait(u_lock.unique_lock_); + } + } + + // Timed wait for the event to become signalled. + template + bool wait_for_usec(Lock& lock, long usec) + { + ASIO_ASSERT(lock.locked()); + unique_lock_adapter u_lock(lock); + if ((state_ & 1) == 0) + { + waiter w(state_); + cond_.wait_for(u_lock.unique_lock_, std::chrono::microseconds(usec)); + } + return (state_ & 1) != 0; + } + +private: + // Helper class to temporarily adapt a scoped_lock into a unique_lock so that + // it can be passed to std::condition_variable::wait(). + struct unique_lock_adapter + { + template + explicit unique_lock_adapter(Lock& lock) + : unique_lock_(lock.mutex().mutex_, std::adopt_lock) + { + } + + ~unique_lock_adapter() + { + unique_lock_.release(); + } + + std::unique_lock unique_lock_; + }; + + // Helper to increment and decrement the state to track outstanding waiters. + class waiter + { + public: + explicit waiter(std::size_t& state) + : state_(state) + { + state_ += 2; + } + + ~waiter() + { + state_ -= 2; + } + + private: + std::size_t& state_; + }; + + std::condition_variable cond_; + std::size_t state_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) + +#endif // ASIO_DETAIL_STD_EVENT_HPP diff --git a/tools/sdk/include/asio/asio/detail/std_fenced_block.hpp b/tools/sdk/include/asio/asio/detail/std_fenced_block.hpp new file mode 100644 index 00000000..0d8ade02 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/std_fenced_block.hpp @@ -0,0 +1,62 @@ +// +// detail/std_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_STD_FENCED_BLOCK_HPP +#define ASIO_DETAIL_STD_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_STD_ATOMIC) + +#include +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class std_fenced_block + : private noncopyable +{ +public: + enum half_t { half }; + enum full_t { full }; + + // Constructor for a half fenced block. + explicit std_fenced_block(half_t) + { + } + + // Constructor for a full fenced block. + explicit std_fenced_block(full_t) + { + std::atomic_thread_fence(std::memory_order_acquire); + } + + // Destructor. + ~std_fenced_block() + { + std::atomic_thread_fence(std::memory_order_release); + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_STD_ATOMIC) + +#endif // ASIO_DETAIL_STD_FENCED_BLOCK_HPP diff --git a/tools/sdk/include/asio/asio/detail/std_global.hpp b/tools/sdk/include/asio/asio/detail/std_global.hpp new file mode 100644 index 00000000..0c5173e6 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/std_global.hpp @@ -0,0 +1,70 @@ +// +// detail/std_global.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_STD_GLOBAL_HPP +#define ASIO_DETAIL_STD_GLOBAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_STD_CALL_ONCE) + +#include +#include + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +struct std_global_impl +{ + // Helper function to perform initialisation. + static void do_init() + { + instance_.ptr_ = new T; + } + + // Destructor automatically cleans up the global. + ~std_global_impl() + { + delete ptr_; + } + + static std::once_flag init_once_; + static std_global_impl instance_; + T* ptr_; +}; + +template +std::once_flag std_global_impl::init_once_; + +template +std_global_impl std_global_impl::instance_; + +template +T& std_global() +{ + std::call_once(std_global_impl::init_once_, &std_global_impl::do_init); + return *std_global_impl::instance_.ptr_; +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_STD_CALL_ONCE) + +#endif // ASIO_DETAIL_STD_GLOBAL_HPP diff --git a/tools/sdk/include/asio/asio/detail/std_mutex.hpp b/tools/sdk/include/asio/asio/detail/std_mutex.hpp new file mode 100644 index 00000000..159049e8 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/std_mutex.hpp @@ -0,0 +1,73 @@ +// +// detail/std_mutex.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_STD_MUTEX_HPP +#define ASIO_DETAIL_STD_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) + +#include +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/scoped_lock.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class std_event; + +class std_mutex + : private noncopyable +{ +public: + typedef asio::detail::scoped_lock scoped_lock; + + // Constructor. + std_mutex() + { + } + + // Destructor. + ~std_mutex() + { + } + + // Lock the mutex. + void lock() + { + mutex_.lock(); + } + + // Unlock the mutex. + void unlock() + { + mutex_.unlock(); + } + +private: + friend class std_event; + std::mutex mutex_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) + +#endif // ASIO_DETAIL_STD_MUTEX_HPP diff --git a/tools/sdk/include/asio/asio/detail/std_static_mutex.hpp b/tools/sdk/include/asio/asio/detail/std_static_mutex.hpp new file mode 100644 index 00000000..e9c9dc5e --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/std_static_mutex.hpp @@ -0,0 +1,81 @@ +// +// detail/std_static_mutex.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_STD_STATIC_MUTEX_HPP +#define ASIO_DETAIL_STD_STATIC_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) + +#include +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/scoped_lock.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class std_event; + +class std_static_mutex + : private noncopyable +{ +public: + typedef asio::detail::scoped_lock scoped_lock; + + // Constructor. + std_static_mutex(int) + { + } + + // Destructor. + ~std_static_mutex() + { + } + + // Initialise the mutex. + void init() + { + // Nothing to do. + } + + // Lock the mutex. + void lock() + { + mutex_.lock(); + } + + // Unlock the mutex. + void unlock() + { + mutex_.unlock(); + } + +private: + friend class std_event; + std::mutex mutex_; +}; + +#define ASIO_STD_STATIC_MUTEX_INIT 0 + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) + +#endif // ASIO_DETAIL_STD_STATIC_MUTEX_HPP diff --git a/tools/sdk/include/asio/asio/detail/std_thread.hpp b/tools/sdk/include/asio/asio/detail/std_thread.hpp new file mode 100644 index 00000000..a240308d --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/std_thread.hpp @@ -0,0 +1,71 @@ +// +// detail/std_thread.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_STD_THREAD_HPP +#define ASIO_DETAIL_STD_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_STD_THREAD) + +#include +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class std_thread + : private noncopyable +{ +public: + // Constructor. + template + std_thread(Function f, unsigned int = 0) + : thread_(f) + { + } + + // Destructor. + ~std_thread() + { + join(); + } + + // Wait for the thread to exit. + void join() + { + if (thread_.joinable()) + thread_.join(); + } + + // Get number of CPUs. + static std::size_t hardware_concurrency() + { + return std::thread::hardware_concurrency(); + } + +private: + std::thread thread_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_STD_THREAD) + +#endif // ASIO_DETAIL_STD_THREAD_HPP diff --git a/tools/sdk/include/asio/asio/detail/strand_executor_service.hpp b/tools/sdk/include/asio/asio/detail/strand_executor_service.hpp new file mode 100644 index 00000000..67e84274 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/strand_executor_service.hpp @@ -0,0 +1,142 @@ +// +// detail/strand_executor_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_STRAND_EXECUTOR_SERVICE_HPP +#define ASIO_DETAIL_STRAND_EXECUTOR_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/atomic_count.hpp" +#include "asio/detail/executor_op.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/scheduler_operation.hpp" +#include "asio/detail/scoped_ptr.hpp" +#include "asio/execution_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Default service implementation for a strand. +class strand_executor_service + : public execution_context_service_base +{ +public: + // The underlying implementation of a strand. + class strand_impl + { + public: + ASIO_DECL ~strand_impl(); + + private: + friend class strand_executor_service; + + // Mutex to protect access to internal data. + mutex* mutex_; + + // Indicates whether the strand is currently "locked" by a handler. This + // means that there is a handler upcall in progress, or that the strand + // itself has been scheduled in order to invoke some pending handlers. + bool locked_; + + // Indicates that the strand has been shut down and will accept no further + // handlers. + bool shutdown_; + + // The handlers that are waiting on the strand but should not be run until + // after the next time the strand is scheduled. This queue must only be + // modified while the mutex is locked. + op_queue waiting_queue_; + + // The handlers that are ready to be run. Logically speaking, these are the + // handlers that hold the strand's lock. The ready queue is only modified + // from within the strand and so may be accessed without locking the mutex. + op_queue ready_queue_; + + // Pointers to adjacent handle implementations in linked list. + strand_impl* next_; + strand_impl* prev_; + + // The strand service in where the implementation is held. + strand_executor_service* service_; + }; + + typedef shared_ptr implementation_type; + + // Construct a new strand service for the specified context. + ASIO_DECL explicit strand_executor_service(execution_context& context); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Create a new strand_executor implementation. + ASIO_DECL implementation_type create_implementation(); + + // Request invocation of the given function. + template + static void dispatch(const implementation_type& impl, Executor& ex, + ASIO_MOVE_ARG(Function) function, const Allocator& a); + + // Request invocation of the given function and return immediately. + template + static void post(const implementation_type& impl, Executor& ex, + ASIO_MOVE_ARG(Function) function, const Allocator& a); + + // Request invocation of the given function and return immediately. + template + static void defer(const implementation_type& impl, Executor& ex, + ASIO_MOVE_ARG(Function) function, const Allocator& a); + + // Determine whether the strand is running in the current thread. + ASIO_DECL static bool running_in_this_thread( + const implementation_type& impl); + +private: + friend class strand_impl; + template class invoker; + + // Adds a function to the strand. Returns true if it acquires the lock. + ASIO_DECL static bool enqueue(const implementation_type& impl, + scheduler_operation* op); + + // Mutex to protect access to the service-wide state. + mutex mutex_; + + // Number of mutexes shared between all strand objects. + enum { num_mutexes = 193 }; + + // Pool of mutexes. + scoped_ptr mutexes_[num_mutexes]; + + // Extra value used when hashing to prevent recycled memory locations from + // getting the same mutex. + std::size_t salt_; + + // The head of a linked list of all implementations. + strand_impl* impl_list_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/impl/strand_executor_service.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/strand_executor_service.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_DETAIL_STRAND_EXECUTOR_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/strand_service.hpp b/tools/sdk/include/asio/asio/detail/strand_service.hpp new file mode 100644 index 00000000..edc14a0f --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/strand_service.hpp @@ -0,0 +1,142 @@ +// +// detail/strand_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_STRAND_SERVICE_HPP +#define ASIO_DETAIL_STRAND_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/io_context.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/operation.hpp" +#include "asio/detail/scoped_ptr.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Default service implementation for a strand. +class strand_service + : public asio::detail::service_base +{ +private: + // Helper class to re-post the strand on exit. + struct on_do_complete_exit; + + // Helper class to re-post the strand on exit. + struct on_dispatch_exit; + +public: + + // The underlying implementation of a strand. + class strand_impl + : public operation + { + public: + strand_impl(); + + private: + // Only this service will have access to the internal values. + friend class strand_service; + friend struct on_do_complete_exit; + friend struct on_dispatch_exit; + + // Mutex to protect access to internal data. + asio::detail::mutex mutex_; + + // Indicates whether the strand is currently "locked" by a handler. This + // means that there is a handler upcall in progress, or that the strand + // itself has been scheduled in order to invoke some pending handlers. + bool locked_; + + // The handlers that are waiting on the strand but should not be run until + // after the next time the strand is scheduled. This queue must only be + // modified while the mutex is locked. + op_queue waiting_queue_; + + // The handlers that are ready to be run. Logically speaking, these are the + // handlers that hold the strand's lock. The ready queue is only modified + // from within the strand and so may be accessed without locking the mutex. + op_queue ready_queue_; + }; + + typedef strand_impl* implementation_type; + + // Construct a new strand service for the specified io_context. + ASIO_DECL explicit strand_service(asio::io_context& io_context); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Construct a new strand implementation. + ASIO_DECL void construct(implementation_type& impl); + + // Request the io_context to invoke the given handler. + template + void dispatch(implementation_type& impl, Handler& handler); + + // Request the io_context to invoke the given handler and return immediately. + template + void post(implementation_type& impl, Handler& handler); + + // Determine whether the strand is running in the current thread. + ASIO_DECL bool running_in_this_thread( + const implementation_type& impl) const; + +private: + // Helper function to dispatch a handler. Returns true if the handler should + // be dispatched immediately. + ASIO_DECL bool do_dispatch(implementation_type& impl, operation* op); + + // Helper fiunction to post a handler. + ASIO_DECL void do_post(implementation_type& impl, + operation* op, bool is_continuation); + + ASIO_DECL static void do_complete(void* owner, + operation* base, const asio::error_code& ec, + std::size_t bytes_transferred); + + // The io_context implementation used to post completions. + io_context_impl& io_context_; + + // Mutex to protect access to the array of implementations. + asio::detail::mutex mutex_; + + // Number of implementations shared between all strand objects. +#if defined(ASIO_STRAND_IMPLEMENTATIONS) + enum { num_implementations = ASIO_STRAND_IMPLEMENTATIONS }; +#else // defined(ASIO_STRAND_IMPLEMENTATIONS) + enum { num_implementations = 193 }; +#endif // defined(ASIO_STRAND_IMPLEMENTATIONS) + + // Pool of implementations. + scoped_ptr implementations_[num_implementations]; + + // Extra value used when hashing to prevent recycled memory locations from + // getting the same strand implementation. + std::size_t salt_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/impl/strand_service.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/strand_service.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_DETAIL_STRAND_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/string_view.hpp b/tools/sdk/include/asio/asio/detail/string_view.hpp new file mode 100644 index 00000000..f09cebc2 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/string_view.hpp @@ -0,0 +1,47 @@ +// +// detail/string_view.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_STRING_VIEW_HPP +#define ASIO_DETAIL_STRING_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_STRING_VIEW) + +#if defined(ASIO_HAS_STD_STRING_VIEW) +# include +#elif defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) +# include +#else // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) +# error ASIO_HAS_STRING_VIEW is set but no string_view is available +#endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) + +namespace asio { + +#if defined(ASIO_HAS_STD_STRING_VIEW) +using std::basic_string_view; +using std::string_view; +#elif defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) +using std::experimental::basic_string_view; +using std::experimental::string_view; +#endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) + +} // namespace asio + +# define ASIO_STRING_VIEW_PARAM asio::string_view +#else // defined(ASIO_HAS_STRING_VIEW) +# define ASIO_STRING_VIEW_PARAM const std::string& +#endif // defined(ASIO_HAS_STRING_VIEW) + +#endif // ASIO_DETAIL_STRING_VIEW_HPP diff --git a/tools/sdk/include/asio/asio/detail/thread.hpp b/tools/sdk/include/asio/asio/detail/thread.hpp new file mode 100644 index 00000000..ea556dba --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/thread.hpp @@ -0,0 +1,60 @@ +// +// detail/thread.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_THREAD_HPP +#define ASIO_DETAIL_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_THREADS) +# include "asio/detail/null_thread.hpp" +#elif defined(ASIO_WINDOWS) +# if defined(UNDER_CE) +# include "asio/detail/wince_thread.hpp" +# elif defined(ASIO_WINDOWS_APP) +# include "asio/detail/winapp_thread.hpp" +# else +# include "asio/detail/win_thread.hpp" +# endif +#elif defined(ASIO_HAS_PTHREADS) +# include "asio/detail/posix_thread.hpp" +#elif defined(ASIO_HAS_STD_THREAD) +# include "asio/detail/std_thread.hpp" +#else +# error Only Windows, POSIX and std::thread are supported! +#endif + +namespace asio { +namespace detail { + +#if !defined(ASIO_HAS_THREADS) +typedef null_thread thread; +#elif defined(ASIO_WINDOWS) +# if defined(UNDER_CE) +typedef wince_thread thread; +# elif defined(ASIO_WINDOWS_APP) +typedef winapp_thread thread; +# else +typedef win_thread thread; +# endif +#elif defined(ASIO_HAS_PTHREADS) +typedef posix_thread thread; +#elif defined(ASIO_HAS_STD_THREAD) +typedef std_thread thread; +#endif + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_THREAD_HPP diff --git a/tools/sdk/include/asio/asio/detail/thread_context.hpp b/tools/sdk/include/asio/asio/detail/thread_context.hpp new file mode 100644 index 00000000..88b4f311 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/thread_context.hpp @@ -0,0 +1,42 @@ +// +// detail/thread_context.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_THREAD_CONTEXT_HPP +#define ASIO_DETAIL_THREAD_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include "asio/detail/call_stack.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class thread_info_base; + +// Base class for things that manage threads (scheduler, win_iocp_io_context). +class thread_context +{ +public: + // Per-thread call stack to track the state of each thread in the context. + typedef call_stack thread_call_stack; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_THREAD_CONTEXT_HPP diff --git a/tools/sdk/include/asio/asio/detail/thread_group.hpp b/tools/sdk/include/asio/asio/detail/thread_group.hpp new file mode 100644 index 00000000..1e400b03 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/thread_group.hpp @@ -0,0 +1,89 @@ +// +// detail/thread_group.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_THREAD_GROUP_HPP +#define ASIO_DETAIL_THREAD_GROUP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/scoped_ptr.hpp" +#include "asio/detail/thread.hpp" + +namespace asio { +namespace detail { + +class thread_group +{ +public: + // Constructor initialises an empty thread group. + thread_group() + : first_(0) + { + } + + // Destructor joins any remaining threads in the group. + ~thread_group() + { + join(); + } + + // Create a new thread in the group. + template + void create_thread(Function f) + { + first_ = new item(f, first_); + } + + // Create new threads in the group. + template + void create_threads(Function f, std::size_t num_threads) + { + for (std::size_t i = 0; i < num_threads; ++i) + create_thread(f); + } + + // Wait for all threads in the group to exit. + void join() + { + while (first_) + { + first_->thread_.join(); + item* tmp = first_; + first_ = first_->next_; + delete tmp; + } + } + +private: + // Structure used to track a single thread in the group. + struct item + { + template + explicit item(Function f, item* next) + : thread_(f), + next_(next) + { + } + + asio::detail::thread thread_; + item* next_; + }; + + // The first thread in the group. + item* first_; +}; + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_THREAD_GROUP_HPP diff --git a/tools/sdk/include/asio/asio/detail/thread_info_base.hpp b/tools/sdk/include/asio/asio/detail/thread_info_base.hpp new file mode 100644 index 00000000..1b222074 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/thread_info_base.hpp @@ -0,0 +1,121 @@ +// +// detail/thread_info_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_THREAD_INFO_BASE_HPP +#define ASIO_DETAIL_THREAD_INFO_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class thread_info_base + : private noncopyable +{ +public: + struct default_tag + { + enum { mem_index = 0 }; + }; + + struct awaitee_tag + { + enum { mem_index = 1 }; + }; + + thread_info_base() + { + for (int i = 0; i < max_mem_index; ++i) + reusable_memory_[i] = 0; + } + + ~thread_info_base() + { + for (int i = 0; i < max_mem_index; ++i) + if (reusable_memory_[i]) + ::operator delete(reusable_memory_[i]); + } + + static void* allocate(thread_info_base* this_thread, std::size_t size) + { + return allocate(default_tag(), this_thread, size); + } + + static void deallocate(thread_info_base* this_thread, + void* pointer, std::size_t size) + { + deallocate(default_tag(), this_thread, pointer, size); + } + + template + static void* allocate(Purpose, thread_info_base* this_thread, + std::size_t size) + { + std::size_t chunks = (size + chunk_size - 1) / chunk_size; + + if (this_thread && this_thread->reusable_memory_[Purpose::mem_index]) + { + void* const pointer = this_thread->reusable_memory_[Purpose::mem_index]; + this_thread->reusable_memory_[Purpose::mem_index] = 0; + + unsigned char* const mem = static_cast(pointer); + if (static_cast(mem[0]) >= chunks) + { + mem[size] = mem[0]; + return pointer; + } + + ::operator delete(pointer); + } + + void* const pointer = ::operator new(chunks * chunk_size + 1); + unsigned char* const mem = static_cast(pointer); + mem[size] = (chunks <= UCHAR_MAX) ? static_cast(chunks) : 0; + return pointer; + } + + template + static void deallocate(Purpose, thread_info_base* this_thread, + void* pointer, std::size_t size) + { + if (size <= chunk_size * UCHAR_MAX) + { + if (this_thread && this_thread->reusable_memory_[Purpose::mem_index] == 0) + { + unsigned char* const mem = static_cast(pointer); + mem[0] = mem[size]; + this_thread->reusable_memory_[Purpose::mem_index] = pointer; + return; + } + } + + ::operator delete(pointer); + } + +private: + enum { chunk_size = 4 }; + enum { max_mem_index = 2 }; + void* reusable_memory_[max_mem_index]; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_THREAD_INFO_BASE_HPP diff --git a/tools/sdk/include/asio/asio/detail/throw_error.hpp b/tools/sdk/include/asio/asio/detail/throw_error.hpp new file mode 100644 index 00000000..5dd87855 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/throw_error.hpp @@ -0,0 +1,53 @@ +// +// detail/throw_error.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_THROW_ERROR_HPP +#define ASIO_DETAIL_THROW_ERROR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/error_code.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +ASIO_DECL void do_throw_error(const asio::error_code& err); + +ASIO_DECL void do_throw_error(const asio::error_code& err, + const char* location); + +inline void throw_error(const asio::error_code& err) +{ + if (err) + do_throw_error(err); +} + +inline void throw_error(const asio::error_code& err, + const char* location) +{ + if (err) + do_throw_error(err, location); +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/throw_error.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_DETAIL_THROW_ERROR_HPP diff --git a/tools/sdk/include/asio/asio/detail/throw_exception.hpp b/tools/sdk/include/asio/asio/detail/throw_exception.hpp new file mode 100644 index 00000000..f9f7bfb9 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/throw_exception.hpp @@ -0,0 +1,51 @@ +// +// detail/throw_exception.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_THROW_EXCEPTION_HPP +#define ASIO_DETAIL_THROW_EXCEPTION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_BOOST_THROW_EXCEPTION) +# include +#endif // defined(ASIO_BOOST_THROW_EXCEPTION) + +namespace asio { +namespace detail { + +#if defined(ASIO_HAS_BOOST_THROW_EXCEPTION) +using boost::throw_exception; +#else // defined(ASIO_HAS_BOOST_THROW_EXCEPTION) + +// Declare the throw_exception function for all targets. +template +void throw_exception(const Exception& e); + +// Only define the throw_exception function when exceptions are enabled. +// Otherwise, it is up to the application to provide a definition of this +// function. +# if !defined(ASIO_NO_EXCEPTIONS) +template +void throw_exception(const Exception& e) +{ + throw e; +} +# endif // !defined(ASIO_NO_EXCEPTIONS) + +#endif // defined(ASIO_HAS_BOOST_THROW_EXCEPTION) + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_THROW_EXCEPTION_HPP diff --git a/tools/sdk/include/asio/asio/detail/timer_queue.hpp b/tools/sdk/include/asio/asio/detail/timer_queue.hpp new file mode 100644 index 00000000..380e7791 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/timer_queue.hpp @@ -0,0 +1,358 @@ +// +// detail/timer_queue.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_TIMER_QUEUE_HPP +#define ASIO_DETAIL_TIMER_QUEUE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include +#include "asio/detail/cstdint.hpp" +#include "asio/detail/date_time_fwd.hpp" +#include "asio/detail/limits.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/timer_queue_base.hpp" +#include "asio/detail/wait_op.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class timer_queue + : public timer_queue_base +{ +public: + // The time type. + typedef typename Time_Traits::time_type time_type; + + // The duration type. + typedef typename Time_Traits::duration_type duration_type; + + // Per-timer data. + class per_timer_data + { + public: + per_timer_data() : + heap_index_((std::numeric_limits::max)()), + next_(0), prev_(0) + { + } + + private: + friend class timer_queue; + + // The operations waiting on the timer. + op_queue op_queue_; + + // The index of the timer in the heap. + std::size_t heap_index_; + + // Pointers to adjacent timers in a linked list. + per_timer_data* next_; + per_timer_data* prev_; + }; + + // Constructor. + timer_queue() + : timers_(), + heap_() + { + } + + // Add a new timer to the queue. Returns true if this is the timer that is + // earliest in the queue, in which case the reactor's event demultiplexing + // function call may need to be interrupted and restarted. + bool enqueue_timer(const time_type& time, per_timer_data& timer, wait_op* op) + { + // Enqueue the timer object. + if (timer.prev_ == 0 && &timer != timers_) + { + if (this->is_positive_infinity(time)) + { + // No heap entry is required for timers that never expire. + timer.heap_index_ = (std::numeric_limits::max)(); + } + else + { + // Put the new timer at the correct position in the heap. This is done + // first since push_back() can throw due to allocation failure. + timer.heap_index_ = heap_.size(); + heap_entry entry = { time, &timer }; + heap_.push_back(entry); + up_heap(heap_.size() - 1); + } + + // Insert the new timer into the linked list of active timers. + timer.next_ = timers_; + timer.prev_ = 0; + if (timers_) + timers_->prev_ = &timer; + timers_ = &timer; + } + + // Enqueue the individual timer operation. + timer.op_queue_.push(op); + + // Interrupt reactor only if newly added timer is first to expire. + return timer.heap_index_ == 0 && timer.op_queue_.front() == op; + } + + // Whether there are no timers in the queue. + virtual bool empty() const + { + return timers_ == 0; + } + + // Get the time for the timer that is earliest in the queue. + virtual long wait_duration_msec(long max_duration) const + { + if (heap_.empty()) + return max_duration; + + return this->to_msec( + Time_Traits::to_posix_duration( + Time_Traits::subtract(heap_[0].time_, Time_Traits::now())), + max_duration); + } + + // Get the time for the timer that is earliest in the queue. + virtual long wait_duration_usec(long max_duration) const + { + if (heap_.empty()) + return max_duration; + + return this->to_usec( + Time_Traits::to_posix_duration( + Time_Traits::subtract(heap_[0].time_, Time_Traits::now())), + max_duration); + } + + // Dequeue all timers not later than the current time. + virtual void get_ready_timers(op_queue& ops) + { + if (!heap_.empty()) + { + const time_type now = Time_Traits::now(); + while (!heap_.empty() && !Time_Traits::less_than(now, heap_[0].time_)) + { + per_timer_data* timer = heap_[0].timer_; + ops.push(timer->op_queue_); + remove_timer(*timer); + } + } + } + + // Dequeue all timers. + virtual void get_all_timers(op_queue& ops) + { + while (timers_) + { + per_timer_data* timer = timers_; + timers_ = timers_->next_; + ops.push(timer->op_queue_); + timer->next_ = 0; + timer->prev_ = 0; + } + + heap_.clear(); + } + + // Cancel and dequeue operations for the given timer. + std::size_t cancel_timer(per_timer_data& timer, op_queue& ops, + std::size_t max_cancelled = (std::numeric_limits::max)()) + { + std::size_t num_cancelled = 0; + if (timer.prev_ != 0 || &timer == timers_) + { + while (wait_op* op = (num_cancelled != max_cancelled) + ? timer.op_queue_.front() : 0) + { + op->ec_ = asio::error::operation_aborted; + timer.op_queue_.pop(); + ops.push(op); + ++num_cancelled; + } + if (timer.op_queue_.empty()) + remove_timer(timer); + } + return num_cancelled; + } + + // Move operations from one timer to another, empty timer. + void move_timer(per_timer_data& target, per_timer_data& source) + { + target.op_queue_.push(source.op_queue_); + + target.heap_index_ = source.heap_index_; + source.heap_index_ = (std::numeric_limits::max)(); + + if (target.heap_index_ < heap_.size()) + heap_[target.heap_index_].timer_ = ⌖ + + if (timers_ == &source) + timers_ = ⌖ + if (source.prev_) + source.prev_->next_ = ⌖ + if (source.next_) + source.next_->prev_= ⌖ + target.next_ = source.next_; + target.prev_ = source.prev_; + source.next_ = 0; + source.prev_ = 0; + } + +private: + // Move the item at the given index up the heap to its correct position. + void up_heap(std::size_t index) + { + while (index > 0) + { + std::size_t parent = (index - 1) / 2; + if (!Time_Traits::less_than(heap_[index].time_, heap_[parent].time_)) + break; + swap_heap(index, parent); + index = parent; + } + } + + // Move the item at the given index down the heap to its correct position. + void down_heap(std::size_t index) + { + std::size_t child = index * 2 + 1; + while (child < heap_.size()) + { + std::size_t min_child = (child + 1 == heap_.size() + || Time_Traits::less_than( + heap_[child].time_, heap_[child + 1].time_)) + ? child : child + 1; + if (Time_Traits::less_than(heap_[index].time_, heap_[min_child].time_)) + break; + swap_heap(index, min_child); + index = min_child; + child = index * 2 + 1; + } + } + + // Swap two entries in the heap. + void swap_heap(std::size_t index1, std::size_t index2) + { + heap_entry tmp = heap_[index1]; + heap_[index1] = heap_[index2]; + heap_[index2] = tmp; + heap_[index1].timer_->heap_index_ = index1; + heap_[index2].timer_->heap_index_ = index2; + } + + // Remove a timer from the heap and list of timers. + void remove_timer(per_timer_data& timer) + { + // Remove the timer from the heap. + std::size_t index = timer.heap_index_; + if (!heap_.empty() && index < heap_.size()) + { + if (index == heap_.size() - 1) + { + heap_.pop_back(); + } + else + { + swap_heap(index, heap_.size() - 1); + heap_.pop_back(); + if (index > 0 && Time_Traits::less_than( + heap_[index].time_, heap_[(index - 1) / 2].time_)) + up_heap(index); + else + down_heap(index); + } + } + + // Remove the timer from the linked list of active timers. + if (timers_ == &timer) + timers_ = timer.next_; + if (timer.prev_) + timer.prev_->next_ = timer.next_; + if (timer.next_) + timer.next_->prev_= timer.prev_; + timer.next_ = 0; + timer.prev_ = 0; + } + + // Determine if the specified absolute time is positive infinity. + template + static bool is_positive_infinity(const Time_Type&) + { + return false; + } + + // Determine if the specified absolute time is positive infinity. + template + static bool is_positive_infinity( + const boost::date_time::base_time& time) + { + return time.is_pos_infinity(); + } + + // Helper function to convert a duration into milliseconds. + template + long to_msec(const Duration& d, long max_duration) const + { + if (d.ticks() <= 0) + return 0; + int64_t msec = d.total_milliseconds(); + if (msec == 0) + return 1; + if (msec > max_duration) + return max_duration; + return static_cast(msec); + } + + // Helper function to convert a duration into microseconds. + template + long to_usec(const Duration& d, long max_duration) const + { + if (d.ticks() <= 0) + return 0; + int64_t usec = d.total_microseconds(); + if (usec == 0) + return 1; + if (usec > max_duration) + return max_duration; + return static_cast(usec); + } + + // The head of a linked list of all active timers. + per_timer_data* timers_; + + struct heap_entry + { + // The time when the timer should fire. + time_type time_; + + // The associated timer with enqueued operations. + per_timer_data* timer_; + }; + + // The heap of timers, with the earliest timer at the front. + std::vector heap_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TIMER_QUEUE_HPP diff --git a/tools/sdk/include/asio/asio/detail/timer_queue_base.hpp b/tools/sdk/include/asio/asio/detail/timer_queue_base.hpp new file mode 100644 index 00000000..4af995f2 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/timer_queue_base.hpp @@ -0,0 +1,68 @@ +// +// detail/timer_queue_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_TIMER_QUEUE_BASE_HPP +#define ASIO_DETAIL_TIMER_QUEUE_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/operation.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class timer_queue_base + : private noncopyable +{ +public: + // Constructor. + timer_queue_base() : next_(0) {} + + // Destructor. + virtual ~timer_queue_base() {} + + // Whether there are no timers in the queue. + virtual bool empty() const = 0; + + // Get the time to wait until the next timer. + virtual long wait_duration_msec(long max_duration) const = 0; + + // Get the time to wait until the next timer. + virtual long wait_duration_usec(long max_duration) const = 0; + + // Dequeue all ready timers. + virtual void get_ready_timers(op_queue& ops) = 0; + + // Dequeue all timers. + virtual void get_all_timers(op_queue& ops) = 0; + +private: + friend class timer_queue_set; + + // Next timer queue in the set. + timer_queue_base* next_; +}; + +template +class timer_queue; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TIMER_QUEUE_BASE_HPP diff --git a/tools/sdk/include/asio/asio/detail/timer_queue_ptime.hpp b/tools/sdk/include/asio/asio/detail/timer_queue_ptime.hpp new file mode 100644 index 00000000..84e83385 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/timer_queue_ptime.hpp @@ -0,0 +1,99 @@ +// +// detail/timer_queue_ptime.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_TIMER_QUEUE_PTIME_HPP +#define ASIO_DETAIL_TIMER_QUEUE_PTIME_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_BOOST_DATE_TIME) + +#include "asio/time_traits.hpp" +#include "asio/detail/timer_queue.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +struct forwarding_posix_time_traits : time_traits {}; + +// Template specialisation for the commonly used instantation. +template <> +class timer_queue > + : public timer_queue_base +{ +public: + // The time type. + typedef boost::posix_time::ptime time_type; + + // The duration type. + typedef boost::posix_time::time_duration duration_type; + + // Per-timer data. + typedef timer_queue::per_timer_data + per_timer_data; + + // Constructor. + ASIO_DECL timer_queue(); + + // Destructor. + ASIO_DECL virtual ~timer_queue(); + + // Add a new timer to the queue. Returns true if this is the timer that is + // earliest in the queue, in which case the reactor's event demultiplexing + // function call may need to be interrupted and restarted. + ASIO_DECL bool enqueue_timer(const time_type& time, + per_timer_data& timer, wait_op* op); + + // Whether there are no timers in the queue. + ASIO_DECL virtual bool empty() const; + + // Get the time for the timer that is earliest in the queue. + ASIO_DECL virtual long wait_duration_msec(long max_duration) const; + + // Get the time for the timer that is earliest in the queue. + ASIO_DECL virtual long wait_duration_usec(long max_duration) const; + + // Dequeue all timers not later than the current time. + ASIO_DECL virtual void get_ready_timers(op_queue& ops); + + // Dequeue all timers. + ASIO_DECL virtual void get_all_timers(op_queue& ops); + + // Cancel and dequeue operations for the given timer. + ASIO_DECL std::size_t cancel_timer( + per_timer_data& timer, op_queue& ops, + std::size_t max_cancelled = (std::numeric_limits::max)()); + + // Move operations from one timer to another, empty timer. + ASIO_DECL void move_timer(per_timer_data& target, + per_timer_data& source); + +private: + timer_queue impl_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/timer_queue_ptime.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + +#endif // ASIO_DETAIL_TIMER_QUEUE_PTIME_HPP diff --git a/tools/sdk/include/asio/asio/detail/timer_queue_set.hpp b/tools/sdk/include/asio/asio/detail/timer_queue_set.hpp new file mode 100644 index 00000000..0ea372ae --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/timer_queue_set.hpp @@ -0,0 +1,66 @@ +// +// detail/timer_queue_set.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_TIMER_QUEUE_SET_HPP +#define ASIO_DETAIL_TIMER_QUEUE_SET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/timer_queue_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class timer_queue_set +{ +public: + // Constructor. + ASIO_DECL timer_queue_set(); + + // Add a timer queue to the set. + ASIO_DECL void insert(timer_queue_base* q); + + // Remove a timer queue from the set. + ASIO_DECL void erase(timer_queue_base* q); + + // Determine whether all queues are empty. + ASIO_DECL bool all_empty() const; + + // Get the wait duration in milliseconds. + ASIO_DECL long wait_duration_msec(long max_duration) const; + + // Get the wait duration in microseconds. + ASIO_DECL long wait_duration_usec(long max_duration) const; + + // Dequeue all ready timers. + ASIO_DECL void get_ready_timers(op_queue& ops); + + // Dequeue all timers. + ASIO_DECL void get_all_timers(op_queue& ops); + +private: + timer_queue_base* first_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/timer_queue_set.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_DETAIL_TIMER_QUEUE_SET_HPP diff --git a/tools/sdk/include/asio/asio/detail/timer_scheduler.hpp b/tools/sdk/include/asio/asio/detail/timer_scheduler.hpp new file mode 100644 index 00000000..b1f8df45 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/timer_scheduler.hpp @@ -0,0 +1,35 @@ +// +// detail/timer_scheduler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_TIMER_SCHEDULER_HPP +#define ASIO_DETAIL_TIMER_SCHEDULER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/timer_scheduler_fwd.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/winrt_timer_scheduler.hpp" +#elif defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_io_context.hpp" +#elif defined(ASIO_HAS_EPOLL) +# include "asio/detail/epoll_reactor.hpp" +#elif defined(ASIO_HAS_KQUEUE) +# include "asio/detail/kqueue_reactor.hpp" +#elif defined(ASIO_HAS_DEV_POLL) +# include "asio/detail/dev_poll_reactor.hpp" +#else +# include "asio/detail/select_reactor.hpp" +#endif + +#endif // ASIO_DETAIL_TIMER_SCHEDULER_HPP diff --git a/tools/sdk/include/asio/asio/detail/timer_scheduler_fwd.hpp b/tools/sdk/include/asio/asio/detail/timer_scheduler_fwd.hpp new file mode 100644 index 00000000..80bae503 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/timer_scheduler_fwd.hpp @@ -0,0 +1,40 @@ +// +// detail/timer_scheduler_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_TIMER_SCHEDULER_FWD_HPP +#define ASIO_DETAIL_TIMER_SCHEDULER_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +namespace asio { +namespace detail { + +#if defined(ASIO_WINDOWS_RUNTIME) +typedef class winrt_timer_scheduler timer_scheduler; +#elif defined(ASIO_HAS_IOCP) +typedef class win_iocp_io_context timer_scheduler; +#elif defined(ASIO_HAS_EPOLL) +typedef class epoll_reactor timer_scheduler; +#elif defined(ASIO_HAS_KQUEUE) +typedef class kqueue_reactor timer_scheduler; +#elif defined(ASIO_HAS_DEV_POLL) +typedef class dev_poll_reactor timer_scheduler; +#else +typedef class select_reactor timer_scheduler; +#endif + +} // namespace detail +} // namespace asio + +#endif // ASIO_DETAIL_TIMER_SCHEDULER_FWD_HPP diff --git a/tools/sdk/include/asio/asio/detail/tss_ptr.hpp b/tools/sdk/include/asio/asio/detail/tss_ptr.hpp new file mode 100644 index 00000000..e628abe9 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/tss_ptr.hpp @@ -0,0 +1,69 @@ +// +// detail/tss_ptr.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_TSS_PTR_HPP +#define ASIO_DETAIL_TSS_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_THREADS) +# include "asio/detail/null_tss_ptr.hpp" +#elif defined(ASIO_HAS_THREAD_KEYWORD_EXTENSION) +# include "asio/detail/keyword_tss_ptr.hpp" +#elif defined(ASIO_WINDOWS) +# include "asio/detail/win_tss_ptr.hpp" +#elif defined(ASIO_HAS_PTHREADS) +# include "asio/detail/posix_tss_ptr.hpp" +#else +# error Only Windows and POSIX are supported! +#endif + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class tss_ptr +#if !defined(ASIO_HAS_THREADS) + : public null_tss_ptr +#elif defined(ASIO_HAS_THREAD_KEYWORD_EXTENSION) + : public keyword_tss_ptr +#elif defined(ASIO_WINDOWS) + : public win_tss_ptr +#elif defined(ASIO_HAS_PTHREADS) + : public posix_tss_ptr +#endif +{ +public: + void operator=(T* value) + { +#if !defined(ASIO_HAS_THREADS) + null_tss_ptr::operator=(value); +#elif defined(ASIO_HAS_THREAD_KEYWORD_EXTENSION) + keyword_tss_ptr::operator=(value); +#elif defined(ASIO_WINDOWS) + win_tss_ptr::operator=(value); +#elif defined(ASIO_HAS_PTHREADS) + posix_tss_ptr::operator=(value); +#endif + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TSS_PTR_HPP diff --git a/tools/sdk/include/asio/asio/detail/type_traits.hpp b/tools/sdk/include/asio/asio/detail/type_traits.hpp new file mode 100644 index 00000000..edf09281 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/type_traits.hpp @@ -0,0 +1,86 @@ +// +// detail/type_traits.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_TYPE_TRAITS_HPP +#define ASIO_DETAIL_TYPE_TRAITS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_STD_TYPE_TRAITS) +# include +#else // defined(ASIO_HAS_TYPE_TRAITS) +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif // defined(ASIO_HAS_TYPE_TRAITS) + +namespace asio { + +#if defined(ASIO_HAS_STD_TYPE_TRAITS) +using std::add_const; +using std::conditional; +using std::decay; +using std::enable_if; +using std::false_type; +using std::integral_constant; +using std::is_base_of; +using std::is_class; +using std::is_const; +using std::is_convertible; +using std::is_function; +using std::is_same; +using std::remove_pointer; +using std::remove_reference; +#if defined(ASIO_HAS_STD_INVOKE_RESULT) +template struct result_of; +template +struct result_of : std::invoke_result {}; +#else // defined(ASIO_HAS_STD_INVOKE_RESULT) +using std::result_of; +#endif // defined(ASIO_HAS_STD_INVOKE_RESULT) +using std::true_type; +#else // defined(ASIO_HAS_STD_TYPE_TRAITS) +using boost::add_const; +template +struct enable_if : boost::enable_if_c {}; +using boost::conditional; +using boost::decay; +using boost::false_type; +using boost::integral_constant; +using boost::is_base_of; +using boost::is_class; +using boost::is_const; +using boost::is_convertible; +using boost::is_function; +using boost::is_same; +using boost::remove_pointer; +using boost::remove_reference; +using boost::result_of; +using boost::true_type; +#endif // defined(ASIO_HAS_STD_TYPE_TRAITS) + +} // namespace asio + +#endif // ASIO_DETAIL_TYPE_TRAITS_HPP diff --git a/tools/sdk/include/asio/asio/detail/variadic_templates.hpp b/tools/sdk/include/asio/asio/detail/variadic_templates.hpp new file mode 100644 index 00000000..d54eb4e4 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/variadic_templates.hpp @@ -0,0 +1,119 @@ +// +// detail/variadic_templates.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_VARIADIC_TEMPLATES_HPP +#define ASIO_DETAIL_VARIADIC_TEMPLATES_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_HAS_VARIADIC_TEMPLATES) + +# define ASIO_VARIADIC_TPARAMS(n) ASIO_VARIADIC_TPARAMS_##n + +# define ASIO_VARIADIC_TPARAMS_1 \ + typename T1 +# define ASIO_VARIADIC_TPARAMS_2 \ + typename T1, typename T2 +# define ASIO_VARIADIC_TPARAMS_3 \ + typename T1, typename T2, typename T3 +# define ASIO_VARIADIC_TPARAMS_4 \ + typename T1, typename T2, typename T3, typename T4 +# define ASIO_VARIADIC_TPARAMS_5 \ + typename T1, typename T2, typename T3, typename T4, typename T5 + +# define ASIO_VARIADIC_TARGS(n) ASIO_VARIADIC_TARGS_##n + +# define ASIO_VARIADIC_TARGS_1 T1 +# define ASIO_VARIADIC_TARGS_2 T1, T2 +# define ASIO_VARIADIC_TARGS_3 T1, T2, T3 +# define ASIO_VARIADIC_TARGS_4 T1, T2, T3, T4 +# define ASIO_VARIADIC_TARGS_5 T1, T2, T3, T4, T5 + +# define ASIO_VARIADIC_BYVAL_PARAMS(n) \ + ASIO_VARIADIC_BYVAL_PARAMS_##n + +# define ASIO_VARIADIC_BYVAL_PARAMS_1 T1 x1 +# define ASIO_VARIADIC_BYVAL_PARAMS_2 T1 x1, T2 x2 +# define ASIO_VARIADIC_BYVAL_PARAMS_3 T1 x1, T2 x2, T3 x3 +# define ASIO_VARIADIC_BYVAL_PARAMS_4 T1 x1, T2 x2, T3 x3, T4 x4 +# define ASIO_VARIADIC_BYVAL_PARAMS_5 T1 x1, T2 x2, T3 x3, T4 x4, T5 x5 + +# define ASIO_VARIADIC_BYVAL_ARGS(n) \ + ASIO_VARIADIC_BYVAL_ARGS_##n + +# define ASIO_VARIADIC_BYVAL_ARGS_1 x1 +# define ASIO_VARIADIC_BYVAL_ARGS_2 x1, x2 +# define ASIO_VARIADIC_BYVAL_ARGS_3 x1, x2, x3 +# define ASIO_VARIADIC_BYVAL_ARGS_4 x1, x2, x3, x4 +# define ASIO_VARIADIC_BYVAL_ARGS_5 x1, x2, x3, x4, x5 + +# define ASIO_VARIADIC_MOVE_PARAMS(n) \ + ASIO_VARIADIC_MOVE_PARAMS_##n + +# define ASIO_VARIADIC_MOVE_PARAMS_1 \ + ASIO_MOVE_ARG(T1) x1 +# define ASIO_VARIADIC_MOVE_PARAMS_2 \ + ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2 +# define ASIO_VARIADIC_MOVE_PARAMS_3 \ + ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \ + ASIO_MOVE_ARG(T3) x3 +# define ASIO_VARIADIC_MOVE_PARAMS_4 \ + ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \ + ASIO_MOVE_ARG(T3) x3, ASIO_MOVE_ARG(T4) x4 +# define ASIO_VARIADIC_MOVE_PARAMS_5 \ + ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \ + ASIO_MOVE_ARG(T3) x3, ASIO_MOVE_ARG(T4) x4, \ + ASIO_MOVE_ARG(T5) x5 + +# define ASIO_VARIADIC_MOVE_ARGS(n) \ + ASIO_VARIADIC_MOVE_ARGS_##n + +# define ASIO_VARIADIC_MOVE_ARGS_1 \ + ASIO_MOVE_CAST(T1)(x1) +# define ASIO_VARIADIC_MOVE_ARGS_2 \ + ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2) +# define ASIO_VARIADIC_MOVE_ARGS_3 \ + ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \ + ASIO_MOVE_CAST(T3)(x3) +# define ASIO_VARIADIC_MOVE_ARGS_4 \ + ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \ + ASIO_MOVE_CAST(T3)(x3), ASIO_MOVE_CAST(T4)(x4) +# define ASIO_VARIADIC_MOVE_ARGS_5 \ + ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \ + ASIO_MOVE_CAST(T3)(x3), ASIO_MOVE_CAST(T4)(x4), \ + ASIO_MOVE_CAST(T5)(x5) + +# define ASIO_VARIADIC_DECAY(n) \ + ASIO_VARIADIC_DECAY_##n + +# define ASIO_VARIADIC_DECAY_1 \ + typename decay::type +# define ASIO_VARIADIC_DECAY_2 \ + typename decay::type, typename decay::type +# define ASIO_VARIADIC_DECAY_3 \ + typename decay::type, typename decay::type, \ + typename decay::type +# define ASIO_VARIADIC_DECAY_4 \ + typename decay::type, typename decay::type, \ + typename decay::type, typename decay::type +# define ASIO_VARIADIC_DECAY_5 \ + typename decay::type, typename decay::type, \ + typename decay::type, typename decay::type, \ + typename decay::type + +# define ASIO_VARIADIC_GENERATE(m) m(1) m(2) m(3) m(4) m(5) + +#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) + +#endif // ASIO_DETAIL_VARIADIC_TEMPLATES_HPP diff --git a/tools/sdk/include/asio/asio/detail/wait_handler.hpp b/tools/sdk/include/asio/asio/detail/wait_handler.hpp new file mode 100644 index 00000000..bd3dc244 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/wait_handler.hpp @@ -0,0 +1,85 @@ +// +// detail/wait_handler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WAIT_HANDLER_HPP +#define ASIO_DETAIL_WAIT_HANDLER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/wait_op.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class wait_handler : public wait_op +{ +public: + ASIO_DEFINE_HANDLER_PTR(wait_handler); + + wait_handler(Handler& h) + : wait_op(&wait_handler::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(h)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + wait_handler* h(static_cast(base)); + ptr p = { asio::detail::addressof(h->handler_), h, h }; + handler_work w(h->handler_); + + ASIO_HANDLER_COMPLETION((*h)); + + // 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::binder1 + handler(h->handler_, h->ec_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WAIT_HANDLER_HPP diff --git a/tools/sdk/include/asio/asio/detail/wait_op.hpp b/tools/sdk/include/asio/asio/detail/wait_op.hpp new file mode 100644 index 00000000..1a3017ba --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/wait_op.hpp @@ -0,0 +1,45 @@ +// +// detail/wait_op.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WAIT_OP_HPP +#define ASIO_DETAIL_WAIT_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/operation.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class wait_op + : public operation +{ +public: + // The error code to be passed to the completion handler. + asio::error_code ec_; + +protected: + wait_op(func_type func) + : operation(func) + { + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WAIT_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_event.hpp b/tools/sdk/include/asio/asio/detail/win_event.hpp new file mode 100644 index 00000000..859cdee7 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_event.hpp @@ -0,0 +1,151 @@ +// +// detail/win_event.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_EVENT_HPP +#define ASIO_DETAIL_WIN_EVENT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS) + +#include "asio/detail/assert.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class win_event + : private noncopyable +{ +public: + // Constructor. + ASIO_DECL win_event(); + + // Destructor. + ASIO_DECL ~win_event(); + + // Signal the event. (Retained for backward compatibility.) + template + void signal(Lock& lock) + { + this->signal_all(lock); + } + + // Signal all waiters. + template + void signal_all(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + (void)lock; + state_ |= 1; + ::SetEvent(events_[0]); + } + + // Unlock the mutex and signal one waiter. + template + void unlock_and_signal_one(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + state_ |= 1; + bool have_waiters = (state_ > 1); + lock.unlock(); + if (have_waiters) + ::SetEvent(events_[1]); + } + + // If there's a waiter, unlock the mutex and signal it. + template + bool maybe_unlock_and_signal_one(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + state_ |= 1; + if (state_ > 1) + { + lock.unlock(); + ::SetEvent(events_[1]); + return true; + } + return false; + } + + // Reset the event. + template + void clear(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + (void)lock; + ::ResetEvent(events_[0]); + state_ &= ~std::size_t(1); + } + + // Wait for the event to become signalled. + template + void wait(Lock& lock) + { + ASIO_ASSERT(lock.locked()); + while ((state_ & 1) == 0) + { + state_ += 2; + lock.unlock(); +#if defined(ASIO_WINDOWS_APP) + ::WaitForMultipleObjectsEx(2, events_, false, INFINITE, false); +#else // defined(ASIO_WINDOWS_APP) + ::WaitForMultipleObjects(2, events_, false, INFINITE); +#endif // defined(ASIO_WINDOWS_APP) + lock.lock(); + state_ -= 2; + } + } + + // Timed wait for the event to become signalled. + template + bool wait_for_usec(Lock& lock, long usec) + { + ASIO_ASSERT(lock.locked()); + if ((state_ & 1) == 0) + { + state_ += 2; + lock.unlock(); + DWORD msec = usec > 0 ? (usec < 1000 ? 1 : usec / 1000) : 0; +#if defined(ASIO_WINDOWS_APP) + ::WaitForMultipleObjectsEx(2, events_, false, msec, false); +#else // defined(ASIO_WINDOWS_APP) + ::WaitForMultipleObjects(2, events_, false, msec); +#endif // defined(ASIO_WINDOWS_APP) + lock.lock(); + state_ -= 2; + } + return (state_ & 1) != 0; + } + +private: + HANDLE events_[2]; + std::size_t state_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/win_event.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_WINDOWS) + +#endif // ASIO_DETAIL_WIN_EVENT_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_fd_set_adapter.hpp b/tools/sdk/include/asio/asio/detail/win_fd_set_adapter.hpp new file mode 100644 index 00000000..8d5e700e --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_fd_set_adapter.hpp @@ -0,0 +1,149 @@ +// +// detail/win_fd_set_adapter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP +#define ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/reactor_op_queue.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Adapts the FD_SET type to meet the Descriptor_Set concept's requirements. +class win_fd_set_adapter : noncopyable +{ +public: + enum { default_fd_set_size = 1024 }; + + win_fd_set_adapter() + : capacity_(default_fd_set_size), + max_descriptor_(invalid_socket) + { + fd_set_ = static_cast(::operator new( + sizeof(win_fd_set) - sizeof(SOCKET) + + sizeof(SOCKET) * (capacity_))); + fd_set_->fd_count = 0; + } + + ~win_fd_set_adapter() + { + ::operator delete(fd_set_); + } + + void reset() + { + fd_set_->fd_count = 0; + max_descriptor_ = invalid_socket; + } + + bool set(socket_type descriptor) + { + for (u_int i = 0; i < fd_set_->fd_count; ++i) + if (fd_set_->fd_array[i] == descriptor) + return true; + + reserve(fd_set_->fd_count + 1); + fd_set_->fd_array[fd_set_->fd_count++] = descriptor; + return true; + } + + void set(reactor_op_queue& operations, op_queue&) + { + reactor_op_queue::iterator i = operations.begin(); + while (i != operations.end()) + { + reactor_op_queue::iterator op_iter = i++; + reserve(fd_set_->fd_count + 1); + fd_set_->fd_array[fd_set_->fd_count++] = op_iter->first; + } + } + + bool is_set(socket_type descriptor) const + { + return !!__WSAFDIsSet(descriptor, + const_cast(reinterpret_cast(fd_set_))); + } + + operator fd_set*() + { + return reinterpret_cast(fd_set_); + } + + socket_type max_descriptor() const + { + return max_descriptor_; + } + + void perform(reactor_op_queue& operations, + op_queue& ops) const + { + for (u_int i = 0; i < fd_set_->fd_count; ++i) + operations.perform_operations(fd_set_->fd_array[i], ops); + } + +private: + // This structure is defined to be compatible with the Windows API fd_set + // structure, but without being dependent on the value of FD_SETSIZE. We use + // the "struct hack" to allow the number of descriptors to be varied at + // runtime. + struct win_fd_set + { + u_int fd_count; + SOCKET fd_array[1]; + }; + + // Increase the fd_set_ capacity to at least the specified number of elements. + void reserve(u_int n) + { + if (n <= capacity_) + return; + + u_int new_capacity = capacity_ + capacity_ / 2; + if (new_capacity < n) + new_capacity = n; + + win_fd_set* new_fd_set = static_cast(::operator new( + sizeof(win_fd_set) - sizeof(SOCKET) + + sizeof(SOCKET) * (new_capacity))); + + new_fd_set->fd_count = fd_set_->fd_count; + for (u_int i = 0; i < fd_set_->fd_count; ++i) + new_fd_set->fd_array[i] = fd_set_->fd_array[i]; + + ::operator delete(fd_set_); + fd_set_ = new_fd_set; + capacity_ = new_capacity; + } + + win_fd_set* fd_set_; + u_int capacity_; + socket_type max_descriptor_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) + +#endif // ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_fenced_block.hpp b/tools/sdk/include/asio/asio/detail/win_fenced_block.hpp new file mode 100644 index 00000000..1ce6e13b --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_fenced_block.hpp @@ -0,0 +1,90 @@ +// +// detail/win_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_FENCED_BLOCK_HPP +#define ASIO_DETAIL_WIN_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS) && !defined(UNDER_CE) + +#include "asio/detail/socket_types.hpp" +#include "asio/detail/noncopyable.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class win_fenced_block + : private noncopyable +{ +public: + enum half_t { half }; + enum full_t { full }; + + // Constructor for a half fenced block. + explicit win_fenced_block(half_t) + { + } + + // Constructor for a full fenced block. + explicit win_fenced_block(full_t) + { +#if defined(__BORLANDC__) + LONG barrier = 0; + ::InterlockedExchange(&barrier, 1); +#elif defined(ASIO_MSVC) \ + && ((ASIO_MSVC < 1400) || !defined(MemoryBarrier)) +# if defined(_M_IX86) +# pragma warning(push) +# pragma warning(disable:4793) + LONG barrier; + __asm { xchg barrier, eax } +# pragma warning(pop) +# endif // defined(_M_IX86) +#else + MemoryBarrier(); +#endif + } + + // Destructor. + ~win_fenced_block() + { +#if defined(__BORLANDC__) + LONG barrier = 0; + ::InterlockedExchange(&barrier, 1); +#elif defined(ASIO_MSVC) \ + && ((ASIO_MSVC < 1400) || !defined(MemoryBarrier)) +# if defined(_M_IX86) +# pragma warning(push) +# pragma warning(disable:4793) + LONG barrier; + __asm { xchg barrier, eax } +# pragma warning(pop) +# endif // defined(_M_IX86) +#else + MemoryBarrier(); +#endif + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_WINDOWS) && !defined(UNDER_CE) + +#endif // ASIO_DETAIL_WIN_FENCED_BLOCK_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_global.hpp b/tools/sdk/include/asio/asio/detail/win_global.hpp new file mode 100644 index 00000000..3b15a32d --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_global.hpp @@ -0,0 +1,73 @@ +// +// detail/win_global.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_GLOBAL_HPP +#define ASIO_DETAIL_WIN_GLOBAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/static_mutex.hpp" +#include "asio/detail/tss_ptr.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +struct win_global_impl +{ + // Destructor automatically cleans up the global. + ~win_global_impl() + { + delete ptr_; + } + + static win_global_impl instance_; + static static_mutex mutex_; + static T* ptr_; + static tss_ptr tss_ptr_; +}; + +template +win_global_impl win_global_impl::instance_ = { 0 }; + +template +static_mutex win_global_impl::mutex_ = ASIO_STATIC_MUTEX_INIT; + +template +T* win_global_impl::ptr_ = 0; + +template +tss_ptr win_global_impl::tss_ptr_; + +template +T& win_global() +{ + if (static_cast(win_global_impl::tss_ptr_) == 0) + { + win_global_impl::mutex_.init(); + static_mutex::scoped_lock lock(win_global_impl::mutex_); + win_global_impl::ptr_ = new T; + win_global_impl::tss_ptr_ = win_global_impl::ptr_; + } + + return *win_global_impl::tss_ptr_; +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_GLOBAL_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_handle_read_op.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_handle_read_op.hpp new file mode 100644 index 00000000..88e3f6c7 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_handle_read_op.hpp @@ -0,0 +1,111 @@ +// +// detail/win_iocp_handle_read_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// 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 ASIO_DETAIL_WIN_IOCP_HANDLE_READ_OP_HPP +#define ASIO_DETAIL_WIN_IOCP_HANDLE_READ_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/error.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/operation.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class win_iocp_handle_read_op : public operation +{ +public: + ASIO_DEFINE_HANDLER_PTR(win_iocp_handle_read_op); + + win_iocp_handle_read_op( + const MutableBufferSequence& buffers, Handler& handler) + : operation(&win_iocp_handle_read_op::do_complete), + buffers_(buffers), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& result_ec, + std::size_t bytes_transferred) + { + asio::error_code ec(result_ec); + + // Take ownership of the operation object. + win_iocp_handle_read_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + ASIO_HANDLER_COMPLETION((*o)); + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + if (owner) + { + // Check whether buffers are still valid. + buffer_sequence_adapter::validate(o->buffers_); + } +#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) + + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_HANDLE_EOF) + ec = asio::error::eof; + + // 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::binder2 + handler(o->handler_, ec, bytes_transferred); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + MutableBufferSequence buffers_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_HANDLE_READ_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_handle_service.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_handle_service.hpp new file mode 100644 index 00000000..849fe8f1 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_handle_service.hpp @@ -0,0 +1,323 @@ +// +// detail/win_iocp_handle_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// 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 ASIO_DETAIL_WIN_IOCP_HANDLE_SERVICE_HPP +#define ASIO_DETAIL_WIN_IOCP_HANDLE_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/cstdint.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/operation.hpp" +#include "asio/detail/win_iocp_handle_read_op.hpp" +#include "asio/detail/win_iocp_handle_write_op.hpp" +#include "asio/detail/win_iocp_io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class win_iocp_handle_service : + public service_base +{ +public: + // The native type of a stream handle. + typedef HANDLE native_handle_type; + + // The implementation type of the stream handle. + class implementation_type + { + public: + // Default constructor. + implementation_type() + : handle_(INVALID_HANDLE_VALUE), + safe_cancellation_thread_id_(0), + next_(0), + prev_(0) + { + } + + private: + // Only this service will have access to the internal values. + friend class win_iocp_handle_service; + + // The native stream handle representation. + native_handle_type handle_; + + // The ID of the thread from which it is safe to cancel asynchronous + // operations. 0 means no asynchronous operations have been started yet. + // ~0 means asynchronous operations have been started from more than one + // thread, and cancellation is not supported for the handle. + DWORD safe_cancellation_thread_id_; + + // Pointers to adjacent handle implementations in linked list. + implementation_type* next_; + implementation_type* prev_; + }; + + ASIO_DECL win_iocp_handle_service(asio::io_context& io_context); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Construct a new handle implementation. + ASIO_DECL void construct(implementation_type& impl); + + // Move-construct a new handle implementation. + ASIO_DECL void move_construct(implementation_type& impl, + implementation_type& other_impl); + + // Move-assign from another handle implementation. + ASIO_DECL void move_assign(implementation_type& impl, + win_iocp_handle_service& other_service, + implementation_type& other_impl); + + // Destroy a handle implementation. + ASIO_DECL void destroy(implementation_type& impl); + + // Assign a native handle to a handle implementation. + ASIO_DECL asio::error_code assign(implementation_type& impl, + const native_handle_type& handle, asio::error_code& ec); + + // Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return impl.handle_ != INVALID_HANDLE_VALUE; + } + + // Destroy a handle implementation. + ASIO_DECL asio::error_code close(implementation_type& impl, + asio::error_code& ec); + + // Get the native handle representation. + native_handle_type native_handle(const implementation_type& impl) const + { + return impl.handle_; + } + + // Cancel all operations associated with the handle. + ASIO_DECL asio::error_code cancel(implementation_type& impl, + asio::error_code& ec); + + // Write the given data. Returns the number of bytes written. + template + size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return write_some_at(impl, 0, buffers, ec); + } + + // Write the given data at the specified offset. Returns the number of bytes + // written. + template + size_t write_some_at(implementation_type& impl, uint64_t offset, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + asio::const_buffer buffer = + buffer_sequence_adapter::first(buffers); + + return do_write(impl, offset, buffer, ec); + } + + // Start an asynchronous write. The data being written must be valid for the + // lifetime of the asynchronous operation. + template + void async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, Handler& handler) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_handle_write_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(buffers, handler); + + ASIO_HANDLER_CREATION((iocp_service_.context(), *p.p, "handle", &impl, + reinterpret_cast(impl.handle_), "async_write_some")); + + start_write_op(impl, 0, + buffer_sequence_adapter::first(buffers), p.p); + p.v = p.p = 0; + } + + // Start an asynchronous write at a specified offset. The data being written + // must be valid for the lifetime of the asynchronous operation. + template + void async_write_some_at(implementation_type& impl, uint64_t offset, + const ConstBufferSequence& buffers, Handler& handler) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_handle_write_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(buffers, handler); + + ASIO_HANDLER_CREATION((iocp_service_.context(), *p.p, "handle", &impl, + reinterpret_cast(impl.handle_), "async_write_some_at")); + + start_write_op(impl, offset, + buffer_sequence_adapter::first(buffers), p.p); + p.v = p.p = 0; + } + + // Read some data. Returns the number of bytes received. + template + size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return read_some_at(impl, 0, buffers, ec); + } + + // Read some data at a specified offset. Returns the number of bytes received. + template + size_t read_some_at(implementation_type& impl, uint64_t offset, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + asio::mutable_buffer buffer = + buffer_sequence_adapter::first(buffers); + + return do_read(impl, offset, buffer, ec); + } + + // Start an asynchronous read. The buffer for the data being received must be + // valid for the lifetime of the asynchronous operation. + template + void async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, Handler& handler) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_handle_read_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(buffers, handler); + + ASIO_HANDLER_CREATION((iocp_service_.context(), *p.p, "handle", &impl, + reinterpret_cast(impl.handle_), "async_read_some")); + + start_read_op(impl, 0, + buffer_sequence_adapter::first(buffers), p.p); + p.v = p.p = 0; + } + + // Start an asynchronous read at a specified offset. The buffer for the data + // being received must be valid for the lifetime of the asynchronous + // operation. + template + void async_read_some_at(implementation_type& impl, uint64_t offset, + const MutableBufferSequence& buffers, Handler& handler) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_handle_read_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(buffers, handler); + + ASIO_HANDLER_CREATION((iocp_service_.context(), *p.p, "handle", &impl, + reinterpret_cast(impl.handle_), "async_read_some_at")); + + start_read_op(impl, offset, + buffer_sequence_adapter::first(buffers), p.p); + p.v = p.p = 0; + } + +private: + // Prevent the use of the null_buffers type with this service. + size_t write_some(implementation_type& impl, + const null_buffers& buffers, asio::error_code& ec); + size_t write_some_at(implementation_type& impl, uint64_t offset, + const null_buffers& buffers, asio::error_code& ec); + template + void async_write_some(implementation_type& impl, + const null_buffers& buffers, Handler& handler); + template + void async_write_some_at(implementation_type& impl, uint64_t offset, + const null_buffers& buffers, Handler& handler); + size_t read_some(implementation_type& impl, + const null_buffers& buffers, asio::error_code& ec); + size_t read_some_at(implementation_type& impl, uint64_t offset, + const null_buffers& buffers, asio::error_code& ec); + template + void async_read_some(implementation_type& impl, + const null_buffers& buffers, Handler& handler); + template + void async_read_some_at(implementation_type& impl, uint64_t offset, + const null_buffers& buffers, Handler& handler); + + // Helper class for waiting for synchronous operations to complete. + class overlapped_wrapper; + + // Helper function to perform a synchronous write operation. + ASIO_DECL size_t do_write(implementation_type& impl, + uint64_t offset, const asio::const_buffer& buffer, + asio::error_code& ec); + + // Helper function to start a write operation. + ASIO_DECL void start_write_op(implementation_type& impl, + uint64_t offset, const asio::const_buffer& buffer, + operation* op); + + // Helper function to perform a synchronous write operation. + ASIO_DECL size_t do_read(implementation_type& impl, + uint64_t offset, const asio::mutable_buffer& buffer, + asio::error_code& ec); + + // Helper function to start a read operation. + ASIO_DECL void start_read_op(implementation_type& impl, + uint64_t offset, const asio::mutable_buffer& buffer, + operation* op); + + // Update the ID of the thread from which cancellation is safe. + ASIO_DECL void update_cancellation_thread_id(implementation_type& impl); + + // Helper function to close a handle when the associated object is being + // destroyed. + ASIO_DECL void close_for_destruction(implementation_type& impl); + + // The IOCP service used for running asynchronous operations and dispatching + // handlers. + win_iocp_io_context& iocp_service_; + + // Mutex to protect access to the linked list of implementations. + mutex mutex_; + + // The head of a linked list of all implementations. + implementation_type* impl_list_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/win_iocp_handle_service.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_HANDLE_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_handle_write_op.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_handle_write_op.hpp new file mode 100644 index 00000000..d7bb9443 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_handle_write_op.hpp @@ -0,0 +1,103 @@ +// +// detail/win_iocp_handle_write_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// 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 ASIO_DETAIL_WIN_IOCP_HANDLE_WRITE_OP_HPP +#define ASIO_DETAIL_WIN_IOCP_HANDLE_WRITE_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/error.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/operation.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class win_iocp_handle_write_op : public operation +{ +public: + ASIO_DEFINE_HANDLER_PTR(win_iocp_handle_write_op); + + win_iocp_handle_write_op(const ConstBufferSequence& buffers, Handler& handler) + : operation(&win_iocp_handle_write_op::do_complete), + buffers_(buffers), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + win_iocp_handle_write_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + ASIO_HANDLER_COMPLETION((*o)); + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + if (owner) + { + // Check whether buffers are still valid. + buffer_sequence_adapter::validate(o->buffers_); + } +#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) + + // 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::binder2 + handler(o->handler_, ec, bytes_transferred); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + ConstBufferSequence buffers_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_HANDLE_WRITE_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_io_context.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_io_context.hpp new file mode 100644 index 00000000..11bf58b7 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_io_context.hpp @@ -0,0 +1,328 @@ +// +// detail/win_iocp_io_context.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_IO_CONTEXT_HPP +#define ASIO_DETAIL_WIN_IOCP_IO_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/limits.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/scoped_ptr.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/thread.hpp" +#include "asio/detail/thread_context.hpp" +#include "asio/detail/timer_queue_base.hpp" +#include "asio/detail/timer_queue_set.hpp" +#include "asio/detail/wait_op.hpp" +#include "asio/detail/win_iocp_operation.hpp" +#include "asio/detail/win_iocp_thread_info.hpp" +#include "asio/execution_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class wait_op; + +class win_iocp_io_context + : public execution_context_service_base, + public thread_context +{ +public: + // Constructor. Specifies a concurrency hint that is passed through to the + // underlying I/O completion port. + ASIO_DECL win_iocp_io_context(asio::execution_context& ctx, + int concurrency_hint = -1); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Initialise the task. Nothing to do here. + void init_task() + { + } + + // Register a handle with the IO completion port. + ASIO_DECL asio::error_code register_handle( + HANDLE handle, asio::error_code& ec); + + // Run the event loop until stopped or no more work. + ASIO_DECL size_t run(asio::error_code& ec); + + // Run until stopped or one operation is performed. + ASIO_DECL size_t run_one(asio::error_code& ec); + + // Run until timeout, interrupted, or one operation is performed. + ASIO_DECL size_t wait_one(long usec, asio::error_code& ec); + + // Poll for operations without blocking. + ASIO_DECL size_t poll(asio::error_code& ec); + + // Poll for one operation without blocking. + ASIO_DECL size_t poll_one(asio::error_code& ec); + + // Stop the event processing loop. + ASIO_DECL void stop(); + + // Determine whether the io_context is stopped. + bool stopped() const + { + return ::InterlockedExchangeAdd(&stopped_, 0) != 0; + } + + // Restart in preparation for a subsequent run invocation. + void restart() + { + ::InterlockedExchange(&stopped_, 0); + } + + // Notify that some work has started. + void work_started() + { + ::InterlockedIncrement(&outstanding_work_); + } + + // Notify that some work has finished. + void work_finished() + { + if (::InterlockedDecrement(&outstanding_work_) == 0) + stop(); + } + + // Return whether a handler can be dispatched immediately. + bool can_dispatch() + { + return thread_call_stack::contains(this) != 0; + } + + // Request invocation of the given operation and return immediately. Assumes + // that work_started() has not yet been called for the operation. + void post_immediate_completion(win_iocp_operation* op, bool) + { + work_started(); + post_deferred_completion(op); + } + + // Request invocation of the given operation and return immediately. Assumes + // that work_started() was previously called for the operation. + ASIO_DECL void post_deferred_completion(win_iocp_operation* op); + + // Request invocation of the given operation and return immediately. Assumes + // that work_started() was previously called for the operations. + ASIO_DECL void post_deferred_completions( + op_queue& ops); + + // Request invocation of the given operation using the thread-private queue + // and return immediately. Assumes that work_started() has not yet been + // called for the operation. + void post_private_immediate_completion(win_iocp_operation* op) + { + post_immediate_completion(op, false); + } + + // Request invocation of the given operation using the thread-private queue + // and return immediately. Assumes that work_started() was previously called + // for the operation. + void post_private_deferred_completion(win_iocp_operation* op) + { + post_deferred_completion(op); + } + + // Enqueue the given operation following a failed attempt to dispatch the + // operation for immediate invocation. + void do_dispatch(operation* op) + { + post_immediate_completion(op, false); + } + + // Process unfinished operations as part of a shutdown operation. Assumes + // that work_started() was previously called for the operations. + ASIO_DECL void abandon_operations(op_queue& ops); + + // Called after starting an overlapped I/O operation that did not complete + // immediately. The caller must have already called work_started() prior to + // starting the operation. + ASIO_DECL void on_pending(win_iocp_operation* op); + + // Called after starting an overlapped I/O operation that completed + // immediately. The caller must have already called work_started() prior to + // starting the operation. + ASIO_DECL void on_completion(win_iocp_operation* op, + DWORD last_error = 0, DWORD bytes_transferred = 0); + + // Called after starting an overlapped I/O operation that completed + // immediately. The caller must have already called work_started() prior to + // starting the operation. + ASIO_DECL void on_completion(win_iocp_operation* op, + const asio::error_code& ec, DWORD bytes_transferred = 0); + + // Add a new timer queue to the service. + template + void add_timer_queue(timer_queue& timer_queue); + + // Remove a timer queue from the service. + template + void remove_timer_queue(timer_queue& timer_queue); + + // Schedule a new operation in the given timer queue to expire at the + // specified absolute time. + template + void schedule_timer(timer_queue& queue, + const typename Time_Traits::time_type& time, + typename timer_queue::per_timer_data& timer, wait_op* op); + + // Cancel the timer associated with the given token. Returns the number of + // handlers that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& queue, + typename timer_queue::per_timer_data& timer, + std::size_t max_cancelled = (std::numeric_limits::max)()); + + // Move the timer operations associated with the given timer. + template + void move_timer(timer_queue& queue, + typename timer_queue::per_timer_data& to, + typename timer_queue::per_timer_data& from); + + // Get the concurrency hint that was used to initialise the io_context. + int concurrency_hint() const + { + return concurrency_hint_; + } + +private: +#if defined(WINVER) && (WINVER < 0x0500) + typedef DWORD dword_ptr_t; + typedef ULONG ulong_ptr_t; +#else // defined(WINVER) && (WINVER < 0x0500) + typedef DWORD_PTR dword_ptr_t; + typedef ULONG_PTR ulong_ptr_t; +#endif // defined(WINVER) && (WINVER < 0x0500) + + // Dequeues at most one operation from the I/O completion port, and then + // executes it. Returns the number of operations that were dequeued (i.e. + // either 0 or 1). + ASIO_DECL size_t do_one(DWORD msec, asio::error_code& ec); + + // Helper to calculate the GetQueuedCompletionStatus timeout. + ASIO_DECL static DWORD get_gqcs_timeout(); + + // Helper function to add a new timer queue. + ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); + + // Helper function to remove a timer queue. + ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); + + // Called to recalculate and update the timeout. + ASIO_DECL void update_timeout(); + + // Helper class to call work_finished() on block exit. + struct work_finished_on_block_exit; + + // Helper class for managing a HANDLE. + struct auto_handle + { + HANDLE handle; + auto_handle() : handle(0) {} + ~auto_handle() { if (handle) ::CloseHandle(handle); } + }; + + // The IO completion port used for queueing operations. + auto_handle iocp_; + + // The count of unfinished work. + long outstanding_work_; + + // Flag to indicate whether the event loop has been stopped. + mutable long stopped_; + + // Flag to indicate whether there is an in-flight stop event. Every event + // posted using PostQueuedCompletionStatus consumes non-paged pool, so to + // avoid exhausting this resouce we limit the number of outstanding events. + long stop_event_posted_; + + // Flag to indicate whether the service has been shut down. + long shutdown_; + + enum + { + // Timeout to use with GetQueuedCompletionStatus on older versions of + // Windows. Some versions of windows have a "bug" where a call to + // GetQueuedCompletionStatus can appear stuck even though there are events + // waiting on the queue. Using a timeout helps to work around the issue. + default_gqcs_timeout = 500, + + // Maximum waitable timer timeout, in milliseconds. + max_timeout_msec = 5 * 60 * 1000, + + // Maximum waitable timer timeout, in microseconds. + max_timeout_usec = max_timeout_msec * 1000, + + // Completion key value used to wake up a thread to dispatch timers or + // completed operations. + wake_for_dispatch = 1, + + // Completion key value to indicate that an operation has posted with the + // original last_error and bytes_transferred values stored in the fields of + // the OVERLAPPED structure. + overlapped_contains_result = 2 + }; + + // Timeout to use with GetQueuedCompletionStatus. + const DWORD gqcs_timeout_; + + // Function object for processing timeouts in a background thread. + struct timer_thread_function; + friend struct timer_thread_function; + + // Background thread used for processing timeouts. + scoped_ptr timer_thread_; + + // A waitable timer object used for waiting for timeouts. + auto_handle waitable_timer_; + + // Non-zero if timers or completed operations need to be dispatched. + long dispatch_required_; + + // Mutex for protecting access to the timer queues and completed operations. + mutex dispatch_mutex_; + + // The timer queues. + timer_queue_set timer_queues_; + + // The operations that are ready to dispatch. + op_queue completed_ops_; + + // The concurrency hint used to initialise the io_context. + const int concurrency_hint_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/impl/win_iocp_io_context.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/win_iocp_io_context.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_IO_CONTEXT_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_null_buffers_op.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_null_buffers_op.hpp new file mode 100644 index 00000000..db70cb28 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_null_buffers_op.hpp @@ -0,0 +1,121 @@ +// +// detail/win_iocp_null_buffers_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_NULL_BUFFERS_OP_HPP +#define ASIO_DETAIL_WIN_IOCP_NULL_BUFFERS_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class win_iocp_null_buffers_op : public reactor_op +{ +public: + ASIO_DEFINE_HANDLER_PTR(win_iocp_null_buffers_op); + + win_iocp_null_buffers_op(socket_ops::weak_cancel_token_type cancel_token, + Handler& handler) + : reactor_op(&win_iocp_null_buffers_op::do_perform, + &win_iocp_null_buffers_op::do_complete), + cancel_token_(cancel_token), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static status do_perform(reactor_op*) + { + return done; + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& result_ec, + std::size_t bytes_transferred) + { + asio::error_code ec(result_ec); + + // Take ownership of the operation object. + win_iocp_null_buffers_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + ASIO_HANDLER_COMPLETION((*o)); + + // The reactor may have stored a result in the operation object. + if (o->ec_) + ec = o->ec_; + + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_NETNAME_DELETED) + { + if (o->cancel_token_.expired()) + ec = asio::error::operation_aborted; + else + ec = asio::error::connection_reset; + } + else if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = asio::error::connection_refused; + } + + // 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::binder2 + handler(o->handler_, ec, bytes_transferred); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + socket_ops::weak_cancel_token_type cancel_token_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_NULL_BUFFERS_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_operation.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_operation.hpp new file mode 100644 index 00000000..81d43f07 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_operation.hpp @@ -0,0 +1,96 @@ +// +// detail/win_iocp_operation.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_OPERATION_HPP +#define ASIO_DETAIL_WIN_IOCP_OPERATION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/handler_tracking.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/error_code.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class win_iocp_io_context; + +// Base class for all operations. A function pointer is used instead of virtual +// functions to avoid the associated overhead. +class win_iocp_operation + : public OVERLAPPED + ASIO_ALSO_INHERIT_TRACKED_HANDLER +{ +public: + typedef win_iocp_operation operation_type; + + void complete(void* owner, const asio::error_code& ec, + std::size_t bytes_transferred) + { + func_(owner, this, ec, bytes_transferred); + } + + void destroy() + { + func_(0, this, asio::error_code(), 0); + } + +protected: + typedef void (*func_type)( + void*, win_iocp_operation*, + const asio::error_code&, std::size_t); + + win_iocp_operation(func_type func) + : next_(0), + func_(func) + { + reset(); + } + + // Prevents deletion through this type. + ~win_iocp_operation() + { + } + + void reset() + { + Internal = 0; + InternalHigh = 0; + Offset = 0; + OffsetHigh = 0; + hEvent = 0; + ready_ = 0; + } + +private: + friend class op_queue_access; + friend class win_iocp_io_context; + win_iocp_operation* next_; + func_type func_; + long ready_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_OPERATION_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_overlapped_op.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_overlapped_op.hpp new file mode 100644 index 00000000..2b2cc319 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_overlapped_op.hpp @@ -0,0 +1,90 @@ +// +// detail/win_iocp_overlapped_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_OVERLAPPED_OP_HPP +#define ASIO_DETAIL_WIN_IOCP_OVERLAPPED_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/error.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/operation.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class win_iocp_overlapped_op : public operation +{ +public: + ASIO_DEFINE_HANDLER_PTR(win_iocp_overlapped_op); + + win_iocp_overlapped_op(Handler& handler) + : operation(&win_iocp_overlapped_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + win_iocp_overlapped_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + 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::binder2 + handler(o->handler_, ec, bytes_transferred); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_OVERLAPPED_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_overlapped_ptr.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_overlapped_ptr.hpp new file mode 100644 index 00000000..7a191143 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_overlapped_ptr.hpp @@ -0,0 +1,143 @@ +// +// detail/win_iocp_overlapped_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP +#define ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/io_context.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/win_iocp_overlapped_op.hpp" +#include "asio/detail/win_iocp_io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Wraps a handler to create an OVERLAPPED object for use with overlapped I/O. +class win_iocp_overlapped_ptr + : private noncopyable +{ +public: + // Construct an empty win_iocp_overlapped_ptr. + win_iocp_overlapped_ptr() + : ptr_(0), + iocp_service_(0) + { + } + + // Construct an win_iocp_overlapped_ptr to contain the specified handler. + template + explicit win_iocp_overlapped_ptr( + asio::io_context& io_context, ASIO_MOVE_ARG(Handler) handler) + : ptr_(0), + iocp_service_(0) + { + this->reset(io_context, ASIO_MOVE_CAST(Handler)(handler)); + } + + // Destructor automatically frees the OVERLAPPED object unless released. + ~win_iocp_overlapped_ptr() + { + reset(); + } + + // Reset to empty. + void reset() + { + if (ptr_) + { + ptr_->destroy(); + ptr_ = 0; + iocp_service_->work_finished(); + iocp_service_ = 0; + } + } + + // Reset to contain the specified handler, freeing any current OVERLAPPED + // object. + template + void reset(asio::io_context& io_context, Handler handler) + { + typedef win_iocp_overlapped_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + ASIO_HANDLER_CREATION((io_context, *p.p, + "io_context", &io_context.impl_, 0, "overlapped")); + + io_context.impl_.work_started(); + reset(); + ptr_ = p.p; + p.v = p.p = 0; + iocp_service_ = &io_context.impl_; + } + + // Get the contained OVERLAPPED object. + OVERLAPPED* get() + { + return ptr_; + } + + // Get the contained OVERLAPPED object. + const OVERLAPPED* get() const + { + return ptr_; + } + + // Release ownership of the OVERLAPPED object. + OVERLAPPED* release() + { + if (ptr_) + iocp_service_->on_pending(ptr_); + + OVERLAPPED* tmp = ptr_; + ptr_ = 0; + iocp_service_ = 0; + return tmp; + } + + // Post completion notification for overlapped operation. Releases ownership. + void complete(const asio::error_code& ec, + std::size_t bytes_transferred) + { + if (ptr_) + { + iocp_service_->on_completion(ptr_, ec, + static_cast(bytes_transferred)); + ptr_ = 0; + iocp_service_ = 0; + } + } + +private: + win_iocp_operation* ptr_; + win_iocp_io_context* iocp_service_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_serial_port_service.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_serial_port_service.hpp new file mode 100644 index 00000000..ac06348e --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_serial_port_service.hpp @@ -0,0 +1,230 @@ +// +// detail/win_iocp_serial_port_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// 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 ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP +#define ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) && defined(ASIO_HAS_SERIAL_PORT) + +#include +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/detail/win_iocp_handle_service.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Extend win_iocp_handle_service to provide serial port support. +class win_iocp_serial_port_service : + public service_base +{ +public: + // The native type of a serial port. + typedef win_iocp_handle_service::native_handle_type native_handle_type; + + // The implementation type of the serial port. + typedef win_iocp_handle_service::implementation_type implementation_type; + + // Constructor. + ASIO_DECL win_iocp_serial_port_service( + asio::io_context& io_context); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Construct a new serial port implementation. + void construct(implementation_type& impl) + { + handle_service_.construct(impl); + } + + // Move-construct a new serial port implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + handle_service_.move_construct(impl, other_impl); + } + + // Move-assign from another serial port implementation. + void move_assign(implementation_type& impl, + win_iocp_serial_port_service& other_service, + implementation_type& other_impl) + { + handle_service_.move_assign(impl, + other_service.handle_service_, other_impl); + } + + // Destroy a serial port implementation. + void destroy(implementation_type& impl) + { + handle_service_.destroy(impl); + } + + // Open the serial port using the specified device name. + ASIO_DECL asio::error_code open(implementation_type& impl, + const std::string& device, asio::error_code& ec); + + // Assign a native handle to a serial port implementation. + asio::error_code assign(implementation_type& impl, + const native_handle_type& handle, asio::error_code& ec) + { + return handle_service_.assign(impl, handle, ec); + } + + // Determine whether the serial port is open. + bool is_open(const implementation_type& impl) const + { + return handle_service_.is_open(impl); + } + + // Destroy a serial port implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + return handle_service_.close(impl, ec); + } + + // Get the native serial port representation. + native_handle_type native_handle(implementation_type& impl) + { + return handle_service_.native_handle(impl); + } + + // Cancel all operations associated with the handle. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + return handle_service_.cancel(impl, ec); + } + + // Set an option on the serial port. + template + asio::error_code set_option(implementation_type& impl, + const SettableSerialPortOption& option, asio::error_code& ec) + { + return do_set_option(impl, + &win_iocp_serial_port_service::store_option, + &option, ec); + } + + // Get an option from the serial port. + template + asio::error_code get_option(const implementation_type& impl, + GettableSerialPortOption& option, asio::error_code& ec) const + { + return do_get_option(impl, + &win_iocp_serial_port_service::load_option, + &option, ec); + } + + // Send a break sequence to the serial port. + asio::error_code send_break(implementation_type&, + asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Write the given data. Returns the number of bytes sent. + template + size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return handle_service_.write_some(impl, buffers, ec); + } + + // Start an asynchronous write. The data being written must be valid for the + // lifetime of the asynchronous operation. + template + void async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, Handler& handler) + { + handle_service_.async_write_some(impl, buffers, handler); + } + + // Read some data. Returns the number of bytes received. + template + size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return handle_service_.read_some(impl, buffers, ec); + } + + // Start an asynchronous read. The buffer for the data being received must be + // valid for the lifetime of the asynchronous operation. + template + void async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, Handler& handler) + { + handle_service_.async_read_some(impl, buffers, handler); + } + +private: + // Function pointer type for storing a serial port option. + typedef asio::error_code (*store_function_type)( + const void*, ::DCB&, asio::error_code&); + + // Helper function template to store a serial port option. + template + static asio::error_code store_option(const void* option, + ::DCB& storage, asio::error_code& ec) + { + static_cast(option)->store(storage, ec); + return ec; + } + + // Helper function to set a serial port option. + ASIO_DECL asio::error_code do_set_option( + implementation_type& impl, store_function_type store, + const void* option, asio::error_code& ec); + + // Function pointer type for loading a serial port option. + typedef asio::error_code (*load_function_type)( + void*, const ::DCB&, asio::error_code&); + + // Helper function template to load a serial port option. + template + static asio::error_code load_option(void* option, + const ::DCB& storage, asio::error_code& ec) + { + static_cast(option)->load(storage, ec); + return ec; + } + + // Helper function to get a serial port option. + ASIO_DECL asio::error_code do_get_option( + const implementation_type& impl, load_function_type load, + void* option, asio::error_code& ec) const; + + // The implementation used for initiating asynchronous operations. + win_iocp_handle_service handle_service_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/win_iocp_serial_port_service.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_IOCP) && defined(ASIO_HAS_SERIAL_PORT) + +#endif // ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_socket_accept_op.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_socket_accept_op.hpp new file mode 100644 index 00000000..18e73356 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_socket_accept_op.hpp @@ -0,0 +1,297 @@ +// +// detail/win_iocp_socket_accept_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_HPP +#define ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/operation.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/win_iocp_socket_service_base.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class win_iocp_socket_accept_op : public operation +{ +public: + ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_accept_op); + + win_iocp_socket_accept_op(win_iocp_socket_service_base& socket_service, + socket_type socket, Socket& peer, const Protocol& protocol, + typename Protocol::endpoint* peer_endpoint, + bool enable_connection_aborted, Handler& handler) + : operation(&win_iocp_socket_accept_op::do_complete), + socket_service_(socket_service), + socket_(socket), + peer_(peer), + protocol_(protocol), + peer_endpoint_(peer_endpoint), + enable_connection_aborted_(enable_connection_aborted), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + socket_holder& new_socket() + { + return new_socket_; + } + + void* output_buffer() + { + return output_buffer_; + } + + DWORD address_length() + { + return sizeof(sockaddr_storage_type) + 16; + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& result_ec, + std::size_t /*bytes_transferred*/) + { + asio::error_code ec(result_ec); + + // Take ownership of the operation object. + win_iocp_socket_accept_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + if (owner) + { + typename Protocol::endpoint peer_endpoint; + std::size_t addr_len = peer_endpoint.capacity(); + socket_ops::complete_iocp_accept(o->socket_, + o->output_buffer(), o->address_length(), + peer_endpoint.data(), &addr_len, + o->new_socket_.get(), ec); + + // Restart the accept operation if we got the connection_aborted error + // and the enable_connection_aborted socket option is not set. + if (ec == asio::error::connection_aborted + && !o->enable_connection_aborted_) + { + o->reset(); + o->socket_service_.restart_accept_op(o->socket_, + o->new_socket_, o->protocol_.family(), + o->protocol_.type(), o->protocol_.protocol(), + o->output_buffer(), o->address_length(), o); + p.v = p.p = 0; + return; + } + + // If the socket was successfully accepted, transfer ownership of the + // socket to the peer object. + if (!ec) + { + o->peer_.assign(o->protocol_, + typename Socket::native_handle_type( + o->new_socket_.get(), peer_endpoint), ec); + if (!ec) + o->new_socket_.release(); + } + + // Pass endpoint back to caller. + if (o->peer_endpoint_) + *o->peer_endpoint_ = peer_endpoint; + } + + 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::binder1 + handler(o->handler_, ec); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + win_iocp_socket_service_base& socket_service_; + socket_type socket_; + socket_holder new_socket_; + Socket& peer_; + Protocol protocol_; + typename Protocol::endpoint* peer_endpoint_; + unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2]; + bool enable_connection_aborted_; + Handler handler_; +}; + +#if defined(ASIO_HAS_MOVE) + +template +class win_iocp_socket_move_accept_op : public operation +{ +public: + ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_move_accept_op); + + win_iocp_socket_move_accept_op( + win_iocp_socket_service_base& socket_service, socket_type socket, + const Protocol& protocol, asio::io_context& peer_io_context, + typename Protocol::endpoint* peer_endpoint, + bool enable_connection_aborted, Handler& handler) + : operation(&win_iocp_socket_move_accept_op::do_complete), + socket_service_(socket_service), + socket_(socket), + peer_(peer_io_context), + protocol_(protocol), + peer_endpoint_(peer_endpoint), + enable_connection_aborted_(enable_connection_aborted), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + socket_holder& new_socket() + { + return new_socket_; + } + + void* output_buffer() + { + return output_buffer_; + } + + DWORD address_length() + { + return sizeof(sockaddr_storage_type) + 16; + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& result_ec, + std::size_t /*bytes_transferred*/) + { + asio::error_code ec(result_ec); + + // Take ownership of the operation object. + win_iocp_socket_move_accept_op* o( + static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + if (owner) + { + typename Protocol::endpoint peer_endpoint; + std::size_t addr_len = peer_endpoint.capacity(); + socket_ops::complete_iocp_accept(o->socket_, + o->output_buffer(), o->address_length(), + peer_endpoint.data(), &addr_len, + o->new_socket_.get(), ec); + + // Restart the accept operation if we got the connection_aborted error + // and the enable_connection_aborted socket option is not set. + if (ec == asio::error::connection_aborted + && !o->enable_connection_aborted_) + { + o->reset(); + o->socket_service_.restart_accept_op(o->socket_, + o->new_socket_, o->protocol_.family(), + o->protocol_.type(), o->protocol_.protocol(), + o->output_buffer(), o->address_length(), o); + p.v = p.p = 0; + return; + } + + // If the socket was successfully accepted, transfer ownership of the + // socket to the peer object. + if (!ec) + { + o->peer_.assign(o->protocol_, + typename Protocol::socket::native_handle_type( + o->new_socket_.get(), peer_endpoint), ec); + if (!ec) + o->new_socket_.release(); + } + + // Pass endpoint back to caller. + if (o->peer_endpoint_) + *o->peer_endpoint_ = peer_endpoint; + } + + 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::move_binder2 + handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), ec, + ASIO_MOVE_CAST(typename Protocol::socket)(o->peer_)); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "...")); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + win_iocp_socket_service_base& socket_service_; + socket_type socket_; + socket_holder new_socket_; + typename Protocol::socket peer_; + Protocol protocol_; + typename Protocol::endpoint* peer_endpoint_; + unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2]; + bool enable_connection_aborted_; + Handler handler_; +}; + +#endif // defined(ASIO_HAS_MOVE) + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_socket_connect_op.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_socket_connect_op.hpp new file mode 100644 index 00000000..e0c52dc9 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_socket_connect_op.hpp @@ -0,0 +1,127 @@ +// +// detail/win_iocp_socket_connect_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_SOCKET_CONNECT_OP_HPP +#define ASIO_DETAIL_WIN_IOCP_SOCKET_CONNECT_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class win_iocp_socket_connect_op_base : public reactor_op +{ +public: + win_iocp_socket_connect_op_base(socket_type socket, func_type complete_func) + : reactor_op(&win_iocp_socket_connect_op_base::do_perform, complete_func), + socket_(socket), + connect_ex_(false) + { + } + + static status do_perform(reactor_op* base) + { + win_iocp_socket_connect_op_base* o( + static_cast(base)); + + return socket_ops::non_blocking_connect( + o->socket_, o->ec_) ? done : not_done; + } + + socket_type socket_; + bool connect_ex_; +}; + +template +class win_iocp_socket_connect_op : public win_iocp_socket_connect_op_base +{ +public: + ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_connect_op); + + win_iocp_socket_connect_op(socket_type socket, Handler& handler) + : win_iocp_socket_connect_op_base(socket, + &win_iocp_socket_connect_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& result_ec, + std::size_t /*bytes_transferred*/) + { + asio::error_code ec(result_ec); + + // Take ownership of the operation object. + win_iocp_socket_connect_op* o( + static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + if (owner) + { + if (o->connect_ex_) + socket_ops::complete_iocp_connect(o->socket_, ec); + else + ec = o->ec_; + } + + 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::binder1 + handler(o->handler_, ec); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_SOCKET_CONNECT_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_socket_recv_op.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_socket_recv_op.hpp new file mode 100644 index 00000000..41595405 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_socket_recv_op.hpp @@ -0,0 +1,117 @@ +// +// detail/win_iocp_socket_recv_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_SOCKET_RECV_OP_HPP +#define ASIO_DETAIL_WIN_IOCP_SOCKET_RECV_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/operation.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class win_iocp_socket_recv_op : public operation +{ +public: + ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_recv_op); + + win_iocp_socket_recv_op(socket_ops::state_type state, + socket_ops::weak_cancel_token_type cancel_token, + const MutableBufferSequence& buffers, Handler& handler) + : operation(&win_iocp_socket_recv_op::do_complete), + state_(state), + cancel_token_(cancel_token), + buffers_(buffers), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& result_ec, + std::size_t bytes_transferred) + { + asio::error_code ec(result_ec); + + // Take ownership of the operation object. + win_iocp_socket_recv_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + ASIO_HANDLER_COMPLETION((*o)); + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + if (owner) + { + buffer_sequence_adapter::validate(o->buffers_); + } +#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) + + socket_ops::complete_iocp_recv(o->state_, o->cancel_token_, + buffer_sequence_adapter::all_empty(o->buffers_), + ec, bytes_transferred); + + // 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::binder2 + handler(o->handler_, ec, bytes_transferred); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + socket_ops::state_type state_; + socket_ops::weak_cancel_token_type cancel_token_; + MutableBufferSequence buffers_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_SOCKET_RECV_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_socket_recvfrom_op.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_socket_recvfrom_op.hpp new file mode 100644 index 00000000..843ce5bb --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_socket_recvfrom_op.hpp @@ -0,0 +1,125 @@ +// +// detail/win_iocp_socket_recvfrom_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_SOCKET_RECVFROM_OP_HPP +#define ASIO_DETAIL_WIN_IOCP_SOCKET_RECVFROM_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/operation.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class win_iocp_socket_recvfrom_op : public operation +{ +public: + ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_recvfrom_op); + + win_iocp_socket_recvfrom_op(Endpoint& endpoint, + socket_ops::weak_cancel_token_type cancel_token, + const MutableBufferSequence& buffers, Handler& handler) + : operation(&win_iocp_socket_recvfrom_op::do_complete), + endpoint_(endpoint), + endpoint_size_(static_cast(endpoint.capacity())), + cancel_token_(cancel_token), + buffers_(buffers), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + int& endpoint_size() + { + return endpoint_size_; + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& result_ec, + std::size_t bytes_transferred) + { + asio::error_code ec(result_ec); + + // Take ownership of the operation object. + win_iocp_socket_recvfrom_op* o( + static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + ASIO_HANDLER_COMPLETION((*o)); + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + if (owner) + { + buffer_sequence_adapter::validate(o->buffers_); + } +#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) + + socket_ops::complete_iocp_recvfrom(o->cancel_token_, ec); + + // Record the size of the endpoint returned by the operation. + o->endpoint_.resize(o->endpoint_size_); + + // 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::binder2 + handler(o->handler_, ec, bytes_transferred); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Endpoint& endpoint_; + int endpoint_size_; + socket_ops::weak_cancel_token_type cancel_token_; + MutableBufferSequence buffers_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_SOCKET_RECVFROM_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_socket_recvmsg_op.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_socket_recvmsg_op.hpp new file mode 100644 index 00000000..78f36b7f --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_socket_recvmsg_op.hpp @@ -0,0 +1,118 @@ +// +// detail/win_iocp_socket_recvmsg_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_SOCKET_RECVMSG_OP_HPP +#define ASIO_DETAIL_WIN_IOCP_SOCKET_RECVMSG_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/operation.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/error.hpp" +#include "asio/socket_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class win_iocp_socket_recvmsg_op : public operation +{ +public: + ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_recvmsg_op); + + win_iocp_socket_recvmsg_op( + socket_ops::weak_cancel_token_type cancel_token, + const MutableBufferSequence& buffers, + socket_base::message_flags& out_flags, Handler& handler) + : operation(&win_iocp_socket_recvmsg_op::do_complete), + cancel_token_(cancel_token), + buffers_(buffers), + out_flags_(out_flags), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& result_ec, + std::size_t bytes_transferred) + { + asio::error_code ec(result_ec); + + // Take ownership of the operation object. + win_iocp_socket_recvmsg_op* o( + static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + ASIO_HANDLER_COMPLETION((*o)); + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + if (owner) + { + buffer_sequence_adapter::validate(o->buffers_); + } +#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) + + socket_ops::complete_iocp_recvmsg(o->cancel_token_, ec); + o->out_flags_ = 0; + + // 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::binder2 + handler(o->handler_, ec, bytes_transferred); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + socket_ops::weak_cancel_token_type cancel_token_; + MutableBufferSequence buffers_; + socket_base::message_flags& out_flags_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_SOCKET_RECVMSG_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_socket_send_op.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_socket_send_op.hpp new file mode 100644 index 00000000..e1c7ab93 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_socket_send_op.hpp @@ -0,0 +1,111 @@ +// +// detail/win_iocp_socket_send_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_SOCKET_SEND_OP_HPP +#define ASIO_DETAIL_WIN_IOCP_SOCKET_SEND_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/operation.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class win_iocp_socket_send_op : public operation +{ +public: + ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_send_op); + + win_iocp_socket_send_op(socket_ops::weak_cancel_token_type cancel_token, + const ConstBufferSequence& buffers, Handler& handler) + : operation(&win_iocp_socket_send_op::do_complete), + cancel_token_(cancel_token), + buffers_(buffers), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& result_ec, + std::size_t bytes_transferred) + { + asio::error_code ec(result_ec); + + // Take ownership of the operation object. + win_iocp_socket_send_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + ASIO_HANDLER_COMPLETION((*o)); + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + if (owner) + { + buffer_sequence_adapter::validate(o->buffers_); + } +#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) + + socket_ops::complete_iocp_send(o->cancel_token_, ec); + + // 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::binder2 + handler(o->handler_, ec, bytes_transferred); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + socket_ops::weak_cancel_token_type cancel_token_; + ConstBufferSequence buffers_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_SOCKET_SEND_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_socket_service.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_socket_service.hpp new file mode 100644 index 00000000..3f01b4d3 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_socket_service.hpp @@ -0,0 +1,599 @@ +// +// detail/win_iocp_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP +#define ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/socket_base.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/operation.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/select_reactor.hpp" +#include "asio/detail/socket_holder.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/win_iocp_io_context.hpp" +#include "asio/detail/win_iocp_null_buffers_op.hpp" +#include "asio/detail/win_iocp_socket_accept_op.hpp" +#include "asio/detail/win_iocp_socket_connect_op.hpp" +#include "asio/detail/win_iocp_socket_recvfrom_op.hpp" +#include "asio/detail/win_iocp_socket_send_op.hpp" +#include "asio/detail/win_iocp_socket_service_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class win_iocp_socket_service : + public service_base >, + public win_iocp_socket_service_base +{ +public: + // The protocol type. + typedef Protocol protocol_type; + + // The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + // The native type of a socket. + class native_handle_type + { + public: + native_handle_type(socket_type s) + : socket_(s), + have_remote_endpoint_(false) + { + } + + native_handle_type(socket_type s, const endpoint_type& ep) + : socket_(s), + have_remote_endpoint_(true), + remote_endpoint_(ep) + { + } + + void operator=(socket_type s) + { + socket_ = s; + have_remote_endpoint_ = false; + remote_endpoint_ = endpoint_type(); + } + + operator socket_type() const + { + return socket_; + } + + bool have_remote_endpoint() const + { + return have_remote_endpoint_; + } + + endpoint_type remote_endpoint() const + { + return remote_endpoint_; + } + + private: + socket_type socket_; + bool have_remote_endpoint_; + endpoint_type remote_endpoint_; + }; + + // The implementation type of the socket. + struct implementation_type : + win_iocp_socket_service_base::base_implementation_type + { + // Default constructor. + implementation_type() + : protocol_(endpoint_type().protocol()), + have_remote_endpoint_(false), + remote_endpoint_() + { + } + + // The protocol associated with the socket. + protocol_type protocol_; + + // Whether we have a cached remote endpoint. + bool have_remote_endpoint_; + + // A cached remote endpoint. + endpoint_type remote_endpoint_; + }; + + // Constructor. + win_iocp_socket_service(asio::io_context& io_context) + : service_base >(io_context), + win_iocp_socket_service_base(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(); + + impl.have_remote_endpoint_ = other_impl.have_remote_endpoint_; + other_impl.have_remote_endpoint_ = false; + + impl.remote_endpoint_ = other_impl.remote_endpoint_; + other_impl.remote_endpoint_ = endpoint_type(); + } + + // Move-assign from another socket implementation. + void move_assign(implementation_type& impl, + win_iocp_socket_service_base& 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(); + + impl.have_remote_endpoint_ = other_impl.have_remote_endpoint_; + other_impl.have_remote_endpoint_ = false; + + impl.remote_endpoint_ = other_impl.remote_endpoint_; + other_impl.remote_endpoint_ = endpoint_type(); + } + + // Move-construct a new socket implementation from another protocol type. + template + void converting_move_construct(implementation_type& impl, + win_iocp_socket_service&, + typename win_iocp_socket_service< + 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(); + + impl.have_remote_endpoint_ = other_impl.have_remote_endpoint_; + other_impl.have_remote_endpoint_ = false; + + impl.remote_endpoint_ = other_impl.remote_endpoint_; + other_impl.remote_endpoint_ = typename Protocol1::endpoint(); + } + + // Open a new socket implementation. + asio::error_code open(implementation_type& impl, + const protocol_type& protocol, asio::error_code& ec) + { + if (!do_open(impl, protocol.family(), + protocol.type(), protocol.protocol(), ec)) + { + impl.protocol_ = protocol; + impl.have_remote_endpoint_ = false; + impl.remote_endpoint_ = endpoint_type(); + } + return ec; + } + + // Assign a native socket to a socket implementation. + asio::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_handle_type& native_socket, + asio::error_code& ec) + { + if (!do_assign(impl, protocol.type(), native_socket, ec)) + { + impl.protocol_ = protocol; + impl.have_remote_endpoint_ = native_socket.have_remote_endpoint(); + impl.remote_endpoint_ = native_socket.remote_endpoint(); + } + return ec; + } + + // Get the native socket representation. + native_handle_type native_handle(implementation_type& impl) + { + if (impl.have_remote_endpoint_) + return native_handle_type(impl.socket_, impl.remote_endpoint_); + return native_handle_type(impl.socket_); + } + + // Bind the socket to the specified local endpoint. + asio::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); + return ec; + } + + // Set a socket option. + template + asio::error_code set_option(implementation_type& impl, + const Option& option, asio::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 + asio::error_code get_option(const implementation_type& impl, + Option& option, asio::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, + asio::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, + asio::error_code& ec) const + { + endpoint_type endpoint = impl.remote_endpoint_; + std::size_t addr_len = endpoint.capacity(); + if (socket_ops::getpeername(impl.socket_, endpoint.data(), + &addr_len, impl.have_remote_endpoint_, ec)) + return endpoint_type(); + endpoint.resize(addr_len); + return endpoint; + } + + // Disable sends or receives on the socket. + asio::error_code shutdown(base_implementation_type& impl, + socket_base::shutdown_type what, asio::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, + asio::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, + asio::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) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_socket_send_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, buffers, handler); + + ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_send_to")); + + buffer_sequence_adapter bufs(buffers); + + start_send_to_op(impl, bufs.buffers(), bufs.count(), + destination.data(), static_cast(destination.size()), + flags, p.p); + 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) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_null_buffers_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, handler); + + ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_send_to(null_buffers)")); + + start_reactor_op(impl, select_reactor::write_op, p.p); + 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, + asio::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, asio::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_endp, + socket_base::message_flags flags, Handler& handler) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_socket_recvfrom_op< + MutableBufferSequence, endpoint_type, Handler> op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(sender_endp, impl.cancel_token_, buffers, handler); + + ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_receive_from")); + + buffer_sequence_adapter bufs(buffers); + + start_receive_from_op(impl, bufs.buffers(), bufs.count(), + sender_endp.data(), flags, &p.p->endpoint_size(), p.p); + 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) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_null_buffers_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, handler); + + ASIO_HANDLER_CREATION((io_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_null_buffers_receive_op(impl, flags, p.p); + p.v = p.p = 0; + } + + // Accept a new connection. + template + asio::error_code accept(implementation_type& impl, Socket& peer, + endpoint_type* peer_endpoint, asio::error_code& ec) + { + // We cannot accept a socket that is already open. + if (peer.is_open()) + { + ec = 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(ASIO_HAS_MOVE) + // Accept a new connection. + typename Protocol::socket accept(implementation_type& impl, + io_context* peer_io_context, endpoint_type* peer_endpoint, + asio::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(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) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_socket_accept_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + bool enable_connection_aborted = + (impl.state_ & socket_ops::enable_connection_aborted) != 0; + p.p = new (p.v) op(*this, impl.socket_, peer, impl.protocol_, + peer_endpoint, enable_connection_aborted, handler); + + ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_accept")); + + start_accept_op(impl, peer.is_open(), p.p->new_socket(), + impl.protocol_.family(), impl.protocol_.type(), + impl.protocol_.protocol(), p.p->output_buffer(), + p.p->address_length(), p.p); + p.v = p.p = 0; + } + +#if defined(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, + asio::io_context* peer_io_context, + endpoint_type* peer_endpoint, Handler& handler) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_socket_move_accept_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + bool enable_connection_aborted = + (impl.state_ & socket_ops::enable_connection_aborted) != 0; + p.p = new (p.v) op(*this, impl.socket_, impl.protocol_, + peer_io_context ? *peer_io_context : io_context_, + peer_endpoint, enable_connection_aborted, handler); + + ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_accept")); + + start_accept_op(impl, false, p.p->new_socket(), + impl.protocol_.family(), impl.protocol_.type(), + impl.protocol_.protocol(), p.p->output_buffer(), + p.p->address_length(), p.p); + p.v = p.p = 0; + } +#endif // defined(ASIO_HAS_MOVE) + + // Connect the socket to the specified endpoint. + asio::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, asio::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) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_socket_connect_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.socket_, handler); + + ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_connect")); + + start_connect_op(impl, impl.protocol_.family(), impl.protocol_.type(), + peer_endpoint.data(), static_cast(peer_endpoint.size()), p.p); + p.v = p.p = 0; + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_socket_service_base.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_socket_service_base.hpp new file mode 100644 index 00000000..ef1d7180 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_socket_service_base.hpp @@ -0,0 +1,591 @@ +// +// detail/win_iocp_socket_service_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_BASE_HPP +#define ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/socket_base.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/operation.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/select_reactor.hpp" +#include "asio/detail/socket_holder.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/win_iocp_io_context.hpp" +#include "asio/detail/win_iocp_null_buffers_op.hpp" +#include "asio/detail/win_iocp_socket_connect_op.hpp" +#include "asio/detail/win_iocp_socket_send_op.hpp" +#include "asio/detail/win_iocp_socket_recv_op.hpp" +#include "asio/detail/win_iocp_socket_recvmsg_op.hpp" +#include "asio/detail/win_iocp_wait_op.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class win_iocp_socket_service_base +{ +public: + // 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_; + + // We use a shared pointer as a cancellation token here to work around the + // broken Windows support for cancellation. MSDN says that when you call + // closesocket any outstanding WSARecv or WSASend operations will complete + // with the error ERROR_OPERATION_ABORTED. In practice they complete with + // ERROR_NETNAME_DELETED, which means you can't tell the difference between + // a local cancellation and the socket being hard-closed by the peer. + socket_ops::shared_cancel_token_type cancel_token_; + + // Per-descriptor data used by the reactor. + select_reactor::per_descriptor_data reactor_data_; + +#if defined(ASIO_ENABLE_CANCELIO) + // The ID of the thread from which it is safe to cancel asynchronous + // operations. 0 means no asynchronous operations have been started yet. + // ~0 means asynchronous operations have been started from more than one + // thread, and cancellation is not supported for the socket. + DWORD safe_cancellation_thread_id_; +#endif // defined(ASIO_ENABLE_CANCELIO) + + // Pointers to adjacent socket implementations in linked list. + base_implementation_type* next_; + base_implementation_type* prev_; + }; + + // Constructor. + ASIO_DECL win_iocp_socket_service_base( + asio::io_context& io_context); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void base_shutdown(); + + // Construct a new socket implementation. + ASIO_DECL void construct(base_implementation_type& impl); + + // Move-construct a new socket implementation. + ASIO_DECL void base_move_construct(base_implementation_type& impl, + base_implementation_type& other_impl); + + // Move-assign from another socket implementation. + ASIO_DECL void base_move_assign(base_implementation_type& impl, + win_iocp_socket_service_base& other_service, + base_implementation_type& other_impl); + + // Destroy a socket implementation. + 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. + ASIO_DECL asio::error_code close( + base_implementation_type& impl, asio::error_code& ec); + + // Release ownership of the socket. + ASIO_DECL socket_type release( + base_implementation_type& impl, asio::error_code& ec); + + // Cancel all operations associated with the socket. + ASIO_DECL asio::error_code cancel( + base_implementation_type& impl, asio::error_code& ec); + + // Determine whether the socket is at the out-of-band data mark. + bool at_mark(const base_implementation_type& impl, + asio::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, + asio::error_code& ec) const + { + return socket_ops::available(impl.socket_, ec); + } + + // Place the socket into the state where it will listen for new connections. + asio::error_code listen(base_implementation_type& impl, + int backlog, asio::error_code& ec) + { + socket_ops::listen(impl.socket_, backlog, ec); + return ec; + } + + // Perform an IO control command on the socket. + template + asio::error_code io_control(base_implementation_type& impl, + IO_Control_Command& command, asio::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. + asio::error_code non_blocking(base_implementation_type& impl, + bool mode, asio::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. + asio::error_code native_non_blocking(base_implementation_type& impl, + bool mode, asio::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. + asio::error_code wait(base_implementation_type& impl, + socket_base::wait_type w, asio::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 = 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 = + asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_wait_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, handler); + + ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_wait")); + + switch (w) + { + case socket_base::wait_read: + start_null_buffers_receive_op(impl, 0, p.p); + break; + case socket_base::wait_write: + start_reactor_op(impl, select_reactor::write_op, p.p); + break; + case socket_base::wait_error: + start_reactor_op(impl, select_reactor::except_op, p.p); + break; + default: + p.p->ec_ = asio::error::invalid_argument; + iocp_service_.post_immediate_completion(p.p, is_continuation); + break; + } + + p.v = p.p = 0; + } + + // Send the given data to the peer. Returns the number of bytes sent. + template + size_t send(base_implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, asio::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, asio::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) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_socket_send_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, buffers, handler); + + ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_send")); + + buffer_sequence_adapter bufs(buffers); + + start_send_op(impl, bufs.buffers(), bufs.count(), flags, + (impl.state_ & socket_ops::stream_oriented) != 0 && bufs.all_empty(), + p.p); + 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) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_null_buffers_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, handler); + + ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_send(null_buffers)")); + + start_reactor_op(impl, select_reactor::write_op, p.p); + 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, asio::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, asio::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) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_socket_recv_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.state_, impl.cancel_token_, buffers, handler); + + ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_receive")); + + buffer_sequence_adapter bufs(buffers); + + start_receive_op(impl, bufs.buffers(), bufs.count(), flags, + (impl.state_ & socket_ops::stream_oriented) != 0 && bufs.all_empty(), + p.p); + 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) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_null_buffers_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, handler); + + ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_receive(null_buffers)")); + + start_null_buffers_receive_op(impl, flags, p.p); + 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, asio::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, asio::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) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_socket_recvmsg_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, buffers, out_flags, handler); + + ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_receive_with_flags")); + + buffer_sequence_adapter bufs(buffers); + + start_receive_op(impl, bufs.buffers(), bufs.count(), in_flags, false, p.p); + 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) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_null_buffers_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, handler); + + ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); + + // Reset out_flags since it can be given no sensible value at this time. + out_flags = 0; + + start_null_buffers_receive_op(impl, in_flags, p.p); + p.v = p.p = 0; + } + + // Helper function to restart an asynchronous accept operation. + ASIO_DECL void restart_accept_op(socket_type s, + socket_holder& new_socket, int family, int type, int protocol, + void* output_buffer, DWORD address_length, operation* op); + +protected: + // Open a new socket implementation. + ASIO_DECL asio::error_code do_open( + base_implementation_type& impl, int family, int type, + int protocol, asio::error_code& ec); + + // Assign a native socket to a socket implementation. + ASIO_DECL asio::error_code do_assign( + base_implementation_type& impl, int type, + socket_type native_socket, asio::error_code& ec); + + // Helper function to start an asynchronous send operation. + ASIO_DECL void start_send_op(base_implementation_type& impl, + WSABUF* buffers, std::size_t buffer_count, + socket_base::message_flags flags, bool noop, operation* op); + + // Helper function to start an asynchronous send_to operation. + ASIO_DECL void start_send_to_op(base_implementation_type& impl, + WSABUF* buffers, std::size_t buffer_count, + const socket_addr_type* addr, int addrlen, + socket_base::message_flags flags, operation* op); + + // Helper function to start an asynchronous receive operation. + ASIO_DECL void start_receive_op(base_implementation_type& impl, + WSABUF* buffers, std::size_t buffer_count, + socket_base::message_flags flags, bool noop, operation* op); + + // Helper function to start an asynchronous null_buffers receive operation. + ASIO_DECL void start_null_buffers_receive_op( + base_implementation_type& impl, + socket_base::message_flags flags, reactor_op* op); + + // Helper function to start an asynchronous receive_from operation. + ASIO_DECL void start_receive_from_op(base_implementation_type& impl, + WSABUF* buffers, std::size_t buffer_count, socket_addr_type* addr, + socket_base::message_flags flags, int* addrlen, operation* op); + + // Helper function to start an asynchronous accept operation. + ASIO_DECL void start_accept_op(base_implementation_type& impl, + bool peer_is_open, socket_holder& new_socket, int family, int type, + int protocol, void* output_buffer, DWORD address_length, operation* op); + + // Start an asynchronous read or write operation using the reactor. + ASIO_DECL void start_reactor_op(base_implementation_type& impl, + int op_type, reactor_op* op); + + // Start the asynchronous connect operation using the reactor. + ASIO_DECL void start_connect_op(base_implementation_type& impl, + int family, int type, const socket_addr_type* remote_addr, + std::size_t remote_addrlen, win_iocp_socket_connect_op_base* op); + + // Helper function to close a socket when the associated object is being + // destroyed. + ASIO_DECL void close_for_destruction(base_implementation_type& impl); + + // Update the ID of the thread from which cancellation is safe. + ASIO_DECL void update_cancellation_thread_id( + base_implementation_type& impl); + + // Helper function to get the reactor. If no reactor has been created yet, a + // new one is obtained from the io_context and a pointer to it is cached in + // this service. + ASIO_DECL select_reactor& get_reactor(); + + // The type of a ConnectEx function pointer, as old SDKs may not provide it. + typedef BOOL (PASCAL *connect_ex_fn)(SOCKET, + const socket_addr_type*, int, void*, DWORD, DWORD*, OVERLAPPED*); + + // Helper function to get the ConnectEx pointer. If no ConnectEx pointer has + // been obtained yet, one is obtained using WSAIoctl and the pointer is + // cached. Returns a null pointer if ConnectEx is not available. + ASIO_DECL connect_ex_fn get_connect_ex( + base_implementation_type& impl, int type); + + // The type of a NtSetInformationFile function pointer. + typedef LONG (NTAPI *nt_set_info_fn)(HANDLE, ULONG_PTR*, void*, ULONG, ULONG); + + // Helper function to get the NtSetInformationFile function pointer. If no + // NtSetInformationFile pointer has been obtained yet, one is obtained using + // GetProcAddress and the pointer is cached. Returns a null pointer if + // NtSetInformationFile is not available. + ASIO_DECL nt_set_info_fn get_nt_set_info(); + + // Helper function to emulate InterlockedCompareExchangePointer functionality + // for: + // - very old Platform SDKs; and + // - platform SDKs where MSVC's /Wp64 option causes spurious warnings. + ASIO_DECL void* interlocked_compare_exchange_pointer( + void** dest, void* exch, void* cmp); + + // Helper function to emulate InterlockedExchangePointer functionality for: + // - very old Platform SDKs; and + // - platform SDKs where MSVC's /Wp64 option causes spurious warnings. + ASIO_DECL void* interlocked_exchange_pointer(void** dest, void* val); + + // The io_context used to obtain the reactor, if required. + asio::io_context& io_context_; + + // The IOCP service used for running asynchronous operations and dispatching + // handlers. + win_iocp_io_context& iocp_service_; + + // The reactor used for performing connect operations. This object is created + // only if needed. + select_reactor* reactor_; + + // Pointer to ConnectEx implementation. + void* connect_ex_; + + // Pointer to NtSetInformationFile implementation. + void* nt_set_info_; + + // Mutex to protect access to the linked list of implementations. + asio::detail::mutex mutex_; + + // The head of a linked list of all implementations. + base_implementation_type* impl_list_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/win_iocp_socket_service_base.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_BASE_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_thread_info.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_thread_info.hpp new file mode 100644 index 00000000..13181e2e --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_thread_info.hpp @@ -0,0 +1,34 @@ +// +// detail/win_iocp_thread_info.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_THREAD_INFO_HPP +#define ASIO_DETAIL_WIN_IOCP_THREAD_INFO_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/thread_info_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +struct win_iocp_thread_info : public thread_info_base +{ +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_IOCP_THREAD_INFO_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_iocp_wait_op.hpp b/tools/sdk/include/asio/asio/detail/win_iocp_wait_op.hpp new file mode 100644 index 00000000..472eea38 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_iocp_wait_op.hpp @@ -0,0 +1,121 @@ +// +// detail/win_iocp_wait_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_IOCP_WAIT_OP_HPP +#define ASIO_DETAIL_WIN_IOCP_WAIT_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class win_iocp_wait_op : public reactor_op +{ +public: + ASIO_DEFINE_HANDLER_PTR(win_iocp_wait_op); + + win_iocp_wait_op(socket_ops::weak_cancel_token_type cancel_token, + Handler& handler) + : reactor_op(&win_iocp_wait_op::do_perform, + &win_iocp_wait_op::do_complete), + cancel_token_(cancel_token), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static status do_perform(reactor_op*) + { + return done; + } + + static void do_complete(void* owner, operation* base, + const asio::error_code& result_ec, + std::size_t /*bytes_transferred*/) + { + asio::error_code ec(result_ec); + + // Take ownership of the operation object. + win_iocp_wait_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + ASIO_HANDLER_COMPLETION((*o)); + + // The reactor may have stored a result in the operation object. + if (o->ec_) + ec = o->ec_; + + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_NETNAME_DELETED) + { + if (o->cancel_token_.expired()) + ec = asio::error::operation_aborted; + else + ec = asio::error::connection_reset; + } + else if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = asio::error::connection_refused; + } + + // 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::binder1 + handler(o->handler_, ec); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + socket_ops::weak_cancel_token_type cancel_token_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_IOCP) + +#endif // ASIO_DETAIL_WIN_IOCP_WAIT_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_mutex.hpp b/tools/sdk/include/asio/asio/detail/win_mutex.hpp new file mode 100644 index 00000000..ce52a2f7 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_mutex.hpp @@ -0,0 +1,78 @@ +// +// detail/win_mutex.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_MUTEX_HPP +#define ASIO_DETAIL_WIN_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS) + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/scoped_lock.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class win_mutex + : private noncopyable +{ +public: + typedef asio::detail::scoped_lock scoped_lock; + + // Constructor. + ASIO_DECL win_mutex(); + + // Destructor. + ~win_mutex() + { + ::DeleteCriticalSection(&crit_section_); + } + + // Lock the mutex. + void lock() + { + ::EnterCriticalSection(&crit_section_); + } + + // Unlock the mutex. + void unlock() + { + ::LeaveCriticalSection(&crit_section_); + } + +private: + // Initialisation must be performed in a separate function to the constructor + // since the compiler does not support the use of structured exceptions and + // C++ exceptions in the same function. + ASIO_DECL int do_init(); + + ::CRITICAL_SECTION crit_section_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/win_mutex.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_WINDOWS) + +#endif // ASIO_DETAIL_WIN_MUTEX_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_object_handle_service.hpp b/tools/sdk/include/asio/asio/detail/win_object_handle_service.hpp new file mode 100644 index 00000000..1d8abc9c --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_object_handle_service.hpp @@ -0,0 +1,184 @@ +// +// detail/win_object_handle_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2011 Boris Schaeling (boris@highscore.de) +// +// 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 ASIO_DETAIL_WIN_OBJECT_HANDLE_SERVICE_HPP +#define ASIO_DETAIL_WIN_OBJECT_HANDLE_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) + +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/wait_handler.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class win_object_handle_service : + public service_base +{ +public: + // The native type of an object handle. + typedef HANDLE native_handle_type; + + // The implementation type of the object handle. + class implementation_type + { + public: + // Default constructor. + implementation_type() + : handle_(INVALID_HANDLE_VALUE), + wait_handle_(INVALID_HANDLE_VALUE), + owner_(0), + next_(0), + prev_(0) + { + } + + private: + // Only this service will have access to the internal values. + friend class win_object_handle_service; + + // The native object handle representation. May be accessed or modified + // without locking the mutex. + native_handle_type handle_; + + // The handle used to unregister the wait operation. The mutex must be + // locked when accessing or modifying this member. + HANDLE wait_handle_; + + // The operations waiting on the object handle. If there is a registered + // wait then the mutex must be locked when accessing or modifying this + // member + op_queue op_queue_; + + // The service instance that owns the object handle implementation. + win_object_handle_service* owner_; + + // Pointers to adjacent handle implementations in linked list. The mutex + // must be locked when accessing or modifying these members. + implementation_type* next_; + implementation_type* prev_; + }; + + // Constructor. + ASIO_DECL win_object_handle_service( + asio::io_context& io_context); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Construct a new handle implementation. + ASIO_DECL void construct(implementation_type& impl); + + // Move-construct a new handle implementation. + ASIO_DECL void move_construct(implementation_type& impl, + implementation_type& other_impl); + + // Move-assign from another handle implementation. + ASIO_DECL void move_assign(implementation_type& impl, + win_object_handle_service& other_service, + implementation_type& other_impl); + + // Destroy a handle implementation. + ASIO_DECL void destroy(implementation_type& impl); + + // Assign a native handle to a handle implementation. + ASIO_DECL asio::error_code assign(implementation_type& impl, + const native_handle_type& handle, asio::error_code& ec); + + // Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return impl.handle_ != INVALID_HANDLE_VALUE && impl.handle_ != 0; + } + + // Destroy a handle implementation. + ASIO_DECL asio::error_code close(implementation_type& impl, + asio::error_code& ec); + + // Get the native handle representation. + native_handle_type native_handle(const implementation_type& impl) const + { + return impl.handle_; + } + + // Cancel all operations associated with the handle. + ASIO_DECL asio::error_code cancel(implementation_type& impl, + asio::error_code& ec); + + // Perform a synchronous wait for the object to enter a signalled state. + ASIO_DECL void wait(implementation_type& impl, + asio::error_code& ec); + + /// Start an asynchronous wait. + template + void async_wait(implementation_type& impl, Handler& handler) + { + // Allocate and construct an operation to wrap the handler. + typedef wait_handler op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + ASIO_HANDLER_CREATION((io_context_.context(), *p.p, "object_handle", + &impl, reinterpret_cast(impl.wait_handle_), "async_wait")); + + start_wait_op(impl, p.p); + p.v = p.p = 0; + } + +private: + // Helper function to start an asynchronous wait operation. + ASIO_DECL void start_wait_op(implementation_type& impl, wait_op* op); + + // Helper function to register a wait operation. + ASIO_DECL void register_wait_callback( + implementation_type& impl, mutex::scoped_lock& lock); + + // Callback function invoked when the registered wait completes. + static ASIO_DECL VOID CALLBACK wait_callback( + PVOID param, BOOLEAN timeout); + + // The io_context implementation used to post completions. + io_context_impl& io_context_; + + // Mutex to protect access to internal state. + mutex mutex_; + + // The head of a linked list of all implementations. + implementation_type* impl_list_; + + // Flag to indicate that the dispatcher has been shut down. + bool shutdown_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/win_object_handle_service.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) + +#endif // ASIO_DETAIL_WIN_OBJECT_HANDLE_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_static_mutex.hpp b/tools/sdk/include/asio/asio/detail/win_static_mutex.hpp new file mode 100644 index 00000000..b1696886 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_static_mutex.hpp @@ -0,0 +1,74 @@ +// +// detail/win_static_mutex.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_STATIC_MUTEX_HPP +#define ASIO_DETAIL_WIN_STATIC_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS) + +#include "asio/detail/scoped_lock.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +struct win_static_mutex +{ + typedef asio::detail::scoped_lock scoped_lock; + + // Initialise the mutex. + ASIO_DECL void init(); + + // Initialisation must be performed in a separate function to the "public" + // init() function since the compiler does not support the use of structured + // exceptions and C++ exceptions in the same function. + ASIO_DECL int do_init(); + + // Lock the mutex. + void lock() + { + ::EnterCriticalSection(&crit_section_); + } + + // Unlock the mutex. + void unlock() + { + ::LeaveCriticalSection(&crit_section_); + } + + bool initialised_; + ::CRITICAL_SECTION crit_section_; +}; + +#if defined(UNDER_CE) +# define ASIO_WIN_STATIC_MUTEX_INIT { false, { 0, 0, 0, 0, 0 } } +#else // defined(UNDER_CE) +# define ASIO_WIN_STATIC_MUTEX_INIT { false, { 0, 0, 0, 0, 0, 0 } } +#endif // defined(UNDER_CE) + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/win_static_mutex.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_WINDOWS) + +#endif // ASIO_DETAIL_WIN_STATIC_MUTEX_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_thread.hpp b/tools/sdk/include/asio/asio/detail/win_thread.hpp new file mode 100644 index 00000000..8b28a90b --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_thread.hpp @@ -0,0 +1,147 @@ +// +// detail/win_thread.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_THREAD_HPP +#define ASIO_DETAIL_WIN_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS) \ + && !defined(ASIO_WINDOWS_APP) \ + && !defined(UNDER_CE) + +#include +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +ASIO_DECL unsigned int __stdcall win_thread_function(void* arg); + +#if defined(WINVER) && (WINVER < 0x0500) +ASIO_DECL void __stdcall apc_function(ULONG data); +#else +ASIO_DECL void __stdcall apc_function(ULONG_PTR data); +#endif + +template +class win_thread_base +{ +public: + static bool terminate_threads() + { + return ::InterlockedExchangeAdd(&terminate_threads_, 0) != 0; + } + + static void set_terminate_threads(bool b) + { + ::InterlockedExchange(&terminate_threads_, b ? 1 : 0); + } + +private: + static long terminate_threads_; +}; + +template +long win_thread_base::terminate_threads_ = 0; + +class win_thread + : private noncopyable, + public win_thread_base +{ +public: + // Constructor. + template + win_thread(Function f, unsigned int stack_size = 0) + : thread_(0), + exit_event_(0) + { + start_thread(new func(f), stack_size); + } + + // Destructor. + ASIO_DECL ~win_thread(); + + // Wait for the thread to exit. + ASIO_DECL void join(); + + // Get number of CPUs. + ASIO_DECL static std::size_t hardware_concurrency(); + +private: + friend ASIO_DECL unsigned int __stdcall win_thread_function(void* arg); + +#if defined(WINVER) && (WINVER < 0x0500) + friend ASIO_DECL void __stdcall apc_function(ULONG); +#else + friend ASIO_DECL void __stdcall apc_function(ULONG_PTR); +#endif + + class func_base + { + public: + virtual ~func_base() {} + virtual void run() = 0; + ::HANDLE entry_event_; + ::HANDLE exit_event_; + }; + + struct auto_func_base_ptr + { + func_base* ptr; + ~auto_func_base_ptr() { delete ptr; } + }; + + template + class func + : public func_base + { + public: + func(Function f) + : f_(f) + { + } + + virtual void run() + { + f_(); + } + + private: + Function f_; + }; + + ASIO_DECL void start_thread(func_base* arg, unsigned int stack_size); + + ::HANDLE thread_; + ::HANDLE exit_event_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/win_thread.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_WINDOWS) + // && !defined(ASIO_WINDOWS_APP) + // && !defined(UNDER_CE) + +#endif // ASIO_DETAIL_WIN_THREAD_HPP diff --git a/tools/sdk/include/asio/asio/detail/win_tss_ptr.hpp b/tools/sdk/include/asio/asio/detail/win_tss_ptr.hpp new file mode 100644 index 00000000..4207108a --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/win_tss_ptr.hpp @@ -0,0 +1,79 @@ +// +// detail/win_tss_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WIN_TSS_PTR_HPP +#define ASIO_DETAIL_WIN_TSS_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS) + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +// Helper function to create thread-specific storage. +ASIO_DECL DWORD win_tss_ptr_create(); + +template +class win_tss_ptr + : private noncopyable +{ +public: + // Constructor. + win_tss_ptr() + : tss_key_(win_tss_ptr_create()) + { + } + + // Destructor. + ~win_tss_ptr() + { + ::TlsFree(tss_key_); + } + + // Get the value. + operator T*() const + { + return static_cast(::TlsGetValue(tss_key_)); + } + + // Set the value. + void operator=(T* value) + { + ::TlsSetValue(tss_key_, value); + } + +private: + // Thread-specific storage to allow unlocked access to determine whether a + // thread is a member of the pool. + DWORD tss_key_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/win_tss_ptr.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_WINDOWS) + +#endif // ASIO_DETAIL_WIN_TSS_PTR_HPP diff --git a/tools/sdk/include/asio/asio/detail/winapp_thread.hpp b/tools/sdk/include/asio/asio/detail/winapp_thread.hpp new file mode 100644 index 00000000..69dcf08d --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/winapp_thread.hpp @@ -0,0 +1,124 @@ +// +// detail/winapp_thread.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WINAPP_THREAD_HPP +#define ASIO_DETAIL_WINAPP_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS) && defined(ASIO_WINDOWS_APP) + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/scoped_ptr.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +DWORD WINAPI winapp_thread_function(LPVOID arg); + +class winapp_thread + : private noncopyable +{ +public: + // Constructor. + template + winapp_thread(Function f, unsigned int = 0) + { + scoped_ptr arg(new func(f)); + DWORD thread_id = 0; + thread_ = ::CreateThread(0, 0, winapp_thread_function, + arg.get(), 0, &thread_id); + if (!thread_) + { + DWORD last_error = ::GetLastError(); + asio::error_code ec(last_error, + asio::error::get_system_category()); + asio::detail::throw_error(ec, "thread"); + } + arg.release(); + } + + // Destructor. + ~winapp_thread() + { + ::CloseHandle(thread_); + } + + // Wait for the thread to exit. + void join() + { + ::WaitForSingleObjectEx(thread_, INFINITE, false); + } + + // Get number of CPUs. + static std::size_t hardware_concurrency() + { + SYSTEM_INFO system_info; + ::GetNativeSystemInfo(&system_info); + return system_info.dwNumberOfProcessors; + } + +private: + friend DWORD WINAPI winapp_thread_function(LPVOID arg); + + class func_base + { + public: + virtual ~func_base() {} + virtual void run() = 0; + }; + + template + class func + : public func_base + { + public: + func(Function f) + : f_(f) + { + } + + virtual void run() + { + f_(); + } + + private: + Function f_; + }; + + ::HANDLE thread_; +}; + +inline DWORD WINAPI winapp_thread_function(LPVOID arg) +{ + scoped_ptr func( + static_cast(arg)); + func->run(); + return 0; +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_WINDOWS) && defined(ASIO_WINDOWS_APP) + +#endif // ASIO_DETAIL_WINAPP_THREAD_HPP diff --git a/tools/sdk/include/asio/asio/detail/wince_thread.hpp b/tools/sdk/include/asio/asio/detail/wince_thread.hpp new file mode 100644 index 00000000..a2863f62 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/wince_thread.hpp @@ -0,0 +1,124 @@ +// +// detail/wince_thread.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WINCE_THREAD_HPP +#define ASIO_DETAIL_WINCE_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS) && defined(UNDER_CE) + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/scoped_ptr.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +DWORD WINAPI wince_thread_function(LPVOID arg); + +class wince_thread + : private noncopyable +{ +public: + // Constructor. + template + wince_thread(Function f, unsigned int = 0) + { + scoped_ptr arg(new func(f)); + DWORD thread_id = 0; + thread_ = ::CreateThread(0, 0, wince_thread_function, + arg.get(), 0, &thread_id); + if (!thread_) + { + DWORD last_error = ::GetLastError(); + asio::error_code ec(last_error, + asio::error::get_system_category()); + asio::detail::throw_error(ec, "thread"); + } + arg.release(); + } + + // Destructor. + ~wince_thread() + { + ::CloseHandle(thread_); + } + + // Wait for the thread to exit. + void join() + { + ::WaitForSingleObject(thread_, INFINITE); + } + + // Get number of CPUs. + static std::size_t hardware_concurrency() + { + SYSTEM_INFO system_info; + ::GetSystemInfo(&system_info); + return system_info.dwNumberOfProcessors; + } + +private: + friend DWORD WINAPI wince_thread_function(LPVOID arg); + + class func_base + { + public: + virtual ~func_base() {} + virtual void run() = 0; + }; + + template + class func + : public func_base + { + public: + func(Function f) + : f_(f) + { + } + + virtual void run() + { + f_(); + } + + private: + Function f_; + }; + + ::HANDLE thread_; +}; + +inline DWORD WINAPI wince_thread_function(LPVOID arg) +{ + scoped_ptr func( + static_cast(arg)); + func->run(); + return 0; +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE) + +#endif // ASIO_DETAIL_WINCE_THREAD_HPP diff --git a/tools/sdk/include/asio/asio/detail/winrt_async_manager.hpp b/tools/sdk/include/asio/asio/detail/winrt_async_manager.hpp new file mode 100644 index 00000000..e22ad52e --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/winrt_async_manager.hpp @@ -0,0 +1,294 @@ +// +// detail/winrt_async_manager.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WINRT_ASYNC_MANAGER_HPP +#define ASIO_DETAIL_WINRT_ASYNC_MANAGER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) + +#include +#include "asio/detail/atomic_count.hpp" +#include "asio/detail/winrt_async_op.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class winrt_async_manager + : public asio::detail::service_base +{ +public: + // Constructor. + winrt_async_manager(asio::io_context& io_context) + : asio::detail::service_base(io_context), + io_context_(use_service(io_context)), + outstanding_ops_(1) + { + } + + // Destructor. + ~winrt_async_manager() + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown() + { + if (--outstanding_ops_ > 0) + { + // Block until last operation is complete. + std::future f = promise_.get_future(); + f.wait(); + } + } + + void sync(Windows::Foundation::IAsyncAction^ action, + asio::error_code& ec) + { + using namespace Windows::Foundation; + using Windows::Foundation::AsyncStatus; + + auto promise = std::make_shared>(); + auto future = promise->get_future(); + + action->Completed = ref new AsyncActionCompletedHandler( + [promise](IAsyncAction^ action, AsyncStatus status) + { + switch (status) + { + case AsyncStatus::Canceled: + promise->set_value(asio::error::operation_aborted); + break; + case AsyncStatus::Error: + case AsyncStatus::Completed: + default: + asio::error_code ec( + action->ErrorCode.Value, + asio::system_category()); + promise->set_value(ec); + break; + } + }); + + ec = future.get(); + } + + template + TResult sync(Windows::Foundation::IAsyncOperation^ operation, + asio::error_code& ec) + { + using namespace Windows::Foundation; + using Windows::Foundation::AsyncStatus; + + auto promise = std::make_shared>(); + auto future = promise->get_future(); + + operation->Completed = ref new AsyncOperationCompletedHandler( + [promise](IAsyncOperation^ operation, AsyncStatus status) + { + switch (status) + { + case AsyncStatus::Canceled: + promise->set_value(asio::error::operation_aborted); + break; + case AsyncStatus::Error: + case AsyncStatus::Completed: + default: + asio::error_code ec( + operation->ErrorCode.Value, + asio::system_category()); + promise->set_value(ec); + break; + } + }); + + ec = future.get(); + return operation->GetResults(); + } + + template + TResult sync( + Windows::Foundation::IAsyncOperationWithProgress< + TResult, TProgress>^ operation, + asio::error_code& ec) + { + using namespace Windows::Foundation; + using Windows::Foundation::AsyncStatus; + + auto promise = std::make_shared>(); + auto future = promise->get_future(); + + operation->Completed + = ref new AsyncOperationWithProgressCompletedHandler( + [promise](IAsyncOperationWithProgress^ operation, + AsyncStatus status) + { + switch (status) + { + case AsyncStatus::Canceled: + promise->set_value(asio::error::operation_aborted); + break; + case AsyncStatus::Started: + break; + case AsyncStatus::Error: + case AsyncStatus::Completed: + default: + asio::error_code ec( + operation->ErrorCode.Value, + asio::system_category()); + promise->set_value(ec); + break; + } + }); + + ec = future.get(); + return operation->GetResults(); + } + + void async(Windows::Foundation::IAsyncAction^ action, + winrt_async_op* handler) + { + using namespace Windows::Foundation; + using Windows::Foundation::AsyncStatus; + + auto on_completed = ref new AsyncActionCompletedHandler( + [this, handler](IAsyncAction^ action, AsyncStatus status) + { + switch (status) + { + case AsyncStatus::Canceled: + handler->ec_ = asio::error::operation_aborted; + break; + case AsyncStatus::Started: + return; + case AsyncStatus::Completed: + case AsyncStatus::Error: + default: + handler->ec_ = asio::error_code( + action->ErrorCode.Value, + asio::system_category()); + break; + } + io_context_.post_deferred_completion(handler); + if (--outstanding_ops_ == 0) + promise_.set_value(); + }); + + io_context_.work_started(); + ++outstanding_ops_; + action->Completed = on_completed; + } + + template + void async(Windows::Foundation::IAsyncOperation^ operation, + winrt_async_op* handler) + { + using namespace Windows::Foundation; + using Windows::Foundation::AsyncStatus; + + auto on_completed = ref new AsyncOperationCompletedHandler( + [this, handler](IAsyncOperation^ operation, AsyncStatus status) + { + switch (status) + { + case AsyncStatus::Canceled: + handler->ec_ = asio::error::operation_aborted; + break; + case AsyncStatus::Started: + return; + case AsyncStatus::Completed: + handler->result_ = operation->GetResults(); + // Fall through. + case AsyncStatus::Error: + default: + handler->ec_ = asio::error_code( + operation->ErrorCode.Value, + asio::system_category()); + break; + } + io_context_.post_deferred_completion(handler); + if (--outstanding_ops_ == 0) + promise_.set_value(); + }); + + io_context_.work_started(); + ++outstanding_ops_; + operation->Completed = on_completed; + } + + template + void async( + Windows::Foundation::IAsyncOperationWithProgress< + TResult, TProgress>^ operation, + winrt_async_op* handler) + { + using namespace Windows::Foundation; + using Windows::Foundation::AsyncStatus; + + auto on_completed + = ref new AsyncOperationWithProgressCompletedHandler( + [this, handler](IAsyncOperationWithProgress< + TResult, TProgress>^ operation, AsyncStatus status) + { + switch (status) + { + case AsyncStatus::Canceled: + handler->ec_ = asio::error::operation_aborted; + break; + case AsyncStatus::Started: + return; + case AsyncStatus::Completed: + handler->result_ = operation->GetResults(); + // Fall through. + case AsyncStatus::Error: + default: + handler->ec_ = asio::error_code( + operation->ErrorCode.Value, + asio::system_category()); + break; + } + io_context_.post_deferred_completion(handler); + if (--outstanding_ops_ == 0) + promise_.set_value(); + }); + + io_context_.work_started(); + ++outstanding_ops_; + operation->Completed = on_completed; + } + +private: + // The io_context implementation used to post completed handlers. + io_context_impl& io_context_; + + // Count of outstanding operations. + atomic_count outstanding_ops_; + + // Used to keep wait for outstanding operations to complete. + std::promise promise_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_WINRT_ASYNC_MANAGER_HPP diff --git a/tools/sdk/include/asio/asio/detail/winrt_async_op.hpp b/tools/sdk/include/asio/asio/detail/winrt_async_op.hpp new file mode 100644 index 00000000..75891a4a --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/winrt_async_op.hpp @@ -0,0 +1,65 @@ +// +// detail/winrt_async_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WINRT_ASYNC_OP_HPP +#define ASIO_DETAIL_WINRT_ASYNC_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/operation.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class winrt_async_op + : public operation +{ +public: + // The error code to be passed to the completion handler. + asio::error_code ec_; + + // The result of the operation, to be passed to the completion handler. + TResult result_; + +protected: + winrt_async_op(func_type complete_func) + : operation(complete_func), + result_() + { + } +}; + +template <> +class winrt_async_op + : public operation +{ +public: + // The error code to be passed to the completion handler. + asio::error_code ec_; + +protected: + winrt_async_op(func_type complete_func) + : operation(complete_func) + { + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WINRT_ASYNC_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/winrt_resolve_op.hpp b/tools/sdk/include/asio/asio/detail/winrt_resolve_op.hpp new file mode 100644 index 00000000..07efd29d --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/winrt_resolve_op.hpp @@ -0,0 +1,118 @@ +// +// detail/winrt_resolve_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WINRT_RESOLVE_OP_HPP +#define ASIO_DETAIL_WINRT_RESOLVE_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/winrt_async_op.hpp" +#include "asio/ip/basic_resolver_results.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class winrt_resolve_op : + public winrt_async_op< + Windows::Foundation::Collections::IVectorView< + Windows::Networking::EndpointPair^>^> +{ +public: + ASIO_DEFINE_HANDLER_PTR(winrt_resolve_op); + + typedef typename Protocol::endpoint endpoint_type; + typedef asio::ip::basic_resolver_query query_type; + typedef asio::ip::basic_resolver_results results_type; + + winrt_resolve_op(const query_type& query, Handler& handler) + : winrt_async_op< + Windows::Foundation::Collections::IVectorView< + Windows::Networking::EndpointPair^>^>( + &winrt_resolve_op::do_complete), + query_(query), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code&, std::size_t) + { + // Take ownership of the operation object. + winrt_resolve_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + ASIO_HANDLER_COMPLETION((*o)); + + results_type results = results_type(); + if (!o->ec_) + { + try + { + results = results_type::create(o->result_, o->query_.hints(), + o->query_.host_name(), o->query_.service_name()); + } + catch (Platform::Exception^ e) + { + o->ec_ = asio::error_code(e->HResult, + asio::system_category()); + } + } + + // 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::binder2 + handler(o->handler_, o->ec_, results); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "...")); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + query_type query_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_WINRT_RESOLVE_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/winrt_resolver_service.hpp b/tools/sdk/include/asio/asio/detail/winrt_resolver_service.hpp new file mode 100644 index 00000000..aeb44485 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/winrt_resolver_service.hpp @@ -0,0 +1,198 @@ +// +// detail/winrt_resolver_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WINRT_RESOLVER_SERVICE_HPP +#define ASIO_DETAIL_WINRT_RESOLVER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/ip/basic_resolver_results.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/winrt_async_manager.hpp" +#include "asio/detail/winrt_resolve_op.hpp" +#include "asio/detail/winrt_utils.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class winrt_resolver_service : + public service_base > +{ +public: + // The implementation type of the resolver. A cancellation token is used to + // indicate to the asynchronous operation that the operation has been + // cancelled. + typedef socket_ops::shared_cancel_token_type implementation_type; + + // The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + // The query type. + typedef asio::ip::basic_resolver_query query_type; + + // The results type. + typedef asio::ip::basic_resolver_results results_type; + + // Constructor. + winrt_resolver_service(asio::io_context& io_context) + : service_base >(io_context), + io_context_(use_service(io_context)), + async_manager_(use_service(io_context)) + { + } + + // Destructor. + ~winrt_resolver_service() + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown() + { + } + + // Perform any fork-related housekeeping. + void notify_fork(asio::io_context::fork_event) + { + } + + // Construct a new resolver implementation. + void construct(implementation_type&) + { + } + + // Move-construct a new resolver implementation. + void move_construct(implementation_type&, + implementation_type&) + { + } + + // Move-assign from another resolver implementation. + void move_assign(implementation_type&, + winrt_resolver_service&, implementation_type&) + { + } + + // Destroy a resolver implementation. + void destroy(implementation_type&) + { + } + + // Cancel pending asynchronous operations. + void cancel(implementation_type&) + { + } + + // Resolve a query to a list of entries. + results_type resolve(implementation_type&, + const query_type& query, asio::error_code& ec) + { + try + { + using namespace Windows::Networking::Sockets; + auto endpoint_pairs = async_manager_.sync( + DatagramSocket::GetEndpointPairsAsync( + winrt_utils::host_name(query.host_name()), + winrt_utils::string(query.service_name())), ec); + + if (ec) + return results_type(); + + return results_type::create( + endpoint_pairs, query.hints(), + query.host_name(), query.service_name()); + } + catch (Platform::Exception^ e) + { + ec = asio::error_code(e->HResult, + asio::system_category()); + return results_type(); + } + } + + // Asynchronously resolve a query to a list of entries. + template + void async_resolve(implementation_type& impl, + const query_type& query, Handler& handler) + { + bool is_continuation = + asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef winrt_resolve_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(query, handler); + + ASIO_HANDLER_CREATION((io_context_.context(), + *p.p, "resolver", &impl, 0, "async_resolve")); + (void)impl; + + try + { + using namespace Windows::Networking::Sockets; + async_manager_.async(DatagramSocket::GetEndpointPairsAsync( + winrt_utils::host_name(query.host_name()), + winrt_utils::string(query.service_name())), p.p); + p.v = p.p = 0; + } + catch (Platform::Exception^ e) + { + p.p->ec_ = asio::error_code( + e->HResult, asio::system_category()); + io_context_.post_immediate_completion(p.p, is_continuation); + p.v = p.p = 0; + } + } + + // Resolve an endpoint to a list of entries. + results_type resolve(implementation_type&, + const endpoint_type&, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return results_type(); + } + + // Asynchronously resolve an endpoint to a list of entries. + template + void async_resolve(implementation_type&, + const endpoint_type&, Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + const results_type results; + io_context_.get_io_context().post( + detail::bind_handler(handler, ec, results)); + } + +private: + io_context_impl& io_context_; + winrt_async_manager& async_manager_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_WINRT_RESOLVER_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/winrt_socket_connect_op.hpp b/tools/sdk/include/asio/asio/detail/winrt_socket_connect_op.hpp new file mode 100644 index 00000000..f18b445f --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/winrt_socket_connect_op.hpp @@ -0,0 +1,92 @@ +// +// detail/winrt_socket_connect_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WINRT_SOCKET_CONNECT_OP_HPP +#define ASIO_DETAIL_WINRT_SOCKET_CONNECT_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/winrt_async_op.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class winrt_socket_connect_op : + public winrt_async_op +{ +public: + ASIO_DEFINE_HANDLER_PTR(winrt_socket_connect_op); + + winrt_socket_connect_op(Handler& handler) + : winrt_async_op(&winrt_socket_connect_op::do_complete), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code&, std::size_t) + { + // Take ownership of the operation object. + winrt_socket_connect_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + 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::binder1 + handler(o->handler_, o->ec_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_WINRT_SOCKET_CONNECT_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/winrt_socket_recv_op.hpp b/tools/sdk/include/asio/asio/detail/winrt_socket_recv_op.hpp new file mode 100644 index 00000000..8f1fcf57 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/winrt_socket_recv_op.hpp @@ -0,0 +1,112 @@ +// +// detail/winrt_socket_recv_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WINRT_SOCKET_RECV_OP_HPP +#define ASIO_DETAIL_WINRT_SOCKET_RECV_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/winrt_async_op.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class winrt_socket_recv_op : + public winrt_async_op +{ +public: + ASIO_DEFINE_HANDLER_PTR(winrt_socket_recv_op); + + winrt_socket_recv_op(const MutableBufferSequence& buffers, Handler& handler) + : winrt_async_op( + &winrt_socket_recv_op::do_complete), + buffers_(buffers), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code&, std::size_t) + { + // Take ownership of the operation object. + winrt_socket_recv_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + ASIO_HANDLER_COMPLETION((*o)); + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + if (owner) + { + buffer_sequence_adapter::validate(o->buffers_); + } +#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) + + std::size_t bytes_transferred = o->result_ ? o->result_->Length : 0; + if (bytes_transferred == 0 && !o->ec_ && + !buffer_sequence_adapter::all_empty(o->buffers_)) + { + o->ec_ = asio::error::eof; + } + + // 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::binder2 + handler(o->handler_, o->ec_, bytes_transferred); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + MutableBufferSequence buffers_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_WINRT_SOCKET_RECV_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/winrt_socket_send_op.hpp b/tools/sdk/include/asio/asio/detail/winrt_socket_send_op.hpp new file mode 100644 index 00000000..1148c24e --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/winrt_socket_send_op.hpp @@ -0,0 +1,103 @@ +// +// detail/winrt_socket_send_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WINRT_SOCKET_SEND_OP_HPP +#define ASIO_DETAIL_WINRT_SOCKET_SEND_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/winrt_async_op.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class winrt_socket_send_op : + public winrt_async_op +{ +public: + ASIO_DEFINE_HANDLER_PTR(winrt_socket_send_op); + + winrt_socket_send_op(const ConstBufferSequence& buffers, Handler& handler) + : winrt_async_op(&winrt_socket_send_op::do_complete), + buffers_(buffers), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + handler_work::start(handler_); + } + + static void do_complete(void* owner, operation* base, + const asio::error_code&, std::size_t) + { + // Take ownership of the operation object. + winrt_socket_send_op* o(static_cast(base)); + ptr p = { asio::detail::addressof(o->handler_), o, o }; + handler_work w(o->handler_); + + ASIO_HANDLER_COMPLETION((*o)); + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + if (owner) + { + buffer_sequence_adapter::validate(o->buffers_); + } +#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) + + // 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::binder2 + handler(o->handler_, o->ec_, o->result_); + p.h = asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); + w.complete(handler, handler.handler_); + ASIO_HANDLER_INVOCATION_END; + } + } + +private: + ConstBufferSequence buffers_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_WINRT_SOCKET_SEND_OP_HPP diff --git a/tools/sdk/include/asio/asio/detail/winrt_ssocket_service.hpp b/tools/sdk/include/asio/asio/detail/winrt_ssocket_service.hpp new file mode 100644 index 00000000..603724a3 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/winrt_ssocket_service.hpp @@ -0,0 +1,241 @@ +// +// detail/winrt_ssocket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WINRT_SSOCKET_SERVICE_HPP +#define ASIO_DETAIL_WINRT_SSOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/winrt_socket_connect_op.hpp" +#include "asio/detail/winrt_ssocket_service_base.hpp" +#include "asio/detail/winrt_utils.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class winrt_ssocket_service : + public service_base >, + public winrt_ssocket_service_base +{ +public: + // The protocol type. + typedef Protocol protocol_type; + + // The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + // The native type of a socket. + typedef Windows::Networking::Sockets::StreamSocket^ native_handle_type; + + // The implementation type of the socket. + struct implementation_type : base_implementation_type + { + // Default constructor. + implementation_type() + : base_implementation_type(), + protocol_(endpoint_type().protocol()) + { + } + + // The protocol associated with the socket. + protocol_type protocol_; + }; + + // Constructor. + winrt_ssocket_service(asio::io_context& io_context) + : service_base >(io_context), + winrt_ssocket_service_base(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, + winrt_ssocket_service& 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, + winrt_ssocket_service&, + typename winrt_ssocket_service< + 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. + asio::error_code open(implementation_type& impl, + const protocol_type& protocol, asio::error_code& ec) + { + if (is_open(impl)) + { + ec = asio::error::already_open; + return ec; + } + + try + { + impl.socket_ = ref new Windows::Networking::Sockets::StreamSocket; + impl.protocol_ = protocol; + ec = asio::error_code(); + } + catch (Platform::Exception^ e) + { + ec = asio::error_code(e->HResult, + asio::system_category()); + } + + return ec; + } + + // Assign a native socket to a socket implementation. + asio::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_handle_type& native_socket, + asio::error_code& ec) + { + if (is_open(impl)) + { + ec = asio::error::already_open; + return ec; + } + + impl.socket_ = native_socket; + impl.protocol_ = protocol; + ec = asio::error_code(); + + return ec; + } + + // Bind the socket to the specified local endpoint. + asio::error_code bind(implementation_type&, + const endpoint_type&, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + endpoint_type endpoint; + endpoint.resize(do_get_endpoint(impl, true, + endpoint.data(), endpoint.size(), ec)); + return endpoint; + } + + // Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + endpoint_type endpoint; + endpoint.resize(do_get_endpoint(impl, false, + endpoint.data(), endpoint.size(), ec)); + return endpoint; + } + + // Set a socket option. + template + asio::error_code set_option(implementation_type& impl, + const Option& option, asio::error_code& ec) + { + return do_set_option(impl, option.level(impl.protocol_), + option.name(impl.protocol_), option.data(impl.protocol_), + option.size(impl.protocol_), ec); + } + + // Get a socket option. + template + asio::error_code get_option(const implementation_type& impl, + Option& option, asio::error_code& ec) const + { + std::size_t size = option.size(impl.protocol_); + do_get_option(impl, option.level(impl.protocol_), + option.name(impl.protocol_), + option.data(impl.protocol_), &size, ec); + if (!ec) + option.resize(impl.protocol_, size); + return ec; + } + + // Connect the socket to the specified endpoint. + asio::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, asio::error_code& ec) + { + return do_connect(impl, peer_endpoint.data(), ec); + } + + // Start an asynchronous connect. + template + void async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, Handler& handler) + { + bool is_continuation = + asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef winrt_socket_connect_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + ASIO_HANDLER_CREATION((io_context_.context(), + *p.p, "socket", &impl, 0, "async_connect")); + + start_connect_op(impl, peer_endpoint.data(), p.p, is_continuation); + p.v = p.p = 0; + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_WINRT_SSOCKET_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/detail/winrt_ssocket_service_base.hpp b/tools/sdk/include/asio/asio/detail/winrt_ssocket_service_base.hpp new file mode 100644 index 00000000..61328d0a --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/winrt_ssocket_service_base.hpp @@ -0,0 +1,359 @@ +// +// detail/winrt_ssocket_service_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WINRT_SSOCKET_SERVICE_BASE_HPP +#define ASIO_DETAIL_WINRT_SSOCKET_SERVICE_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/buffer.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/socket_base.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/winrt_async_manager.hpp" +#include "asio/detail/winrt_socket_recv_op.hpp" +#include "asio/detail/winrt_socket_send_op.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class winrt_ssocket_service_base +{ +public: + // The native type of a socket. + typedef Windows::Networking::Sockets::StreamSocket^ native_handle_type; + + // The implementation type of the socket. + struct base_implementation_type + { + // Default constructor. + base_implementation_type() + : socket_(nullptr), + next_(0), + prev_(0) + { + } + + // The underlying native socket. + native_handle_type socket_; + + // Pointers to adjacent socket implementations in linked list. + base_implementation_type* next_; + base_implementation_type* prev_; + }; + + // Constructor. + ASIO_DECL winrt_ssocket_service_base( + asio::io_context& io_context); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void base_shutdown(); + + // Construct a new socket implementation. + ASIO_DECL void construct(base_implementation_type&); + + // Move-construct a new socket implementation. + ASIO_DECL void base_move_construct(base_implementation_type& impl, + base_implementation_type& other_impl); + + // Move-assign from another socket implementation. + ASIO_DECL void base_move_assign(base_implementation_type& impl, + winrt_ssocket_service_base& other_service, + base_implementation_type& other_impl); + + // Destroy a socket implementation. + 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_ != nullptr; + } + + // Destroy a socket implementation. + ASIO_DECL asio::error_code close( + base_implementation_type& impl, asio::error_code& ec); + + // Release ownership of the socket. + ASIO_DECL native_handle_type release( + base_implementation_type& impl, asio::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. + asio::error_code cancel(base_implementation_type&, + asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Determine whether the socket is at the out-of-band data mark. + bool at_mark(const base_implementation_type&, + asio::error_code& ec) const + { + ec = asio::error::operation_not_supported; + return false; + } + + // Determine the number of bytes available for reading. + std::size_t available(const base_implementation_type&, + asio::error_code& ec) const + { + ec = asio::error::operation_not_supported; + return 0; + } + + // Perform an IO control command on the socket. + template + asio::error_code io_control(base_implementation_type&, + IO_Control_Command&, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Gets the non-blocking mode of the socket. + bool non_blocking(const base_implementation_type&) const + { + return false; + } + + // Sets the non-blocking mode of the socket. + asio::error_code non_blocking(base_implementation_type&, + bool, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Gets the non-blocking mode of the native socket implementation. + bool native_non_blocking(const base_implementation_type&) const + { + return false; + } + + // Sets the non-blocking mode of the native socket implementation. + asio::error_code native_non_blocking(base_implementation_type&, + bool, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Disable sends or receives on the socket. + asio::error_code shutdown(base_implementation_type&, + socket_base::shutdown_type, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Send the given data to the peer. + template + std::size_t send(base_implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + return do_send(impl, + buffer_sequence_adapter::first(buffers), flags, ec); + } + + // Wait until data can be sent without blocking. + std::size_t send(base_implementation_type&, const null_buffers&, + socket_base::message_flags, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + 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 = + asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef winrt_socket_send_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(buffers, handler); + + ASIO_HANDLER_CREATION((io_context_.context(), + *p.p, "socket", &impl, 0, "async_send")); + + start_send_op(impl, + buffer_sequence_adapter::first(buffers), + flags, p.p, is_continuation); + p.v = p.p = 0; + } + + // Start an asynchronous wait until data can be sent without blocking. + template + void async_send(base_implementation_type&, const null_buffers&, + socket_base::message_flags, Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + const std::size_t bytes_transferred = 0; + io_context_.get_io_context().post( + detail::bind_handler(handler, ec, bytes_transferred)); + } + + // Receive some data from the peer. Returns the number of bytes received. + template + std::size_t receive(base_implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + return do_receive(impl, + buffer_sequence_adapter::first(buffers), flags, ec); + } + + // Wait until data can be received without blocking. + std::size_t receive(base_implementation_type&, const null_buffers&, + socket_base::message_flags, asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + 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 = + asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef winrt_socket_recv_op op; + typename op::ptr p = { asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(buffers, handler); + + ASIO_HANDLER_CREATION((io_context_.context(), + *p.p, "socket", &impl, 0, "async_receive")); + + start_receive_op(impl, + buffer_sequence_adapter::first(buffers), + flags, p.p, is_continuation); + p.v = p.p = 0; + } + + // Wait until data can be received without blocking. + template + void async_receive(base_implementation_type&, const null_buffers&, + socket_base::message_flags, Handler& handler) + { + asio::error_code ec = asio::error::operation_not_supported; + const std::size_t bytes_transferred = 0; + io_context_.get_io_context().post( + detail::bind_handler(handler, ec, bytes_transferred)); + } + +protected: + // Helper function to obtain endpoints associated with the connection. + ASIO_DECL std::size_t do_get_endpoint( + const base_implementation_type& impl, bool local, + void* addr, std::size_t addr_len, asio::error_code& ec) const; + + // Helper function to set a socket option. + ASIO_DECL asio::error_code do_set_option( + base_implementation_type& impl, + int level, int optname, const void* optval, + std::size_t optlen, asio::error_code& ec); + + // Helper function to get a socket option. + ASIO_DECL void do_get_option( + const base_implementation_type& impl, + int level, int optname, void* optval, + std::size_t* optlen, asio::error_code& ec) const; + + // Helper function to perform a synchronous connect. + ASIO_DECL asio::error_code do_connect( + base_implementation_type& impl, + const void* addr, asio::error_code& ec); + + // Helper function to start an asynchronous connect. + ASIO_DECL void start_connect_op( + base_implementation_type& impl, const void* addr, + winrt_async_op* op, bool is_continuation); + + // Helper function to perform a synchronous send. + ASIO_DECL std::size_t do_send( + base_implementation_type& impl, const asio::const_buffer& data, + socket_base::message_flags flags, asio::error_code& ec); + + // Helper function to start an asynchronous send. + ASIO_DECL void start_send_op(base_implementation_type& impl, + const asio::const_buffer& data, socket_base::message_flags flags, + winrt_async_op* op, bool is_continuation); + + // Helper function to perform a synchronous receive. + ASIO_DECL std::size_t do_receive( + base_implementation_type& impl, const asio::mutable_buffer& data, + socket_base::message_flags flags, asio::error_code& ec); + + // Helper function to start an asynchronous receive. + ASIO_DECL void start_receive_op(base_implementation_type& impl, + const asio::mutable_buffer& data, socket_base::message_flags flags, + winrt_async_op* op, + bool is_continuation); + + // The io_context implementation used for delivering completions. + io_context_impl& io_context_; + + // The manager that keeps track of outstanding operations. + winrt_async_manager& async_manager_; + + // Mutex to protect access to the linked list of implementations. + asio::detail::mutex mutex_; + + // The head of a linked list of all implementations. + base_implementation_type* impl_list_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/winrt_ssocket_service_base.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_WINRT_SSOCKET_SERVICE_BASE_HPP diff --git a/tools/sdk/include/asio/asio/detail/winrt_timer_scheduler.hpp b/tools/sdk/include/asio/asio/detail/winrt_timer_scheduler.hpp new file mode 100644 index 00000000..5dec7c0b --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/winrt_timer_scheduler.hpp @@ -0,0 +1,137 @@ +// +// detail/winrt_timer_scheduler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WINRT_TIMER_SCHEDULER_HPP +#define ASIO_DETAIL_WINRT_TIMER_SCHEDULER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) + +#include +#include "asio/detail/event.hpp" +#include "asio/detail/limits.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/thread.hpp" +#include "asio/detail/timer_queue_base.hpp" +#include "asio/detail/timer_queue_set.hpp" +#include "asio/detail/wait_op.hpp" +#include "asio/io_context.hpp" + +#if defined(ASIO_HAS_IOCP) +# include "asio/detail/thread.hpp" +#endif // defined(ASIO_HAS_IOCP) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class winrt_timer_scheduler + : public asio::detail::service_base +{ +public: + // Constructor. + ASIO_DECL winrt_timer_scheduler(asio::io_context& io_context); + + // Destructor. + ASIO_DECL ~winrt_timer_scheduler(); + + // Destroy all user-defined handler objects owned by the service. + ASIO_DECL void shutdown(); + + // Recreate internal descriptors following a fork. + ASIO_DECL void notify_fork( + asio::io_context::fork_event fork_ev); + + // Initialise the task. No effect as this class uses its own thread. + ASIO_DECL void init_task(); + + // Add a new timer queue to the reactor. + template + void add_timer_queue(timer_queue& queue); + + // Remove a timer queue from the reactor. + template + void remove_timer_queue(timer_queue& queue); + + // Schedule a new operation in the given timer queue to expire at the + // specified absolute time. + template + void schedule_timer(timer_queue& queue, + const typename Time_Traits::time_type& time, + typename timer_queue::per_timer_data& timer, wait_op* op); + + // Cancel the timer operations associated with the given token. Returns the + // number of operations that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& queue, + typename timer_queue::per_timer_data& timer, + std::size_t max_cancelled = (std::numeric_limits::max)()); + + // Move the timer operations associated with the given timer. + template + void move_timer(timer_queue& queue, + typename timer_queue::per_timer_data& to, + typename timer_queue::per_timer_data& from); + +private: + // Run the select loop in the thread. + ASIO_DECL void run_thread(); + + // Entry point for the select loop thread. + ASIO_DECL static void call_run_thread(winrt_timer_scheduler* reactor); + + // Helper function to add a new timer queue. + ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); + + // Helper function to remove a timer queue. + ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); + + // The io_context implementation used to post completions. + io_context_impl& io_context_; + + // Mutex used to protect internal variables. + asio::detail::mutex mutex_; + + // Event used to wake up background thread. + asio::detail::event event_; + + // The timer queues. + timer_queue_set timer_queues_; + + // The background thread that is waiting for timers to expire. + asio::detail::thread* thread_; + + // Does the background thread need to stop. + bool stop_thread_; + + // Whether the service has been shut down. + bool shutdown_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/impl/winrt_timer_scheduler.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/winrt_timer_scheduler.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_WINRT_TIMER_SCHEDULER_HPP diff --git a/tools/sdk/include/asio/asio/detail/winrt_utils.hpp b/tools/sdk/include/asio/asio/detail/winrt_utils.hpp new file mode 100644 index 00000000..22a24895 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/winrt_utils.hpp @@ -0,0 +1,106 @@ +// +// detail/winrt_utils.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WINRT_UTILS_HPP +#define ASIO_DETAIL_WINRT_UTILS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) + +#include +#include +#include +#include +#include +#include +#include +#include "asio/buffer.hpp" +#include "asio/error_code.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/socket_ops.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { +namespace winrt_utils { + +inline Platform::String^ string(const char* from) +{ + std::wstring tmp(from, from + std::strlen(from)); + return ref new Platform::String(tmp.c_str()); +} + +inline Platform::String^ string(const std::string& from) +{ + std::wstring tmp(from.begin(), from.end()); + return ref new Platform::String(tmp.c_str()); +} + +inline std::string string(Platform::String^ from) +{ + std::wstring_convert> converter; + return converter.to_bytes(from->Data()); +} + +inline Platform::String^ string(unsigned short from) +{ + return string(std::to_string(from)); +} + +template +inline Platform::String^ string(const T& from) +{ + return string(from.to_string()); +} + +inline int integer(Platform::String^ from) +{ + return _wtoi(from->Data()); +} + +template +inline Windows::Networking::HostName^ host_name(const T& from) +{ + return ref new Windows::Networking::HostName((string)(from)); +} + +template +inline Windows::Storage::Streams::IBuffer^ buffer_dup( + const ConstBufferSequence& buffers) +{ + using Microsoft::WRL::ComPtr; + using asio::buffer_size; + std::size_t size = buffer_size(buffers); + auto b = ref new Windows::Storage::Streams::Buffer(size); + ComPtr insp = reinterpret_cast(b); + ComPtr bacc; + insp.As(&bacc); + byte* bytes = nullptr; + bacc->Buffer(&bytes); + asio::buffer_copy(asio::buffer(bytes, size), buffers); + b->Length = size; + return b; +} + +} // namespace winrt_utils +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#endif // ASIO_DETAIL_WINRT_UTILS_HPP diff --git a/tools/sdk/include/asio/asio/detail/winsock_init.hpp b/tools/sdk/include/asio/asio/detail/winsock_init.hpp new file mode 100644 index 00000000..9094363a --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/winsock_init.hpp @@ -0,0 +1,128 @@ +// +// detail/winsock_init.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WINSOCK_INIT_HPP +#define ASIO_DETAIL_WINSOCK_INIT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class winsock_init_base +{ +protected: + // Structure to track result of initialisation and number of uses. POD is used + // to ensure that the values are zero-initialised prior to any code being run. + struct data + { + long init_count_; + long result_; + }; + + ASIO_DECL static void startup(data& d, + unsigned char major, unsigned char minor); + + ASIO_DECL static void manual_startup(data& d); + + ASIO_DECL static void cleanup(data& d); + + ASIO_DECL static void manual_cleanup(data& d); + + ASIO_DECL static void throw_on_error(data& d); +}; + +template +class winsock_init : private winsock_init_base +{ +public: + winsock_init(bool allow_throw = true) + { + startup(data_, Major, Minor); + if (allow_throw) + throw_on_error(data_); + } + + winsock_init(const winsock_init&) + { + startup(data_, Major, Minor); + throw_on_error(data_); + } + + ~winsock_init() + { + cleanup(data_); + } + + // This class may be used to indicate that user code will manage Winsock + // initialisation and cleanup. This may be required in the case of a DLL, for + // example, where it is not safe to initialise Winsock from global object + // constructors. + // + // To prevent asio from initialising Winsock, the object must be constructed + // before any Asio's own global objects. With MSVC, this may be accomplished + // by adding the following code to the DLL: + // + // #pragma warning(push) + // #pragma warning(disable:4073) + // #pragma init_seg(lib) + // asio::detail::winsock_init<>::manual manual_winsock_init; + // #pragma warning(pop) + class manual + { + public: + manual() + { + manual_startup(data_); + } + + manual(const manual&) + { + manual_startup(data_); + } + + ~manual() + { + manual_cleanup(data_); + } + }; + +private: + friend class manual; + static data data_; +}; + +template +winsock_init_base::data winsock_init::data_; + +// Static variable to ensure that winsock is initialised before main, and +// therefore before any other threads can get started. +static const winsock_init<>& winsock_init_instance = winsock_init<>(false); + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/detail/impl/winsock_init.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) + +#endif // ASIO_DETAIL_WINSOCK_INIT_HPP diff --git a/tools/sdk/include/asio/asio/detail/work_dispatcher.hpp b/tools/sdk/include/asio/asio/detail/work_dispatcher.hpp new file mode 100644 index 00000000..7abce497 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/work_dispatcher.hpp @@ -0,0 +1,72 @@ +// +// detail/work_dispatcher.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WORK_DISPATCHER_HPP +#define ASIO_DETAIL_WORK_DISPATCHER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/associated_executor.hpp" +#include "asio/associated_allocator.hpp" +#include "asio/executor_work_guard.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class work_dispatcher +{ +public: + work_dispatcher(Handler& handler) + : work_((get_associated_executor)(handler)), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + work_dispatcher(const work_dispatcher& other) + : work_(other.work_), + handler_(other.handler_) + { + } + + work_dispatcher(work_dispatcher&& other) + : work_(ASIO_MOVE_CAST(executor_work_guard< + typename associated_executor::type>)(other.work_)), + handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()() + { + typename associated_allocator::type alloc( + (get_associated_allocator)(handler_)); + work_.get_executor().dispatch( + ASIO_MOVE_CAST(Handler)(handler_), alloc); + work_.reset(); + } + +private: + executor_work_guard::type> work_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WORK_DISPATCHER_HPP diff --git a/tools/sdk/include/asio/asio/detail/wrapped_handler.hpp b/tools/sdk/include/asio/asio/detail/wrapped_handler.hpp new file mode 100644 index 00000000..751f0ea8 --- /dev/null +++ b/tools/sdk/include/asio/asio/detail/wrapped_handler.hpp @@ -0,0 +1,291 @@ +// +// detail/wrapped_handler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DETAIL_WRAPPED_HANDLER_HPP +#define ASIO_DETAIL_WRAPPED_HANDLER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +struct is_continuation_delegated +{ + template + bool operator()(Dispatcher&, Handler& handler) const + { + return asio_handler_cont_helpers::is_continuation(handler); + } +}; + +struct is_continuation_if_running +{ + template + bool operator()(Dispatcher& dispatcher, Handler&) const + { + return dispatcher.running_in_this_thread(); + } +}; + +template +class wrapped_handler +{ +public: + typedef void result_type; + + wrapped_handler(Dispatcher dispatcher, Handler& handler) + : dispatcher_(dispatcher), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + wrapped_handler(const wrapped_handler& other) + : dispatcher_(other.dispatcher_), + handler_(other.handler_) + { + } + + wrapped_handler(wrapped_handler&& other) + : dispatcher_(other.dispatcher_), + handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()() + { + dispatcher_.dispatch(ASIO_MOVE_CAST(Handler)(handler_)); + } + + void operator()() const + { + dispatcher_.dispatch(handler_); + } + + template + void operator()(const Arg1& arg1) + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1)); + } + + template + void operator()(const Arg1& arg1) const + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2) + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2) const + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) const + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, + const Arg4& arg4) + { + dispatcher_.dispatch( + detail::bind_handler(handler_, arg1, arg2, arg3, arg4)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, + const Arg4& arg4) const + { + dispatcher_.dispatch( + detail::bind_handler(handler_, arg1, arg2, arg3, arg4)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, + const Arg4& arg4, const Arg5& arg5) + { + dispatcher_.dispatch( + detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, + const Arg4& arg4, const Arg5& arg5) const + { + dispatcher_.dispatch( + detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5)); + } + +//private: + Dispatcher dispatcher_; + Handler handler_; +}; + +template +class rewrapped_handler +{ +public: + explicit rewrapped_handler(Handler& handler, const Context& context) + : context_(context), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + } + + explicit rewrapped_handler(const Handler& handler, const Context& context) + : context_(context), + handler_(handler) + { + } + +#if defined(ASIO_HAS_MOVE) + rewrapped_handler(const rewrapped_handler& other) + : context_(other.context_), + handler_(other.handler_) + { + } + + rewrapped_handler(rewrapped_handler&& other) + : context_(ASIO_MOVE_CAST(Context)(other.context_)), + handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()() + { + handler_(); + } + + void operator()() const + { + handler_(); + } + +//private: + Context context_; + Handler handler_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + wrapped_handler* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + wrapped_handler* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline bool asio_handler_is_continuation( + wrapped_handler* this_handler) +{ + return IsContinuation()(this_handler->dispatcher_, this_handler->handler_); +} + +template +inline void asio_handler_invoke(Function& function, + wrapped_handler* this_handler) +{ + this_handler->dispatcher_.dispatch( + rewrapped_handler( + function, this_handler->handler_)); +} + +template +inline void asio_handler_invoke(const Function& function, + wrapped_handler* this_handler) +{ + this_handler->dispatcher_.dispatch( + rewrapped_handler( + function, this_handler->handler_)); +} + +template +inline void* asio_handler_allocate(std::size_t size, + rewrapped_handler* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->context_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + rewrapped_handler* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->context_); +} + +template +inline bool asio_handler_is_continuation( + rewrapped_handler* this_handler) +{ + return asio_handler_cont_helpers::is_continuation( + this_handler->context_); +} + +template +inline void asio_handler_invoke(Function& function, + rewrapped_handler* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->context_); +} + +template +inline void asio_handler_invoke(const Function& function, + rewrapped_handler* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->context_); +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WRAPPED_HANDLER_HPP diff --git a/tools/sdk/include/asio/asio/dispatch.hpp b/tools/sdk/include/asio/asio/dispatch.hpp new file mode 100644 index 00000000..b8dfd691 --- /dev/null +++ b/tools/sdk/include/asio/asio/dispatch.hpp @@ -0,0 +1,108 @@ +// +// dispatch.hpp +// ~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_DISPATCH_HPP +#define ASIO_DISPATCH_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/async_result.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/execution_context.hpp" +#include "asio/is_executor.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Submits a completion token or function object for execution. +/** + * This function submits an object for execution using the object's associated + * executor. The function object is queued for execution, and is never called + * from the current thread prior to returning from dispatch(). + * + * This function has the following effects: + * + * @li Constructs a function object handler of type @c Handler, initialized + * with handler(forward(token)). + * + * @li Constructs an object @c result of type async_result, + * initializing the object as result(handler). + * + * @li Obtains the handler's associated executor object @c ex by performing + * get_associated_executor(handler). + * + * @li Obtains the handler's associated allocator object @c alloc by performing + * get_associated_allocator(handler). + * + * @li Performs ex.dispatch(std::move(handler), alloc). + * + * @li Returns result.get(). + */ +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch( + ASIO_MOVE_ARG(CompletionToken) token); + +/// Submits a completion token or function object for execution. +/** + * This function submits an object for execution using the specified executor. + * The function object is queued for execution, and is never called from the + * current thread prior to returning from dispatch(). + * + * This function has the following effects: + * + * @li Constructs a function object handler of type @c Handler, initialized + * with handler(forward(token)). + * + * @li Constructs an object @c result of type async_result, + * initializing the object as result(handler). + * + * @li Obtains the handler's associated executor object @c ex1 by performing + * get_associated_executor(handler). + * + * @li Creates a work object @c w by performing make_work(ex1). + * + * @li Obtains the handler's associated allocator object @c alloc by performing + * get_associated_allocator(handler). + * + * @li Constructs a function object @c f with a function call operator that + * performs ex1.dispatch(std::move(handler), alloc) followed by + * w.reset(). + * + * @li Performs Executor(ex).dispatch(std::move(f), alloc). + * + * @li Returns result.get(). + */ +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch( + const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token, + typename enable_if::value>::type* = 0); + +/// Submits a completion token or function object for execution. +/** + * @returns dispatch(ctx.get_executor(), + * forward(token)). + */ +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch( + ExecutionContext& ctx, ASIO_MOVE_ARG(CompletionToken) token, + typename enable_if::value>::type* = 0); + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/dispatch.hpp" + +#endif // ASIO_DISPATCH_HPP diff --git a/tools/sdk/include/asio/asio/error.hpp b/tools/sdk/include/asio/asio/error.hpp new file mode 100644 index 00000000..2be9bdee --- /dev/null +++ b/tools/sdk/include/asio/asio/error.hpp @@ -0,0 +1,356 @@ +// +// error.hpp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_ERROR_HPP +#define ASIO_ERROR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/error_code.hpp" +#include "asio/system_error.hpp" +#if defined(ASIO_WINDOWS) \ + || defined(__CYGWIN__) \ + || defined(ASIO_WINDOWS_RUNTIME) +# include +#else +# include +# include +#endif + +#if defined(GENERATING_DOCUMENTATION) +/// INTERNAL ONLY. +# define ASIO_NATIVE_ERROR(e) implementation_defined +/// INTERNAL ONLY. +# define ASIO_SOCKET_ERROR(e) implementation_defined +/// INTERNAL ONLY. +# define ASIO_NETDB_ERROR(e) implementation_defined +/// INTERNAL ONLY. +# define ASIO_GETADDRINFO_ERROR(e) implementation_defined +/// INTERNAL ONLY. +# define ASIO_WIN_OR_POSIX(e_win, e_posix) implementation_defined +#elif defined(ASIO_WINDOWS_RUNTIME) +# define ASIO_NATIVE_ERROR(e) __HRESULT_FROM_WIN32(e) +# define ASIO_SOCKET_ERROR(e) __HRESULT_FROM_WIN32(WSA ## e) +# define ASIO_NETDB_ERROR(e) __HRESULT_FROM_WIN32(WSA ## e) +# define ASIO_GETADDRINFO_ERROR(e) __HRESULT_FROM_WIN32(WSA ## e) +# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_win +#elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) +# define ASIO_NATIVE_ERROR(e) e +# define ASIO_SOCKET_ERROR(e) WSA ## e +# define ASIO_NETDB_ERROR(e) WSA ## e +# define ASIO_GETADDRINFO_ERROR(e) WSA ## e +# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_win +#else +# define ASIO_NATIVE_ERROR(e) e +# define ASIO_SOCKET_ERROR(e) e +# define ASIO_NETDB_ERROR(e) e +# define ASIO_GETADDRINFO_ERROR(e) e +# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix +#endif + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace error { + +enum basic_errors +{ + /// Permission denied. + access_denied = ASIO_SOCKET_ERROR(EACCES), + + /// Address family not supported by protocol. + address_family_not_supported = ASIO_SOCKET_ERROR(EAFNOSUPPORT), + + /// Address already in use. + address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE), + + /// Transport endpoint is already connected. + already_connected = ASIO_SOCKET_ERROR(EISCONN), + + /// Operation already in progress. + already_started = ASIO_SOCKET_ERROR(EALREADY), + + /// Broken pipe. + broken_pipe = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(ERROR_BROKEN_PIPE), + ASIO_NATIVE_ERROR(EPIPE)), + + /// A connection has been aborted. + connection_aborted = ASIO_SOCKET_ERROR(ECONNABORTED), + + /// Connection refused. + connection_refused = ASIO_SOCKET_ERROR(ECONNREFUSED), + + /// Connection reset by peer. + connection_reset = ASIO_SOCKET_ERROR(ECONNRESET), + + /// Bad file descriptor. + bad_descriptor = ASIO_SOCKET_ERROR(EBADF), + + /// Bad address. + fault = ASIO_SOCKET_ERROR(EFAULT), + + /// No route to host. + host_unreachable = ASIO_SOCKET_ERROR(EHOSTUNREACH), + + /// Operation now in progress. + in_progress = ASIO_SOCKET_ERROR(EINPROGRESS), + + /// Interrupted system call. + interrupted = ASIO_SOCKET_ERROR(EINTR), + + /// Invalid argument. + invalid_argument = ASIO_SOCKET_ERROR(EINVAL), + + /// Message too long. + message_size = ASIO_SOCKET_ERROR(EMSGSIZE), + + /// The name was too long. + name_too_long = ASIO_SOCKET_ERROR(ENAMETOOLONG), + + /// Network is down. + network_down = ASIO_SOCKET_ERROR(ENETDOWN), + + /// Network dropped connection on reset. + network_reset = ASIO_SOCKET_ERROR(ENETRESET), + + /// Network is unreachable. + network_unreachable = ASIO_SOCKET_ERROR(ENETUNREACH), + + /// Too many open files. + no_descriptors = ASIO_SOCKET_ERROR(EMFILE), + + /// No buffer space available. + no_buffer_space = ASIO_SOCKET_ERROR(ENOBUFS), + + /// Cannot allocate memory. + no_memory = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(ERROR_OUTOFMEMORY), + ASIO_NATIVE_ERROR(ENOMEM)), + + /// Operation not permitted. + no_permission = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(ERROR_ACCESS_DENIED), + ASIO_NATIVE_ERROR(EPERM)), + + /// Protocol not available. + no_protocol_option = ASIO_SOCKET_ERROR(ENOPROTOOPT), + + /// No such device. + no_such_device = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(ERROR_BAD_UNIT), + ASIO_NATIVE_ERROR(ENODEV)), + + /// Transport endpoint is not connected. + not_connected = ASIO_SOCKET_ERROR(ENOTCONN), + + /// Socket operation on non-socket. + not_socket = ASIO_SOCKET_ERROR(ENOTSOCK), + + /// Operation cancelled. + operation_aborted = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(ERROR_OPERATION_ABORTED), + ASIO_NATIVE_ERROR(ECANCELED)), + + /// Operation not supported. + operation_not_supported = ASIO_SOCKET_ERROR(EOPNOTSUPP), + + /// Cannot send after transport endpoint shutdown. + shut_down = ASIO_SOCKET_ERROR(ESHUTDOWN), + + /// Connection timed out. + timed_out = ASIO_SOCKET_ERROR(ETIMEDOUT), + + /// Resource temporarily unavailable. + try_again = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(ERROR_RETRY), + ASIO_NATIVE_ERROR(EAGAIN)), + + /// The socket is marked non-blocking and the requested operation would block. + would_block = ASIO_SOCKET_ERROR(EWOULDBLOCK) +}; + +enum netdb_errors +{ + /// Host not found (authoritative). + host_not_found = ASIO_NETDB_ERROR(HOST_NOT_FOUND), + + /// Host not found (non-authoritative). + host_not_found_try_again = ASIO_NETDB_ERROR(TRY_AGAIN), + + /// The query is valid but does not have associated address data. + no_data = ASIO_NETDB_ERROR(NO_DATA), + + /// A non-recoverable error occurred. + no_recovery = ASIO_NETDB_ERROR(NO_RECOVERY) +}; + +enum addrinfo_errors +{ + /// The service is not supported for the given socket type. + service_not_found = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(WSATYPE_NOT_FOUND), + ASIO_GETADDRINFO_ERROR(EAI_SERVICE)), + + /// The socket type is not supported. + socket_type_not_supported = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(WSAESOCKTNOSUPPORT), + ASIO_GETADDRINFO_ERROR(EAI_SOCKTYPE)) +}; + +enum misc_errors +{ + /// Already open. + already_open = 1, + + /// End of file or stream. + eof, + + /// Element not found. + not_found, + + /// The descriptor cannot fit into the select system call's fd_set. + fd_set_failure +}; + +inline const asio::error_category& get_system_category() +{ + return asio::system_category(); +} + +#if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) + +extern ASIO_DECL +const asio::error_category& get_netdb_category(); + +extern ASIO_DECL +const asio::error_category& get_addrinfo_category(); + +#else // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) + +inline const asio::error_category& get_netdb_category() +{ + return get_system_category(); +} + +inline const asio::error_category& get_addrinfo_category() +{ + return get_system_category(); +} + +#endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) + +extern ASIO_DECL +const asio::error_category& get_misc_category(); + +static const asio::error_category& + system_category ASIO_UNUSED_VARIABLE + = asio::error::get_system_category(); +static const asio::error_category& + netdb_category ASIO_UNUSED_VARIABLE + = asio::error::get_netdb_category(); +static const asio::error_category& + addrinfo_category ASIO_UNUSED_VARIABLE + = asio::error::get_addrinfo_category(); +static const asio::error_category& + misc_category ASIO_UNUSED_VARIABLE + = asio::error::get_misc_category(); + +} // namespace error +} // namespace asio + +#if defined(ASIO_HAS_STD_SYSTEM_ERROR) +namespace std { + +template<> struct is_error_code_enum +{ + static const bool value = true; +}; + +template<> struct is_error_code_enum +{ + static const bool value = true; +}; + +template<> struct is_error_code_enum +{ + static const bool value = true; +}; + +template<> struct is_error_code_enum +{ + static const bool value = true; +}; + +} // namespace std +#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) + +namespace asio { +namespace error { + +inline asio::error_code make_error_code(basic_errors e) +{ + return asio::error_code( + static_cast(e), get_system_category()); +} + +inline asio::error_code make_error_code(netdb_errors e) +{ + return asio::error_code( + static_cast(e), get_netdb_category()); +} + +inline asio::error_code make_error_code(addrinfo_errors e) +{ + return asio::error_code( + static_cast(e), get_addrinfo_category()); +} + +inline asio::error_code make_error_code(misc_errors e) +{ + return asio::error_code( + static_cast(e), get_misc_category()); +} + +} // namespace error +namespace stream_errc { + // Simulates the proposed stream_errc scoped enum. + using error::eof; + using error::not_found; +} // namespace stream_errc +namespace socket_errc { + // Simulates the proposed socket_errc scoped enum. + using error::already_open; + using error::not_found; +} // namespace socket_errc +namespace resolver_errc { + // Simulates the proposed resolver_errc scoped enum. + using error::host_not_found; + const error::netdb_errors try_again = error::host_not_found_try_again; + using error::service_not_found; +} // namespace resolver_errc +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#undef ASIO_NATIVE_ERROR +#undef ASIO_SOCKET_ERROR +#undef ASIO_NETDB_ERROR +#undef ASIO_GETADDRINFO_ERROR +#undef ASIO_WIN_OR_POSIX + +#if defined(ASIO_HEADER_ONLY) +# include "asio/impl/error.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_ERROR_HPP diff --git a/tools/sdk/include/asio/asio/error_code.hpp b/tools/sdk/include/asio/asio/error_code.hpp new file mode 100644 index 00000000..042ab853 --- /dev/null +++ b/tools/sdk/include/asio/asio/error_code.hpp @@ -0,0 +1,206 @@ +// +// error_code.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_ERROR_CODE_HPP +#define ASIO_ERROR_CODE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#ifdef ESP_PLATFORM +# include "lwip/sockets.h" +#endif + +#if defined(ASIO_HAS_STD_SYSTEM_ERROR) +# include +#else // defined(ASIO_HAS_STD_SYSTEM_ERROR) +# include +# include "asio/detail/noncopyable.hpp" +# if !defined(ASIO_NO_IOSTREAM) +# include +# endif // !defined(ASIO_NO_IOSTREAM) +#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +#if defined(ASIO_HAS_STD_SYSTEM_ERROR) + +typedef std::error_category error_category; + +#else // defined(ASIO_HAS_STD_SYSTEM_ERROR) + +/// Base class for all error categories. +class error_category : private noncopyable +{ +public: + /// Destructor. + virtual ~error_category() + { + } + + /// Returns a string naming the error gategory. + virtual const char* name() const = 0; + + /// Returns a string describing the error denoted by @c value. + virtual std::string message(int value) const = 0; + + /// Equality operator to compare two error categories. + bool operator==(const error_category& rhs) const + { + return this == &rhs; + } + + /// Inequality operator to compare two error categories. + bool operator!=(const error_category& rhs) const + { + return !(*this == rhs); + } +}; + +#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) + +/// Returns the error category used for the system errors produced by asio. +extern ASIO_DECL const error_category& system_category(); + +#if defined(ASIO_HAS_STD_SYSTEM_ERROR) + +typedef std::error_code error_code; + +#else // defined(ASIO_HAS_STD_SYSTEM_ERROR) + +/// Class to represent an error code value. +class error_code +{ +public: + /// Default constructor. + error_code() + : value_(0), + category_(&system_category()) + { + } + + /// Construct with specific error code and category. + error_code(int v, const error_category& c) + : value_(v), + category_(&c) + { + } + + /// Construct from an error code enum. + template + error_code(ErrorEnum e) + { + *this = make_error_code(e); + } + + /// Clear the error value to the default. + void clear() + { + value_ = 0; + category_ = &system_category(); + } + + /// Assign a new error value. + void assign(int v, const error_category& c) + { + value_ = v; + category_ = &c; + } + + /// Get the error value. + int value() const + { + return value_; + } + + /// Get the error category. + const error_category& category() const + { + return *category_; + } + + /// Get the message associated with the error. + std::string message() const + { + return category_->message(value_); + } + + struct unspecified_bool_type_t + { + }; + + typedef void (*unspecified_bool_type)(unspecified_bool_type_t); + + static void unspecified_bool_true(unspecified_bool_type_t) {} + + /// Operator returns non-null if there is a non-success error code. + operator unspecified_bool_type() const + { + if (value_ == 0) + return 0; + else + return &error_code::unspecified_bool_true; + } + + /// Operator to test if the error represents success. + bool operator!() const + { + return value_ == 0; + } + + /// Equality operator to compare two error objects. + friend bool operator==(const error_code& e1, const error_code& e2) + { + return e1.value_ == e2.value_ && e1.category_ == e2.category_; + } + + /// Inequality operator to compare two error objects. + friend bool operator!=(const error_code& e1, const error_code& e2) + { + return e1.value_ != e2.value_ || e1.category_ != e2.category_; + } + +private: + // The value associated with the error code. + int value_; + + // The category associated with the error code. + const error_category* category_; +}; + +# if !defined(ASIO_NO_IOSTREAM) + +/// Output an error code. +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const error_code& ec) +{ + os << ec.category().name() << ':' << ec.value(); + return os; +} + +# endif // !defined(ASIO_NO_IOSTREAM) + +#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/impl/error_code.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_ERROR_CODE_HPP diff --git a/tools/sdk/include/asio/asio/execution_context.hpp b/tools/sdk/include/asio/asio/execution_context.hpp new file mode 100644 index 00000000..1476d19b --- /dev/null +++ b/tools/sdk/include/asio/asio/execution_context.hpp @@ -0,0 +1,411 @@ +// +// execution_context.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_EXECUTION_CONTEXT_HPP +#define ASIO_EXECUTION_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include +#include +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/variadic_templates.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +class execution_context; +class io_context; + +#if !defined(GENERATING_DOCUMENTATION) +template Service& use_service(execution_context&); +template Service& use_service(io_context&); +template void add_service(execution_context&, Service*); +template bool has_service(execution_context&); +#endif // !defined(GENERATING_DOCUMENTATION) + +namespace detail { class service_registry; } + +/// A context for function object execution. +/** + * An execution context represents a place where function objects will be + * executed. An @c io_context is an example of an execution context. + * + * @par The execution_context class and services + * + * Class execution_context implements an extensible, type-safe, polymorphic set + * of services, indexed by service type. + * + * Services exist to manage the resources that are shared across an execution + * context. For example, timers may be implemented in terms of a single timer + * queue, and this queue would be stored in a service. + * + * Access to the services of an execution_context is via three function + * templates, use_service(), add_service() and has_service(). + * + * In a call to @c use_service(), the type argument chooses a service, + * making available all members of the named type. If @c Service is not present + * in an execution_context, an object of type @c Service is created and added + * to the execution_context. A C++ program can check if an execution_context + * implements a particular service with the function template @c + * has_service(). + * + * Service objects may be explicitly added to an execution_context using the + * function template @c add_service(). If the @c Service is already + * present, the service_already_exists exception is thrown. If the owner of the + * service is not the same object as the execution_context parameter, the + * invalid_service_owner exception is thrown. + * + * Once a service reference is obtained from an execution_context object by + * calling use_service(), that reference remains usable as long as the owning + * execution_context object exists. + * + * All service implementations have execution_context::service as a public base + * class. Custom services may be implemented by deriving from this class and + * then added to an execution_context using the facilities described above. + * + * @par The execution_context as a base class + * + * Class execution_context may be used only as a base class for concrete + * execution context types. The @c io_context is an example of such a derived + * type. + * + * On destruction, a class that is derived from execution_context must perform + * execution_context::shutdown() followed by + * execution_context::destroy(). + * + * This destruction sequence permits programs to simplify their resource + * management by using @c shared_ptr<>. Where an object's lifetime is tied to + * the lifetime of a connection (or some other sequence of asynchronous + * operations), a @c shared_ptr to the object would be bound into the handlers + * for all asynchronous operations associated with it. This works as follows: + * + * @li When a single connection ends, all associated asynchronous operations + * complete. The corresponding handler objects are destroyed, and all @c + * shared_ptr references to the objects are destroyed. + * + * @li To shut down the whole program, the io_context function stop() is called + * to terminate any run() calls as soon as possible. The io_context destructor + * calls @c shutdown() and @c destroy() to destroy all pending handlers, + * causing all @c shared_ptr references to all connection objects to be + * destroyed. + */ +class execution_context + : private noncopyable +{ +public: + class id; + class service; + +protected: + /// Constructor. + ASIO_DECL execution_context(); + + /// Destructor. + ASIO_DECL ~execution_context(); + + /// Shuts down all services in the context. + /** + * This function is implemented as follows: + * + * @li For each service object @c svc in the execution_context set, in + * reverse order of the beginning of service object lifetime, performs @c + * svc->shutdown(). + */ + ASIO_DECL void shutdown(); + + /// Destroys all services in the context. + /** + * This function is implemented as follows: + * + * @li For each service object @c svc in the execution_context set, in + * reverse order * of the beginning of service object lifetime, performs + * delete static_cast(svc). + */ + ASIO_DECL void destroy(); + +public: + /// Fork-related event notifications. + enum fork_event + { + /// Notify the context that the process is about to fork. + fork_prepare, + + /// Notify the context that the process has forked and is the parent. + fork_parent, + + /// Notify the context that the process has forked and is the child. + fork_child + }; + + /// Notify the execution_context of a fork-related event. + /** + * This function is used to inform the execution_context that the process is + * about to fork, or has just forked. This allows the execution_context, and + * the services it contains, to perform any necessary housekeeping to ensure + * correct operation following a fork. + * + * This function must not be called while any other execution_context + * function, or any function associated with the execution_context's derived + * class, is being called in another thread. It is, however, safe to call + * this function from within a completion handler, provided no other thread + * is accessing the execution_context or its derived class. + * + * @param event A fork-related event. + * + * @throws asio::system_error Thrown on failure. If the notification + * fails the execution_context object should no longer be used and should be + * destroyed. + * + * @par Example + * The following code illustrates how to incorporate the notify_fork() + * function: + * @code my_execution_context.notify_fork(execution_context::fork_prepare); + * if (fork() == 0) + * { + * // This is the child process. + * my_execution_context.notify_fork(execution_context::fork_child); + * } + * else + * { + * // This is the parent process. + * my_execution_context.notify_fork(execution_context::fork_parent); + * } @endcode + * + * @note For each service object @c svc in the execution_context set, + * performs svc->notify_fork();. When processing the fork_prepare + * event, services are visited in reverse order of the beginning of service + * object lifetime. Otherwise, services are visited in order of the beginning + * of service object lifetime. + */ + ASIO_DECL void notify_fork(fork_event event); + + /// Obtain the service object corresponding to the given type. + /** + * This function is used to locate a service object that corresponds to the + * given service type. If there is no existing implementation of the service, + * then the execution_context will create a new instance of the service. + * + * @param e The execution_context object that owns the service. + * + * @return The service interface implementing the specified service type. + * Ownership of the service interface is not transferred to the caller. + */ + template + friend Service& use_service(execution_context& e); + + /// Obtain the service object corresponding to the given type. + /** + * This function is used to locate a service object that corresponds to the + * given service type. If there is no existing implementation of the service, + * then the io_context will create a new instance of the service. + * + * @param ioc The io_context object that owns the service. + * + * @return The service interface implementing the specified service type. + * Ownership of the service interface is not transferred to the caller. + * + * @note This overload is preserved for backwards compatibility with services + * that inherit from io_context::service. + */ + template + friend Service& use_service(io_context& ioc); + +#if defined(GENERATING_DOCUMENTATION) + + /// Creates a service object and adds it to the execution_context. + /** + * This function is used to add a service to the execution_context. + * + * @param e The execution_context object that owns the service. + * + * @param args Zero or more arguments to be passed to the service + * constructor. + * + * @throws asio::service_already_exists Thrown if a service of the + * given type is already present in the execution_context. + */ + template + friend Service& make_service(execution_context& e, Args&&... args); + +#elif defined(ASIO_HAS_VARIADIC_TEMPLATES) + + template + friend Service& make_service(execution_context& e, + ASIO_MOVE_ARG(Args)... args); + +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + + template + friend Service& make_service(execution_context& e); + +#define ASIO_PRIVATE_MAKE_SERVICE_DEF(n) \ + template \ + friend Service& make_service(execution_context& e, \ + ASIO_VARIADIC_MOVE_PARAMS(n)); \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_MAKE_SERVICE_DEF) +#undef ASIO_PRIVATE_MAKE_SERVICE_DEF + +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) + + /// (Deprecated: Use make_service().) Add a service object to the + /// execution_context. + /** + * This function is used to add a service to the execution_context. + * + * @param e The execution_context object that owns the service. + * + * @param svc The service object. On success, ownership of the service object + * is transferred to the execution_context. When the execution_context object + * is destroyed, it will destroy the service object by performing: @code + * delete static_cast(svc) @endcode + * + * @throws asio::service_already_exists Thrown if a service of the + * given type is already present in the execution_context. + * + * @throws asio::invalid_service_owner Thrown if the service's owning + * execution_context is not the execution_context object specified by the + * @c e parameter. + */ + template + friend void add_service(execution_context& e, Service* svc); + + /// Determine if an execution_context contains a specified service type. + /** + * This function is used to determine whether the execution_context contains a + * service object corresponding to the given service type. + * + * @param e The execution_context object that owns the service. + * + * @return A boolean indicating whether the execution_context contains the + * service. + */ + template + friend bool has_service(execution_context& e); + +private: + // The service registry. + asio::detail::service_registry* service_registry_; +}; + +/// Class used to uniquely identify a service. +class execution_context::id + : private noncopyable +{ +public: + /// Constructor. + id() {} +}; + +/// Base class for all io_context services. +class execution_context::service + : private noncopyable +{ +public: + /// Get the context object that owns the service. + execution_context& context(); + +protected: + /// Constructor. + /** + * @param owner The execution_context object that owns the service. + */ + ASIO_DECL service(execution_context& owner); + + /// Destructor. + ASIO_DECL virtual ~service(); + +private: + /// Destroy all user-defined handler objects owned by the service. + virtual void shutdown() = 0; + + /// Handle notification of a fork-related event to perform any necessary + /// housekeeping. + /** + * This function is not a pure virtual so that services only have to + * implement it if necessary. The default implementation does nothing. + */ + ASIO_DECL virtual void notify_fork( + execution_context::fork_event event); + + friend class asio::detail::service_registry; + struct key + { + key() : type_info_(0), id_(0) {} + const std::type_info* type_info_; + const execution_context::id* id_; + } key_; + + execution_context& owner_; + service* next_; +}; + +/// Exception thrown when trying to add a duplicate service to an +/// execution_context. +class service_already_exists + : public std::logic_error +{ +public: + ASIO_DECL service_already_exists(); +}; + +/// Exception thrown when trying to add a service object to an +/// execution_context where the service has a different owner. +class invalid_service_owner + : public std::logic_error +{ +public: + ASIO_DECL invalid_service_owner(); +}; + +namespace detail { + +// Special derived service id type to keep classes header-file only. +template +class service_id + : public execution_context::id +{ +}; + +// Special service base class to keep classes header-file only. +template +class execution_context_service_base + : public execution_context::service +{ +public: + static service_id id; + + // Constructor. + execution_context_service_base(execution_context& e) + : execution_context::service(e) + { + } +}; + +template +service_id execution_context_service_base::id; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/execution_context.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/impl/execution_context.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_EXECUTION_CONTEXT_HPP diff --git a/tools/sdk/include/asio/asio/executor.hpp b/tools/sdk/include/asio/asio/executor.hpp new file mode 100644 index 00000000..e552cfbf --- /dev/null +++ b/tools/sdk/include/asio/asio/executor.hpp @@ -0,0 +1,341 @@ +// +// executor.hpp +// ~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_EXECUTOR_HPP +#define ASIO_EXECUTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/detail/cstddef.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/execution_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Exception thrown when trying to access an empty polymorphic executor. +class bad_executor + : public std::exception +{ +public: + /// Constructor. + ASIO_DECL bad_executor() ASIO_NOEXCEPT; + + /// Obtain message associated with exception. + ASIO_DECL virtual const char* what() const + ASIO_NOEXCEPT_OR_NOTHROW; +}; + +/// Polymorphic wrapper for executors. +class executor +{ +public: + /// Default constructor. + executor() ASIO_NOEXCEPT + : impl_(0) + { + } + + /// Construct from nullptr. + executor(nullptr_t) ASIO_NOEXCEPT + : impl_(0) + { + } + + /// Copy constructor. + executor(const executor& other) ASIO_NOEXCEPT + : impl_(other.clone()) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move constructor. + executor(executor&& other) ASIO_NOEXCEPT + : impl_(other.impl_) + { + other.impl_ = 0; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Construct a polymorphic wrapper for the specified executor. + template + executor(Executor e); + + /// Allocator-aware constructor to create a polymorphic wrapper for the + /// specified executor. + template + executor(allocator_arg_t, const Allocator& a, Executor e); + + /// Destructor. + ~executor() + { + destroy(); + } + + /// Assignment operator. + executor& operator=(const executor& other) ASIO_NOEXCEPT + { + destroy(); + impl_ = other.clone(); + return *this; + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + // Move assignment operator. + executor& operator=(executor&& other) ASIO_NOEXCEPT + { + destroy(); + impl_ = other.impl_; + other.impl_ = 0; + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Assignment operator for nullptr_t. + executor& operator=(nullptr_t) ASIO_NOEXCEPT + { + destroy(); + impl_ = 0; + return *this; + } + + /// Assignment operator to create a polymorphic wrapper for the specified + /// executor. + template + executor& operator=(ASIO_MOVE_ARG(Executor) e) ASIO_NOEXCEPT + { + executor tmp(ASIO_MOVE_CAST(Executor)(e)); + destroy(); + impl_ = tmp.impl_; + tmp.impl_ = 0; + return *this; + } + + /// Obtain the underlying execution context. + execution_context& context() const ASIO_NOEXCEPT + { + return get_impl()->context(); + } + + /// Inform the executor that it has some outstanding work to do. + void on_work_started() const ASIO_NOEXCEPT + { + get_impl()->on_work_started(); + } + + /// Inform the executor that some work is no longer outstanding. + void on_work_finished() const ASIO_NOEXCEPT + { + get_impl()->on_work_finished(); + } + + /// Request the executor to invoke the given function object. + /** + * This function is used to ask the executor to execute the given function + * object. The function object is executed according to the rules of the + * target executor object. + * + * @param f The function object to be called. The executor will make a copy + * of the handler object as required. The function signature of the function + * object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; + + /// Request the executor to invoke the given function object. + /** + * This function is used to ask the executor to execute the given function + * object. The function object is executed according to the rules of the + * target executor object. + * + * @param f The function object to be called. The executor will make + * a copy of the handler object as required. The function signature of the + * function object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; + + /// Request the executor to invoke the given function object. + /** + * This function is used to ask the executor to execute the given function + * object. The function object is executed according to the rules of the + * target executor object. + * + * @param f The function object to be called. The executor will make + * a copy of the handler object as required. The function signature of the + * function object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; + + struct unspecified_bool_type_t {}; + typedef void (*unspecified_bool_type)(unspecified_bool_type_t); + static void unspecified_bool_true(unspecified_bool_type_t) {} + + /// Operator to test if the executor contains a valid target. + operator unspecified_bool_type() const ASIO_NOEXCEPT + { + return impl_ ? &executor::unspecified_bool_true : 0; + } + + /// Obtain type information for the target executor object. + /** + * @returns If @c *this has a target type of type @c T, typeid(T); + * otherwise, typeid(void). + */ +#if !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION) + const std::type_info& target_type() const ASIO_NOEXCEPT + { + return impl_ ? impl_->target_type() : typeid(void); + } +#else // !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION) + const void* target_type() const ASIO_NOEXCEPT + { + return impl_ ? impl_->target_type() : 0; + } +#endif // !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION) + + /// Obtain a pointer to the target executor object. + /** + * @returns If target_type() == typeid(T), a pointer to the stored + * executor target; otherwise, a null pointer. + */ + template + Executor* target() ASIO_NOEXCEPT; + + /// Obtain a pointer to the target executor object. + /** + * @returns If target_type() == typeid(T), a pointer to the stored + * executor target; otherwise, a null pointer. + */ + template + const Executor* target() const ASIO_NOEXCEPT; + + /// Compare two executors for equality. + friend bool operator==(const executor& a, + const executor& b) ASIO_NOEXCEPT + { + if (a.impl_ == b.impl_) + return true; + if (!a.impl_ || !b.impl_) + return false; + return a.impl_->equals(b.impl_); + } + + /// Compare two executors for inequality. + friend bool operator!=(const executor& a, + const executor& b) ASIO_NOEXCEPT + { + return !(a == b); + } + +private: +#if !defined(GENERATING_DOCUMENTATION) + class function; + template class impl; + +#if !defined(ASIO_NO_TYPEID) + typedef const std::type_info& type_id_result_type; +#else // !defined(ASIO_NO_TYPEID) + typedef const void* type_id_result_type; +#endif // !defined(ASIO_NO_TYPEID) + + template + static type_id_result_type type_id() + { +#if !defined(ASIO_NO_TYPEID) + return typeid(T); +#else // !defined(ASIO_NO_TYPEID) + static int unique_id; + return &unique_id; +#endif // !defined(ASIO_NO_TYPEID) + } + + // Base class for all polymorphic executor implementations. + class impl_base + { + public: + virtual impl_base* clone() const ASIO_NOEXCEPT = 0; + virtual void destroy() ASIO_NOEXCEPT = 0; + virtual execution_context& context() ASIO_NOEXCEPT = 0; + virtual void on_work_started() ASIO_NOEXCEPT = 0; + virtual void on_work_finished() ASIO_NOEXCEPT = 0; + virtual void dispatch(ASIO_MOVE_ARG(function)) = 0; + virtual void post(ASIO_MOVE_ARG(function)) = 0; + virtual void defer(ASIO_MOVE_ARG(function)) = 0; + virtual type_id_result_type target_type() const ASIO_NOEXCEPT = 0; + virtual void* target() ASIO_NOEXCEPT = 0; + virtual const void* target() const ASIO_NOEXCEPT = 0; + virtual bool equals(const impl_base* e) const ASIO_NOEXCEPT = 0; + + protected: + impl_base(bool fast_dispatch) : fast_dispatch_(fast_dispatch) {} + virtual ~impl_base() {} + + private: + friend class executor; + const bool fast_dispatch_; + }; + + // Helper function to check and return the implementation pointer. + impl_base* get_impl() const + { + if (!impl_) + { + bad_executor ex; + asio::detail::throw_exception(ex); + } + return impl_; + } + + // Helper function to clone another implementation. + impl_base* clone() const ASIO_NOEXCEPT + { + return impl_ ? impl_->clone() : 0; + } + + // Helper function to destroy an implementation. + void destroy() ASIO_NOEXCEPT + { + if (impl_) + impl_->destroy(); + } + + impl_base* impl_; +#endif // !defined(GENERATING_DOCUMENTATION) +}; + +} // namespace asio + +ASIO_USES_ALLOCATOR(asio::executor) + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/executor.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/impl/executor.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_EXECUTOR_HPP diff --git a/tools/sdk/include/asio/asio/executor_work_guard.hpp b/tools/sdk/include/asio/asio/executor_work_guard.hpp new file mode 100644 index 00000000..1875f542 --- /dev/null +++ b/tools/sdk/include/asio/asio/executor_work_guard.hpp @@ -0,0 +1,170 @@ +// +// executor_work_guard.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_EXECUTOR_WORK_GUARD_HPP +#define ASIO_EXECUTOR_WORK_GUARD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/associated_executor.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/is_executor.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// An object of type @c executor_work_guard controls ownership of executor work +/// within a scope. +template +class executor_work_guard +{ +public: + /// The underlying executor type. + typedef Executor executor_type; + + /// Constructs a @c executor_work_guard object for the specified executor. + /** + * Stores a copy of @c e and calls on_work_started() on it. + */ + explicit executor_work_guard(const executor_type& e) ASIO_NOEXCEPT + : executor_(e), + owns_(true) + { + executor_.on_work_started(); + } + + /// Copy constructor. + executor_work_guard(const executor_work_guard& other) ASIO_NOEXCEPT + : executor_(other.executor_), + owns_(other.owns_) + { + if (owns_) + executor_.on_work_started(); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move constructor. + executor_work_guard(executor_work_guard&& other) + : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)), + owns_(other.owns_) + { + other.owns_ = false; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destructor. + /** + * Unless the object has already been reset, or is in a moved-from state, + * calls on_work_finished() on the stored executor. + */ + ~executor_work_guard() + { + if (owns_) + executor_.on_work_finished(); + } + + /// Obtain the associated executor. + executor_type get_executor() const ASIO_NOEXCEPT + { + return executor_; + } + + /// Whether the executor_work_guard object owns some outstanding work. + bool owns_work() const ASIO_NOEXCEPT + { + return owns_; + } + + /// Indicate that the work is no longer outstanding. + /* + * Unless the object has already been reset, or is in a moved-from state, + * calls on_work_finished() on the stored executor. + */ + void reset() ASIO_NOEXCEPT + { + if (owns_) + { + executor_.on_work_finished(); + owns_ = false; + } + } + +private: + // Disallow assignment. + executor_work_guard& operator=(const executor_work_guard&); + + executor_type executor_; + bool owns_; +}; + +/// Create an @ref executor_work_guard object. +template +inline executor_work_guard make_work_guard(const Executor& ex, + typename enable_if::value>::type* = 0) +{ + return executor_work_guard(ex); +} + +/// Create an @ref executor_work_guard object. +template +inline executor_work_guard +make_work_guard(ExecutionContext& ctx, + typename enable_if< + is_convertible::value>::type* = 0) +{ + return executor_work_guard( + ctx.get_executor()); +} + +/// Create an @ref executor_work_guard object. +template +inline executor_work_guard::type> +make_work_guard(const T& t, + typename enable_if::value && + !is_convertible::value>::type* = 0) +{ + return executor_work_guard::type>( + associated_executor::get(t)); +} + +/// Create an @ref executor_work_guard object. +template +inline executor_work_guard::type> +make_work_guard(const T& t, const Executor& ex, + typename enable_if::value>::type* = 0) +{ + return executor_work_guard::type>( + associated_executor::get(t, ex)); +} + +/// Create an @ref executor_work_guard object. +template +inline executor_work_guard::type> +make_work_guard(const T& t, ExecutionContext& ctx, + typename enable_if::value && + !is_convertible::value && + is_convertible::value>::type* = 0) +{ + return executor_work_guard::type>( + associated_executor::get( + t, ctx.get_executor())); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_EXECUTOR_WORK_GUARD_HPP diff --git a/tools/sdk/include/asio/asio/experimental.hpp b/tools/sdk/include/asio/asio/experimental.hpp new file mode 100644 index 00000000..5765c37d --- /dev/null +++ b/tools/sdk/include/asio/asio/experimental.hpp @@ -0,0 +1,22 @@ +// +// experimental.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_EXPERIMENTAL_HPP +#define ASIO_EXPERIMENTAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/experimental/co_spawn.hpp" +#include "asio/experimental/detached.hpp" +#include "asio/experimental/redirect_error.hpp" + +#endif // ASIO_EXPERIMENTAL_HPP diff --git a/tools/sdk/include/asio/asio/experimental/co_spawn.hpp b/tools/sdk/include/asio/asio/experimental/co_spawn.hpp new file mode 100644 index 00000000..cbf5bc52 --- /dev/null +++ b/tools/sdk/include/asio/asio/experimental/co_spawn.hpp @@ -0,0 +1,226 @@ +// +// experimental/co_spawn.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_EXPERIMENTAL_CO_SPAWN_HPP +#define ASIO_EXPERIMENTAL_CO_SPAWN_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/executor.hpp" +#include "asio/strand.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace experimental { +namespace detail { + +using std::experimental::coroutine_handle; + +template class awaiter; +template class awaitee_base; +template class awaitee; +template class await_handler_base; +template +auto co_spawn(const Executor& ex, F&& f, CompletionToken&& token); + +} // namespace detail + +namespace this_coro { + +/// Awaitable type that returns a completion token for the current coroutine. +struct token_t {}; + +/// Awaitable object that returns a completion token for the current coroutine. +constexpr inline token_t token() { return {}; } + +/// Awaitable type that returns the executor of the current coroutine. +struct executor_t {}; + +/// Awaitable object that returns the executor of the current coroutine. +constexpr inline executor_t executor() { return {}; } + +} // namespace this_coro + +/// A completion token that represents the currently executing coroutine. +/** + * The await_token class is used to represent the currently executing + * coroutine. An await_token may be passed as a handler to an asynchronous + * operation. For example: + * + * @code awaitable my_coroutine() + * { + * await_token token = co_await this_coro::token(); + * ... + * std::size_t n = co_await my_socket.async_read_some(buffer, token); + * ... + * } @endcode + * + * The initiating function (async_read_some in the above example) suspends the + * current coroutine. The coroutine is resumed when the asynchronous operation + * completes, and the result of the operation is returned. + */ +template +class await_token +{ +public: + /// The associated executor type. + typedef Executor executor_type; + + /// Copy constructor. + await_token(const await_token& other) noexcept + : awaiter_(other.awaiter_) + { + } + + /// Move constructor. + await_token(await_token&& other) noexcept + : awaiter_(std::exchange(other.awaiter_, nullptr)) + { + } + + /// Get the associated executor. + executor_type get_executor() const noexcept + { + return awaiter_->get_executor(); + } + +private: + // No assignment allowed. + await_token& operator=(const await_token&) = delete; + + template friend class detail::awaitee_base; + template friend class detail::await_handler_base; + + // Private constructor used by awaitee_base. + explicit await_token(detail::awaiter* a) + : awaiter_(a) + { + } + + detail::awaiter* awaiter_; +}; + +/// The return type of a coroutine or asynchronous operation. +template > +class awaitable +{ +public: + /// The type of the awaited value. + typedef T value_type; + + /// The executor type that will be used for the coroutine. + typedef Executor executor_type; + + /// Move constructor. + awaitable(awaitable&& other) noexcept + : awaitee_(std::exchange(other.awaitee_, nullptr)) + { + } + + /// Destructor + ~awaitable() + { + if (awaitee_) + { + detail::coroutine_handle< + detail::awaitee>::from_promise( + *awaitee_).destroy(); + } + } + +#if !defined(GENERATING_DOCUMENTATION) + + // Support for co_await keyword. + bool await_ready() const noexcept + { + return awaitee_->ready(); + } + + // Support for co_await keyword. + void await_suspend(detail::coroutine_handle> h) + { + awaitee_->attach_caller(h); + } + + // Support for co_await keyword. + template + void await_suspend(detail::coroutine_handle> h) + { + awaitee_->attach_caller(h); + } + + // Support for co_await keyword. + T await_resume() + { + return awaitee_->get(); + } + +#endif // !defined(GENERATING_DOCUMENTATION) + +private: + template friend class detail::awaitee; + template friend class detail::await_handler_base; + + // Not copy constructible or copy assignable. + awaitable(const awaitable&) = delete; + awaitable& operator=(const awaitable&) = delete; + + // Construct the awaitable from a coroutine's promise object. + explicit awaitable(detail::awaitee* a) : awaitee_(a) {} + + detail::awaitee* awaitee_; +}; + +/// Spawn a new thread of execution. +template ::value>::type> +inline auto co_spawn(const Executor& ex, F&& f, CompletionToken&& token) +{ + return detail::co_spawn(ex, std::forward(f), + std::forward(token)); +} + +/// Spawn a new thread of execution. +template ::value>::type> +inline auto co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token) +{ + return detail::co_spawn(ctx.get_executor(), std::forward(f), + std::forward(token)); +} + +/// Spawn a new thread of execution. +template +inline auto co_spawn(const await_token& parent, + F&& f, CompletionToken&& token) +{ + return detail::co_spawn(parent.get_executor(), std::forward(f), + std::forward(token)); +} + +} // namespace experimental +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/experimental/impl/co_spawn.hpp" + +#endif // defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_EXPERIMENTAL_CO_SPAWN_HPP diff --git a/tools/sdk/include/asio/asio/experimental/detached.hpp b/tools/sdk/include/asio/asio/experimental/detached.hpp new file mode 100644 index 00000000..d484f18f --- /dev/null +++ b/tools/sdk/include/asio/asio/experimental/detached.hpp @@ -0,0 +1,65 @@ +// +// experimental/detached.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_EXPERIMENTAL_DETACHED_HPP +#define ASIO_EXPERIMENTAL_DETACHED_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace experimental { + +/// Class used to specify that an asynchronous operation is detached. +/** + + * The detached_t class is used to indicate that an asynchronous operation is + * detached. That is, there is no completion handler waiting for the + * operation's result. A detached_t object may be passed as a handler to an + * asynchronous operation, typically using the special value + * @c asio::experimental::detached. For example: + + * @code my_socket.async_send(my_buffer, asio::experimental::detached); + * @endcode + */ +class detached_t +{ +public: + /// Constructor. + ASIO_CONSTEXPR detached_t() + { + } +}; + +/// A special value, similar to std::nothrow. +/** + * See the documentation for asio::experimental::detached_t for a usage + * example. + */ +#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) +constexpr detached_t detached; +#elif defined(ASIO_MSVC) +__declspec(selectany) detached_t detached; +#endif + +} // namespace experimental +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/experimental/impl/detached.hpp" + +#endif // ASIO_EXPERIMENTAL_DETACHED_HPP diff --git a/tools/sdk/include/asio/asio/experimental/impl/co_spawn.hpp b/tools/sdk/include/asio/asio/experimental/impl/co_spawn.hpp new file mode 100644 index 00000000..8263eff9 --- /dev/null +++ b/tools/sdk/include/asio/asio/experimental/impl/co_spawn.hpp @@ -0,0 +1,876 @@ +// +// experimental/impl/co_spawn.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_EXPERIMENTAL_IMPL_CO_SPAWN_HPP +#define ASIO_EXPERIMENTAL_IMPL_CO_SPAWN_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include +#include +#include +#include +#include +#include "asio/async_result.hpp" +#include "asio/detail/thread_context.hpp" +#include "asio/detail/thread_info_base.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/dispatch.hpp" +#include "asio/post.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace experimental { +namespace detail { + +// Promise object for coroutine at top of thread-of-execution "stack". +template +class awaiter +{ +public: + struct deleter + { + void operator()(awaiter* a) + { + if (a) + a->release(); + } + }; + + typedef std::unique_ptr ptr; + + typedef Executor executor_type; + + ~awaiter() + { + if (has_executor_) + static_cast(static_cast(executor_))->~Executor(); + } + + void set_executor(const Executor& ex) + { + new (&executor_) Executor(ex); + has_executor_ = true; + } + + executor_type get_executor() const noexcept + { + return *static_cast(static_cast(executor_)); + } + + awaiter* get_return_object() + { + return this; + } + + auto initial_suspend() + { + return std::experimental::suspend_always(); + } + + auto final_suspend() + { + return std::experimental::suspend_always(); + } + + void return_void() + { + } + + awaiter* add_ref() + { + ++ref_count_; + return this; + } + + void release() + { + if (--ref_count_ == 0) + coroutine_handle::from_promise(*this).destroy(); + } + + void unhandled_exception() + { + pending_exception_ = std::current_exception(); + } + + void rethrow_unhandled_exception() + { + if (pending_exception_) + { + std::exception_ptr ex = std::exchange(pending_exception_, nullptr); + std::rethrow_exception(ex); + } + } + +private: + std::size_t ref_count_ = 0; + std::exception_ptr pending_exception_ = nullptr; + alignas(Executor) unsigned char executor_[sizeof(Executor)]; + bool has_executor_ = false; +}; + +// Base promise for coroutines further down the thread-of-execution "stack". +template +class awaitee_base +{ +public: +#if !defined(ASIO_DISABLE_AWAITEE_RECYCLING) + void* operator new(std::size_t size) + { + return asio::detail::thread_info_base::allocate( + asio::detail::thread_info_base::awaitee_tag(), + asio::detail::thread_context::thread_call_stack::top(), + size); + } + + void operator delete(void* pointer, std::size_t size) + { + asio::detail::thread_info_base::deallocate( + asio::detail::thread_info_base::awaitee_tag(), + asio::detail::thread_context::thread_call_stack::top(), + pointer, size); + } +#endif // !defined(ASIO_DISABLE_AWAITEE_RECYCLING) + + auto initial_suspend() + { + return std::experimental::suspend_never(); + } + + struct final_suspender + { + awaitee_base* this_; + + bool await_ready() const noexcept + { + return false; + } + + void await_suspend(coroutine_handle) + { + this_->wake_caller(); + } + + void await_resume() const noexcept + { + } + }; + + auto final_suspend() + { + return final_suspender{this}; + } + + void set_except(std::exception_ptr e) + { + pending_exception_ = e; + } + + void unhandled_exception() + { + set_except(std::current_exception()); + } + + void rethrow_exception() + { + if (pending_exception_) + { + std::exception_ptr ex = std::exchange(pending_exception_, nullptr); + std::rethrow_exception(ex); + } + } + + awaiter* top() + { + return awaiter_; + } + + coroutine_handle caller() + { + return caller_; + } + + bool ready() const + { + return ready_; + } + + void wake_caller() + { + if (caller_) + caller_.resume(); + else + ready_ = true; + } + + class awaitable_executor + { + public: + explicit awaitable_executor(awaitee_base* a) + : this_(a) + { + } + + bool await_ready() const noexcept + { + return this_->awaiter_ != nullptr; + } + + template + void await_suspend(coroutine_handle> h) noexcept + { + this_->resume_on_attach_ = h; + } + + Executor await_resume() + { + return this_->awaiter_->get_executor(); + } + + private: + awaitee_base* this_; + }; + + awaitable_executor await_transform(this_coro::executor_t) noexcept + { + return awaitable_executor(this); + } + + class awaitable_token + { + public: + explicit awaitable_token(awaitee_base* a) + : this_(a) + { + } + + bool await_ready() const noexcept + { + return this_->awaiter_ != nullptr; + } + + template + void await_suspend(coroutine_handle> h) noexcept + { + this_->resume_on_attach_ = h; + } + + await_token await_resume() + { + return await_token(this_->awaiter_); + } + + private: + awaitee_base* this_; + }; + + awaitable_token await_transform(this_coro::token_t) noexcept + { + return awaitable_token(this); + } + + template + awaitable await_transform(awaitable& t) const + { + return std::move(t); + } + + template + awaitable await_transform(awaitable&& t) const + { + return std::move(t); + } + + std::experimental::suspend_always await_transform( + std::experimental::suspend_always) const + { + return std::experimental::suspend_always(); + } + + void attach_caller(coroutine_handle> h) + { + this->caller_ = h; + this->attach_callees(&h.promise()); + } + + template + void attach_caller(coroutine_handle> h) + { + this->caller_ = h; + if (h.promise().awaiter_) + this->attach_callees(h.promise().awaiter_); + else + h.promise().unattached_callee_ = this; + } + + void attach_callees(awaiter* a) + { + for (awaitee_base* curr = this; curr != nullptr; + curr = std::exchange(curr->unattached_callee_, nullptr)) + { + curr->awaiter_ = a; + if (curr->resume_on_attach_) + return std::exchange(curr->resume_on_attach_, nullptr).resume(); + } + } + +protected: + awaiter* awaiter_ = nullptr; + coroutine_handle caller_ = nullptr; + awaitee_base* unattached_callee_ = nullptr; + std::exception_ptr pending_exception_ = nullptr; + coroutine_handle resume_on_attach_ = nullptr; + bool ready_ = false; +}; + +// Promise object for coroutines further down the thread-of-execution "stack". +template +class awaitee + : public awaitee_base +{ +public: + awaitee() + { + } + + awaitee(awaitee&& other) noexcept + : awaitee_base(std::move(other)) + { + } + + ~awaitee() + { + if (has_result_) + static_cast(static_cast(result_))->~T(); + } + + awaitable get_return_object() + { + return awaitable(this); + }; + + template + void return_value(U&& u) + { + new (&result_) T(std::forward(u)); + has_result_ = true; + } + + T get() + { + this->caller_ = nullptr; + this->rethrow_exception(); + return std::move(*static_cast(static_cast(result_))); + } + +private: + alignas(T) unsigned char result_[sizeof(T)]; + bool has_result_ = false; +}; + +// Promise object for coroutines further down the thread-of-execution "stack". +template +class awaitee + : public awaitee_base +{ +public: + awaitable get_return_object() + { + return awaitable(this); + }; + + void return_void() + { + } + + void get() + { + this->caller_ = nullptr; + this->rethrow_exception(); + } +}; + +template +class awaiter_task +{ +public: + typedef Executor executor_type; + + awaiter_task(awaiter* a) + : awaiter_(a->add_ref()) + { + } + + awaiter_task(awaiter_task&& other) noexcept + : awaiter_(std::exchange(other.awaiter_, nullptr)) + { + } + + ~awaiter_task() + { + if (awaiter_) + { + // Coroutine "stack unwinding" must be performed through the executor. + executor_type ex(awaiter_->get_executor()); + (post)(ex, + [a = std::move(awaiter_)]() mutable + { + typename awaiter::ptr(std::move(a)); + }); + } + } + + executor_type get_executor() const noexcept + { + return awaiter_->get_executor(); + } + +protected: + typename awaiter::ptr awaiter_; +}; + +template +class co_spawn_handler : public awaiter_task +{ +public: + using awaiter_task::awaiter_task; + + void operator()() + { + typename awaiter::ptr ptr(std::move(this->awaiter_)); + coroutine_handle>::from_promise(*ptr.get()).resume(); + } +}; + +template +class await_handler_base : public awaiter_task +{ +public: + typedef awaitable awaitable_type; + + await_handler_base(await_token token) + : awaiter_task(token.awaiter_), + awaitee_(nullptr) + { + } + + await_handler_base(await_handler_base&& other) noexcept + : awaiter_task(std::move(other)), + awaitee_(std::exchange(other.awaitee_, nullptr)) + { + } + + void attach_awaitee(const awaitable& a) + { + awaitee_ = a.awaitee_; + } + +protected: + awaitee* awaitee_; +}; + +template class await_handler; + +template +class await_handler + : public await_handler_base +{ +public: + using await_handler_base::await_handler_base; + + void operator()() + { + typename awaiter::ptr ptr(std::move(this->awaiter_)); + this->awaitee_->return_void(); + this->awaitee_->wake_caller(); + ptr->rethrow_unhandled_exception(); + } +}; + +template +class await_handler + : public await_handler_base +{ +public: + typedef void return_type; + + using await_handler_base::await_handler_base; + + void operator()(const asio::error_code& ec) + { + typename awaiter::ptr ptr(std::move(this->awaiter_)); + if (ec) + { + this->awaitee_->set_except( + std::make_exception_ptr(asio::system_error(ec))); + } + else + this->awaitee_->return_void(); + this->awaitee_->wake_caller(); + ptr->rethrow_unhandled_exception(); + } +}; + +template +class await_handler + : public await_handler_base +{ +public: + using await_handler_base::await_handler_base; + + void operator()(std::exception_ptr ex) + { + typename awaiter::ptr ptr(std::move(this->awaiter_)); + if (ex) + this->awaitee_->set_except(ex); + else + this->awaitee_->return_void(); + this->awaitee_->wake_caller(); + ptr->rethrow_unhandled_exception(); + } +}; + +template +class await_handler + : public await_handler_base +{ +public: + using await_handler_base::await_handler_base; + + template + void operator()(Arg&& arg) + { + typename awaiter::ptr ptr(std::move(this->awaiter_)); + this->awaitee_->return_value(std::forward(arg)); + this->awaitee_->wake_caller(); + ptr->rethrow_unhandled_exception(); + } +}; + +template +class await_handler + : public await_handler_base +{ +public: + using await_handler_base::await_handler_base; + + template + void operator()(const asio::error_code& ec, Arg&& arg) + { + typename awaiter::ptr ptr(std::move(this->awaiter_)); + if (ec) + { + this->awaitee_->set_except( + std::make_exception_ptr(asio::system_error(ec))); + } + else + this->awaitee_->return_value(std::forward(arg)); + this->awaitee_->wake_caller(); + ptr->rethrow_unhandled_exception(); + } +}; + +template +class await_handler + : public await_handler_base +{ +public: + using await_handler_base::await_handler_base; + + template + void operator()(std::exception_ptr ex, Arg&& arg) + { + typename awaiter::ptr ptr(std::move(this->awaiter_)); + if (ex) + this->awaitee_->set_except(ex); + else + this->awaitee_->return_value(std::forward(arg)); + this->awaitee_->wake_caller(); + ptr->rethrow_unhandled_exception(); + } +}; + +template +class await_handler + : public await_handler_base> +{ +public: + using await_handler_base>::await_handler_base; + + template + void operator()(Args&&... args) + { + typename awaiter::ptr ptr(std::move(this->awaiter_)); + this->awaitee_->return_value( + std::forward_as_tuple(std::forward(args)...)); + this->awaitee_->wake_caller(); + ptr->rethrow_unhandled_exception(); + } +}; + +template +class await_handler + : public await_handler_base> +{ +public: + using await_handler_base>::await_handler_base; + + template + void operator()(const asio::error_code& ec, Args&&... args) + { + typename awaiter::ptr ptr(std::move(this->awaiter_)); + if (ec) + { + this->awaitee_->set_except( + std::make_exception_ptr(asio::system_error(ec))); + } + else + { + this->awaitee_->return_value( + std::forward_as_tuple(std::forward(args)...)); + } + this->awaitee_->wake_caller(); + ptr->rethrow_unhandled_exception(); + } +}; + +template +class await_handler + : public await_handler_base> +{ +public: + using await_handler_base>::await_handler_base; + + template + void operator()(std::exception_ptr ex, Args&&... args) + { + typename awaiter::ptr ptr(std::move(this->awaiter_)); + if (ex) + this->awaitee_->set_except(ex); + else + { + this->awaitee_->return_value( + std::forward_as_tuple(std::forward(args)...)); + } + this->awaitee_->wake_caller(); + ptr->rethrow_unhandled_exception(); + } +}; + +template +struct awaitable_signature; + +template +struct awaitable_signature> +{ + typedef void type(std::exception_ptr, T); +}; + +template +struct awaitable_signature> +{ + typedef void type(std::exception_ptr); +}; + +template +awaiter* co_spawn_entry_point(awaitable*, + executor_work_guard work_guard, F f, Handler handler) +{ + bool done = false; + + try + { + T t = co_await f(); + + done = true; + + (dispatch)(work_guard.get_executor(), + [handler = std::move(handler), t = std::move(t)]() mutable + { + handler(std::exception_ptr(), std::move(t)); + }); + } + catch (...) + { + if (done) + throw; + + (dispatch)(work_guard.get_executor(), + [handler = std::move(handler), e = std::current_exception()]() mutable + { + handler(e, T()); + }); + } +} + +template +awaiter* co_spawn_entry_point(awaitable*, + executor_work_guard work_guard, F f, Handler handler) +{ + std::exception_ptr e = nullptr; + + try + { + co_await f(); + } + catch (...) + { + e = std::current_exception(); + } + + (dispatch)(work_guard.get_executor(), + [handler = std::move(handler), e]() mutable + { + handler(e); + }); +} + +template +auto co_spawn(const Executor& ex, F&& f, CompletionToken&& token) +{ + typedef typename result_of::type awaitable_type; + typedef typename awaitable_type::executor_type executor_type; + typedef typename awaitable_signature::type signature_type; + + async_completion completion(token); + + executor_type ex2(ex); + auto work_guard = make_work_guard(completion.completion_handler, ex2); + + auto* a = (co_spawn_entry_point)( + static_cast(nullptr), std::move(work_guard), + std::forward(f), std::move(completion.completion_handler)); + + a->set_executor(ex2); + (post)(co_spawn_handler(a)); + + return completion.result.get(); +} + +#if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable:4033) +#endif // defined(_MSC_VER) + +#if defined(_MSC_VER) +template T dummy_return() +{ + return std::move(*static_cast(nullptr)); +} + +template <> +inline void dummy_return() +{ +} +#endif // defined(_MSC_VER) + +template +inline Awaitable make_dummy_awaitable() +{ + for (;;) co_await std::experimental::suspend_always(); +#if defined(_MSC_VER) + co_return dummy_return(); +#endif // defined(_MSC_VER) +} + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif // defined(_MSC_VER) + +} // namespace detail +} // namespace experimental + +template +class async_result, R(Args...)> +{ +public: + typedef experimental::detail::await_handler< + Executor, typename decay::type...> completion_handler_type; + + typedef typename experimental::detail::await_handler< + Executor, Args...>::awaitable_type return_type; + + async_result(completion_handler_type& h) + : awaitable_(experimental::detail::make_dummy_awaitable()) + { + h.attach_awaitee(awaitable_); + } + + return_type get() + { + return std::move(awaitable_); + } + +private: + return_type awaitable_; +}; + +#if !defined(ASIO_NO_DEPRECATED) + +template +struct handler_type, R(Args...)> +{ + typedef experimental::detail::await_handler< + Executor, typename decay::type...> type; +}; + +template +class async_result> +{ +public: + typedef typename experimental::detail::await_handler< + Executor, Args...>::awaitable_type type; + + async_result(experimental::detail::await_handler& h) + : awaitable_(experimental::detail::make_dummy_awaitable()) + { + h.attach_awaitee(awaitable_); + } + + type get() + { + return std::move(awaitable_); + } + +private: + type awaitable_; +}; + +#endif // !defined(ASIO_NO_DEPRECATED) + +} // namespace asio + +namespace std { namespace experimental { + +template +struct coroutine_traits< + asio::experimental::detail::awaiter*, Args...> +{ + typedef asio::experimental::detail::awaiter promise_type; +}; + +template +struct coroutine_traits< + asio::experimental::awaitable, Args...> +{ + typedef asio::experimental::detail::awaitee promise_type; +}; + +}} // namespace std::experimental + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_EXPERIMENTAL_IMPL_CO_SPAWN_HPP diff --git a/tools/sdk/include/asio/asio/experimental/impl/detached.hpp b/tools/sdk/include/asio/asio/experimental/impl/detached.hpp new file mode 100644 index 00000000..6ce88872 --- /dev/null +++ b/tools/sdk/include/asio/asio/experimental/impl/detached.hpp @@ -0,0 +1,91 @@ +// +// experimental/impl/detached.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_EXPERIMENTAL_IMPL_DETACHED_HPP +#define ASIO_EXPERIMENTAL_IMPL_DETACHED_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/async_result.hpp" +#include "asio/detail/variadic_templates.hpp" +#include "asio/handler_type.hpp" +#include "asio/system_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace experimental { +namespace detail { + + // Class to adapt a detached_t as a completion handler. + class detached_handler + { + public: + detached_handler(detached_t) + { + } + +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) + + template + void operator()(Args...) + { + } + +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + + void operator()() + { + } + +#define ASIO_PRIVATE_DETACHED_DEF(n) \ + template \ + void operator()(ASIO_VARIADIC_BYVAL_PARAMS(n)) \ + { \ + } \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_DETACHED_DEF) +#undef ASIO_PRIVATE_DETACHED_DEF + +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) + }; + +} // namespace detail +} // namespace experimental + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct async_result +{ + typedef asio::experimental::detail::detached_handler + completion_handler_type; + + typedef void return_type; + + explicit async_result(completion_handler_type&) + { + } + + void get() + { + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_EXPERIMENTAL_IMPL_DETACHED_HPP diff --git a/tools/sdk/include/asio/asio/experimental/impl/redirect_error.hpp b/tools/sdk/include/asio/asio/experimental/impl/redirect_error.hpp new file mode 100644 index 00000000..d3b97fac --- /dev/null +++ b/tools/sdk/include/asio/asio/experimental/impl/redirect_error.hpp @@ -0,0 +1,294 @@ +// +// experimental/impl/redirect_error.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_EXPERIMENTAL_IMPL_REDIRECT_ERROR_HPP +#define ASIO_EXPERIMENTAL_IMPL_REDIRECT_ERROR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/associated_executor.hpp" +#include "asio/associated_allocator.hpp" +#include "asio/async_result.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/detail/variadic_templates.hpp" +#include "asio/handler_type.hpp" +#include "asio/system_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace experimental { +namespace detail { + +// Class to adapt a redirect_error_t as a completion handler. +template +class redirect_error_handler +{ +public: + template + redirect_error_handler(redirect_error_t e) + : ec_(e.ec_), + handler_(ASIO_MOVE_CAST(CompletionToken)(e.token_)) + { + } + + void operator()() + { + handler_(); + } + +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) + + template + typename enable_if< + !is_same::type, asio::error_code>::value + >::type + operator()(ASIO_MOVE_ARG(Arg) arg, ASIO_MOVE_ARG(Args)... args) + { + handler_(ASIO_MOVE_CAST(Arg)(arg), + ASIO_MOVE_CAST(Args)(args)...); + } + + template + void operator()(const asio::error_code& ec, + ASIO_MOVE_ARG(Args)... args) + { + ec_ = ec; + handler_(ASIO_MOVE_CAST(Args)(args)...); + } + +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + + template + typename enable_if< + !is_same::type, asio::error_code>::value + >::type + operator()(ASIO_MOVE_ARG(Arg) arg) + { + handler_(ASIO_MOVE_CAST(Arg)(arg)); + } + + void operator()(const asio::error_code& ec) + { + ec_ = ec; + handler_(); + } + +#define ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \ + template \ + typename enable_if< \ + !is_same::type, asio::error_code>::value \ + >::type \ + operator()(ASIO_MOVE_ARG(Arg) arg, ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + handler_(ASIO_MOVE_CAST(Arg)(arg), \ + ASIO_VARIADIC_MOVE_ARGS(n)); \ + } \ + \ + template \ + void operator()(const asio::error_code& ec, \ + ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + ec_ = ec; \ + handler_(ASIO_VARIADIC_MOVE_ARGS(n)); \ + } \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_REDIRECT_ERROR_DEF) +#undef ASIO_PRIVATE_REDIRECT_ERROR_DEF + +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +//private: + asio::error_code& ec_; + Handler handler_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + redirect_error_handler* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + redirect_error_handler* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline bool asio_handler_is_continuation( + redirect_error_handler* this_handler) +{ + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); +} + +template +inline void asio_handler_invoke(Function& function, + redirect_error_handler* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + redirect_error_handler* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +struct redirect_error_signature +{ + typedef Signature type; +}; + +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) + +template +struct redirect_error_signature +{ + typedef R type(Args...); +}; + +template +struct redirect_error_signature +{ + typedef R type(Args...); +}; + +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +template +struct redirect_error_signature +{ + typedef R type(); +}; + +template +struct redirect_error_signature +{ + typedef R type(); +}; + +#define ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \ + template \ + struct redirect_error_signature< \ + R(asio::error_code, ASIO_VARIADIC_TARGS(n))> \ + { \ + typedef R type(ASIO_VARIADIC_TARGS(n)); \ + }; \ + \ + template \ + struct redirect_error_signature< \ + R(const asio::error_code&, ASIO_VARIADIC_TARGS(n))> \ + { \ + typedef R type(ASIO_VARIADIC_TARGS(n)); \ + }; \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_REDIRECT_ERROR_DEF) +#undef ASIO_PRIVATE_REDIRECT_ERROR_DEF + +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +} // namespace detail +} // namespace experimental + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct async_result, Signature> + : async_result::type> +{ + typedef experimental::detail::redirect_error_handler< + typename async_result::type> + ::completion_handler_type> completion_handler_type; + + explicit async_result(completion_handler_type& h) + : async_result::type>(h.handler_) + { + } +}; + +#if !defined(ASIO_NO_DEPRECATED) + +template +struct handler_type, Signature> +{ + typedef experimental::detail::redirect_error_handler< + typename async_result::type> + ::completion_handler_type> type; +}; + +template +struct async_result > + : async_result +{ + explicit async_result( + experimental::detail::redirect_error_handler& h) + : async_result(h.handler_) + { + } +}; + +#endif // !defined(ASIO_NO_DEPRECATED) + +template +struct associated_executor< + experimental::detail::redirect_error_handler, Executor> +{ + typedef typename associated_executor::type type; + + static type get( + const experimental::detail::redirect_error_handler& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +template +struct associated_allocator< + experimental::detail::redirect_error_handler, Allocator> +{ + typedef typename associated_allocator::type type; + + static type get( + const experimental::detail::redirect_error_handler& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_EXPERIMENTAL_IMPL_REDIRECT_ERROR_HPP diff --git a/tools/sdk/include/asio/asio/experimental/redirect_error.hpp b/tools/sdk/include/asio/asio/experimental/redirect_error.hpp new file mode 100644 index 00000000..30e81cf5 --- /dev/null +++ b/tools/sdk/include/asio/asio/experimental/redirect_error.hpp @@ -0,0 +1,67 @@ +// +// experimental/redirect_error.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_EXPERIMENTAL_REDIRECT_ERROR_HPP +#define ASIO_EXPERIMENTAL_REDIRECT_ERROR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error_code.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace experimental { + +/// Completion token type used to specify that an error produced by an +/// asynchronous operation is captured to an error_code variable. +/** + * The redirect_error_t class is used to indicate that any error_code produced + * by an asynchronous operation is captured to a specified variable. + */ +template +class redirect_error_t +{ +public: + /// Constructor. + template + redirect_error_t(ASIO_MOVE_ARG(T) completion_token, + asio::error_code& ec) + : token_(ASIO_MOVE_CAST(T)(completion_token)), + ec_(ec) + { + } + +//private: + CompletionToken token_; + asio::error_code& ec_; +}; + +/// Create a completion token to capture error_code values to a variable. +template +inline redirect_error_t::type> redirect_error( + CompletionToken&& completion_token, asio::error_code& ec) +{ + return redirect_error_t::type>( + ASIO_MOVE_CAST(CompletionToken)(completion_token), ec); +} + +} // namespace experimental +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/experimental/impl/redirect_error.hpp" + +#endif // ASIO_EXPERIMENTAL_REDIRECT_ERROR_HPP diff --git a/tools/sdk/include/asio/asio/generic/basic_endpoint.hpp b/tools/sdk/include/asio/asio/generic/basic_endpoint.hpp new file mode 100644 index 00000000..73aa151d --- /dev/null +++ b/tools/sdk/include/asio/asio/generic/basic_endpoint.hpp @@ -0,0 +1,193 @@ +// +// generic/basic_endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_GENERIC_BASIC_ENDPOINT_HPP +#define ASIO_GENERIC_BASIC_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/generic/detail/endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace generic { + +/// Describes an endpoint for any socket type. +/** + * The asio::generic::basic_endpoint class template describes an endpoint + * that may be associated with any socket type. + * + * @note The socket types sockaddr type must be able to fit into a + * @c sockaddr_storage structure. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * Endpoint. + */ +template +class basic_endpoint +{ +public: + /// The protocol type associated with the endpoint. + typedef Protocol protocol_type; + + /// The type of the endpoint structure. This type is dependent on the + /// underlying implementation of the socket layer. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined data_type; +#else + typedef asio::detail::socket_addr_type data_type; +#endif + + /// Default constructor. + basic_endpoint() + { + } + + /// Construct an endpoint from the specified socket address. + basic_endpoint(const void* socket_address, + std::size_t socket_address_size, int socket_protocol = 0) + : impl_(socket_address, socket_address_size, socket_protocol) + { + } + + /// Construct an endpoint from the specific endpoint type. + template + basic_endpoint(const Endpoint& endpoint) + : impl_(endpoint.data(), endpoint.size(), endpoint.protocol().protocol()) + { + } + + /// Copy constructor. + basic_endpoint(const basic_endpoint& other) + : impl_(other.impl_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + basic_endpoint(basic_endpoint&& other) + : impl_(other.impl_) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from another endpoint. + basic_endpoint& operator=(const basic_endpoint& other) + { + impl_ = other.impl_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move-assign from another endpoint. + basic_endpoint& operator=(basic_endpoint&& other) + { + impl_ = other.impl_; + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// The protocol associated with the endpoint. + protocol_type protocol() const + { + return protocol_type(impl_.family(), impl_.protocol()); + } + + /// Get the underlying endpoint in the native type. + data_type* data() + { + return impl_.data(); + } + + /// Get the underlying endpoint in the native type. + const data_type* data() const + { + return impl_.data(); + } + + /// Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + return impl_.size(); + } + + /// Set the underlying size of the endpoint in the native type. + void resize(std::size_t new_size) + { + impl_.resize(new_size); + } + + /// Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return impl_.capacity(); + } + + /// Compare two endpoints for equality. + friend bool operator==(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e1.impl_ == e2.impl_; + } + + /// Compare two endpoints for inequality. + friend bool operator!=(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return !(e1.impl_ == e2.impl_); + } + + /// Compare endpoints for ordering. + friend bool operator<(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e1.impl_ < e2.impl_; + } + + /// Compare endpoints for ordering. + friend bool operator>(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e2.impl_ < e1.impl_; + } + + /// Compare endpoints for ordering. + friend bool operator<=(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return !(e2 < e1); + } + + /// Compare endpoints for ordering. + friend bool operator>=(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return !(e1 < e2); + } + +private: + // The underlying generic endpoint. + asio::generic::detail::endpoint impl_; +}; + +} // namespace generic +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_GENERIC_BASIC_ENDPOINT_HPP diff --git a/tools/sdk/include/asio/asio/generic/datagram_protocol.hpp b/tools/sdk/include/asio/asio/generic/datagram_protocol.hpp new file mode 100644 index 00000000..8678ad85 --- /dev/null +++ b/tools/sdk/include/asio/asio/generic/datagram_protocol.hpp @@ -0,0 +1,123 @@ +// +// generic/datagram_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_GENERIC_DATAGRAM_PROTOCOL_HPP +#define ASIO_GENERIC_DATAGRAM_PROTOCOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include +#include "asio/basic_datagram_socket.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/generic/basic_endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace generic { + +/// Encapsulates the flags needed for a generic datagram-oriented socket. +/** + * The asio::generic::datagram_protocol class contains flags necessary + * for datagram-oriented sockets of any address family and protocol. + * + * @par Examples + * Constructing using a native address family and socket protocol: + * @code datagram_protocol p(AF_INET, IPPROTO_UDP); @endcode + * Constructing from a specific protocol type: + * @code datagram_protocol p(asio::ip::udp::v4()); @endcode + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol. + */ +class datagram_protocol +{ +public: + /// Construct a protocol object for a specific address family and protocol. + datagram_protocol(int address_family, int socket_protocol) + : family_(address_family), + protocol_(socket_protocol) + { + } + + /// Construct a generic protocol object from a specific protocol. + /** + * @throws @c bad_cast Thrown if the source protocol is not datagram-oriented. + */ + template + datagram_protocol(const Protocol& source_protocol) + : family_(source_protocol.family()), + protocol_(source_protocol.protocol()) + { + if (source_protocol.type() != type()) + { + std::bad_cast ex; + asio::detail::throw_exception(ex); + } + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return ASIO_OS_DEF(SOCK_DGRAM); + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return protocol_; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// Compare two protocols for equality. + friend bool operator==(const datagram_protocol& p1, + const datagram_protocol& p2) + { + return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const datagram_protocol& p1, + const datagram_protocol& p2) + { + return !(p1 == p2); + } + + /// The type of an endpoint. + typedef basic_endpoint endpoint; + + /// The generic socket type. + typedef basic_datagram_socket socket; + +private: + int family_; + int protocol_; +}; + +} // namespace generic +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_GENERIC_DATAGRAM_PROTOCOL_HPP diff --git a/tools/sdk/include/asio/asio/generic/detail/endpoint.hpp b/tools/sdk/include/asio/asio/generic/detail/endpoint.hpp new file mode 100644 index 00000000..190beb14 --- /dev/null +++ b/tools/sdk/include/asio/asio/generic/detail/endpoint.hpp @@ -0,0 +1,133 @@ +// +// generic/detail/endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_GENERIC_DETAIL_ENDPOINT_HPP +#define ASIO_GENERIC_DETAIL_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace generic { +namespace detail { + +// Helper class for implementing a generic socket endpoint. +class endpoint +{ +public: + // Default constructor. + ASIO_DECL endpoint(); + + // Construct an endpoint from the specified raw bytes. + ASIO_DECL endpoint(const void* sock_addr, + std::size_t sock_addr_size, int sock_protocol); + + // Copy constructor. + endpoint(const endpoint& other) + : data_(other.data_), + size_(other.size_), + protocol_(other.protocol_) + { + } + + // Assign from another endpoint. + endpoint& operator=(const endpoint& other) + { + data_ = other.data_; + size_ = other.size_; + protocol_ = other.protocol_; + return *this; + } + + // Get the address family associated with the endpoint. + int family() const + { + return data_.base.sa_family; + } + + // Get the socket protocol associated with the endpoint. + int protocol() const + { + return protocol_; + } + + // Get the underlying endpoint in the native type. + asio::detail::socket_addr_type* data() + { + return &data_.base; + } + + // Get the underlying endpoint in the native type. + const asio::detail::socket_addr_type* data() const + { + return &data_.base; + } + + // Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + return size_; + } + + // Set the underlying size of the endpoint in the native type. + ASIO_DECL void resize(std::size_t size); + + // Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return sizeof(asio::detail::sockaddr_storage_type); + } + + // Compare two endpoints for equality. + ASIO_DECL friend bool operator==( + const endpoint& e1, const endpoint& e2); + + // Compare endpoints for ordering. + ASIO_DECL friend bool operator<( + const endpoint& e1, const endpoint& e2); + +private: + // The underlying socket address. + union data_union + { + asio::detail::socket_addr_type base; + asio::detail::sockaddr_storage_type generic; + } data_; + + // The length of the socket address stored in the endpoint. + std::size_t size_; + + // The socket protocol associated with the endpoint. + int protocol_; + + // Initialise with a specified memory. + ASIO_DECL void init(const void* sock_addr, + std::size_t sock_addr_size, int sock_protocol); +}; + +} // namespace detail +} // namespace generic +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/generic/detail/impl/endpoint.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_GENERIC_DETAIL_ENDPOINT_HPP diff --git a/tools/sdk/include/asio/asio/generic/raw_protocol.hpp b/tools/sdk/include/asio/asio/generic/raw_protocol.hpp new file mode 100644 index 00000000..b83dca6e --- /dev/null +++ b/tools/sdk/include/asio/asio/generic/raw_protocol.hpp @@ -0,0 +1,121 @@ +// +// generic/raw_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_GENERIC_RAW_PROTOCOL_HPP +#define ASIO_GENERIC_RAW_PROTOCOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include +#include "asio/basic_raw_socket.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/generic/basic_endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace generic { + +/// Encapsulates the flags needed for a generic raw socket. +/** + * The asio::generic::raw_protocol class contains flags necessary for + * raw sockets of any address family and protocol. + * + * @par Examples + * Constructing using a native address family and socket protocol: + * @code raw_protocol p(AF_INET, IPPROTO_ICMP); @endcode + * Constructing from a specific protocol type: + * @code raw_protocol p(asio::ip::icmp::v4()); @endcode + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol. + */ +class raw_protocol +{ +public: + /// Construct a protocol object for a specific address family and protocol. + raw_protocol(int address_family, int socket_protocol) + : family_(address_family), + protocol_(socket_protocol) + { + } + + /// Construct a generic protocol object from a specific protocol. + /** + * @throws @c bad_cast Thrown if the source protocol is not raw-oriented. + */ + template + raw_protocol(const Protocol& source_protocol) + : family_(source_protocol.family()), + protocol_(source_protocol.protocol()) + { + if (source_protocol.type() != type()) + { + std::bad_cast ex; + asio::detail::throw_exception(ex); + } + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return ASIO_OS_DEF(SOCK_RAW); + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return protocol_; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// Compare two protocols for equality. + friend bool operator==(const raw_protocol& p1, const raw_protocol& p2) + { + return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const raw_protocol& p1, const raw_protocol& p2) + { + return !(p1 == p2); + } + + /// The type of an endpoint. + typedef basic_endpoint endpoint; + + /// The generic socket type. + typedef basic_raw_socket socket; + +private: + int family_; + int protocol_; +}; + +} // namespace generic +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_GENERIC_RAW_PROTOCOL_HPP diff --git a/tools/sdk/include/asio/asio/generic/seq_packet_protocol.hpp b/tools/sdk/include/asio/asio/generic/seq_packet_protocol.hpp new file mode 100644 index 00000000..f92a4c8f --- /dev/null +++ b/tools/sdk/include/asio/asio/generic/seq_packet_protocol.hpp @@ -0,0 +1,122 @@ +// +// generic/seq_packet_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_GENERIC_SEQ_PACKET_PROTOCOL_HPP +#define ASIO_GENERIC_SEQ_PACKET_PROTOCOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include +#include "asio/basic_seq_packet_socket.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/generic/basic_endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace generic { + +/// Encapsulates the flags needed for a generic sequenced packet socket. +/** + * The asio::generic::seq_packet_protocol class contains flags necessary + * for seq_packet-oriented sockets of any address family and protocol. + * + * @par Examples + * Constructing using a native address family and socket protocol: + * @code seq_packet_protocol p(AF_INET, IPPROTO_SCTP); @endcode + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol. + */ +class seq_packet_protocol +{ +public: + /// Construct a protocol object for a specific address family and protocol. + seq_packet_protocol(int address_family, int socket_protocol) + : family_(address_family), + protocol_(socket_protocol) + { + } + + /// Construct a generic protocol object from a specific protocol. + /** + * @throws @c bad_cast Thrown if the source protocol is not based around + * sequenced packets. + */ + template + seq_packet_protocol(const Protocol& source_protocol) + : family_(source_protocol.family()), + protocol_(source_protocol.protocol()) + { + if (source_protocol.type() != type()) + { + std::bad_cast ex; + asio::detail::throw_exception(ex); + } + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return ASIO_OS_DEF(SOCK_SEQPACKET); + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return protocol_; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// Compare two protocols for equality. + friend bool operator==(const seq_packet_protocol& p1, + const seq_packet_protocol& p2) + { + return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const seq_packet_protocol& p1, + const seq_packet_protocol& p2) + { + return !(p1 == p2); + } + + /// The type of an endpoint. + typedef basic_endpoint endpoint; + + /// The generic socket type. + typedef basic_seq_packet_socket socket; + +private: + int family_; + int protocol_; +}; + +} // namespace generic +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_GENERIC_SEQ_PACKET_PROTOCOL_HPP diff --git a/tools/sdk/include/asio/asio/generic/stream_protocol.hpp b/tools/sdk/include/asio/asio/generic/stream_protocol.hpp new file mode 100644 index 00000000..8349f25b --- /dev/null +++ b/tools/sdk/include/asio/asio/generic/stream_protocol.hpp @@ -0,0 +1,127 @@ +// +// generic/stream_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_GENERIC_STREAM_PROTOCOL_HPP +#define ASIO_GENERIC_STREAM_PROTOCOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include +#include "asio/basic_socket_iostream.hpp" +#include "asio/basic_stream_socket.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/generic/basic_endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace generic { + +/// Encapsulates the flags needed for a generic stream-oriented socket. +/** + * The asio::generic::stream_protocol class contains flags necessary for + * stream-oriented sockets of any address family and protocol. + * + * @par Examples + * Constructing using a native address family and socket protocol: + * @code stream_protocol p(AF_INET, IPPROTO_TCP); @endcode + * Constructing from a specific protocol type: + * @code stream_protocol p(asio::ip::tcp::v4()); @endcode + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol. + */ +class stream_protocol +{ +public: + /// Construct a protocol object for a specific address family and protocol. + stream_protocol(int address_family, int socket_protocol) + : family_(address_family), + protocol_(socket_protocol) + { + } + + /// Construct a generic protocol object from a specific protocol. + /** + * @throws @c bad_cast Thrown if the source protocol is not stream-oriented. + */ + template + stream_protocol(const Protocol& source_protocol) + : family_(source_protocol.family()), + protocol_(source_protocol.protocol()) + { + if (source_protocol.type() != type()) + { + std::bad_cast ex; + asio::detail::throw_exception(ex); + } + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return ASIO_OS_DEF(SOCK_STREAM); + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return protocol_; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// Compare two protocols for equality. + friend bool operator==(const stream_protocol& p1, const stream_protocol& p2) + { + return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const stream_protocol& p1, const stream_protocol& p2) + { + return !(p1 == p2); + } + + /// The type of an endpoint. + typedef basic_endpoint endpoint; + + /// The generic socket type. + typedef basic_stream_socket socket; + +#if !defined(ASIO_NO_IOSTREAM) + /// The generic socket iostream type. + typedef basic_socket_iostream iostream; +#endif // !defined(ASIO_NO_IOSTREAM) + +private: + int family_; + int protocol_; +}; + +} // namespace generic +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_GENERIC_STREAM_PROTOCOL_HPP diff --git a/tools/sdk/include/asio/asio/handler_alloc_hook.hpp b/tools/sdk/include/asio/asio/handler_alloc_hook.hpp new file mode 100644 index 00000000..d7fe2b01 --- /dev/null +++ b/tools/sdk/include/asio/asio/handler_alloc_hook.hpp @@ -0,0 +1,81 @@ +// +// handler_alloc_hook.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_HANDLER_ALLOC_HOOK_HPP +#define ASIO_HANDLER_ALLOC_HOOK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Default allocation function for handlers. +/** + * Asynchronous operations may need to allocate temporary objects. Since + * asynchronous operations have a handler function object, these temporary + * objects can be said to be associated with the handler. + * + * Implement asio_handler_allocate and asio_handler_deallocate for your own + * handlers to provide custom allocation for these temporary objects. + * + * The default implementation of these allocation hooks uses ::operator + * new and ::operator delete. + * + * @note All temporary objects associated with a handler will be deallocated + * before the upcall to the handler is performed. This allows the same memory to + * be reused for a subsequent asynchronous operation initiated by the handler. + * + * @par Example + * @code + * class my_handler; + * + * void* asio_handler_allocate(std::size_t size, my_handler* context) + * { + * return ::operator new(size); + * } + * + * void asio_handler_deallocate(void* pointer, std::size_t size, + * my_handler* context) + * { + * ::operator delete(pointer); + * } + * @endcode + */ +ASIO_DECL void* asio_handler_allocate( + std::size_t size, ...); + +/// Default deallocation function for handlers. +/** + * Implement asio_handler_allocate and asio_handler_deallocate for your own + * handlers to provide custom allocation for the associated temporary objects. + * + * The default implementation of these allocation hooks uses ::operator + * new and ::operator delete. + * + * @sa asio_handler_allocate. + */ +ASIO_DECL void asio_handler_deallocate( + void* pointer, std::size_t size, ...); + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/impl/handler_alloc_hook.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_HANDLER_ALLOC_HOOK_HPP diff --git a/tools/sdk/include/asio/asio/handler_continuation_hook.hpp b/tools/sdk/include/asio/asio/handler_continuation_hook.hpp new file mode 100644 index 00000000..d41d1059 --- /dev/null +++ b/tools/sdk/include/asio/asio/handler_continuation_hook.hpp @@ -0,0 +1,54 @@ +// +// handler_continuation_hook.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_HANDLER_CONTINUATION_HOOK_HPP +#define ASIO_HANDLER_CONTINUATION_HOOK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Default continuation function for handlers. +/** + * Asynchronous operations may represent a continuation of the asynchronous + * control flow associated with the current handler. The implementation can use + * this knowledge to optimise scheduling of the handler. + * + * Implement asio_handler_is_continuation for your own handlers to indicate + * when a handler represents a continuation. + * + * The default implementation of the continuation hook returns false. + * + * @par Example + * @code + * class my_handler; + * + * bool asio_handler_is_continuation(my_handler* context) + * { + * return true; + * } + * @endcode + */ +inline bool asio_handler_is_continuation(...) +{ + return false; +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_HANDLER_CONTINUATION_HOOK_HPP diff --git a/tools/sdk/include/asio/asio/handler_invoke_hook.hpp b/tools/sdk/include/asio/asio/handler_invoke_hook.hpp new file mode 100644 index 00000000..ee618e5e --- /dev/null +++ b/tools/sdk/include/asio/asio/handler_invoke_hook.hpp @@ -0,0 +1,85 @@ +// +// handler_invoke_hook.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_HANDLER_INVOKE_HOOK_HPP +#define ASIO_HANDLER_INVOKE_HOOK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/** @defgroup asio_handler_invoke asio::asio_handler_invoke + * + * @brief Default invoke function for handlers. + * + * Completion handlers for asynchronous operations are invoked by the + * io_context associated with the corresponding object (e.g. a socket or + * deadline_timer). Certain guarantees are made on when the handler may be + * invoked, in particular that a handler can only be invoked from a thread that + * is currently calling @c run() on the corresponding io_context object. + * Handlers may subsequently be invoked through other objects (such as + * io_context::strand objects) that provide additional guarantees. + * + * When asynchronous operations are composed from other asynchronous + * operations, all intermediate handlers should be invoked using the same + * method as the final handler. This is required to ensure that user-defined + * objects are not accessed in a way that may violate the guarantees. This + * hooking function ensures that the invoked method used for the final handler + * is accessible at each intermediate step. + * + * Implement asio_handler_invoke for your own handlers to specify a custom + * invocation strategy. + * + * This default implementation invokes the function object like so: + * @code function(); @endcode + * If necessary, the default implementation makes a copy of the function object + * so that the non-const operator() can be used. + * + * @par Example + * @code + * class my_handler; + * + * template + * void asio_handler_invoke(Function function, my_handler* context) + * { + * context->strand_.dispatch(function); + * } + * @endcode + */ +/*@{*/ + +/// Default handler invocation hook used for non-const function objects. +template +inline void asio_handler_invoke(Function& function, ...) +{ + function(); +} + +/// Default handler invocation hook used for const function objects. +template +inline void asio_handler_invoke(const Function& function, ...) +{ + Function tmp(function); + tmp(); +} + +/*@}*/ + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_HANDLER_INVOKE_HOOK_HPP diff --git a/tools/sdk/include/asio/asio/handler_type.hpp b/tools/sdk/include/asio/asio/handler_type.hpp new file mode 100644 index 00000000..bc0d3051 --- /dev/null +++ b/tools/sdk/include/asio/asio/handler_type.hpp @@ -0,0 +1,50 @@ +// +// handler_type.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_HANDLER_TYPE_HPP +#define ASIO_HANDLER_TYPE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/type_traits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// (Deprecated: Use two-parameter version of async_result.) Default handler +/// type traits provided for all completion token types. +/** + * The handler_type traits class is used for determining the concrete handler + * type to be used for an asynchronous operation. It allows the handler type to + * be determined at the point where the specific completion handler signature + * is known. + * + * This template may be specialised for user-defined completion token types. + */ +template +struct handler_type +{ + /// The handler type for the specific signature. + typedef typename conditional< + is_same::type>::value, + decay, + handler_type::type, Signature> + >::type::type type; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_HANDLER_TYPE_HPP diff --git a/tools/sdk/include/asio/asio/high_resolution_timer.hpp b/tools/sdk/include/asio/asio/high_resolution_timer.hpp new file mode 100644 index 00000000..0549cc25 --- /dev/null +++ b/tools/sdk/include/asio/asio/high_resolution_timer.hpp @@ -0,0 +1,44 @@ +// +// high_resolution_timer.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_HIGH_RESOLUTION_TIMER_HPP +#define ASIO_HIGH_RESOLUTION_TIMER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) + +#include "asio/basic_waitable_timer.hpp" +#include "asio/detail/chrono.hpp" + +namespace asio { + +/// Typedef for a timer based on the high resolution clock. +/** + * This typedef uses the C++11 @c <chrono> standard library facility, if + * available. Otherwise, it may use the Boost.Chrono library. To explicitly + * utilise Boost.Chrono, use the basic_waitable_timer template directly: + * @code + * typedef basic_waitable_timer timer; + * @endcode + */ +typedef basic_waitable_timer< + chrono::high_resolution_clock> + high_resolution_timer; + +} // namespace asio + +#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_HIGH_RESOLUTION_TIMER_HPP diff --git a/tools/sdk/include/asio/asio/impl/buffered_read_stream.hpp b/tools/sdk/include/asio/asio/impl/buffered_read_stream.hpp new file mode 100644 index 00000000..e0ed20e4 --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/buffered_read_stream.hpp @@ -0,0 +1,429 @@ +// +// impl/buffered_read_stream.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_BUFFERED_READ_STREAM_HPP +#define ASIO_IMPL_BUFFERED_READ_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/associated_allocator.hpp" +#include "asio/associated_executor.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/handler_type_requirements.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +template +std::size_t buffered_read_stream::fill() +{ + detail::buffer_resize_guard + resize_guard(storage_); + std::size_t previous_size = storage_.size(); + storage_.resize(storage_.capacity()); + storage_.resize(previous_size + next_layer_.read_some(buffer( + storage_.data() + previous_size, + storage_.size() - previous_size))); + resize_guard.commit(); + return storage_.size() - previous_size; +} + +template +std::size_t buffered_read_stream::fill(asio::error_code& ec) +{ + detail::buffer_resize_guard + resize_guard(storage_); + std::size_t previous_size = storage_.size(); + storage_.resize(storage_.capacity()); + storage_.resize(previous_size + next_layer_.read_some(buffer( + storage_.data() + previous_size, + storage_.size() - previous_size), + ec)); + resize_guard.commit(); + return storage_.size() - previous_size; +} + +namespace detail +{ + template + class buffered_fill_handler + { + public: + buffered_fill_handler(detail::buffered_stream_storage& storage, + std::size_t previous_size, ReadHandler& handler) + : storage_(storage), + previous_size_(previous_size), + handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + buffered_fill_handler(const buffered_fill_handler& other) + : storage_(other.storage_), + previous_size_(other.previous_size_), + handler_(other.handler_) + { + } + + buffered_fill_handler(buffered_fill_handler&& other) + : storage_(other.storage_), + previous_size_(other.previous_size_), + handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + const std::size_t bytes_transferred) + { + storage_.resize(previous_size_ + bytes_transferred); + handler_(ec, bytes_transferred); + } + + //private: + detail::buffered_stream_storage& storage_; + std::size_t previous_size_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + buffered_fill_handler* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + buffered_fill_handler* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + buffered_fill_handler* this_handler) + { + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + buffered_fill_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + buffered_fill_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::buffered_fill_handler, Allocator> +{ + typedef typename associated_allocator::type type; + + static type get(const detail::buffered_fill_handler& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::buffered_fill_handler, Executor> +{ + typedef typename associated_executor::type type; + + static type get(const detail::buffered_fill_handler& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +buffered_read_stream::async_fill( + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + async_completion init(handler); + + std::size_t previous_size = storage_.size(); + storage_.resize(storage_.capacity()); + next_layer_.async_read_some( + buffer( + storage_.data() + previous_size, + storage_.size() - previous_size), + detail::buffered_fill_handler( + storage_, previous_size, init.completion_handler)); + + return init.result.get(); +} + +template +template +std::size_t buffered_read_stream::read_some( + const MutableBufferSequence& buffers) +{ + using asio::buffer_size; + if (buffer_size(buffers) == 0) + return 0; + + if (storage_.empty()) + this->fill(); + + return this->copy(buffers); +} + +template +template +std::size_t buffered_read_stream::read_some( + const MutableBufferSequence& buffers, asio::error_code& ec) +{ + ec = asio::error_code(); + + using asio::buffer_size; + if (buffer_size(buffers) == 0) + return 0; + + if (storage_.empty() && !this->fill(ec)) + return 0; + + return this->copy(buffers); +} + +namespace detail +{ + template + class buffered_read_some_handler + { + public: + buffered_read_some_handler(detail::buffered_stream_storage& storage, + const MutableBufferSequence& buffers, ReadHandler& handler) + : storage_(storage), + buffers_(buffers), + handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + buffered_read_some_handler(const buffered_read_some_handler& other) + : storage_(other.storage_), + buffers_(other.buffers_), + handler_(other.handler_) + { + } + + buffered_read_some_handler(buffered_read_some_handler&& other) + : storage_(other.storage_), + buffers_(other.buffers_), + handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, std::size_t) + { + if (ec || storage_.empty()) + { + const std::size_t length = 0; + handler_(ec, length); + } + else + { + const std::size_t bytes_copied = asio::buffer_copy( + buffers_, storage_.data(), storage_.size()); + storage_.consume(bytes_copied); + handler_(ec, bytes_copied); + } + } + + //private: + detail::buffered_stream_storage& storage_; + MutableBufferSequence buffers_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::buffered_read_some_handler, + Allocator> +{ + typedef typename associated_allocator::type type; + + static type get( + const detail::buffered_read_some_handler< + MutableBufferSequence, ReadHandler>& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::buffered_read_some_handler, + Executor> +{ + typedef typename associated_executor::type type; + + static type get( + const detail::buffered_read_some_handler< + MutableBufferSequence, ReadHandler>& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +buffered_read_stream::async_read_some( + const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + async_completion init(handler); + + using asio::buffer_size; + if (buffer_size(buffers) == 0 || !storage_.empty()) + { + next_layer_.async_read_some(ASIO_MUTABLE_BUFFER(0, 0), + detail::buffered_read_some_handler< + MutableBufferSequence, ASIO_HANDLER_TYPE( + ReadHandler, void (asio::error_code, std::size_t))>( + storage_, buffers, init.completion_handler)); + } + else + { + this->async_fill(detail::buffered_read_some_handler< + MutableBufferSequence, ASIO_HANDLER_TYPE( + ReadHandler, void (asio::error_code, std::size_t))>( + storage_, buffers, init.completion_handler)); + } + + return init.result.get(); +} + +template +template +std::size_t buffered_read_stream::peek( + const MutableBufferSequence& buffers) +{ + if (storage_.empty()) + this->fill(); + return this->peek_copy(buffers); +} + +template +template +std::size_t buffered_read_stream::peek( + const MutableBufferSequence& buffers, asio::error_code& ec) +{ + ec = asio::error_code(); + if (storage_.empty() && !this->fill(ec)) + return 0; + return this->peek_copy(buffers); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_BUFFERED_READ_STREAM_HPP diff --git a/tools/sdk/include/asio/asio/impl/buffered_write_stream.hpp b/tools/sdk/include/asio/asio/impl/buffered_write_stream.hpp new file mode 100644 index 00000000..bc2d823a --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/buffered_write_stream.hpp @@ -0,0 +1,411 @@ +// +// impl/buffered_write_stream.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_BUFFERED_WRITE_STREAM_HPP +#define ASIO_IMPL_BUFFERED_WRITE_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/associated_allocator.hpp" +#include "asio/associated_executor.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/handler_type_requirements.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +template +std::size_t buffered_write_stream::flush() +{ + std::size_t bytes_written = write(next_layer_, + buffer(storage_.data(), storage_.size())); + storage_.consume(bytes_written); + return bytes_written; +} + +template +std::size_t buffered_write_stream::flush(asio::error_code& ec) +{ + std::size_t bytes_written = write(next_layer_, + buffer(storage_.data(), storage_.size()), + transfer_all(), ec); + storage_.consume(bytes_written); + return bytes_written; +} + +namespace detail +{ + template + class buffered_flush_handler + { + public: + buffered_flush_handler(detail::buffered_stream_storage& storage, + WriteHandler& handler) + : storage_(storage), + handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + buffered_flush_handler(const buffered_flush_handler& other) + : storage_(other.storage_), + handler_(other.handler_) + { + } + + buffered_flush_handler(buffered_flush_handler&& other) + : storage_(other.storage_), + handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + const std::size_t bytes_written) + { + storage_.consume(bytes_written); + handler_(ec, bytes_written); + } + + //private: + detail::buffered_stream_storage& storage_; + WriteHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + buffered_flush_handler* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + buffered_flush_handler* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + buffered_flush_handler* this_handler) + { + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + buffered_flush_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + buffered_flush_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::buffered_flush_handler, Allocator> +{ + typedef typename associated_allocator::type type; + + static type get(const detail::buffered_flush_handler& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::buffered_flush_handler, Executor> +{ + typedef typename associated_executor::type type; + + static type get(const detail::buffered_flush_handler& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +template +ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +buffered_write_stream::async_flush( + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + async_completion init(handler); + + async_write(next_layer_, buffer(storage_.data(), storage_.size()), + detail::buffered_flush_handler( + storage_, init.completion_handler)); + + return init.result.get(); +} + +template +template +std::size_t buffered_write_stream::write_some( + const ConstBufferSequence& buffers) +{ + using asio::buffer_size; + if (buffer_size(buffers) == 0) + return 0; + + if (storage_.size() == storage_.capacity()) + this->flush(); + + return this->copy(buffers); +} + +template +template +std::size_t buffered_write_stream::write_some( + const ConstBufferSequence& buffers, asio::error_code& ec) +{ + ec = asio::error_code(); + + using asio::buffer_size; + if (buffer_size(buffers) == 0) + return 0; + + if (storage_.size() == storage_.capacity() && !flush(ec)) + return 0; + + return this->copy(buffers); +} + +namespace detail +{ + template + class buffered_write_some_handler + { + public: + buffered_write_some_handler(detail::buffered_stream_storage& storage, + const ConstBufferSequence& buffers, WriteHandler& handler) + : storage_(storage), + buffers_(buffers), + handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + buffered_write_some_handler(const buffered_write_some_handler& other) + : storage_(other.storage_), + buffers_(other.buffers_), + handler_(other.handler_) + { + } + + buffered_write_some_handler(buffered_write_some_handler&& other) + : storage_(other.storage_), + buffers_(other.buffers_), + handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, std::size_t) + { + if (ec) + { + const std::size_t length = 0; + handler_(ec, length); + } + else + { + using asio::buffer_size; + std::size_t orig_size = storage_.size(); + std::size_t space_avail = storage_.capacity() - orig_size; + std::size_t bytes_avail = buffer_size(buffers_); + std::size_t length = bytes_avail < space_avail + ? bytes_avail : space_avail; + storage_.resize(orig_size + length); + const std::size_t bytes_copied = asio::buffer_copy( + storage_.data() + orig_size, buffers_, length); + handler_(ec, bytes_copied); + } + } + + //private: + detail::buffered_stream_storage& storage_; + ConstBufferSequence buffers_; + WriteHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + buffered_write_some_handler< + ConstBufferSequence, WriteHandler>* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + buffered_write_some_handler< + ConstBufferSequence, WriteHandler>* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + buffered_write_some_handler< + ConstBufferSequence, WriteHandler>* this_handler) + { + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + buffered_write_some_handler< + ConstBufferSequence, WriteHandler>* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + buffered_write_some_handler< + ConstBufferSequence, WriteHandler>* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::buffered_write_some_handler, + Allocator> +{ + typedef typename associated_allocator::type type; + + static type get( + const detail::buffered_write_some_handler< + ConstBufferSequence, WriteHandler>& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::buffered_write_some_handler, + Executor> +{ + typedef typename associated_executor::type type; + + static type get( + const detail::buffered_write_some_handler< + ConstBufferSequence, WriteHandler>& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +template +ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +buffered_write_stream::async_write_some( + const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + async_completion init(handler); + + using asio::buffer_size; + if (buffer_size(buffers) == 0 + || storage_.size() < storage_.capacity()) + { + next_layer_.async_write_some(ASIO_CONST_BUFFER(0, 0), + detail::buffered_write_some_handler< + ConstBufferSequence, ASIO_HANDLER_TYPE( + WriteHandler, void (asio::error_code, std::size_t))>( + storage_, buffers, init.completion_handler)); + } + else + { + this->async_flush(detail::buffered_write_some_handler< + ConstBufferSequence, ASIO_HANDLER_TYPE( + WriteHandler, void (asio::error_code, std::size_t))>( + storage_, buffers, init.completion_handler)); + } + + return init.result.get(); +} + +template +template +std::size_t buffered_write_stream::copy( + const ConstBufferSequence& buffers) +{ + using asio::buffer_size; + std::size_t orig_size = storage_.size(); + std::size_t space_avail = storage_.capacity() - orig_size; + std::size_t bytes_avail = buffer_size(buffers); + std::size_t length = bytes_avail < space_avail ? bytes_avail : space_avail; + storage_.resize(orig_size + length); + return asio::buffer_copy( + storage_.data() + orig_size, buffers, length); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_BUFFERED_WRITE_STREAM_HPP diff --git a/tools/sdk/include/asio/asio/impl/connect.hpp b/tools/sdk/include/asio/asio/impl/connect.hpp new file mode 100644 index 00000000..bff1913b --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/connect.hpp @@ -0,0 +1,860 @@ +// +// impl/connect.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_CONNECT_HPP +#define ASIO_IMPL_CONNECT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include "asio/associated_allocator.hpp" +#include "asio/associated_executor.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/post.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +namespace detail +{ + struct default_connect_condition + { + template + bool operator()(const asio::error_code&, const Endpoint&) + { + return true; + } + }; + + template + inline typename Protocol::endpoint deref_connect_result( + Iterator iter, asio::error_code& ec) + { + return ec ? typename Protocol::endpoint() : *iter; + } + + template + struct legacy_connect_condition_helper : T + { + typedef char (*fallback_func_type)(...); + operator fallback_func_type() const; + }; + + template + struct legacy_connect_condition_helper + { + R operator()(Arg1, Arg2) const; + char operator()(...) const; + }; + + template + struct is_legacy_connect_condition + { + static char asio_connect_condition_check(char); + static char (&asio_connect_condition_check(Iterator))[2]; + + static const bool value = + sizeof(asio_connect_condition_check( + (*static_cast*>(0))( + *static_cast(0), + *static_cast(0)))) != 1; + }; + + template + inline Iterator call_connect_condition(ConnectCondition& connect_condition, + const asio::error_code& ec, Iterator next, Iterator end, + typename enable_if::value>::type* = 0) + { + if (next != end) + return connect_condition(ec, next); + return end; + } + + template + inline Iterator call_connect_condition(ConnectCondition& connect_condition, + const asio::error_code& ec, Iterator next, Iterator end, + typename enable_if::value>::type* = 0) + { + for (;next != end; ++next) + if (connect_condition(ec, *next)) + return next; + return end; + } +} + +template +typename Protocol::endpoint connect( + basic_socket& s, + const EndpointSequence& endpoints, + typename enable_if::value>::type*) +{ + asio::error_code ec; + typename Protocol::endpoint result = connect(s, endpoints, ec); + asio::detail::throw_error(ec, "connect"); + return result; +} + +template +typename Protocol::endpoint connect( + basic_socket& s, + const EndpointSequence& endpoints, asio::error_code& ec, + typename enable_if::value>::type*) +{ + return detail::deref_connect_result( + connect(s, endpoints.begin(), endpoints.end(), + detail::default_connect_condition(), ec), ec); +} + +#if !defined(ASIO_NO_DEPRECATED) +template +Iterator connect(basic_socket& s, Iterator begin, + typename enable_if::value>::type*) +{ + asio::error_code ec; + Iterator result = connect(s, begin, ec); + asio::detail::throw_error(ec, "connect"); + return result; +} + +template +inline Iterator connect(basic_socket& s, + Iterator begin, asio::error_code& ec, + typename enable_if::value>::type*) +{ + return connect(s, begin, Iterator(), detail::default_connect_condition(), ec); +} +#endif // !defined(ASIO_NO_DEPRECATED) + +template +Iterator connect(basic_socket& s, + Iterator begin, Iterator end) +{ + asio::error_code ec; + Iterator result = connect(s, begin, end, ec); + asio::detail::throw_error(ec, "connect"); + return result; +} + +template +inline Iterator connect(basic_socket& s, + Iterator begin, Iterator end, asio::error_code& ec) +{ + return connect(s, begin, end, detail::default_connect_condition(), ec); +} + +template +typename Protocol::endpoint connect( + basic_socket& s, + const EndpointSequence& endpoints, ConnectCondition connect_condition, + typename enable_if::value>::type*) +{ + asio::error_code ec; + typename Protocol::endpoint result = connect( + s, endpoints, connect_condition, ec); + asio::detail::throw_error(ec, "connect"); + return result; +} + +template +typename Protocol::endpoint connect( + basic_socket& s, + const EndpointSequence& endpoints, ConnectCondition connect_condition, + asio::error_code& ec, + typename enable_if::value>::type*) +{ + return detail::deref_connect_result( + connect(s, endpoints.begin(), endpoints.end(), + connect_condition, ec), ec); +} + +#if !defined(ASIO_NO_DEPRECATED) +template +Iterator connect(basic_socket& s, + Iterator begin, ConnectCondition connect_condition, + typename enable_if::value>::type*) +{ + asio::error_code ec; + Iterator result = connect(s, begin, connect_condition, ec); + asio::detail::throw_error(ec, "connect"); + return result; +} + +template +inline Iterator connect(basic_socket& s, + Iterator begin, ConnectCondition connect_condition, + asio::error_code& ec, + typename enable_if::value>::type*) +{ + return connect(s, begin, Iterator(), connect_condition, ec); +} +#endif // !defined(ASIO_NO_DEPRECATED) + +template +Iterator connect(basic_socket& s, + Iterator begin, Iterator end, ConnectCondition connect_condition) +{ + asio::error_code ec; + Iterator result = connect(s, begin, end, connect_condition, ec); + asio::detail::throw_error(ec, "connect"); + return result; +} + +template +Iterator connect(basic_socket& s, + Iterator begin, Iterator end, ConnectCondition connect_condition, + asio::error_code& ec) +{ + ec = asio::error_code(); + + for (Iterator iter = begin; iter != end; ++iter) + { + iter = (detail::call_connect_condition(connect_condition, ec, iter, end)); + if (iter != end) + { + s.close(ec); + s.connect(*iter, ec); + if (!ec) + return iter; + } + else + break; + } + + if (!ec) + ec = asio::error::not_found; + + return end; +} + +namespace detail +{ + // Enable the empty base class optimisation for the connect condition. + template + class base_from_connect_condition + { + protected: + explicit base_from_connect_condition( + const ConnectCondition& connect_condition) + : connect_condition_(connect_condition) + { + } + + template + void check_condition(const asio::error_code& ec, + Iterator& iter, Iterator& end) + { + iter = detail::call_connect_condition(connect_condition_, ec, iter, end); + } + + private: + ConnectCondition connect_condition_; + }; + + // The default_connect_condition implementation is essentially a no-op. This + // template specialisation lets us eliminate all costs associated with it. + template <> + class base_from_connect_condition + { + protected: + explicit base_from_connect_condition(const default_connect_condition&) + { + } + + template + void check_condition(const asio::error_code&, Iterator&, Iterator&) + { + } + }; + + template + class range_connect_op : base_from_connect_condition + { + public: + range_connect_op(basic_socket& sock, + const EndpointSequence& endpoints, + const ConnectCondition& connect_condition, + RangeConnectHandler& handler) + : base_from_connect_condition(connect_condition), + socket_(sock), + endpoints_(endpoints), + index_(0), + start_(0), + handler_(ASIO_MOVE_CAST(RangeConnectHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + range_connect_op(const range_connect_op& other) + : base_from_connect_condition(other), + socket_(other.socket_), + endpoints_(other.endpoints_), + index_(other.index_), + start_(other.start_), + handler_(other.handler_) + { + } + + range_connect_op(range_connect_op&& other) + : base_from_connect_condition(other), + socket_(other.socket_), + endpoints_(other.endpoints_), + index_(other.index_), + start_(other.start_), + handler_(ASIO_MOVE_CAST(RangeConnectHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(asio::error_code ec, int start = 0) + { + typename EndpointSequence::const_iterator begin = endpoints_.begin(); + typename EndpointSequence::const_iterator iter = begin; + std::advance(iter, index_); + typename EndpointSequence::const_iterator end = endpoints_.end(); + + switch (start_ = start) + { + case 1: + for (;;) + { + this->check_condition(ec, iter, end); + index_ = std::distance(begin, iter); + + if (iter != end) + { + socket_.close(ec); + socket_.async_connect(*iter, + ASIO_MOVE_CAST(range_connect_op)(*this)); + return; + } + + if (start) + { + ec = asio::error::not_found; + asio::post(socket_.get_executor(), + detail::bind_handler( + ASIO_MOVE_CAST(range_connect_op)(*this), ec)); + return; + } + + default: + + if (iter == end) + break; + + if (!socket_.is_open()) + { + ec = asio::error::operation_aborted; + break; + } + + if (!ec) + break; + + ++iter; + ++index_; + } + + handler_(static_cast(ec), + static_cast( + ec || iter == end ? typename Protocol::endpoint() : *iter)); + } + } + + //private: + basic_socket& socket_; + EndpointSequence endpoints_; + std::size_t index_; + int start_; + RangeConnectHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + range_connect_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + range_connect_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + range_connect_op* this_handler) + { + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + range_connect_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + range_connect_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + class iterator_connect_op : base_from_connect_condition + { + public: + iterator_connect_op(basic_socket& sock, + const Iterator& begin, const Iterator& end, + const ConnectCondition& connect_condition, + IteratorConnectHandler& handler) + : base_from_connect_condition(connect_condition), + socket_(sock), + iter_(begin), + end_(end), + start_(0), + handler_(ASIO_MOVE_CAST(IteratorConnectHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + iterator_connect_op(const iterator_connect_op& other) + : base_from_connect_condition(other), + socket_(other.socket_), + iter_(other.iter_), + end_(other.end_), + start_(other.start_), + handler_(other.handler_) + { + } + + iterator_connect_op(iterator_connect_op&& other) + : base_from_connect_condition(other), + socket_(other.socket_), + iter_(other.iter_), + end_(other.end_), + start_(other.start_), + handler_(ASIO_MOVE_CAST(IteratorConnectHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(asio::error_code ec, int start = 0) + { + switch (start_ = start) + { + case 1: + for (;;) + { + this->check_condition(ec, iter_, end_); + + if (iter_ != end_) + { + socket_.close(ec); + socket_.async_connect(*iter_, + ASIO_MOVE_CAST(iterator_connect_op)(*this)); + return; + } + + if (start) + { + ec = asio::error::not_found; + asio::post(socket_.get_executor(), + detail::bind_handler( + ASIO_MOVE_CAST(iterator_connect_op)(*this), ec)); + return; + } + + default: + + if (iter_ == end_) + break; + + if (!socket_.is_open()) + { + ec = asio::error::operation_aborted; + break; + } + + if (!ec) + break; + + ++iter_; + } + + handler_(static_cast(ec), + static_cast(iter_)); + } + } + + //private: + basic_socket& socket_; + Iterator iter_; + Iterator end_; + int start_; + IteratorConnectHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + iterator_connect_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + iterator_connect_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + iterator_connect_op* this_handler) + { + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + iterator_connect_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + iterator_connect_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::range_connect_op, + Allocator> +{ + typedef typename associated_allocator< + RangeConnectHandler, Allocator>::type type; + + static type get( + const detail::range_connect_op& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::range_connect_op, + Executor> +{ + typedef typename associated_executor< + RangeConnectHandler, Executor>::type type; + + static type get( + const detail::range_connect_op& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +template +struct associated_allocator< + detail::iterator_connect_op, + Allocator> +{ + typedef typename associated_allocator< + IteratorConnectHandler, Allocator>::type type; + + static type get( + const detail::iterator_connect_op& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::iterator_connect_op, + Executor> +{ + typedef typename associated_executor< + IteratorConnectHandler, Executor>::type type; + + static type get( + const detail::iterator_connect_op& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +inline ASIO_INITFN_RESULT_TYPE(RangeConnectHandler, + void (asio::error_code, typename Protocol::endpoint)) +async_connect(basic_socket& s, + const EndpointSequence& endpoints, + ASIO_MOVE_ARG(RangeConnectHandler) handler, + typename enable_if::value>::type*) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a RangeConnectHandler. + ASIO_RANGE_CONNECT_HANDLER_CHECK( + RangeConnectHandler, handler, typename Protocol::endpoint) type_check; + + async_completion + init(handler); + + detail::range_connect_op(s, + endpoints, detail::default_connect_condition(), + init.completion_handler)(asio::error_code(), 1); + + return init.result.get(); +} + +#if !defined(ASIO_NO_DEPRECATED) +template +inline ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, + void (asio::error_code, Iterator)) +async_connect(basic_socket& s, + Iterator begin, ASIO_MOVE_ARG(IteratorConnectHandler) handler, + typename enable_if::value>::type*) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a IteratorConnectHandler. + ASIO_ITERATOR_CONNECT_HANDLER_CHECK( + IteratorConnectHandler, handler, Iterator) type_check; + + async_completion init(handler); + + detail::iterator_connect_op(s, + begin, Iterator(), detail::default_connect_condition(), + init.completion_handler)(asio::error_code(), 1); + + return init.result.get(); +} +#endif // !defined(ASIO_NO_DEPRECATED) + +template +inline ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, + void (asio::error_code, Iterator)) +async_connect(basic_socket& s, + Iterator begin, Iterator end, + ASIO_MOVE_ARG(IteratorConnectHandler) handler) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a IteratorConnectHandler. + ASIO_ITERATOR_CONNECT_HANDLER_CHECK( + IteratorConnectHandler, handler, Iterator) type_check; + + async_completion init(handler); + + detail::iterator_connect_op(s, + begin, end, detail::default_connect_condition(), + init.completion_handler)(asio::error_code(), 1); + + return init.result.get(); +} + +template +inline ASIO_INITFN_RESULT_TYPE(RangeConnectHandler, + void (asio::error_code, typename Protocol::endpoint)) +async_connect(basic_socket& s, + const EndpointSequence& endpoints, ConnectCondition connect_condition, + ASIO_MOVE_ARG(RangeConnectHandler) handler, + typename enable_if::value>::type*) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a RangeConnectHandler. + ASIO_RANGE_CONNECT_HANDLER_CHECK( + RangeConnectHandler, handler, typename Protocol::endpoint) type_check; + + async_completion + init(handler); + + detail::range_connect_op(s, + endpoints, connect_condition, init.completion_handler)( + asio::error_code(), 1); + + return init.result.get(); +} + +#if !defined(ASIO_NO_DEPRECATED) +template +inline ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, + void (asio::error_code, Iterator)) +async_connect(basic_socket& s, + Iterator begin, ConnectCondition connect_condition, + ASIO_MOVE_ARG(IteratorConnectHandler) handler, + typename enable_if::value>::type*) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a IteratorConnectHandler. + ASIO_ITERATOR_CONNECT_HANDLER_CHECK( + IteratorConnectHandler, handler, Iterator) type_check; + + async_completion init(handler); + + detail::iterator_connect_op(s, + begin, Iterator(), connect_condition, init.completion_handler)( + asio::error_code(), 1); + + return init.result.get(); +} +#endif // !defined(ASIO_NO_DEPRECATED) + +template +inline ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, + void (asio::error_code, Iterator)) +async_connect(basic_socket& s, + Iterator begin, Iterator end, ConnectCondition connect_condition, + ASIO_MOVE_ARG(IteratorConnectHandler) handler) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a IteratorConnectHandler. + ASIO_ITERATOR_CONNECT_HANDLER_CHECK( + IteratorConnectHandler, handler, Iterator) type_check; + + async_completion init(handler); + + detail::iterator_connect_op(s, + begin, end, connect_condition, init.completion_handler)( + asio::error_code(), 1); + + return init.result.get(); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_CONNECT_HPP diff --git a/tools/sdk/include/asio/asio/impl/defer.hpp b/tools/sdk/include/asio/asio/impl/defer.hpp new file mode 100644 index 00000000..a27df0f1 --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/defer.hpp @@ -0,0 +1,77 @@ +// +// impl/defer.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_DEFER_HPP +#define ASIO_IMPL_DEFER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/associated_allocator.hpp" +#include "asio/associated_executor.hpp" +#include "asio/detail/work_dispatcher.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer( + ASIO_MOVE_ARG(CompletionToken) token) +{ + typedef ASIO_HANDLER_TYPE(CompletionToken, void()) handler; + + async_completion init(token); + + typename associated_executor::type ex( + (get_associated_executor)(init.completion_handler)); + + typename associated_allocator::type alloc( + (get_associated_allocator)(init.completion_handler)); + + ex.defer(ASIO_MOVE_CAST(handler)(init.completion_handler), alloc); + + return init.result.get(); +} + +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer( + const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token, + typename enable_if::value>::type*) +{ + typedef ASIO_HANDLER_TYPE(CompletionToken, void()) handler; + + async_completion init(token); + + typename associated_allocator::type alloc( + (get_associated_allocator)(init.completion_handler)); + + ex.defer(detail::work_dispatcher(init.completion_handler), alloc); + + return init.result.get(); +} + +template +inline ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer( + ExecutionContext& ctx, ASIO_MOVE_ARG(CompletionToken) token, + typename enable_if::value>::type*) +{ + return (defer)(ctx.get_executor(), + ASIO_MOVE_CAST(CompletionToken)(token)); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_DEFER_HPP diff --git a/tools/sdk/include/asio/asio/impl/dispatch.hpp b/tools/sdk/include/asio/asio/impl/dispatch.hpp new file mode 100644 index 00000000..4e11c6b2 --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/dispatch.hpp @@ -0,0 +1,78 @@ +// +// impl/dispatch.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_DISPATCH_HPP +#define ASIO_IMPL_DISPATCH_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/associated_allocator.hpp" +#include "asio/associated_executor.hpp" +#include "asio/detail/work_dispatcher.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch( + ASIO_MOVE_ARG(CompletionToken) token) +{ + typedef ASIO_HANDLER_TYPE(CompletionToken, void()) handler; + + async_completion init(token); + + typename associated_executor::type ex( + (get_associated_executor)(init.completion_handler)); + + typename associated_allocator::type alloc( + (get_associated_allocator)(init.completion_handler)); + + ex.dispatch(ASIO_MOVE_CAST(handler)(init.completion_handler), alloc); + + return init.result.get(); +} + +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch( + const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token, + typename enable_if::value>::type*) +{ + typedef ASIO_HANDLER_TYPE(CompletionToken, void()) handler; + + async_completion init(token); + + typename associated_allocator::type alloc( + (get_associated_allocator)(init.completion_handler)); + + ex.dispatch(detail::work_dispatcher( + init.completion_handler), alloc); + + return init.result.get(); +} + +template +inline ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch( + ExecutionContext& ctx, ASIO_MOVE_ARG(CompletionToken) token, + typename enable_if::value>::type*) +{ + return (dispatch)(ctx.get_executor(), + ASIO_MOVE_CAST(CompletionToken)(token)); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_DISPATCH_HPP diff --git a/tools/sdk/include/asio/asio/impl/execution_context.hpp b/tools/sdk/include/asio/asio/impl/execution_context.hpp new file mode 100644 index 00000000..3d1e457e --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/execution_context.hpp @@ -0,0 +1,107 @@ +// +// impl/execution_context.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_EXECUTION_CONTEXT_HPP +#define ASIO_IMPL_EXECUTION_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/scoped_ptr.hpp" +#include "asio/detail/service_registry.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +template +inline Service& use_service(execution_context& e) +{ + // Check that Service meets the necessary type requirements. + (void)static_cast(static_cast(0)); + + return e.service_registry_->template use_service(); +} + +#if !defined(GENERATING_DOCUMENTATION) +# if defined(ASIO_HAS_VARIADIC_TEMPLATES) + +template +Service& make_service(execution_context& e, ASIO_MOVE_ARG(Args)... args) +{ + detail::scoped_ptr svc( + new Service(e, ASIO_MOVE_CAST(Args)(args)...)); + e.service_registry_->template add_service(svc.get()); + Service& result = *svc; + svc.release(); + return result; +} + +# else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +template +Service& make_service(execution_context& e) +{ + detail::scoped_ptr svc(new Service(e)); + e.service_registry_->template add_service(svc.get()); + Service& result = *svc; + svc.release(); + return result; +} + +#define ASIO_PRIVATE_MAKE_SERVICE_DEF(n) \ + template \ + Service& make_service(execution_context& e, \ + ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + detail::scoped_ptr svc( \ + new Service(e, ASIO_VARIADIC_MOVE_ARGS(n))); \ + e.service_registry_->template add_service(svc.get()); \ + Service& result = *svc; \ + svc.release(); \ + return result; \ + } \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_MAKE_SERVICE_DEF) +#undef ASIO_PRIVATE_MAKE_SERVICE_DEF + +# endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) +#endif // !defined(GENERATING_DOCUMENTATION) + +template +inline void add_service(execution_context& e, Service* svc) +{ + // Check that Service meets the necessary type requirements. + (void)static_cast(static_cast(0)); + + e.service_registry_->template add_service(svc); +} + +template +inline bool has_service(execution_context& e) +{ + // Check that Service meets the necessary type requirements. + (void)static_cast(static_cast(0)); + + return e.service_registry_->template has_service(); +} + +inline execution_context& execution_context::service::context() +{ + return owner_; +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_EXECUTION_CONTEXT_HPP diff --git a/tools/sdk/include/asio/asio/impl/executor.hpp b/tools/sdk/include/asio/asio/impl/executor.hpp new file mode 100644 index 00000000..0fcf5f54 --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/executor.hpp @@ -0,0 +1,386 @@ +// +// impl/executor.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_EXECUTOR_HPP +#define ASIO_IMPL_EXECUTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/atomic_count.hpp" +#include "asio/detail/executor_op.hpp" +#include "asio/detail/global.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/recycling_allocator.hpp" +#include "asio/executor.hpp" +#include "asio/system_executor.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +#if !defined(GENERATING_DOCUMENTATION) + +#if defined(ASIO_HAS_MOVE) + +// Lightweight, move-only function object wrapper. +class executor::function +{ +public: + template + explicit function(F f, const Alloc& a) + { + // Allocate and construct an operation to wrap the function. + typedef detail::executor_op op; + typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; + op_ = new (p.v) op(ASIO_MOVE_CAST(F)(f), a); + p.v = 0; + } + + function(function&& other) + : op_(other.op_) + { + other.op_ = 0; + } + + ~function() + { + if (op_) + op_->destroy(); + } + + void operator()() + { + if (op_) + { + detail::scheduler_operation* op = op_; + op_ = 0; + op->complete(this, asio::error_code(), 0); + } + } + +private: + detail::scheduler_operation* op_; +}; + +#else // defined(ASIO_HAS_MOVE) + +// Not so lightweight, copyable function object wrapper. +class executor::function +{ +public: + template + explicit function(const F& f, const Alloc&) + : impl_(new impl(f)) + { + } + + void operator()() + { + impl_->invoke_(impl_.get()); + } + +private: + // Base class for polymorphic function implementations. + struct impl_base + { + void (*invoke_)(impl_base*); + }; + + // Polymorphic function implementation. + template + struct impl : impl_base + { + impl(const F& f) + : function_(f) + { + invoke_ = &function::invoke; + } + + F function_; + }; + + // Helper to invoke a function. + template + static void invoke(impl_base* i) + { + static_cast*>(i)->function_(); + } + + detail::shared_ptr impl_; +}; + +#endif // defined(ASIO_HAS_MOVE) + +// Default polymorphic allocator implementation. +template +class executor::impl + : public executor::impl_base +{ +public: + typedef ASIO_REBIND_ALLOC(Allocator, impl) allocator_type; + + static impl_base* create(const Executor& e, Allocator a = Allocator()) + { + raw_mem mem(a); + impl* p = new (mem.ptr_) impl(e, a); + mem.ptr_ = 0; + return p; + } + + impl(const Executor& e, const Allocator& a) ASIO_NOEXCEPT + : impl_base(false), + ref_count_(1), + executor_(e), + allocator_(a) + { + } + + impl_base* clone() const ASIO_NOEXCEPT + { + ++ref_count_; + return const_cast(static_cast(this)); + } + + void destroy() ASIO_NOEXCEPT + { + if (--ref_count_ == 0) + { + allocator_type alloc(allocator_); + impl* p = this; + p->~impl(); + alloc.deallocate(p, 1); + } + } + + void on_work_started() ASIO_NOEXCEPT + { + executor_.on_work_started(); + } + + void on_work_finished() ASIO_NOEXCEPT + { + executor_.on_work_finished(); + } + + execution_context& context() ASIO_NOEXCEPT + { + return executor_.context(); + } + + void dispatch(ASIO_MOVE_ARG(function) f) + { + executor_.dispatch(ASIO_MOVE_CAST(function)(f), allocator_); + } + + void post(ASIO_MOVE_ARG(function) f) + { + executor_.post(ASIO_MOVE_CAST(function)(f), allocator_); + } + + void defer(ASIO_MOVE_ARG(function) f) + { + executor_.defer(ASIO_MOVE_CAST(function)(f), allocator_); + } + + type_id_result_type target_type() const ASIO_NOEXCEPT + { + return type_id(); + } + + void* target() ASIO_NOEXCEPT + { + return &executor_; + } + + const void* target() const ASIO_NOEXCEPT + { + return &executor_; + } + + bool equals(const impl_base* e) const ASIO_NOEXCEPT + { + if (this == e) + return true; + if (target_type() != e->target_type()) + return false; + return executor_ == *static_cast(e->target()); + } + +private: + mutable detail::atomic_count ref_count_; + Executor executor_; + Allocator allocator_; + + struct raw_mem + { + allocator_type allocator_; + impl* ptr_; + + explicit raw_mem(const Allocator& a) + : allocator_(a), + ptr_(allocator_.allocate(1)) + { + } + + ~raw_mem() + { + if (ptr_) + allocator_.deallocate(ptr_, 1); + } + + private: + // Disallow copying and assignment. + raw_mem(const raw_mem&); + raw_mem operator=(const raw_mem&); + }; +}; + +// Polymorphic allocator specialisation for system_executor. +template +class executor::impl + : public executor::impl_base +{ +public: + static impl_base* create(const system_executor&, + const Allocator& = Allocator()) + { + return &detail::global > >(); + } + + impl() + : impl_base(true) + { + } + + impl_base* clone() const ASIO_NOEXCEPT + { + return const_cast(static_cast(this)); + } + + void destroy() ASIO_NOEXCEPT + { + } + + void on_work_started() ASIO_NOEXCEPT + { + executor_.on_work_started(); + } + + void on_work_finished() ASIO_NOEXCEPT + { + executor_.on_work_finished(); + } + + execution_context& context() ASIO_NOEXCEPT + { + return executor_.context(); + } + + void dispatch(ASIO_MOVE_ARG(function) f) + { + executor_.dispatch(ASIO_MOVE_CAST(function)(f), allocator_); + } + + void post(ASIO_MOVE_ARG(function) f) + { + executor_.post(ASIO_MOVE_CAST(function)(f), allocator_); + } + + void defer(ASIO_MOVE_ARG(function) f) + { + executor_.defer(ASIO_MOVE_CAST(function)(f), allocator_); + } + + type_id_result_type target_type() const ASIO_NOEXCEPT + { + return type_id(); + } + + void* target() ASIO_NOEXCEPT + { + return &executor_; + } + + const void* target() const ASIO_NOEXCEPT + { + return &executor_; + } + + bool equals(const impl_base* e) const ASIO_NOEXCEPT + { + return this == e; + } + +private: + system_executor executor_; + Allocator allocator_; +}; + +template +executor::executor(Executor e) + : impl_(impl >::create(e)) +{ +} + +template +executor::executor(allocator_arg_t, const Allocator& a, Executor e) + : impl_(impl::create(e, a)) +{ +} + +template +void executor::dispatch(ASIO_MOVE_ARG(Function) f, + const Allocator& a) const +{ + impl_base* i = get_impl(); + if (i->fast_dispatch_) + system_executor().dispatch(ASIO_MOVE_CAST(Function)(f), a); + else + i->dispatch(function(ASIO_MOVE_CAST(Function)(f), a)); +} + +template +void executor::post(ASIO_MOVE_ARG(Function) f, + const Allocator& a) const +{ + get_impl()->post(function(ASIO_MOVE_CAST(Function)(f), a)); +} + +template +void executor::defer(ASIO_MOVE_ARG(Function) f, + const Allocator& a) const +{ + get_impl()->defer(function(ASIO_MOVE_CAST(Function)(f), a)); +} + +template +Executor* executor::target() ASIO_NOEXCEPT +{ + return impl_ && impl_->target_type() == type_id() + ? static_cast(impl_->target()) : 0; +} + +template +const Executor* executor::target() const ASIO_NOEXCEPT +{ + return impl_ && impl_->target_type() == type_id() + ? static_cast(impl_->target()) : 0; +} + +#endif // !defined(GENERATING_DOCUMENTATION) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_EXECUTOR_HPP diff --git a/tools/sdk/include/asio/asio/impl/io_context.hpp b/tools/sdk/include/asio/asio/impl/io_context.hpp new file mode 100644 index 00000000..eaf580da --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/io_context.hpp @@ -0,0 +1,343 @@ +// +// impl/io_context.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_IO_CONTEXT_HPP +#define ASIO_IMPL_IO_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/completion_handler.hpp" +#include "asio/detail/executor_op.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/recycling_allocator.hpp" +#include "asio/detail/service_registry.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/type_traits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +template +inline Service& use_service(io_context& ioc) +{ + // Check that Service meets the necessary type requirements. + (void)static_cast(static_cast(0)); + (void)static_cast(&Service::id); + + return ioc.service_registry_->template use_service(ioc); +} + +template <> +inline detail::io_context_impl& use_service( + io_context& ioc) +{ + return ioc.impl_; +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_io_context.hpp" +#else +# include "asio/detail/scheduler.hpp" +#endif + +#include "asio/detail/push_options.hpp" + +namespace asio { + +inline io_context::executor_type +io_context::get_executor() ASIO_NOEXCEPT +{ + return executor_type(*this); +} + +#if defined(ASIO_HAS_CHRONO) + +template +std::size_t io_context::run_for( + const chrono::duration& rel_time) +{ + return this->run_until(chrono::steady_clock::now() + rel_time); +} + +template +std::size_t io_context::run_until( + const chrono::time_point& abs_time) +{ + std::size_t n = 0; + while (this->run_one_until(abs_time)) + if (n != (std::numeric_limits::max)()) + ++n; + return n; +} + +template +std::size_t io_context::run_one_for( + const chrono::duration& rel_time) +{ + return this->run_one_until(chrono::steady_clock::now() + rel_time); +} + +template +std::size_t io_context::run_one_until( + const chrono::time_point& abs_time) +{ + typename Clock::time_point now = Clock::now(); + while (now < abs_time) + { + typename Clock::duration rel_time = abs_time - now; + if (rel_time > chrono::seconds(1)) + rel_time = chrono::seconds(1); + + asio::error_code ec; + std::size_t s = impl_.wait_one( + static_cast(chrono::duration_cast< + chrono::microseconds>(rel_time).count()), ec); + asio::detail::throw_error(ec); + + if (s || impl_.stopped()) + return s; + + now = Clock::now(); + } + + return 0; +} + +#endif // defined(ASIO_HAS_CHRONO) + +#if !defined(ASIO_NO_DEPRECATED) + +inline void io_context::reset() +{ + restart(); +} + +template +ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ()) +io_context::dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a LegacyCompletionHandler. + ASIO_LEGACY_COMPLETION_HANDLER_CHECK( + LegacyCompletionHandler, handler) type_check; + + async_completion init(handler); + + if (impl_.can_dispatch()) + { + detail::fenced_block b(detail::fenced_block::full); + asio_handler_invoke_helpers::invoke( + init.completion_handler, init.completion_handler); + } + else + { + // Allocate and construct an operation to wrap the handler. + typedef detail::completion_handler< + typename handler_type::type> op; + typename op::ptr p = { detail::addressof(init.completion_handler), + op::ptr::allocate(init.completion_handler), 0 }; + p.p = new (p.v) op(init.completion_handler); + + ASIO_HANDLER_CREATION((*this, *p.p, + "io_context", this, 0, "dispatch")); + + impl_.do_dispatch(p.p); + p.v = p.p = 0; + } + + return init.result.get(); +} + +template +ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ()) +io_context::post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a LegacyCompletionHandler. + ASIO_LEGACY_COMPLETION_HANDLER_CHECK( + LegacyCompletionHandler, handler) type_check; + + async_completion init(handler); + + bool is_continuation = + asio_handler_cont_helpers::is_continuation(init.completion_handler); + + // Allocate and construct an operation to wrap the handler. + typedef detail::completion_handler< + typename handler_type::type> op; + typename op::ptr p = { detail::addressof(init.completion_handler), + op::ptr::allocate(init.completion_handler), 0 }; + p.p = new (p.v) op(init.completion_handler); + + ASIO_HANDLER_CREATION((*this, *p.p, + "io_context", this, 0, "post")); + + impl_.post_immediate_completion(p.p, is_continuation); + p.v = p.p = 0; + + return init.result.get(); +} + +template +#if defined(GENERATING_DOCUMENTATION) +unspecified +#else +inline detail::wrapped_handler +#endif +io_context::wrap(Handler handler) +{ + return detail::wrapped_handler(*this, handler); +} + +#endif // !defined(ASIO_NO_DEPRECATED) + +inline io_context& +io_context::executor_type::context() const ASIO_NOEXCEPT +{ + return io_context_; +} + +inline void +io_context::executor_type::on_work_started() const ASIO_NOEXCEPT +{ + io_context_.impl_.work_started(); +} + +inline void +io_context::executor_type::on_work_finished() const ASIO_NOEXCEPT +{ + io_context_.impl_.work_finished(); +} + +template +void io_context::executor_type::dispatch( + ASIO_MOVE_ARG(Function) f, const Allocator& a) const +{ + typedef typename decay::type function_type; + + // Invoke immediately if we are already inside the thread pool. + if (io_context_.impl_.can_dispatch()) + { + // Make a local, non-const copy of the function. + function_type tmp(ASIO_MOVE_CAST(Function)(f)); + + detail::fenced_block b(detail::fenced_block::full); + asio_handler_invoke_helpers::invoke(tmp, tmp); + return; + } + + // Allocate and construct an operation to wrap the function. + typedef detail::executor_op op; + typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; + p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); + + ASIO_HANDLER_CREATION((this->context(), *p.p, + "io_context", &this->context(), 0, "post")); + + io_context_.impl_.post_immediate_completion(p.p, false); + p.v = p.p = 0; +} + +template +void io_context::executor_type::post( + ASIO_MOVE_ARG(Function) f, const Allocator& a) const +{ + typedef typename decay::type function_type; + + // Allocate and construct an operation to wrap the function. + typedef detail::executor_op op; + typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; + p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); + + ASIO_HANDLER_CREATION((this->context(), *p.p, + "io_context", &this->context(), 0, "post")); + + io_context_.impl_.post_immediate_completion(p.p, false); + p.v = p.p = 0; +} + +template +void io_context::executor_type::defer( + ASIO_MOVE_ARG(Function) f, const Allocator& a) const +{ + typedef typename decay::type function_type; + + // Allocate and construct an operation to wrap the function. + typedef detail::executor_op op; + typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; + p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); + + ASIO_HANDLER_CREATION((this->context(), *p.p, + "io_context", &this->context(), 0, "defer")); + + io_context_.impl_.post_immediate_completion(p.p, true); + p.v = p.p = 0; +} + +inline bool +io_context::executor_type::running_in_this_thread() const ASIO_NOEXCEPT +{ + return io_context_.impl_.can_dispatch(); +} + +#if !defined(ASIO_NO_DEPRECATED) +inline io_context::work::work(asio::io_context& io_context) + : io_context_impl_(io_context.impl_) +{ + io_context_impl_.work_started(); +} + +inline io_context::work::work(const work& other) + : io_context_impl_(other.io_context_impl_) +{ + io_context_impl_.work_started(); +} + +inline io_context::work::~work() +{ + io_context_impl_.work_finished(); +} + +inline asio::io_context& io_context::work::get_io_context() +{ + return static_cast(io_context_impl_.context()); +} + +inline asio::io_context& io_context::work::get_io_service() +{ + return static_cast(io_context_impl_.context()); +} +#endif // !defined(ASIO_NO_DEPRECATED) + +inline asio::io_context& io_context::service::get_io_context() +{ + return static_cast(context()); +} + +#if !defined(ASIO_NO_DEPRECATED) +inline asio::io_context& io_context::service::get_io_service() +{ + return static_cast(context()); +} +#endif // !defined(ASIO_NO_DEPRECATED) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_IO_CONTEXT_HPP diff --git a/tools/sdk/include/asio/asio/impl/post.hpp b/tools/sdk/include/asio/asio/impl/post.hpp new file mode 100644 index 00000000..55389532 --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/post.hpp @@ -0,0 +1,77 @@ +// +// impl/post.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_POST_HPP +#define ASIO_IMPL_POST_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/associated_allocator.hpp" +#include "asio/associated_executor.hpp" +#include "asio/detail/work_dispatcher.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post( + ASIO_MOVE_ARG(CompletionToken) token) +{ + typedef ASIO_HANDLER_TYPE(CompletionToken, void()) handler; + + async_completion init(token); + + typename associated_executor::type ex( + (get_associated_executor)(init.completion_handler)); + + typename associated_allocator::type alloc( + (get_associated_allocator)(init.completion_handler)); + + ex.post(ASIO_MOVE_CAST(handler)(init.completion_handler), alloc); + + return init.result.get(); +} + +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post( + const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token, + typename enable_if::value>::type*) +{ + typedef ASIO_HANDLER_TYPE(CompletionToken, void()) handler; + + async_completion init(token); + + typename associated_allocator::type alloc( + (get_associated_allocator)(init.completion_handler)); + + ex.post(detail::work_dispatcher(init.completion_handler), alloc); + + return init.result.get(); +} + +template +inline ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post( + ExecutionContext& ctx, ASIO_MOVE_ARG(CompletionToken) token, + typename enable_if::value>::type*) +{ + return (post)(ctx.get_executor(), + ASIO_MOVE_CAST(CompletionToken)(token)); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_POST_HPP diff --git a/tools/sdk/include/asio/asio/impl/read.hpp b/tools/sdk/include/asio/asio/impl/read.hpp new file mode 100644 index 00000000..603a7a9b --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/read.hpp @@ -0,0 +1,715 @@ +// +// impl/read.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_READ_HPP +#define ASIO_IMPL_READ_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include "asio/associated_allocator.hpp" +#include "asio/associated_executor.hpp" +#include "asio/buffer.hpp" +#include "asio/completion_condition.hpp" +#include "asio/detail/array_fwd.hpp" +#include "asio/detail/base_from_completion_cond.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/consuming_buffers.hpp" +#include "asio/detail/dependent_type.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +namespace detail +{ + template + std::size_t read_buffer_sequence(SyncReadStream& s, + const MutableBufferSequence& buffers, const MutableBufferIterator&, + CompletionCondition completion_condition, asio::error_code& ec) + { + ec = asio::error_code(); + asio::detail::consuming_buffers tmp(buffers); + while (!tmp.empty()) + { + if (std::size_t max_size = detail::adapt_completion_condition_result( + completion_condition(ec, tmp.total_consumed()))) + tmp.consume(s.read_some(tmp.prepare(max_size), ec)); + else + break; + } + return tmp.total_consumed();; + } +} // namespace detail + +template +std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec, + typename enable_if< + is_mutable_buffer_sequence::value + >::type*) +{ + return detail::read_buffer_sequence(s, buffers, + asio::buffer_sequence_begin(buffers), completion_condition, ec); +} + +template +inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + typename enable_if< + is_mutable_buffer_sequence::value + >::type*) +{ + asio::error_code ec; + std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec); + asio::detail::throw_error(ec, "read"); + return bytes_transferred; +} + +template +inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + asio::error_code& ec, + typename enable_if< + is_mutable_buffer_sequence::value + >::type*) +{ + return read(s, buffers, transfer_all(), ec); +} + +template +inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, + typename enable_if< + is_mutable_buffer_sequence::value + >::type*) +{ + asio::error_code ec; + std::size_t bytes_transferred = read(s, buffers, completion_condition, ec); + asio::detail::throw_error(ec, "read"); + return bytes_transferred; +} + +template +std::size_t read(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + CompletionCondition completion_condition, asio::error_code& ec, + typename enable_if< + is_dynamic_buffer::type>::value + >::type*) +{ + typename decay::type b( + ASIO_MOVE_CAST(DynamicBuffer)(buffers)); + + ec = asio::error_code(); + std::size_t total_transferred = 0; + std::size_t max_size = detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred)); + std::size_t bytes_available = std::min( + std::max(512, b.capacity() - b.size()), + std::min(max_size, b.max_size() - b.size())); + while (bytes_available > 0) + { + std::size_t bytes_transferred = s.read_some(b.prepare(bytes_available), ec); + b.commit(bytes_transferred); + total_transferred += bytes_transferred; + max_size = detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred)); + bytes_available = std::min( + std::max(512, b.capacity() - b.size()), + std::min(max_size, b.max_size() - b.size())); + } + return total_transferred; +} + +template +inline std::size_t read(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + typename enable_if< + is_dynamic_buffer::type>::value + >::type*) +{ + asio::error_code ec; + std::size_t bytes_transferred = read(s, + ASIO_MOVE_CAST(DynamicBuffer)(buffers), transfer_all(), ec); + asio::detail::throw_error(ec, "read"); + return bytes_transferred; +} + +template +inline std::size_t read(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + asio::error_code& ec, + typename enable_if< + is_dynamic_buffer::type>::value + >::type*) +{ + return read(s, ASIO_MOVE_CAST(DynamicBuffer)(buffers), + transfer_all(), ec); +} + +template +inline std::size_t read(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + CompletionCondition completion_condition, + typename enable_if< + is_dynamic_buffer::type>::value + >::type*) +{ + asio::error_code ec; + std::size_t bytes_transferred = read(s, + ASIO_MOVE_CAST(DynamicBuffer)(buffers), + completion_condition, ec); + asio::detail::throw_error(ec, "read"); + return bytes_transferred; +} + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +template +inline std::size_t read(SyncReadStream& s, + asio::basic_streambuf& b, + CompletionCondition completion_condition, asio::error_code& ec) +{ + return read(s, basic_streambuf_ref(b), completion_condition, ec); +} + +template +inline std::size_t read(SyncReadStream& s, + asio::basic_streambuf& b) +{ + return read(s, basic_streambuf_ref(b)); +} + +template +inline std::size_t read(SyncReadStream& s, + asio::basic_streambuf& b, + asio::error_code& ec) +{ + return read(s, basic_streambuf_ref(b), ec); +} + +template +inline std::size_t read(SyncReadStream& s, + asio::basic_streambuf& b, + CompletionCondition completion_condition) +{ + return read(s, basic_streambuf_ref(b), completion_condition); +} + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +namespace detail +{ + template + class read_op + : detail::base_from_completion_cond + { + public: + read_op(AsyncReadStream& stream, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, ReadHandler& handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + buffers_(buffers), + start_(0), + handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + read_op(const read_op& other) + : detail::base_from_completion_cond(other), + stream_(other.stream_), + buffers_(other.buffers_), + start_(other.start_), + handler_(other.handler_) + { + } + + read_op(read_op&& other) + : detail::base_from_completion_cond(other), + stream_(other.stream_), + buffers_(other.buffers_), + start_(other.start_), + handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + std::size_t max_size; + switch (start_ = start) + { + case 1: + max_size = this->check_for_completion(ec, buffers_.total_consumed()); + do + { + stream_.async_read_some(buffers_.prepare(max_size), + ASIO_MOVE_CAST(read_op)(*this)); + return; default: + buffers_.consume(bytes_transferred); + if ((!ec && bytes_transferred == 0) || buffers_.empty()) + break; + max_size = this->check_for_completion(ec, buffers_.total_consumed()); + } while (max_size > 0); + + handler_(ec, buffers_.total_consumed()); + } + } + + //private: + AsyncReadStream& stream_; + asio::detail::consuming_buffers buffers_; + int start_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + read_op* this_handler) + { + return this_handler->start_ == 0 ? true + : asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + read_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void start_read_buffer_sequence_op(AsyncReadStream& stream, + const MutableBufferSequence& buffers, const MutableBufferIterator&, + CompletionCondition completion_condition, ReadHandler& handler) + { + detail::read_op( + stream, buffers, completion_condition, handler)( + asio::error_code(), 0, 1); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::read_op, + Allocator> +{ + typedef typename associated_allocator::type type; + + static type get( + const detail::read_op& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::read_op, + Executor> +{ + typedef typename associated_executor::type type; + + static type get( + const detail::read_op& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +inline ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(ReadHandler) handler, + typename enable_if< + is_mutable_buffer_sequence::value + >::type*) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + async_completion init(handler); + + detail::start_read_buffer_sequence_op(s, buffers, + asio::buffer_sequence_begin(buffers), completion_condition, + init.completion_handler); + + return init.result.get(); +} + +template +inline ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler, + typename enable_if< + is_mutable_buffer_sequence::value + >::type*) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + async_completion init(handler); + + detail::start_read_buffer_sequence_op(s, buffers, + asio::buffer_sequence_begin(buffers), transfer_all(), + init.completion_handler); + + return init.result.get(); +} + +namespace detail +{ + template + class read_dynbuf_op + : detail::base_from_completion_cond + { + public: + template + read_dynbuf_op(AsyncReadStream& stream, + ASIO_MOVE_ARG(BufferSequence) buffers, + CompletionCondition completion_condition, ReadHandler& handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), + start_(0), + total_transferred_(0), + handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + read_dynbuf_op(const read_dynbuf_op& other) + : detail::base_from_completion_cond(other), + stream_(other.stream_), + buffers_(other.buffers_), + start_(other.start_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + read_dynbuf_op(read_dynbuf_op&& other) + : detail::base_from_completion_cond(other), + stream_(other.stream_), + buffers_(ASIO_MOVE_CAST(DynamicBuffer)(other.buffers_)), + start_(other.start_), + total_transferred_(other.total_transferred_), + handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + std::size_t max_size, bytes_available; + switch (start_ = start) + { + case 1: + max_size = this->check_for_completion(ec, total_transferred_); + bytes_available = std::min( + std::max(512, + buffers_.capacity() - buffers_.size()), + std::min(max_size, + buffers_.max_size() - buffers_.size())); + for (;;) + { + stream_.async_read_some(buffers_.prepare(bytes_available), + ASIO_MOVE_CAST(read_dynbuf_op)(*this)); + return; default: + total_transferred_ += bytes_transferred; + buffers_.commit(bytes_transferred); + max_size = this->check_for_completion(ec, total_transferred_); + bytes_available = std::min( + std::max(512, + buffers_.capacity() - buffers_.size()), + std::min(max_size, + buffers_.max_size() - buffers_.size())); + if ((!ec && bytes_transferred == 0) || bytes_available == 0) + break; + } + + handler_(ec, static_cast(total_transferred_)); + } + } + + //private: + AsyncReadStream& stream_; + DynamicBuffer buffers_; + int start_; + std::size_t total_transferred_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_dynbuf_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_dynbuf_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + read_dynbuf_op* this_handler) + { + return this_handler->start_ == 0 ? true + : asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + read_dynbuf_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_dynbuf_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::read_dynbuf_op, + Allocator> +{ + typedef typename associated_allocator::type type; + + static type get( + const detail::read_dynbuf_op& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::read_dynbuf_op, + Executor> +{ + typedef typename associated_executor::type type; + + static type get( + const detail::read_dynbuf_op& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +inline ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read(AsyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + ASIO_MOVE_ARG(ReadHandler) handler, + typename enable_if< + is_dynamic_buffer::type>::value + >::type*) +{ + return async_read(s, + ASIO_MOVE_CAST(DynamicBuffer)(buffers), + transfer_all(), ASIO_MOVE_CAST(ReadHandler)(handler)); +} + +template +inline ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read(AsyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(ReadHandler) handler, + typename enable_if< + is_dynamic_buffer::type>::value + >::type*) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + async_completion init(handler); + + detail::read_dynbuf_op::type, + CompletionCondition, ASIO_HANDLER_TYPE( + ReadHandler, void (asio::error_code, std::size_t))>( + s, ASIO_MOVE_CAST(DynamicBuffer)(buffers), + completion_condition, init.completion_handler)( + asio::error_code(), 0, 1); + + return init.result.get(); +} + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +template +inline ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read(AsyncReadStream& s, basic_streambuf& b, + ASIO_MOVE_ARG(ReadHandler) handler) +{ + return async_read(s, basic_streambuf_ref(b), + ASIO_MOVE_CAST(ReadHandler)(handler)); +} + +template +inline ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read(AsyncReadStream& s, basic_streambuf& b, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(ReadHandler) handler) +{ + return async_read(s, basic_streambuf_ref(b), + completion_condition, ASIO_MOVE_CAST(ReadHandler)(handler)); +} + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_READ_HPP diff --git a/tools/sdk/include/asio/asio/impl/read_at.hpp b/tools/sdk/include/asio/asio/impl/read_at.hpp new file mode 100644 index 00000000..d736d4d3 --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/read_at.hpp @@ -0,0 +1,640 @@ +// +// impl/read_at.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_READ_AT_HPP +#define ASIO_IMPL_READ_AT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include "asio/associated_allocator.hpp" +#include "asio/associated_executor.hpp" +#include "asio/buffer.hpp" +#include "asio/completion_condition.hpp" +#include "asio/detail/array_fwd.hpp" +#include "asio/detail/base_from_completion_cond.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/consuming_buffers.hpp" +#include "asio/detail/dependent_type.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +namespace detail +{ + template + std::size_t read_at_buffer_sequence(SyncRandomAccessReadDevice& d, + uint64_t offset, const MutableBufferSequence& buffers, + const MutableBufferIterator&, CompletionCondition completion_condition, + asio::error_code& ec) + { + ec = asio::error_code(); + asio::detail::consuming_buffers tmp(buffers); + while (!tmp.empty()) + { + if (std::size_t max_size = detail::adapt_completion_condition_result( + completion_condition(ec, tmp.total_consumed()))) + { + tmp.consume(d.read_some_at(offset + tmp.total_consumed(), + tmp.prepare(max_size), ec)); + } + else + break; + } + return tmp.total_consumed();; + } +} // namespace detail + +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec) +{ + return detail::read_at_buffer_sequence(d, offset, buffers, + asio::buffer_sequence_begin(buffers), completion_condition, ec); +} + +template +inline std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, const MutableBufferSequence& buffers) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_at( + d, offset, buffers, transfer_all(), ec); + asio::detail::throw_error(ec, "read_at"); + return bytes_transferred; +} + +template +inline std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, const MutableBufferSequence& buffers, + asio::error_code& ec) +{ + return read_at(d, offset, buffers, transfer_all(), ec); +} + +template +inline std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, const MutableBufferSequence& buffers, + CompletionCondition completion_condition) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_at( + d, offset, buffers, completion_condition, ec); + asio::detail::throw_error(ec, "read_at"); + return bytes_transferred; +} + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, asio::basic_streambuf& b, + CompletionCondition completion_condition, asio::error_code& ec) +{ + ec = asio::error_code(); + std::size_t total_transferred = 0; + std::size_t max_size = detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred)); + std::size_t bytes_available = read_size_helper(b, max_size); + while (bytes_available > 0) + { + std::size_t bytes_transferred = d.read_some_at( + offset + total_transferred, b.prepare(bytes_available), ec); + b.commit(bytes_transferred); + total_transferred += bytes_transferred; + max_size = detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred)); + bytes_available = read_size_helper(b, max_size); + } + return total_transferred; +} + +template +inline std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, asio::basic_streambuf& b) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_at( + d, offset, b, transfer_all(), ec); + asio::detail::throw_error(ec, "read_at"); + return bytes_transferred; +} + +template +inline std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, asio::basic_streambuf& b, + asio::error_code& ec) +{ + return read_at(d, offset, b, transfer_all(), ec); +} + +template +inline std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, asio::basic_streambuf& b, + CompletionCondition completion_condition) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_at( + d, offset, b, completion_condition, ec); + asio::detail::throw_error(ec, "read_at"); + return bytes_transferred; +} + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +namespace detail +{ + template + class read_at_op + : detail::base_from_completion_cond + { + public: + read_at_op(AsyncRandomAccessReadDevice& device, + uint64_t offset, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, ReadHandler& handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + device_(device), + offset_(offset), + buffers_(buffers), + start_(0), + handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + read_at_op(const read_at_op& other) + : detail::base_from_completion_cond(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + start_(other.start_), + handler_(other.handler_) + { + } + + read_at_op(read_at_op&& other) + : detail::base_from_completion_cond(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + start_(other.start_), + handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + std::size_t max_size; + switch (start_ = start) + { + case 1: + max_size = this->check_for_completion(ec, buffers_.total_consumed()); + do + { + device_.async_read_some_at( + offset_ + buffers_.total_consumed(), buffers_.prepare(max_size), + ASIO_MOVE_CAST(read_at_op)(*this)); + return; default: + buffers_.consume(bytes_transferred); + if ((!ec && bytes_transferred == 0) || buffers_.empty()) + break; + max_size = this->check_for_completion(ec, buffers_.total_consumed()); + } while (max_size > 0); + + handler_(ec, buffers_.total_consumed()); + } + } + + //private: + AsyncRandomAccessReadDevice& device_; + uint64_t offset_; + asio::detail::consuming_buffers buffers_; + int start_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_at_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_at_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + read_at_op* this_handler) + { + return this_handler->start_ == 0 ? true + : asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + read_at_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_at_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void start_read_at_buffer_sequence_op(AsyncRandomAccessReadDevice& d, + uint64_t offset, const MutableBufferSequence& buffers, + const MutableBufferIterator&, CompletionCondition completion_condition, + ReadHandler& handler) + { + detail::read_at_op( + d, offset, buffers, completion_condition, handler)( + asio::error_code(), 0, 1); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::read_at_op, + Allocator> +{ + typedef typename associated_allocator::type type; + + static type get( + const detail::read_at_op& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::read_at_op, + Executor> +{ + typedef typename associated_executor::type type; + + static type get( + const detail::read_at_op& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +inline ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_at(AsyncRandomAccessReadDevice& d, + uint64_t offset, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + async_completion init(handler); + + detail::start_read_at_buffer_sequence_op(d, offset, buffers, + asio::buffer_sequence_begin(buffers), completion_condition, + init.completion_handler); + + return init.result.get(); +} + +template +inline ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_at(AsyncRandomAccessReadDevice& d, + uint64_t offset, const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + async_completion init(handler); + + detail::start_read_at_buffer_sequence_op(d, offset, buffers, + asio::buffer_sequence_begin(buffers), transfer_all(), + init.completion_handler); + + return init.result.get(); +} + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +namespace detail +{ + template + class read_at_streambuf_op + : detail::base_from_completion_cond + { + public: + read_at_streambuf_op(AsyncRandomAccessReadDevice& device, + uint64_t offset, basic_streambuf& streambuf, + CompletionCondition completion_condition, ReadHandler& handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + device_(device), + offset_(offset), + streambuf_(streambuf), + start_(0), + total_transferred_(0), + handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + read_at_streambuf_op(const read_at_streambuf_op& other) + : detail::base_from_completion_cond(other), + device_(other.device_), + offset_(other.offset_), + streambuf_(other.streambuf_), + start_(other.start_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + read_at_streambuf_op(read_at_streambuf_op&& other) + : detail::base_from_completion_cond(other), + device_(other.device_), + offset_(other.offset_), + streambuf_(other.streambuf_), + start_(other.start_), + total_transferred_(other.total_transferred_), + handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + std::size_t max_size, bytes_available; + switch (start_ = start) + { + case 1: + max_size = this->check_for_completion(ec, total_transferred_); + bytes_available = read_size_helper(streambuf_, max_size); + for (;;) + { + device_.async_read_some_at(offset_ + total_transferred_, + streambuf_.prepare(bytes_available), + ASIO_MOVE_CAST(read_at_streambuf_op)(*this)); + return; default: + total_transferred_ += bytes_transferred; + streambuf_.commit(bytes_transferred); + max_size = this->check_for_completion(ec, total_transferred_); + bytes_available = read_size_helper(streambuf_, max_size); + if ((!ec && bytes_transferred == 0) || bytes_available == 0) + break; + } + + handler_(ec, static_cast(total_transferred_)); + } + } + + //private: + AsyncRandomAccessReadDevice& device_; + uint64_t offset_; + asio::basic_streambuf& streambuf_; + int start_; + std::size_t total_transferred_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_at_streambuf_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_at_streambuf_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + read_at_streambuf_op* this_handler) + { + return this_handler->start_ == 0 ? true + : asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + read_at_streambuf_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_at_streambuf_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::read_at_streambuf_op, + Allocator1> +{ + typedef typename associated_allocator::type type; + + static type get( + const detail::read_at_streambuf_op& h, + const Allocator1& a = Allocator1()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::read_at_streambuf_op, + Executor1> +{ + typedef typename associated_executor::type type; + + static type get( + const detail::read_at_streambuf_op& h, + const Executor1& ex = Executor1()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +inline ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_at(AsyncRandomAccessReadDevice& d, + uint64_t offset, asio::basic_streambuf& b, + CompletionCondition completion_condition, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + async_completion init(handler); + + detail::read_at_streambuf_op( + d, offset, b, completion_condition, init.completion_handler)( + asio::error_code(), 0, 1); + + return init.result.get(); +} + +template +inline ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_at(AsyncRandomAccessReadDevice& d, + uint64_t offset, asio::basic_streambuf& b, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + async_completion init(handler); + + detail::read_at_streambuf_op( + d, offset, b, transfer_all(), init.completion_handler)( + asio::error_code(), 0, 1); + + return init.result.get(); +} + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_READ_AT_HPP diff --git a/tools/sdk/include/asio/asio/impl/read_until.hpp b/tools/sdk/include/asio/asio/impl/read_until.hpp new file mode 100644 index 00000000..1f39e193 --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/read_until.hpp @@ -0,0 +1,1500 @@ +// +// impl/read_until.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_READ_UNTIL_HPP +#define ASIO_IMPL_READ_UNTIL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#include "asio/associated_allocator.hpp" +#include "asio/associated_executor.hpp" +#include "asio/buffer.hpp" +#include "asio/buffers_iterator.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/limits.hpp" +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +template +inline std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, char delim) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_until(s, + ASIO_MOVE_CAST(DynamicBuffer)(buffers), delim, ec); + asio::detail::throw_error(ec, "read_until"); + return bytes_transferred; +} + +template +std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + char delim, asio::error_code& ec) +{ + typename decay::type b( + ASIO_MOVE_CAST(DynamicBuffer)(buffers)); + + std::size_t search_position = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename DynamicBuffer::const_buffers_type buffers_type; + typedef buffers_iterator iterator; + buffers_type data_buffers = b.data(); + iterator begin = iterator::begin(data_buffers); + iterator start_pos = begin + search_position; + iterator end = iterator::end(data_buffers); + + // Look for a match. + iterator iter = std::find(start_pos, end, delim); + if (iter != end) + { + // Found a match. We're done. + ec = asio::error_code(); + return iter - begin + 1; + } + else + { + // No match. Next search can start with the new data. + search_position = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_to_read = std::min( + std::max(512, b.capacity() - b.size()), + std::min(65536, b.max_size() - b.size())); + b.commit(s.read_some(b.prepare(bytes_to_read), ec)); + if (ec) + return 0; + } +} + +template +inline std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + ASIO_STRING_VIEW_PARAM delim) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_until(s, + ASIO_MOVE_CAST(DynamicBuffer)(buffers), delim, ec); + asio::detail::throw_error(ec, "read_until"); + return bytes_transferred; +} + +namespace detail +{ + // Algorithm that finds a subsequence of equal values in a sequence. Returns + // (iterator,true) if a full match was found, in which case the iterator + // points to the beginning of the match. Returns (iterator,false) if a + // partial match was found at the end of the first sequence, in which case + // the iterator points to the beginning of the partial match. Returns + // (last1,false) if no full or partial match was found. + template + std::pair partial_search( + Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) + { + for (Iterator1 iter1 = first1; iter1 != last1; ++iter1) + { + Iterator1 test_iter1 = iter1; + Iterator2 test_iter2 = first2; + for (;; ++test_iter1, ++test_iter2) + { + if (test_iter2 == last2) + return std::make_pair(iter1, true); + if (test_iter1 == last1) + { + if (test_iter2 != first2) + return std::make_pair(iter1, false); + else + break; + } + if (*test_iter1 != *test_iter2) + break; + } + } + return std::make_pair(last1, false); + } +} // namespace detail + +template +std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec) +{ + typename decay::type b( + ASIO_MOVE_CAST(DynamicBuffer)(buffers)); + + std::size_t search_position = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename DynamicBuffer::const_buffers_type buffers_type; + typedef buffers_iterator iterator; + buffers_type data_buffers = b.data(); + iterator begin = iterator::begin(data_buffers); + iterator start_pos = begin + search_position; + iterator end = iterator::end(data_buffers); + + // Look for a match. + std::pair result = detail::partial_search( + start_pos, end, delim.begin(), delim.end()); + if (result.first != end) + { + if (result.second) + { + // Full match. We're done. + ec = asio::error_code(); + return result.first - begin + delim.length(); + } + else + { + // Partial match. Next search needs to start from beginning of match. + search_position = result.first - begin; + } + } + else + { + // No match. Next search can start with the new data. + search_position = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_to_read = std::min( + std::max(512, b.capacity() - b.size()), + std::min(65536, b.max_size() - b.size())); + b.commit(s.read_some(b.prepare(bytes_to_read), ec)); + if (ec) + return 0; + } +} + +#if !defined(ASIO_NO_EXTENSIONS) +#if defined(ASIO_HAS_BOOST_REGEX) + +template +inline std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + const boost::regex& expr) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_until(s, + ASIO_MOVE_CAST(DynamicBuffer)(buffers), expr, ec); + asio::detail::throw_error(ec, "read_until"); + return bytes_transferred; +} + +template +std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + const boost::regex& expr, asio::error_code& ec) +{ + typename decay::type b( + ASIO_MOVE_CAST(DynamicBuffer)(buffers)); + + std::size_t search_position = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename DynamicBuffer::const_buffers_type buffers_type; + typedef buffers_iterator iterator; + buffers_type data_buffers = b.data(); + iterator begin = iterator::begin(data_buffers); + iterator start_pos = begin + search_position; + iterator end = iterator::end(data_buffers); + + // Look for a match. + boost::match_results >::allocator_type> + match_results; + if (regex_search(start_pos, end, match_results, expr, + boost::match_default | boost::match_partial)) + { + if (match_results[0].matched) + { + // Full match. We're done. + ec = asio::error_code(); + return match_results[0].second - begin; + } + else + { + // Partial match. Next search needs to start from beginning of match. + search_position = match_results[0].first - begin; + } + } + else + { + // No match. Next search can start with the new data. + search_position = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_to_read = read_size_helper(b, 65536); + b.commit(s.read_some(b.prepare(bytes_to_read), ec)); + if (ec) + return 0; + } +} + +#endif // defined(ASIO_HAS_BOOST_REGEX) + +template +inline std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + MatchCondition match_condition, + typename enable_if::value>::type*) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_until(s, + ASIO_MOVE_CAST(DynamicBuffer)(buffers), + match_condition, ec); + asio::detail::throw_error(ec, "read_until"); + return bytes_transferred; +} + +template +std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + MatchCondition match_condition, asio::error_code& ec, + typename enable_if::value>::type*) +{ + typename decay::type b( + ASIO_MOVE_CAST(DynamicBuffer)(buffers)); + + std::size_t search_position = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename DynamicBuffer::const_buffers_type buffers_type; + typedef buffers_iterator iterator; + buffers_type data_buffers = b.data(); + iterator begin = iterator::begin(data_buffers); + iterator start_pos = begin + search_position; + iterator end = iterator::end(data_buffers); + + // Look for a match. + std::pair result = match_condition(start_pos, end); + if (result.second) + { + // Full match. We're done. + ec = asio::error_code(); + return result.first - begin; + } + else if (result.first != end) + { + // Partial match. Next search needs to start from beginning of match. + search_position = result.first - begin; + } + else + { + // No match. Next search can start with the new data. + search_position = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_to_read = std::min( + std::max(512, b.capacity() - b.size()), + std::min(65536, b.max_size() - b.size())); + b.commit(s.read_some(b.prepare(bytes_to_read), ec)); + if (ec) + return 0; + } +} + +#if !defined(ASIO_NO_IOSTREAM) + +template +inline std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, char delim) +{ + return read_until(s, basic_streambuf_ref(b), delim); +} + +template +inline std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, char delim, + asio::error_code& ec) +{ + return read_until(s, basic_streambuf_ref(b), delim, ec); +} + +template +inline std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, + ASIO_STRING_VIEW_PARAM delim) +{ + return read_until(s, basic_streambuf_ref(b), delim); +} + +template +inline std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, + ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec) +{ + return read_until(s, basic_streambuf_ref(b), delim, ec); +} + +#if defined(ASIO_HAS_BOOST_REGEX) + +template +inline std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, const boost::regex& expr) +{ + return read_until(s, basic_streambuf_ref(b), expr); +} + +template +inline std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, const boost::regex& expr, + asio::error_code& ec) +{ + return read_until(s, basic_streambuf_ref(b), expr, ec); +} + +#endif // defined(ASIO_HAS_BOOST_REGEX) + +template +inline std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, MatchCondition match_condition, + typename enable_if::value>::type*) +{ + return read_until(s, basic_streambuf_ref(b), match_condition); +} + +template +inline std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, + MatchCondition match_condition, asio::error_code& ec, + typename enable_if::value>::type*) +{ + return read_until(s, basic_streambuf_ref(b), match_condition, ec); +} + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +namespace detail +{ + template + class read_until_delim_op + { + public: + template + read_until_delim_op(AsyncReadStream& stream, + ASIO_MOVE_ARG(BufferSequence) buffers, + char delim, ReadHandler& handler) + : stream_(stream), + buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), + delim_(delim), + start_(0), + search_position_(0), + handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + read_until_delim_op(const read_until_delim_op& other) + : stream_(other.stream_), + buffers_(other.buffers_), + delim_(other.delim_), + start_(other.start_), + search_position_(other.search_position_), + handler_(other.handler_) + { + } + + read_until_delim_op(read_until_delim_op&& other) + : stream_(other.stream_), + buffers_(ASIO_MOVE_CAST(DynamicBuffer)(other.buffers_)), + delim_(other.delim_), + start_(other.start_), + search_position_(other.search_position_), + handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + const std::size_t not_found = (std::numeric_limits::max)(); + std::size_t bytes_to_read; + switch (start_ = start) + { + case 1: + for (;;) + { + { + // Determine the range of the data to be searched. + typedef typename DynamicBuffer::const_buffers_type + buffers_type; + typedef buffers_iterator iterator; + buffers_type data_buffers = buffers_.data(); + iterator begin = iterator::begin(data_buffers); + iterator start_pos = begin + search_position_; + iterator end = iterator::end(data_buffers); + + // Look for a match. + iterator iter = std::find(start_pos, end, delim_); + if (iter != end) + { + // Found a match. We're done. + search_position_ = iter - begin + 1; + bytes_to_read = 0; + } + + // No match yet. Check if buffer is full. + else if (buffers_.size() == buffers_.max_size()) + { + search_position_ = not_found; + bytes_to_read = 0; + } + + // Need to read some more data. + else + { + // Next search can start with the new data. + search_position_ = end - begin; + bytes_to_read = std::min( + std::max(512, + buffers_.capacity() - buffers_.size()), + std::min(65536, + buffers_.max_size() - buffers_.size())); + } + } + + // Check if we're done. + if (!start && bytes_to_read == 0) + break; + + // Start a new asynchronous read operation to obtain more data. + stream_.async_read_some(buffers_.prepare(bytes_to_read), + ASIO_MOVE_CAST(read_until_delim_op)(*this)); + return; default: + buffers_.commit(bytes_transferred); + if (ec || bytes_transferred == 0) + break; + } + + const asio::error_code result_ec = + (search_position_ == not_found) + ? error::not_found : ec; + + const std::size_t result_n = + (ec || search_position_ == not_found) + ? 0 : search_position_; + + handler_(result_ec, result_n); + } + } + + //private: + AsyncReadStream& stream_; + DynamicBuffer buffers_; + char delim_; + int start_; + std::size_t search_position_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_until_delim_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_delim_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + read_until_delim_op* this_handler) + { + return this_handler->start_ == 0 ? true + : asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + read_until_delim_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_until_delim_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::read_until_delim_op, + Allocator> +{ + typedef typename associated_allocator::type type; + + static type get( + const detail::read_until_delim_op& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::read_until_delim_op, + Executor> +{ + typedef typename associated_executor::type type; + + static type get( + const detail::read_until_delim_op& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + char delim, 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + async_completion init(handler); + + detail::read_until_delim_op::type, + ASIO_HANDLER_TYPE(ReadHandler, + void (asio::error_code, std::size_t))>( + s, ASIO_MOVE_CAST(DynamicBuffer)(buffers), + delim, init.completion_handler)(asio::error_code(), 0, 1); + + return init.result.get(); +} + +namespace detail +{ + template + class read_until_delim_string_op + { + public: + template + read_until_delim_string_op(AsyncReadStream& stream, + ASIO_MOVE_ARG(BufferSequence) buffers, + const std::string& delim, ReadHandler& handler) + : stream_(stream), + buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), + delim_(delim), + start_(0), + search_position_(0), + handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + read_until_delim_string_op(const read_until_delim_string_op& other) + : stream_(other.stream_), + buffers_(other.buffers_), + delim_(other.delim_), + start_(other.start_), + search_position_(other.search_position_), + handler_(other.handler_) + { + } + + read_until_delim_string_op(read_until_delim_string_op&& other) + : stream_(other.stream_), + buffers_(ASIO_MOVE_CAST(DynamicBuffer)(other.buffers_)), + delim_(ASIO_MOVE_CAST(std::string)(other.delim_)), + start_(other.start_), + search_position_(other.search_position_), + handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + const std::size_t not_found = (std::numeric_limits::max)(); + std::size_t bytes_to_read; + switch (start_ = start) + { + case 1: + for (;;) + { + { + // Determine the range of the data to be searched. + typedef typename DynamicBuffer::const_buffers_type + buffers_type; + typedef buffers_iterator iterator; + buffers_type data_buffers = buffers_.data(); + iterator begin = iterator::begin(data_buffers); + iterator start_pos = begin + search_position_; + iterator end = iterator::end(data_buffers); + + // Look for a match. + std::pair result = detail::partial_search( + start_pos, end, delim_.begin(), delim_.end()); + if (result.first != end && result.second) + { + // Full match. We're done. + search_position_ = result.first - begin + delim_.length(); + bytes_to_read = 0; + } + + // No match yet. Check if buffer is full. + else if (buffers_.size() == buffers_.max_size()) + { + search_position_ = not_found; + bytes_to_read = 0; + } + + // Need to read some more data. + else + { + if (result.first != end) + { + // Partial match. Next search needs to start from beginning of + // match. + search_position_ = result.first - begin; + } + else + { + // Next search can start with the new data. + search_position_ = end - begin; + } + + bytes_to_read = std::min( + std::max(512, + buffers_.capacity() - buffers_.size()), + std::min(65536, + buffers_.max_size() - buffers_.size())); + } + } + + // Check if we're done. + if (!start && bytes_to_read == 0) + break; + + // Start a new asynchronous read operation to obtain more data. + stream_.async_read_some(buffers_.prepare(bytes_to_read), + ASIO_MOVE_CAST(read_until_delim_string_op)(*this)); + return; default: + buffers_.commit(bytes_transferred); + if (ec || bytes_transferred == 0) + break; + } + + const asio::error_code result_ec = + (search_position_ == not_found) + ? error::not_found : ec; + + const std::size_t result_n = + (ec || search_position_ == not_found) + ? 0 : search_position_; + + handler_(result_ec, result_n); + } + } + + //private: + AsyncReadStream& stream_; + DynamicBuffer buffers_; + std::string delim_; + int start_; + std::size_t search_position_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_until_delim_string_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_delim_string_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + read_until_delim_string_op* this_handler) + { + return this_handler->start_ == 0 ? true + : asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + read_until_delim_string_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_until_delim_string_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::read_until_delim_string_op, + Allocator> +{ + typedef typename associated_allocator::type type; + + static type get( + const detail::read_until_delim_string_op& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::read_until_delim_string_op, + Executor> +{ + typedef typename associated_executor::type type; + + static type get( + const detail::read_until_delim_string_op& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + ASIO_STRING_VIEW_PARAM delim, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + async_completion init(handler); + + detail::read_until_delim_string_op::type, + ASIO_HANDLER_TYPE(ReadHandler, + void (asio::error_code, std::size_t))>( + s, ASIO_MOVE_CAST(DynamicBuffer)(buffers), + static_cast(delim), + init.completion_handler)(asio::error_code(), 0, 1); + + return init.result.get(); +} + +#if !defined(ASIO_NO_EXTENSIONS) +#if defined(ASIO_HAS_BOOST_REGEX) + +namespace detail +{ + template + class read_until_expr_op + { + public: + template + read_until_expr_op(AsyncReadStream& stream, + ASIO_MOVE_ARG(BufferSequence) buffers, + const boost::regex& expr, ReadHandler& handler) + : stream_(stream), + buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), + expr_(expr), + start_(0), + search_position_(0), + handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + read_until_expr_op(const read_until_expr_op& other) + : stream_(other.stream_), + buffers_(other.buffers_), + expr_(other.expr_), + start_(other.start_), + search_position_(other.search_position_), + handler_(other.handler_) + { + } + + read_until_expr_op(read_until_expr_op&& other) + : stream_(other.stream_), + buffers_(ASIO_MOVE_CAST(DynamicBuffer)(other.buffers_)), + expr_(other.expr_), + start_(other.start_), + search_position_(other.search_position_), + handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + const std::size_t not_found = (std::numeric_limits::max)(); + std::size_t bytes_to_read; + switch (start_ = start) + { + case 1: + for (;;) + { + { + // Determine the range of the data to be searched. + typedef typename DynamicBuffer::const_buffers_type + buffers_type; + typedef buffers_iterator iterator; + buffers_type data_buffers = buffers_.data(); + iterator begin = iterator::begin(data_buffers); + iterator start_pos = begin + search_position_; + iterator end = iterator::end(data_buffers); + + // Look for a match. + boost::match_results >::allocator_type> + match_results; + bool match = regex_search(start_pos, end, match_results, expr_, + boost::match_default | boost::match_partial); + if (match && match_results[0].matched) + { + // Full match. We're done. + search_position_ = match_results[0].second - begin; + bytes_to_read = 0; + } + + // No match yet. Check if buffer is full. + else if (buffers_.size() == buffers_.max_size()) + { + search_position_ = not_found; + bytes_to_read = 0; + } + + // Need to read some more data. + else + { + if (match) + { + // Partial match. Next search needs to start from beginning of + // match. + search_position_ = match_results[0].first - begin; + } + else + { + // Next search can start with the new data. + search_position_ = end - begin; + } + + bytes_to_read = std::min( + std::max(512, + buffers_.capacity() - buffers_.size()), + std::min(65536, + buffers_.max_size() - buffers_.size())); + } + } + + // Check if we're done. + if (!start && bytes_to_read == 0) + break; + + // Start a new asynchronous read operation to obtain more data. + stream_.async_read_some(buffers_.prepare(bytes_to_read), + ASIO_MOVE_CAST(read_until_expr_op)(*this)); + return; default: + buffers_.commit(bytes_transferred); + if (ec || bytes_transferred == 0) + break; + } + + const asio::error_code result_ec = + (search_position_ == not_found) + ? error::not_found : ec; + + const std::size_t result_n = + (ec || search_position_ == not_found) + ? 0 : search_position_; + + handler_(result_ec, result_n); + } + } + + //private: + AsyncReadStream& stream_; + DynamicBuffer buffers_; + RegEx expr_; + int start_; + std::size_t search_position_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_until_expr_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_expr_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + read_until_expr_op* this_handler) + { + return this_handler->start_ == 0 ? true + : asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + read_until_expr_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_until_expr_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::read_until_expr_op, + Allocator> +{ + typedef typename associated_allocator::type type; + + static type get( + const detail::read_until_expr_op& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::read_until_expr_op, + Executor> +{ + typedef typename associated_executor::type type; + + static type get( + const detail::read_until_expr_op& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + const boost::regex& expr, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + async_completion init(handler); + + detail::read_until_expr_op::type, + boost::regex, ASIO_HANDLER_TYPE(ReadHandler, + void (asio::error_code, std::size_t))>( + s, ASIO_MOVE_CAST(DynamicBuffer)(buffers), + expr, init.completion_handler)(asio::error_code(), 0, 1); + + return init.result.get(); +} + +#endif // defined(ASIO_HAS_BOOST_REGEX) + +namespace detail +{ + template + class read_until_match_op + { + public: + template + read_until_match_op(AsyncReadStream& stream, + ASIO_MOVE_ARG(BufferSequence) buffers, + MatchCondition match_condition, ReadHandler& handler) + : stream_(stream), + buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), + match_condition_(match_condition), + start_(0), + search_position_(0), + handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + read_until_match_op(const read_until_match_op& other) + : stream_(other.stream_), + buffers_(other.buffers_), + match_condition_(other.match_condition_), + start_(other.start_), + search_position_(other.search_position_), + handler_(other.handler_) + { + } + + read_until_match_op(read_until_match_op&& other) + : stream_(other.stream_), + buffers_(ASIO_MOVE_CAST(DynamicBuffer)(other.buffers_)), + match_condition_(other.match_condition_), + start_(other.start_), + search_position_(other.search_position_), + handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + const std::size_t not_found = (std::numeric_limits::max)(); + std::size_t bytes_to_read; + switch (start_ = start) + { + case 1: + for (;;) + { + { + // Determine the range of the data to be searched. + typedef typename DynamicBuffer::const_buffers_type + buffers_type; + typedef buffers_iterator iterator; + buffers_type data_buffers = buffers_.data(); + iterator begin = iterator::begin(data_buffers); + iterator start_pos = begin + search_position_; + iterator end = iterator::end(data_buffers); + + // Look for a match. + std::pair result = match_condition_(start_pos, end); + if (result.second) + { + // Full match. We're done. + search_position_ = result.first - begin; + bytes_to_read = 0; + } + + // No match yet. Check if buffer is full. + else if (buffers_.size() == buffers_.max_size()) + { + search_position_ = not_found; + bytes_to_read = 0; + } + + // Need to read some more data. + else + { + if (result.first != end) + { + // Partial match. Next search needs to start from beginning of + // match. + search_position_ = result.first - begin; + } + else + { + // Next search can start with the new data. + search_position_ = end - begin; + } + + bytes_to_read = std::min( + std::max(512, + buffers_.capacity() - buffers_.size()), + std::min(65536, + buffers_.max_size() - buffers_.size())); + } + } + + // Check if we're done. + if (!start && bytes_to_read == 0) + break; + + // Start a new asynchronous read operation to obtain more data. + stream_.async_read_some(buffers_.prepare(bytes_to_read), + ASIO_MOVE_CAST(read_until_match_op)(*this)); + return; default: + buffers_.commit(bytes_transferred); + if (ec || bytes_transferred == 0) + break; + } + + const asio::error_code result_ec = + (search_position_ == not_found) + ? error::not_found : ec; + + const std::size_t result_n = + (ec || search_position_ == not_found) + ? 0 : search_position_; + + handler_(result_ec, result_n); + } + } + + //private: + AsyncReadStream& stream_; + DynamicBuffer buffers_; + MatchCondition match_condition_; + int start_; + std::size_t search_position_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_until_match_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_match_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + read_until_match_op* this_handler) + { + return this_handler->start_ == 0 ? true + : asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + read_until_match_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_until_match_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::read_until_match_op, + Allocator> +{ + typedef typename associated_allocator::type type; + + static type get( + const detail::read_until_match_op& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::read_until_match_op, + Executor> +{ + typedef typename associated_executor::type type; + + static type get( + const detail::read_until_match_op& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + MatchCondition match_condition, ASIO_MOVE_ARG(ReadHandler) handler, + typename enable_if::value>::type*) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + async_completion init(handler); + + detail::read_until_match_op::type, + MatchCondition, ASIO_HANDLER_TYPE(ReadHandler, + void (asio::error_code, std::size_t))>( + s, ASIO_MOVE_CAST(DynamicBuffer)(buffers), + match_condition, init.completion_handler)( + asio::error_code(), 0, 1); + + return init.result.get(); +} + +#if !defined(ASIO_NO_IOSTREAM) + +template +inline ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, + char delim, ASIO_MOVE_ARG(ReadHandler) handler) +{ + return async_read_until(s, basic_streambuf_ref(b), + delim, ASIO_MOVE_CAST(ReadHandler)(handler)); +} + +template +inline ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, + ASIO_STRING_VIEW_PARAM delim, + ASIO_MOVE_ARG(ReadHandler) handler) +{ + return async_read_until(s, basic_streambuf_ref(b), + delim, ASIO_MOVE_CAST(ReadHandler)(handler)); +} + +#if defined(ASIO_HAS_BOOST_REGEX) + +template +inline ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, const boost::regex& expr, + ASIO_MOVE_ARG(ReadHandler) handler) +{ + return async_read_until(s, basic_streambuf_ref(b), + expr, ASIO_MOVE_CAST(ReadHandler)(handler)); +} + +#endif // defined(ASIO_HAS_BOOST_REGEX) + +template +inline ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, + MatchCondition match_condition, ASIO_MOVE_ARG(ReadHandler) handler, + typename enable_if::value>::type*) +{ + return async_read_until(s, basic_streambuf_ref(b), + match_condition, ASIO_MOVE_CAST(ReadHandler)(handler)); +} + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_READ_UNTIL_HPP diff --git a/tools/sdk/include/asio/asio/impl/serial_port_base.hpp b/tools/sdk/include/asio/asio/impl/serial_port_base.hpp new file mode 100644 index 00000000..cdc201d8 --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/serial_port_base.hpp @@ -0,0 +1,59 @@ +// +// impl/serial_port_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// 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 ASIO_IMPL_SERIAL_PORT_BASE_HPP +#define ASIO_IMPL_SERIAL_PORT_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +inline serial_port_base::baud_rate::baud_rate(unsigned int rate) + : value_(rate) +{ +} + +inline unsigned int serial_port_base::baud_rate::value() const +{ + return value_; +} + +inline serial_port_base::flow_control::type +serial_port_base::flow_control::value() const +{ + return value_; +} + +inline serial_port_base::parity::type serial_port_base::parity::value() const +{ + return value_; +} + +inline serial_port_base::stop_bits::type +serial_port_base::stop_bits::value() const +{ + return value_; +} + +inline unsigned int serial_port_base::character_size::value() const +{ + return value_; +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_SERIAL_PORT_BASE_HPP diff --git a/tools/sdk/include/asio/asio/impl/spawn.hpp b/tools/sdk/include/asio/asio/impl/spawn.hpp new file mode 100644 index 00000000..5594ad93 --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/spawn.hpp @@ -0,0 +1,535 @@ +// +// impl/spawn.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_SPAWN_HPP +#define ASIO_IMPL_SPAWN_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/associated_allocator.hpp" +#include "asio/associated_executor.hpp" +#include "asio/async_result.hpp" +#include "asio/bind_executor.hpp" +#include "asio/detail/atomic_count.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/system_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + + template + class coro_handler + { + public: + coro_handler(basic_yield_context ctx) + : coro_(ctx.coro_.lock()), + ca_(ctx.ca_), + handler_(ctx.handler_), + ready_(0), + ec_(ctx.ec_), + value_(0) + { + } + + void operator()(T value) + { + *ec_ = asio::error_code(); + *value_ = ASIO_MOVE_CAST(T)(value); + if (--*ready_ == 0) + (*coro_)(); + } + + void operator()(asio::error_code ec, T value) + { + *ec_ = ec; + *value_ = ASIO_MOVE_CAST(T)(value); + if (--*ready_ == 0) + (*coro_)(); + } + + //private: + shared_ptr::callee_type> coro_; + typename basic_yield_context::caller_type& ca_; + Handler handler_; + atomic_count* ready_; + asio::error_code* ec_; + T* value_; + }; + + template + class coro_handler + { + public: + coro_handler(basic_yield_context ctx) + : coro_(ctx.coro_.lock()), + ca_(ctx.ca_), + handler_(ctx.handler_), + ready_(0), + ec_(ctx.ec_) + { + } + + void operator()() + { + *ec_ = asio::error_code(); + if (--*ready_ == 0) + (*coro_)(); + } + + void operator()(asio::error_code ec) + { + *ec_ = ec; + if (--*ready_ == 0) + (*coro_)(); + } + + //private: + shared_ptr::callee_type> coro_; + typename basic_yield_context::caller_type& ca_; + Handler handler_; + atomic_count* ready_; + asio::error_code* ec_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + coro_handler* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + coro_handler* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation(coro_handler*) + { + return true; + } + + template + inline void asio_handler_invoke(Function& function, + coro_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + coro_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + class coro_async_result + { + public: + typedef coro_handler completion_handler_type; + typedef T return_type; + + explicit coro_async_result(completion_handler_type& h) + : handler_(h), + ca_(h.ca_), + ready_(2) + { + h.ready_ = &ready_; + out_ec_ = h.ec_; + if (!out_ec_) h.ec_ = &ec_; + h.value_ = &value_; + } + + return_type get() + { + // Must not hold shared_ptr to coro while suspended. + handler_.coro_.reset(); + + if (--ready_ != 0) + ca_(); + if (!out_ec_ && ec_) throw asio::system_error(ec_); + return ASIO_MOVE_CAST(return_type)(value_); + } + + private: + completion_handler_type& handler_; + typename basic_yield_context::caller_type& ca_; + atomic_count ready_; + asio::error_code* out_ec_; + asio::error_code ec_; + return_type value_; + }; + + template + class coro_async_result + { + public: + typedef coro_handler completion_handler_type; + typedef void return_type; + + explicit coro_async_result(completion_handler_type& h) + : handler_(h), + ca_(h.ca_), + ready_(2) + { + h.ready_ = &ready_; + out_ec_ = h.ec_; + if (!out_ec_) h.ec_ = &ec_; + } + + void get() + { + // Must not hold shared_ptr to coro while suspended. + handler_.coro_.reset(); + + if (--ready_ != 0) + ca_(); + if (!out_ec_ && ec_) throw asio::system_error(ec_); + } + + private: + completion_handler_type& handler_; + typename basic_yield_context::caller_type& ca_; + atomic_count ready_; + asio::error_code* out_ec_; + asio::error_code ec_; + }; + +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +class async_result, ReturnType()> + : public detail::coro_async_result +{ +public: + explicit async_result( + typename detail::coro_async_result::completion_handler_type& h) + : detail::coro_async_result(h) + { + } +}; + +template +class async_result, ReturnType(Arg1)> + : public detail::coro_async_result::type> +{ +public: + explicit async_result( + typename detail::coro_async_result::type>::completion_handler_type& h) + : detail::coro_async_result::type>(h) + { + } +}; + +template +class async_result, + ReturnType(asio::error_code)> + : public detail::coro_async_result +{ +public: + explicit async_result( + typename detail::coro_async_result::completion_handler_type& h) + : detail::coro_async_result(h) + { + } +}; + +template +class async_result, + ReturnType(asio::error_code, Arg2)> + : public detail::coro_async_result::type> +{ +public: + explicit async_result( + typename detail::coro_async_result::type>::completion_handler_type& h) + : detail::coro_async_result::type>(h) + { + } +}; + +#if !defined(ASIO_NO_DEPRECATED) + +template +struct handler_type, ReturnType()> +{ + typedef detail::coro_handler type; +}; + +template +struct handler_type, ReturnType(Arg1)> +{ + typedef detail::coro_handler::type> type; +}; + +template +struct handler_type, + ReturnType(asio::error_code)> +{ + typedef detail::coro_handler type; +}; + +template +struct handler_type, + ReturnType(asio::error_code, Arg2)> +{ + typedef detail::coro_handler::type> type; +}; + +template +class async_result > + : public detail::coro_async_result +{ +public: + typedef typename detail::coro_async_result::return_type type; + + explicit async_result( + typename detail::coro_async_result::completion_handler_type& h) + : detail::coro_async_result(h) + { + } +}; + +#endif // !defined(ASIO_NO_DEPRECATED) + +template +struct associated_allocator, Allocator> +{ + typedef typename associated_allocator::type type; + + static type get(const detail::coro_handler& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor, Executor> +{ + typedef typename associated_executor::type type; + + static type get(const detail::coro_handler& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +namespace detail { + + template + struct spawn_data : private noncopyable + { + template + spawn_data(ASIO_MOVE_ARG(Hand) handler, + bool call_handler, ASIO_MOVE_ARG(Func) function) + : handler_(ASIO_MOVE_CAST(Hand)(handler)), + call_handler_(call_handler), + function_(ASIO_MOVE_CAST(Func)(function)) + { + } + + weak_ptr::callee_type> coro_; + Handler handler_; + bool call_handler_; + Function function_; + }; + + template + struct coro_entry_point + { + void operator()(typename basic_yield_context::caller_type& ca) + { + shared_ptr > data(data_); +#if !defined(BOOST_COROUTINES_UNIDIRECT) && !defined(BOOST_COROUTINES_V2) + ca(); // Yield until coroutine pointer has been initialised. +#endif // !defined(BOOST_COROUTINES_UNIDIRECT) && !defined(BOOST_COROUTINES_V2) + const basic_yield_context yield( + data->coro_, ca, data->handler_); + + (data->function_)(yield); + if (data->call_handler_) + (data->handler_)(); + } + + shared_ptr > data_; + }; + + template + struct spawn_helper + { + void operator()() + { + typedef typename basic_yield_context::callee_type callee_type; + coro_entry_point entry_point = { data_ }; + shared_ptr coro(new callee_type(entry_point, attributes_)); + data_->coro_ = coro; + (*coro)(); + } + + shared_ptr > data_; + boost::coroutines::attributes attributes_; + }; + + template + inline void asio_handler_invoke(Function& function, + spawn_helper* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->data_->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + spawn_helper* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->data_->handler_); + } + + inline void default_spawn_handler() {} + +} // namespace detail + +template +inline void spawn(ASIO_MOVE_ARG(Function) function, + const boost::coroutines::attributes& attributes) +{ + typedef typename decay::type function_type; + + typename associated_executor::type ex( + (get_associated_executor)(function)); + + asio::spawn(ex, ASIO_MOVE_CAST(Function)(function), attributes); +} + +template +void spawn(ASIO_MOVE_ARG(Handler) handler, + ASIO_MOVE_ARG(Function) function, + const boost::coroutines::attributes& attributes, + typename enable_if::type>::value && + !is_convertible::value>::type*) +{ + typedef typename decay::type handler_type; + typedef typename decay::type function_type; + + typename associated_executor::type ex( + (get_associated_executor)(handler)); + + typename associated_allocator::type a( + (get_associated_allocator)(handler)); + + detail::spawn_helper helper; + helper.data_.reset( + new detail::spawn_data( + ASIO_MOVE_CAST(Handler)(handler), true, + ASIO_MOVE_CAST(Function)(function))); + helper.attributes_ = attributes; + + ex.dispatch(helper, a); +} + +template +void spawn(basic_yield_context ctx, + ASIO_MOVE_ARG(Function) function, + const boost::coroutines::attributes& attributes) +{ + typedef typename decay::type function_type; + + Handler handler(ctx.handler_); // Explicit copy that might be moved from. + + typename associated_executor::type ex( + (get_associated_executor)(handler)); + + typename associated_allocator::type a( + (get_associated_allocator)(handler)); + + detail::spawn_helper helper; + helper.data_.reset( + new detail::spawn_data( + ASIO_MOVE_CAST(Handler)(handler), false, + ASIO_MOVE_CAST(Function)(function))); + helper.attributes_ = attributes; + + ex.dispatch(helper, a); +} + +template +inline void spawn(const Executor& ex, + ASIO_MOVE_ARG(Function) function, + const boost::coroutines::attributes& attributes, + typename enable_if::value>::type*) +{ + asio::spawn(asio::strand(ex), + ASIO_MOVE_CAST(Function)(function), attributes); +} + +template +inline void spawn(const strand& ex, + ASIO_MOVE_ARG(Function) function, + const boost::coroutines::attributes& attributes) +{ + asio::spawn(asio::bind_executor( + ex, &detail::default_spawn_handler), + ASIO_MOVE_CAST(Function)(function), attributes); +} + +template +inline void spawn(const asio::io_context::strand& s, + ASIO_MOVE_ARG(Function) function, + const boost::coroutines::attributes& attributes) +{ + asio::spawn(asio::bind_executor( + s, &detail::default_spawn_handler), + ASIO_MOVE_CAST(Function)(function), attributes); +} + +template +inline void spawn(ExecutionContext& ctx, + ASIO_MOVE_ARG(Function) function, + const boost::coroutines::attributes& attributes, + typename enable_if::value>::type*) +{ + asio::spawn(ctx.get_executor(), + ASIO_MOVE_CAST(Function)(function), attributes); +} + +#endif // !defined(GENERATING_DOCUMENTATION) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_SPAWN_HPP diff --git a/tools/sdk/include/asio/asio/impl/src.hpp b/tools/sdk/include/asio/asio/impl/src.hpp new file mode 100644 index 00000000..a72637b9 --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/src.hpp @@ -0,0 +1,82 @@ +// +// impl/src.hpp +// ~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_SRC_HPP +#define ASIO_IMPL_SRC_HPP + +#define ASIO_SOURCE + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HEADER_ONLY) +# error Do not compile Asio library source with ASIO_HEADER_ONLY defined +#endif + +#include "asio/impl/error.ipp" +#include "asio/impl/error_code.ipp" +#include "asio/impl/execution_context.ipp" +#include "asio/impl/executor.ipp" +#include "asio/impl/handler_alloc_hook.ipp" +#include "asio/impl/io_context.ipp" +#include "asio/impl/serial_port_base.ipp" +#include "asio/impl/system_context.ipp" +#include "asio/impl/thread_pool.ipp" +#include "asio/detail/impl/buffer_sequence_adapter.ipp" +#include "asio/detail/impl/descriptor_ops.ipp" +#include "asio/detail/impl/dev_poll_reactor.ipp" +#include "asio/detail/impl/epoll_reactor.ipp" +#include "asio/detail/impl/eventfd_select_interrupter.ipp" +#include "asio/detail/impl/handler_tracking.ipp" +#include "asio/detail/impl/kqueue_reactor.ipp" +#include "asio/detail/impl/null_event.ipp" +#include "asio/detail/impl/pipe_select_interrupter.ipp" +#include "asio/detail/impl/posix_event.ipp" +#include "asio/detail/impl/posix_mutex.ipp" +#include "asio/detail/impl/posix_thread.ipp" +#include "asio/detail/impl/posix_tss_ptr.ipp" +#include "asio/detail/impl/reactive_descriptor_service.ipp" +#include "asio/detail/impl/reactive_serial_port_service.ipp" +#include "asio/detail/impl/reactive_socket_service_base.ipp" +#include "asio/detail/impl/resolver_service_base.ipp" +#include "asio/detail/impl/scheduler.ipp" +#include "asio/detail/impl/select_reactor.ipp" +#include "asio/detail/impl/service_registry.ipp" +#include "asio/detail/impl/signal_set_service.ipp" +#include "asio/detail/impl/socket_ops.ipp" +#include "asio/detail/impl/socket_select_interrupter.ipp" +#include "asio/detail/impl/strand_executor_service.ipp" +#include "asio/detail/impl/strand_service.ipp" +#include "asio/detail/impl/throw_error.ipp" +#include "asio/detail/impl/timer_queue_ptime.ipp" +#include "asio/detail/impl/timer_queue_set.ipp" +#include "asio/detail/impl/win_iocp_handle_service.ipp" +#include "asio/detail/impl/win_iocp_io_context.ipp" +#include "asio/detail/impl/win_iocp_serial_port_service.ipp" +#include "asio/detail/impl/win_iocp_socket_service_base.ipp" +#include "asio/detail/impl/win_event.ipp" +#include "asio/detail/impl/win_mutex.ipp" +#include "asio/detail/impl/win_object_handle_service.ipp" +#include "asio/detail/impl/win_static_mutex.ipp" +#include "asio/detail/impl/win_thread.ipp" +#include "asio/detail/impl/win_tss_ptr.ipp" +#include "asio/detail/impl/winrt_ssocket_service_base.ipp" +#include "asio/detail/impl/winrt_timer_scheduler.ipp" +#include "asio/detail/impl/winsock_init.ipp" +#include "asio/generic/detail/impl/endpoint.ipp" +#include "asio/ip/impl/address.ipp" +#include "asio/ip/impl/address_v4.ipp" +#include "asio/ip/impl/address_v6.ipp" +#include "asio/ip/impl/host_name.ipp" +#include "asio/ip/impl/network_v4.ipp" +#include "asio/ip/impl/network_v6.ipp" +#include "asio/ip/detail/impl/endpoint.ipp" +#include "asio/local/detail/impl/endpoint.ipp" + +#endif // ASIO_IMPL_SRC_HPP diff --git a/tools/sdk/include/asio/asio/impl/system_context.hpp b/tools/sdk/include/asio/asio/impl/system_context.hpp new file mode 100644 index 00000000..87ffe76a --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/system_context.hpp @@ -0,0 +1,34 @@ +// +// impl/system_context.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_SYSTEM_CONTEXT_HPP +#define ASIO_IMPL_SYSTEM_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/system_executor.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +inline system_context::executor_type +system_context::get_executor() ASIO_NOEXCEPT +{ + return system_executor(); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_SYSTEM_CONTEXT_HPP diff --git a/tools/sdk/include/asio/asio/impl/system_executor.hpp b/tools/sdk/include/asio/asio/impl/system_executor.hpp new file mode 100644 index 00000000..ac4861f5 --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/system_executor.hpp @@ -0,0 +1,85 @@ +// +// impl/system_executor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_SYSTEM_EXECUTOR_HPP +#define ASIO_IMPL_SYSTEM_EXECUTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/executor_op.hpp" +#include "asio/detail/global.hpp" +#include "asio/detail/recycling_allocator.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/system_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +inline system_context& system_executor::context() const ASIO_NOEXCEPT +{ + return detail::global(); +} + +template +void system_executor::dispatch( + ASIO_MOVE_ARG(Function) f, const Allocator&) const +{ + typename decay::type tmp(ASIO_MOVE_CAST(Function)(f)); + asio_handler_invoke_helpers::invoke(tmp, tmp); +} + +template +void system_executor::post( + ASIO_MOVE_ARG(Function) f, const Allocator& a) const +{ + typedef typename decay::type function_type; + + system_context& ctx = detail::global(); + + // Allocate and construct an operation to wrap the function. + typedef detail::executor_op op; + typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; + p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); + + ASIO_HANDLER_CREATION((ctx, *p.p, + "system_executor", &this->context(), 0, "post")); + + ctx.scheduler_.post_immediate_completion(p.p, false); + p.v = p.p = 0; +} + +template +void system_executor::defer( + ASIO_MOVE_ARG(Function) f, const Allocator& a) const +{ + typedef typename decay::type function_type; + + system_context& ctx = detail::global(); + + // Allocate and construct an operation to wrap the function. + typedef detail::executor_op op; + typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; + p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); + + ASIO_HANDLER_CREATION((ctx, *p.p, + "system_executor", &this->context(), 0, "defer")); + + ctx.scheduler_.post_immediate_completion(p.p, true); + p.v = p.p = 0; +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_SYSTEM_EXECUTOR_HPP diff --git a/tools/sdk/include/asio/asio/impl/thread_pool.hpp b/tools/sdk/include/asio/asio/impl/thread_pool.hpp new file mode 100644 index 00000000..058e3771 --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/thread_pool.hpp @@ -0,0 +1,127 @@ +// +// impl/thread_pool.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_THREAD_POOL_HPP +#define ASIO_IMPL_THREAD_POOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/executor_op.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/recycling_allocator.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/execution_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +inline thread_pool::executor_type +thread_pool::get_executor() ASIO_NOEXCEPT +{ + return executor_type(*this); +} + +inline thread_pool& +thread_pool::executor_type::context() const ASIO_NOEXCEPT +{ + return pool_; +} + +inline void +thread_pool::executor_type::on_work_started() const ASIO_NOEXCEPT +{ + pool_.scheduler_.work_started(); +} + +inline void thread_pool::executor_type::on_work_finished() +const ASIO_NOEXCEPT +{ + pool_.scheduler_.work_finished(); +} + +template +void thread_pool::executor_type::dispatch( + ASIO_MOVE_ARG(Function) f, const Allocator& a) const +{ + typedef typename decay::type function_type; + + // Invoke immediately if we are already inside the thread pool. + if (pool_.scheduler_.can_dispatch()) + { + // Make a local, non-const copy of the function. + function_type tmp(ASIO_MOVE_CAST(Function)(f)); + + detail::fenced_block b(detail::fenced_block::full); + asio_handler_invoke_helpers::invoke(tmp, tmp); + return; + } + + // Allocate and construct an operation to wrap the function. + typedef detail::executor_op op; + typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; + p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); + + ASIO_HANDLER_CREATION((pool_, *p.p, + "thread_pool", &this->context(), 0, "dispatch")); + + pool_.scheduler_.post_immediate_completion(p.p, false); + p.v = p.p = 0; +} + +template +void thread_pool::executor_type::post( + ASIO_MOVE_ARG(Function) f, const Allocator& a) const +{ + typedef typename decay::type function_type; + + // Allocate and construct an operation to wrap the function. + typedef detail::executor_op op; + typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; + p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); + + ASIO_HANDLER_CREATION((pool_, *p.p, + "thread_pool", &this->context(), 0, "post")); + + pool_.scheduler_.post_immediate_completion(p.p, false); + p.v = p.p = 0; +} + +template +void thread_pool::executor_type::defer( + ASIO_MOVE_ARG(Function) f, const Allocator& a) const +{ + typedef typename decay::type function_type; + + // Allocate and construct an operation to wrap the function. + typedef detail::executor_op op; + typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; + p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); + + ASIO_HANDLER_CREATION((pool_, *p.p, + "thread_pool", &this->context(), 0, "defer")); + + pool_.scheduler_.post_immediate_completion(p.p, true); + p.v = p.p = 0; +} + +inline bool +thread_pool::executor_type::running_in_this_thread() const ASIO_NOEXCEPT +{ + return pool_.scheduler_.can_dispatch(); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_THREAD_POOL_HPP diff --git a/tools/sdk/include/asio/asio/impl/use_future.hpp b/tools/sdk/include/asio/asio/impl/use_future.hpp new file mode 100644 index 00000000..51eb7e2c --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/use_future.hpp @@ -0,0 +1,938 @@ +// +// impl/use_future.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_USE_FUTURE_HPP +#define ASIO_IMPL_USE_FUTURE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include +#include "asio/async_result.hpp" +#include "asio/detail/memory.hpp" +#include "asio/error_code.hpp" +#include "asio/packaged_task.hpp" +#include "asio/system_error.hpp" +#include "asio/system_executor.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) + +template +inline void promise_invoke_and_set(std::promise& p, + F& f, ASIO_MOVE_ARG(Args)... args) +{ +#if !defined(ASIO_NO_EXCEPTIONS) + try +#endif // !defined(ASIO_NO_EXCEPTIONS) + { + p.set_value(f(ASIO_MOVE_CAST(Args)(args)...)); + } +#if !defined(ASIO_NO_EXCEPTIONS) + catch (...) + { + p.set_exception(std::current_exception()); + } +#endif // !defined(ASIO_NO_EXCEPTIONS) +} + +template +inline void promise_invoke_and_set(std::promise& p, + F& f, ASIO_MOVE_ARG(Args)... args) +{ +#if !defined(ASIO_NO_EXCEPTIONS) + try +#endif // !defined(ASIO_NO_EXCEPTIONS) + { + f(ASIO_MOVE_CAST(Args)(args)...); + p.set_value(); + } +#if !defined(ASIO_NO_EXCEPTIONS) + catch (...) + { + p.set_exception(std::current_exception()); + } +#endif // !defined(ASIO_NO_EXCEPTIONS) +} + +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +template +inline void promise_invoke_and_set(std::promise& p, F& f) +{ +#if !defined(ASIO_NO_EXCEPTIONS) + try +#endif // !defined(ASIO_NO_EXCEPTIONS) + { + p.set_value(f()); + } +#if !defined(ASIO_NO_EXCEPTIONS) + catch (...) + { + p.set_exception(std::current_exception()); + } +#endif // !defined(ASIO_NO_EXCEPTIONS) +} + +template +inline void promise_invoke_and_set(std::promise& p, F& f) +{ +#if !defined(ASIO_NO_EXCEPTIONS) + try +#endif // !defined(ASIO_NO_EXCEPTIONS) + { + f(); + p.set_value(); +#if !defined(ASIO_NO_EXCEPTIONS) + } + catch (...) + { + p.set_exception(std::current_exception()); + } +#endif // !defined(ASIO_NO_EXCEPTIONS) +} + +#if defined(ASIO_NO_EXCEPTIONS) + +#define ASIO_PRIVATE_PROMISE_INVOKE_DEF(n) \ + template \ + inline void promise_invoke_and_set(std::promise& p, \ + F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + p.set_value(f(ASIO_VARIADIC_MOVE_ARGS(n))); \ + } \ + \ + template \ + inline void promise_invoke_and_set(std::promise& p, \ + F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + f(ASIO_VARIADIC_MOVE_ARGS(n)); \ + p.set_value(); \ + } \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_PROMISE_INVOKE_DEF) +#undef ASIO_PRIVATE_PROMISE_INVOKE_DEF + +#else // defined(ASIO_NO_EXCEPTIONS) + +#define ASIO_PRIVATE_PROMISE_INVOKE_DEF(n) \ + template \ + inline void promise_invoke_and_set(std::promise& p, \ + F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + try \ + { \ + p.set_value(f(ASIO_VARIADIC_MOVE_ARGS(n))); \ + } \ + catch (...) \ + { \ + p.set_exception(std::current_exception()); \ + } \ + } \ + \ + template \ + inline void promise_invoke_and_set(std::promise& p, \ + F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + try \ + { \ + f(ASIO_VARIADIC_MOVE_ARGS(n)); \ + p.set_value(); \ + } \ + catch (...) \ + { \ + p.set_exception(std::current_exception()); \ + } \ + } \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_PROMISE_INVOKE_DEF) +#undef ASIO_PRIVATE_PROMISE_INVOKE_DEF + +#endif // defined(ASIO_NO_EXCEPTIONS) + +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +// A function object adapter to invoke a nullary function object and capture +// any exception thrown into a promise. +template +class promise_invoker +{ +public: + promise_invoker(const shared_ptr >& p, + ASIO_MOVE_ARG(F) f) + : p_(p), f_(ASIO_MOVE_CAST(F)(f)) + { + } + + void operator()() + { +#if !defined(ASIO_NO_EXCEPTIONS) + try +#endif // !defined(ASIO_NO_EXCEPTIONS) + { + f_(); + } +#if !defined(ASIO_NO_EXCEPTIONS) + catch (...) + { + p_->set_exception(std::current_exception()); + } +#endif // !defined(ASIO_NO_EXCEPTIONS) + } + +private: + shared_ptr > p_; + typename decay::type f_; +}; + +// An executor that adapts the system_executor to capture any exeption thrown +// by a submitted function object and save it into a promise. +template +class promise_executor +{ +public: + explicit promise_executor(const shared_ptr >& p) + : p_(p) + { + } + + execution_context& context() const ASIO_NOEXCEPT + { + return system_executor().context(); + } + + void on_work_started() const ASIO_NOEXCEPT {} + void on_work_finished() const ASIO_NOEXCEPT {} + + template + void dispatch(ASIO_MOVE_ARG(F) f, const A&) const + { + promise_invoker(p_, ASIO_MOVE_CAST(F)(f))(); + } + + template + void post(ASIO_MOVE_ARG(F) f, const A& a) const + { + system_executor().post( + promise_invoker(p_, ASIO_MOVE_CAST(F)(f)), a); + } + + template + void defer(ASIO_MOVE_ARG(F) f, const A& a) const + { + system_executor().defer( + promise_invoker(p_, ASIO_MOVE_CAST(F)(f)), a); + } + + friend bool operator==(const promise_executor& a, + const promise_executor& b) ASIO_NOEXCEPT + { + return a.p_ == b.p_; + } + + friend bool operator!=(const promise_executor& a, + const promise_executor& b) ASIO_NOEXCEPT + { + return a.p_ != b.p_; + } + +private: + shared_ptr > p_; +}; + +// The base class for all completion handlers that create promises. +template +class promise_creator +{ +public: + typedef promise_executor executor_type; + + executor_type get_executor() const ASIO_NOEXCEPT + { + return executor_type(p_); + } + + typedef std::future future_type; + + future_type get_future() + { + return p_->get_future(); + } + +protected: + template + void create_promise(const Allocator& a) + { + ASIO_REBIND_ALLOC(Allocator, char) b(a); + p_ = std::allocate_shared>(b, std::allocator_arg, b); + } + + shared_ptr > p_; +}; + +// For completion signature void(). +class promise_handler_0 + : public promise_creator +{ +public: + void operator()() + { + this->p_->set_value(); + } +}; + +// For completion signature void(error_code). +class promise_handler_ec_0 + : public promise_creator +{ +public: + void operator()(const asio::error_code& ec) + { + if (ec) + { + this->p_->set_exception( + std::make_exception_ptr( + asio::system_error(ec))); + } + else + { + this->p_->set_value(); + } + } +}; + +// For completion signature void(exception_ptr). +class promise_handler_ex_0 + : public promise_creator +{ +public: + void operator()(const std::exception_ptr& ex) + { + if (ex) + { + this->p_->set_exception(ex); + } + else + { + this->p_->set_value(); + } + } +}; + +// For completion signature void(T). +template +class promise_handler_1 + : public promise_creator +{ +public: + template + void operator()(ASIO_MOVE_ARG(Arg) arg) + { + this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg)); + } +}; + +// For completion signature void(error_code, T). +template +class promise_handler_ec_1 + : public promise_creator +{ +public: + template + void operator()(const asio::error_code& ec, + ASIO_MOVE_ARG(Arg) arg) + { + if (ec) + { + this->p_->set_exception( + std::make_exception_ptr( + asio::system_error(ec))); + } + else + this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg)); + } +}; + +// For completion signature void(exception_ptr, T). +template +class promise_handler_ex_1 + : public promise_creator +{ +public: + template + void operator()(const std::exception_ptr& ex, + ASIO_MOVE_ARG(Arg) arg) + { + if (ex) + this->p_->set_exception(ex); + else + this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg)); + } +}; + +// For completion signature void(T1, ..., Tn); +template +class promise_handler_n + : public promise_creator +{ +public: +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) + + template + void operator()(ASIO_MOVE_ARG(Args)... args) + { + this->p_->set_value( + std::forward_as_tuple( + ASIO_MOVE_CAST(Args)(args)...)); + } + +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +#define ASIO_PRIVATE_CALL_OP_DEF(n) \ + template \ + void operator()(ASIO_VARIADIC_MOVE_PARAMS(n)) \ + {\ + this->p_->set_value( \ + std::forward_as_tuple( \ + ASIO_VARIADIC_MOVE_ARGS(n))); \ + } \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF) +#undef ASIO_PRIVATE_CALL_OP_DEF + +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) +}; + +// For completion signature void(error_code, T1, ..., Tn); +template +class promise_handler_ec_n + : public promise_creator +{ +public: +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) + + template + void operator()(const asio::error_code& ec, + ASIO_MOVE_ARG(Args)... args) + { + if (ec) + { + this->p_->set_exception( + std::make_exception_ptr( + asio::system_error(ec))); + } + else + { + this->p_->set_value( + std::forward_as_tuple( + ASIO_MOVE_CAST(Args)(args)...)); + } + } + +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +#define ASIO_PRIVATE_CALL_OP_DEF(n) \ + template \ + void operator()(const asio::error_code& ec, \ + ASIO_VARIADIC_MOVE_PARAMS(n)) \ + {\ + if (ec) \ + { \ + this->p_->set_exception( \ + std::make_exception_ptr( \ + asio::system_error(ec))); \ + } \ + else \ + { \ + this->p_->set_value( \ + std::forward_as_tuple( \ + ASIO_VARIADIC_MOVE_ARGS(n))); \ + } \ + } \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF) +#undef ASIO_PRIVATE_CALL_OP_DEF + +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) +}; + +// For completion signature void(exception_ptr, T1, ..., Tn); +template +class promise_handler_ex_n + : public promise_creator +{ +public: +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) + + template + void operator()(const std::exception_ptr& ex, + ASIO_MOVE_ARG(Args)... args) + { + if (ex) + this->p_->set_exception(ex); + else + { + this->p_->set_value( + std::forward_as_tuple( + ASIO_MOVE_CAST(Args)(args)...)); + } + } + +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +#define ASIO_PRIVATE_CALL_OP_DEF(n) \ + template \ + void operator()(const std::exception_ptr& ex, \ + ASIO_VARIADIC_MOVE_PARAMS(n)) \ + {\ + if (ex) \ + this->p_->set_exception(ex); \ + else \ + { \ + this->p_->set_value( \ + std::forward_as_tuple( \ + ASIO_VARIADIC_MOVE_ARGS(n))); \ + } \ + } \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF) +#undef ASIO_PRIVATE_CALL_OP_DEF + +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) +}; + +// Helper template to choose the appropriate concrete promise handler +// implementation based on the supplied completion signature. +template class promise_handler_selector; + +template <> +class promise_handler_selector + : public promise_handler_0 {}; + +template <> +class promise_handler_selector + : public promise_handler_ec_0 {}; + +template <> +class promise_handler_selector + : public promise_handler_ex_0 {}; + +template +class promise_handler_selector + : public promise_handler_1 {}; + +template +class promise_handler_selector + : public promise_handler_ec_1 {}; + +template +class promise_handler_selector + : public promise_handler_ex_1 {}; + +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) + +template +class promise_handler_selector + : public promise_handler_n > {}; + +template +class promise_handler_selector + : public promise_handler_ec_n > {}; + +template +class promise_handler_selector + : public promise_handler_ex_n > {}; + +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +#define ASIO_PRIVATE_PROMISE_SELECTOR_DEF(n) \ + template \ + class promise_handler_selector< \ + void(Arg, ASIO_VARIADIC_TARGS(n))> \ + : public promise_handler_n< \ + std::tuple > {}; \ + \ + template \ + class promise_handler_selector< \ + void(asio::error_code, Arg, ASIO_VARIADIC_TARGS(n))> \ + : public promise_handler_ec_n< \ + std::tuple > {}; \ + \ + template \ + class promise_handler_selector< \ + void(std::exception_ptr, Arg, ASIO_VARIADIC_TARGS(n))> \ + : public promise_handler_ex_n< \ + std::tuple > {}; \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_PROMISE_SELECTOR_DEF) +#undef ASIO_PRIVATE_PROMISE_SELECTOR_DEF + +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +// Completion handlers produced from the use_future completion token, when not +// using use_future::operator(). +template +class promise_handler + : public promise_handler_selector +{ +public: + typedef Allocator allocator_type; + typedef void result_type; + + promise_handler(use_future_t u) + : allocator_(u.get_allocator()) + { + this->create_promise(allocator_); + } + + allocator_type get_allocator() const ASIO_NOEXCEPT + { + return allocator_; + } + +private: + Allocator allocator_; +}; + +template +inline void asio_handler_invoke(Function& f, + promise_handler* h) +{ + typename promise_handler::executor_type + ex(h->get_executor()); + ex.dispatch(ASIO_MOVE_CAST(Function)(f), std::allocator()); +} + +template +inline void asio_handler_invoke(const Function& f, + promise_handler* h) +{ + typename promise_handler::executor_type + ex(h->get_executor()); + ex.dispatch(f, std::allocator()); +} + +// Helper base class for async_result specialisation. +template +class promise_async_result +{ +public: + typedef promise_handler completion_handler_type; + typedef typename completion_handler_type::future_type return_type; + + explicit promise_async_result(completion_handler_type& h) + : future_(h.get_future()) + { + } + + return_type get() + { + return ASIO_MOVE_CAST(return_type)(future_); + } + +private: + return_type future_; +}; + +// Return value from use_future::operator(). +template +class packaged_token +{ +public: + packaged_token(Function f, const Allocator& a) + : function_(ASIO_MOVE_CAST(Function)(f)), + allocator_(a) + { + } + +//private: + Function function_; + Allocator allocator_; +}; + +// Completion handlers produced from the use_future completion token, when +// using use_future::operator(). +template +class packaged_handler + : public promise_creator +{ +public: + typedef Allocator allocator_type; + typedef void result_type; + + packaged_handler(packaged_token t) + : function_(ASIO_MOVE_CAST(Function)(t.function_)), + allocator_(t.allocator_) + { + this->create_promise(allocator_); + } + + allocator_type get_allocator() const ASIO_NOEXCEPT + { + return allocator_; + } + +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) + + template + void operator()(ASIO_MOVE_ARG(Args)... args) + { + (promise_invoke_and_set)(*this->p_, + function_, ASIO_MOVE_CAST(Args)(args)...); + } + +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + + void operator()() + { + (promise_invoke_and_set)(*this->p_, function_); + } + +#define ASIO_PRIVATE_CALL_OP_DEF(n) \ + template \ + void operator()(ASIO_VARIADIC_MOVE_PARAMS(n)) \ + {\ + (promise_invoke_and_set)(*this->p_, \ + function_, ASIO_VARIADIC_MOVE_ARGS(n)); \ + } \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF) +#undef ASIO_PRIVATE_CALL_OP_DEF + +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +private: + Function function_; + Allocator allocator_; +}; + +template +inline void asio_handler_invoke(Function& f, + packaged_handler* h) +{ + typename packaged_handler::executor_type + ex(h->get_executor()); + ex.dispatch(ASIO_MOVE_CAST(Function)(f), std::allocator()); +} + +template +inline void asio_handler_invoke(const Function& f, + packaged_handler* h) +{ + typename packaged_handler::executor_type + ex(h->get_executor()); + ex.dispatch(f, std::allocator()); +} + +// Helper base class for async_result specialisation. +template +class packaged_async_result +{ +public: + typedef packaged_handler completion_handler_type; + typedef typename completion_handler_type::future_type return_type; + + explicit packaged_async_result(completion_handler_type& h) + : future_(h.get_future()) + { + } + + return_type get() + { + return ASIO_MOVE_CAST(return_type)(future_); + } + +private: + return_type future_; +}; + +} // namespace detail + +template template +inline detail::packaged_token::type, Allocator> +use_future_t::operator()(ASIO_MOVE_ARG(Function) f) const +{ + return detail::packaged_token::type, Allocator>( + ASIO_MOVE_CAST(Function)(f), allocator_); +} + +#if !defined(GENERATING_DOCUMENTATION) + +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) + +template +class async_result, Result(Args...)> + : public detail::promise_async_result< + void(typename decay::type...), Allocator> +{ +public: + explicit async_result( + typename detail::promise_async_result::type...), + Allocator>::completion_handler_type& h) + : detail::promise_async_result< + void(typename decay::type...), Allocator>(h) + { + } +}; + +template +class async_result, Result(Args...)> + : public detail::packaged_async_result::type> +{ +public: + explicit async_result( + typename detail::packaged_async_result::type>::completion_handler_type& h) + : detail::packaged_async_result::type>(h) + { + } +}; + +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +template +class async_result, Result()> + : public detail::promise_async_result +{ +public: + explicit async_result( + typename detail::promise_async_result< + void(), Allocator>::completion_handler_type& h) + : detail::promise_async_result(h) + { + } +}; + +template +class async_result, Result()> + : public detail::packaged_async_result::type> +{ +public: + explicit async_result( + typename detail::packaged_async_result::type>::completion_handler_type& h) + : detail::packaged_async_result::type>(h) + { + } +}; + +#define ASIO_PRIVATE_ASYNC_RESULT_DEF(n) \ + template \ + class async_result, \ + Result(ASIO_VARIADIC_TARGS(n))> \ + : public detail::promise_async_result< \ + void(ASIO_VARIADIC_DECAY(n)), Allocator> \ + { \ + public: \ + explicit async_result( \ + typename detail::promise_async_result< \ + void(ASIO_VARIADIC_DECAY(n)), \ + Allocator>::completion_handler_type& h) \ + : detail::promise_async_result< \ + void(ASIO_VARIADIC_DECAY(n)), Allocator>(h) \ + { \ + } \ + }; \ + \ + template \ + class async_result, \ + Result(ASIO_VARIADIC_TARGS(n))> \ + : public detail::packaged_async_result::type> \ + { \ + public: \ + explicit async_result( \ + typename detail::packaged_async_result::type \ + >::completion_handler_type& h) \ + : detail::packaged_async_result::type>(h) \ + { \ + } \ + }; \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_RESULT_DEF) +#undef ASIO_PRIVATE_ASYNC_RESULT_DEF + +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +#if !defined(ASIO_NO_DEPRECATED) + +template +struct handler_type, Signature> +{ + typedef typename async_result, + Signature>::completion_handler_type type; +}; + +template +class async_result > + : public detail::promise_async_result +{ +public: + typedef typename detail::promise_async_result< + Signature, Allocator>::return_type type; + + explicit async_result( + typename detail::promise_async_result< + Signature, Allocator>::completion_handler_type& h) + : detail::promise_async_result(h) + { + } +}; + +template +struct handler_type, Signature> +{ + typedef typename async_result, + Signature>::completion_handler_type type; +}; + +template +class async_result > + : public detail::packaged_async_result +{ +public: + typedef typename detail::packaged_async_result< + Function, Allocator, Result>::return_type type; + + explicit async_result( + typename detail::packaged_async_result< + Function, Allocator, Result>::completion_handler_type& h) + : detail::packaged_async_result(h) + { + } +}; + +#endif // !defined(ASIO_NO_DEPRECATED) + +#endif // !defined(GENERATING_DOCUMENTATION) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_USE_FUTURE_HPP diff --git a/tools/sdk/include/asio/asio/impl/write.hpp b/tools/sdk/include/asio/asio/impl/write.hpp new file mode 100644 index 00000000..d07e8d3e --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/write.hpp @@ -0,0 +1,674 @@ +// +// impl/write.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_WRITE_HPP +#define ASIO_IMPL_WRITE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/associated_allocator.hpp" +#include "asio/associated_executor.hpp" +#include "asio/buffer.hpp" +#include "asio/completion_condition.hpp" +#include "asio/detail/array_fwd.hpp" +#include "asio/detail/base_from_completion_cond.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/consuming_buffers.hpp" +#include "asio/detail/dependent_type.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +namespace detail +{ + template + std::size_t write_buffer_sequence(SyncWriteStream& s, + const ConstBufferSequence& buffers, const ConstBufferIterator&, + CompletionCondition completion_condition, asio::error_code& ec) + { + ec = asio::error_code(); + asio::detail::consuming_buffers tmp(buffers); + while (!tmp.empty()) + { + if (std::size_t max_size = detail::adapt_completion_condition_result( + completion_condition(ec, tmp.total_consumed()))) + tmp.consume(s.write_some(tmp.prepare(max_size), ec)); + else + break; + } + return tmp.total_consumed();; + } +} // namespace detail + +template +inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec, + typename enable_if< + is_const_buffer_sequence::value + >::type*) +{ + return detail::write_buffer_sequence(s, buffers, + asio::buffer_sequence_begin(buffers), completion_condition, ec); +} + +template +inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + typename enable_if< + is_const_buffer_sequence::value + >::type*) +{ + asio::error_code ec; + std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec); + asio::detail::throw_error(ec, "write"); + return bytes_transferred; +} + +template +inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + asio::error_code& ec, + typename enable_if< + is_const_buffer_sequence::value + >::type*) +{ + return write(s, buffers, transfer_all(), ec); +} + +template +inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, + typename enable_if< + is_const_buffer_sequence::value + >::type*) +{ + asio::error_code ec; + std::size_t bytes_transferred = write(s, buffers, completion_condition, ec); + asio::detail::throw_error(ec, "write"); + return bytes_transferred; +} + +template +std::size_t write(SyncWriteStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + CompletionCondition completion_condition, asio::error_code& ec, + typename enable_if< + is_dynamic_buffer::type>::value + >::type*) +{ + typename decay::type b( + ASIO_MOVE_CAST(DynamicBuffer)(buffers)); + + std::size_t bytes_transferred = write(s, b.data(), completion_condition, ec); + b.consume(bytes_transferred); + return bytes_transferred; +} + +template +inline std::size_t write(SyncWriteStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + typename enable_if< + is_dynamic_buffer::type>::value + >::type*) +{ + asio::error_code ec; + std::size_t bytes_transferred = write(s, + ASIO_MOVE_CAST(DynamicBuffer)(buffers), + transfer_all(), ec); + asio::detail::throw_error(ec, "write"); + return bytes_transferred; +} + +template +inline std::size_t write(SyncWriteStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + asio::error_code& ec, + typename enable_if< + is_dynamic_buffer::type>::value + >::type*) +{ + return write(s, ASIO_MOVE_CAST(DynamicBuffer)(buffers), + transfer_all(), ec); +} + +template +inline std::size_t write(SyncWriteStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + CompletionCondition completion_condition, + typename enable_if< + is_dynamic_buffer::type>::value + >::type*) +{ + asio::error_code ec; + std::size_t bytes_transferred = write(s, + ASIO_MOVE_CAST(DynamicBuffer)(buffers), + completion_condition, ec); + asio::detail::throw_error(ec, "write"); + return bytes_transferred; +} + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +template +inline std::size_t write(SyncWriteStream& s, + asio::basic_streambuf& b, + CompletionCondition completion_condition, asio::error_code& ec) +{ + return write(s, basic_streambuf_ref(b), completion_condition, ec); +} + +template +inline std::size_t write(SyncWriteStream& s, + asio::basic_streambuf& b) +{ + return write(s, basic_streambuf_ref(b)); +} + +template +inline std::size_t write(SyncWriteStream& s, + asio::basic_streambuf& b, + asio::error_code& ec) +{ + return write(s, basic_streambuf_ref(b), ec); +} + +template +inline std::size_t write(SyncWriteStream& s, + asio::basic_streambuf& b, + CompletionCondition completion_condition) +{ + return write(s, basic_streambuf_ref(b), completion_condition); +} + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +namespace detail +{ + template + class write_op + : detail::base_from_completion_cond + { + public: + write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, WriteHandler& handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + buffers_(buffers), + start_(0), + handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + write_op(const write_op& other) + : detail::base_from_completion_cond(other), + stream_(other.stream_), + buffers_(other.buffers_), + start_(other.start_), + handler_(other.handler_) + { + } + + write_op(write_op&& other) + : detail::base_from_completion_cond(other), + stream_(other.stream_), + buffers_(other.buffers_), + start_(other.start_), + handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + std::size_t max_size; + switch (start_ = start) + { + case 1: + max_size = this->check_for_completion(ec, buffers_.total_consumed()); + do + { + stream_.async_write_some(buffers_.prepare(max_size), + ASIO_MOVE_CAST(write_op)(*this)); + return; default: + buffers_.consume(bytes_transferred); + if ((!ec && bytes_transferred == 0) || buffers_.empty()) + break; + max_size = this->check_for_completion(ec, buffers_.total_consumed()); + } while (max_size > 0); + + handler_(ec, buffers_.total_consumed()); + } + } + + //private: + AsyncWriteStream& stream_; + asio::detail::consuming_buffers buffers_; + int start_; + WriteHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + write_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + write_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + write_op* this_handler) + { + return this_handler->start_ == 0 ? true + : asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + write_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + write_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void start_write_buffer_sequence_op(AsyncWriteStream& stream, + const ConstBufferSequence& buffers, const ConstBufferIterator&, + CompletionCondition completion_condition, WriteHandler& handler) + { + detail::write_op( + stream, buffers, completion_condition, handler)( + asio::error_code(), 0, 1); + } + +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::write_op, + Allocator> +{ + typedef typename associated_allocator::type type; + + static type get( + const detail::write_op& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::write_op, + Executor> +{ + typedef typename associated_executor::type type; + + static type get( + const detail::write_op& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +inline ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(WriteHandler) handler, + typename enable_if< + is_const_buffer_sequence::value + >::type*) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + async_completion init(handler); + + detail::start_write_buffer_sequence_op(s, buffers, + asio::buffer_sequence_begin(buffers), completion_condition, + init.completion_handler); + + return init.result.get(); +} + +template +inline ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler, + typename enable_if< + is_const_buffer_sequence::value + >::type*) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + async_completion init(handler); + + detail::start_write_buffer_sequence_op(s, buffers, + asio::buffer_sequence_begin(buffers), transfer_all(), + init.completion_handler); + + return init.result.get(); +} + +namespace detail +{ + template + class write_dynbuf_op + { + public: + template + write_dynbuf_op(AsyncWriteStream& stream, + ASIO_MOVE_ARG(BufferSequence) buffers, + CompletionCondition completion_condition, WriteHandler& handler) + : stream_(stream), + buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), + completion_condition_( + ASIO_MOVE_CAST(CompletionCondition)(completion_condition)), + handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + write_dynbuf_op(const write_dynbuf_op& other) + : stream_(other.stream_), + buffers_(other.buffers_), + completion_condition_(other.completion_condition_), + handler_(other.handler_) + { + } + + write_dynbuf_op(write_dynbuf_op&& other) + : stream_(other.stream_), + buffers_(ASIO_MOVE_CAST(DynamicBuffer)(other.buffers_)), + completion_condition_( + ASIO_MOVE_CAST(CompletionCondition)( + other.completion_condition_)), + handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + switch (start) + { + case 1: + async_write(stream_, buffers_.data(), completion_condition_, + ASIO_MOVE_CAST(write_dynbuf_op)(*this)); + return; default: + buffers_.consume(bytes_transferred); + handler_(ec, static_cast(bytes_transferred)); + } + } + + //private: + AsyncWriteStream& stream_; + DynamicBuffer buffers_; + CompletionCondition completion_condition_; + WriteHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + write_dynbuf_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + write_dynbuf_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + write_dynbuf_op* this_handler) + { + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + write_dynbuf_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + write_dynbuf_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::write_dynbuf_op, + Allocator> +{ + typedef typename associated_allocator::type type; + + static type get( + const detail::write_dynbuf_op& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::write_dynbuf_op, + Executor> +{ + typedef typename associated_executor::type type; + + static type get( + const detail::write_dynbuf_op& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +inline ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write(AsyncWriteStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + ASIO_MOVE_ARG(WriteHandler) handler, + typename enable_if< + is_dynamic_buffer::type>::value + >::type*) +{ + return async_write(s, + ASIO_MOVE_CAST(DynamicBuffer)(buffers), + transfer_all(), ASIO_MOVE_CAST(WriteHandler)(handler)); +} + +template +inline ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write(AsyncWriteStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(WriteHandler) handler, + typename enable_if< + is_dynamic_buffer::type>::value + >::type*) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + async_completion init(handler); + + detail::write_dynbuf_op::type, + CompletionCondition, ASIO_HANDLER_TYPE( + WriteHandler, void (asio::error_code, std::size_t))>( + s, ASIO_MOVE_CAST(DynamicBuffer)(buffers), + completion_condition, init.completion_handler)( + asio::error_code(), 0, 1); + + return init.result.get(); +} + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +template +inline ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write(AsyncWriteStream& s, + asio::basic_streambuf& b, + ASIO_MOVE_ARG(WriteHandler) handler) +{ + return async_write(s, basic_streambuf_ref(b), + ASIO_MOVE_CAST(WriteHandler)(handler)); +} + +template +inline ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write(AsyncWriteStream& s, + asio::basic_streambuf& b, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(WriteHandler) handler) +{ + return async_write(s, basic_streambuf_ref(b), + completion_condition, ASIO_MOVE_CAST(WriteHandler)(handler)); +} + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_WRITE_HPP diff --git a/tools/sdk/include/asio/asio/impl/write_at.hpp b/tools/sdk/include/asio/asio/impl/write_at.hpp new file mode 100644 index 00000000..cc6f336f --- /dev/null +++ b/tools/sdk/include/asio/asio/impl/write_at.hpp @@ -0,0 +1,572 @@ +// +// impl/write_at.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IMPL_WRITE_AT_HPP +#define ASIO_IMPL_WRITE_AT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/associated_allocator.hpp" +#include "asio/associated_executor.hpp" +#include "asio/buffer.hpp" +#include "asio/completion_condition.hpp" +#include "asio/detail/array_fwd.hpp" +#include "asio/detail/base_from_completion_cond.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/consuming_buffers.hpp" +#include "asio/detail/dependent_type.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +namespace detail +{ + template + std::size_t write_at_buffer_sequence(SyncRandomAccessWriteDevice& d, + uint64_t offset, const ConstBufferSequence& buffers, + const ConstBufferIterator&, CompletionCondition completion_condition, + asio::error_code& ec) + { + ec = asio::error_code(); + asio::detail::consuming_buffers tmp(buffers); + while (!tmp.empty()) + { + if (std::size_t max_size = detail::adapt_completion_condition_result( + completion_condition(ec, tmp.total_consumed()))) + { + tmp.consume(d.write_some_at(offset + tmp.total_consumed(), + tmp.prepare(max_size), ec)); + } + else + break; + } + return tmp.total_consumed();; + } +} // namespace detail + +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, + uint64_t offset, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec) +{ + return detail::write_at_buffer_sequence(d, offset, buffers, + asio::buffer_sequence_begin(buffers), completion_condition, ec); +} + +template +inline std::size_t write_at(SyncRandomAccessWriteDevice& d, + uint64_t offset, const ConstBufferSequence& buffers) +{ + asio::error_code ec; + std::size_t bytes_transferred = write_at( + d, offset, buffers, transfer_all(), ec); + asio::detail::throw_error(ec, "write_at"); + return bytes_transferred; +} + +template +inline std::size_t write_at(SyncRandomAccessWriteDevice& d, + uint64_t offset, const ConstBufferSequence& buffers, + asio::error_code& ec) +{ + return write_at(d, offset, buffers, transfer_all(), ec); +} + +template +inline std::size_t write_at(SyncRandomAccessWriteDevice& d, + uint64_t offset, const ConstBufferSequence& buffers, + CompletionCondition completion_condition) +{ + asio::error_code ec; + std::size_t bytes_transferred = write_at( + d, offset, buffers, completion_condition, ec); + asio::detail::throw_error(ec, "write_at"); + return bytes_transferred; +} + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, + uint64_t offset, asio::basic_streambuf& b, + CompletionCondition completion_condition, asio::error_code& ec) +{ + std::size_t bytes_transferred = write_at( + d, offset, b.data(), completion_condition, ec); + b.consume(bytes_transferred); + return bytes_transferred; +} + +template +inline std::size_t write_at(SyncRandomAccessWriteDevice& d, + uint64_t offset, asio::basic_streambuf& b) +{ + asio::error_code ec; + std::size_t bytes_transferred = write_at(d, offset, b, transfer_all(), ec); + asio::detail::throw_error(ec, "write_at"); + return bytes_transferred; +} + +template +inline std::size_t write_at(SyncRandomAccessWriteDevice& d, + uint64_t offset, asio::basic_streambuf& b, + asio::error_code& ec) +{ + return write_at(d, offset, b, transfer_all(), ec); +} + +template +inline std::size_t write_at(SyncRandomAccessWriteDevice& d, + uint64_t offset, asio::basic_streambuf& b, + CompletionCondition completion_condition) +{ + asio::error_code ec; + std::size_t bytes_transferred = write_at( + d, offset, b, completion_condition, ec); + asio::detail::throw_error(ec, "write_at"); + return bytes_transferred; +} + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +namespace detail +{ + template + class write_at_op + : detail::base_from_completion_cond + { + public: + write_at_op(AsyncRandomAccessWriteDevice& device, + uint64_t offset, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, WriteHandler& handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + device_(device), + offset_(offset), + buffers_(buffers), + start_(0), + handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + write_at_op(const write_at_op& other) + : detail::base_from_completion_cond(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + start_(other.start_), + handler_(other.handler_) + { + } + + write_at_op(write_at_op&& other) + : detail::base_from_completion_cond(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + start_(other.start_), + handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + std::size_t max_size; + switch (start_ = start) + { + case 1: + max_size = this->check_for_completion(ec, buffers_.total_consumed()); + do + { + device_.async_write_some_at( + offset_ + buffers_.total_consumed(), buffers_.prepare(max_size), + ASIO_MOVE_CAST(write_at_op)(*this)); + return; default: + buffers_.consume(bytes_transferred); + if ((!ec && bytes_transferred == 0) || buffers_.empty()) + break; + max_size = this->check_for_completion(ec, buffers_.total_consumed()); + } while (max_size > 0); + + handler_(ec, buffers_.total_consumed()); + } + } + + //private: + AsyncRandomAccessWriteDevice& device_; + uint64_t offset_; + asio::detail::consuming_buffers buffers_; + int start_; + WriteHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + write_at_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + write_at_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + write_at_op* this_handler) + { + return this_handler->start_ == 0 ? true + : asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + write_at_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + write_at_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void start_write_at_buffer_sequence_op(AsyncRandomAccessWriteDevice& d, + uint64_t offset, const ConstBufferSequence& buffers, + const ConstBufferIterator&, CompletionCondition completion_condition, + WriteHandler& handler) + { + detail::write_at_op( + d, offset, buffers, completion_condition, handler)( + asio::error_code(), 0, 1); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::write_at_op, + Allocator> +{ + typedef typename associated_allocator::type type; + + static type get( + const detail::write_at_op& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::write_at_op, + Executor> +{ + typedef typename associated_executor::type type; + + static type get( + const detail::write_at_op& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +inline ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write_at(AsyncRandomAccessWriteDevice& d, + uint64_t offset, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + async_completion init(handler); + + detail::start_write_at_buffer_sequence_op(d, offset, buffers, + asio::buffer_sequence_begin(buffers), completion_condition, + init.completion_handler); + + return init.result.get(); +} + +template +inline ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write_at(AsyncRandomAccessWriteDevice& d, + uint64_t offset, const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + async_completion init(handler); + + detail::start_write_at_buffer_sequence_op(d, offset, buffers, + asio::buffer_sequence_begin(buffers), transfer_all(), + init.completion_handler); + + return init.result.get(); +} + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +namespace detail +{ + template + class write_at_streambuf_op + { + public: + write_at_streambuf_op( + asio::basic_streambuf& streambuf, + WriteHandler& handler) + : streambuf_(streambuf), + handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + write_at_streambuf_op(const write_at_streambuf_op& other) + : streambuf_(other.streambuf_), + handler_(other.handler_) + { + } + + write_at_streambuf_op(write_at_streambuf_op&& other) + : streambuf_(other.streambuf_), + handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + const std::size_t bytes_transferred) + { + streambuf_.consume(bytes_transferred); + handler_(ec, bytes_transferred); + } + + //private: + asio::basic_streambuf& streambuf_; + WriteHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + write_at_streambuf_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + write_at_streambuf_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + write_at_streambuf_op* this_handler) + { + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + write_at_streambuf_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + write_at_streambuf_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline write_at_streambuf_op + make_write_at_streambuf_op( + asio::basic_streambuf& b, WriteHandler handler) + { + return write_at_streambuf_op(b, handler); + } +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template +struct associated_allocator< + detail::write_at_streambuf_op, + Allocator1> +{ + typedef typename associated_allocator::type type; + + static type get( + const detail::write_at_streambuf_op& h, + const Allocator1& a = Allocator1()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + detail::write_at_streambuf_op, + Executor1> +{ + typedef typename associated_executor::type type; + + static type get( + const detail::write_at_streambuf_op& h, + const Executor1& ex = Executor1()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template +inline ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write_at(AsyncRandomAccessWriteDevice& d, + uint64_t offset, asio::basic_streambuf& b, + CompletionCondition completion_condition, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + async_completion init(handler); + + async_write_at(d, offset, b.data(), completion_condition, + detail::write_at_streambuf_op( + b, init.completion_handler)); + + return init.result.get(); +} + +template +inline ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write_at(AsyncRandomAccessWriteDevice& d, + uint64_t offset, asio::basic_streambuf& b, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + async_completion init(handler); + + async_write_at(d, offset, b.data(), transfer_all(), + detail::write_at_streambuf_op( + b, init.completion_handler)); + + return init.result.get(); +} + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_WRITE_AT_HPP diff --git a/tools/sdk/include/asio/asio/io_context.hpp b/tools/sdk/include/asio/asio/io_context.hpp new file mode 100644 index 00000000..4d93be44 --- /dev/null +++ b/tools/sdk/include/asio/asio/io_context.hpp @@ -0,0 +1,876 @@ +// +// io_context.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IO_CONTEXT_HPP +#define ASIO_IO_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include +#include +#include "asio/async_result.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/wrapped_handler.hpp" +#include "asio/error_code.hpp" +#include "asio/execution_context.hpp" + +#if defined(ASIO_HAS_CHRONO) +# include "asio/detail/chrono.hpp" +#endif // defined(ASIO_HAS_CHRONO) + +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) +# include "asio/detail/winsock_init.hpp" +#elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \ + || defined(__osf__) +# include "asio/detail/signal_init.hpp" +#endif + +#include "asio/detail/push_options.hpp" + +namespace asio { + +namespace detail { +#if defined(ASIO_HAS_IOCP) + typedef class win_iocp_io_context io_context_impl; + class win_iocp_overlapped_ptr; +#else + typedef class scheduler io_context_impl; +#endif +} // namespace detail + +/// Provides core I/O functionality. +/** + * The io_context class provides the core I/O functionality for users of the + * asynchronous I/O objects, including: + * + * @li asio::ip::tcp::socket + * @li asio::ip::tcp::acceptor + * @li asio::ip::udp::socket + * @li asio::deadline_timer. + * + * The io_context class also includes facilities intended for developers of + * custom asynchronous services. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe, with the specific exceptions of the restart() + * and notify_fork() functions. Calling restart() while there are unfinished + * run(), run_one(), run_for(), run_until(), poll() or poll_one() calls results + * in undefined behaviour. The notify_fork() function should not be called + * while any io_context function, or any function on an I/O object that is + * associated with the io_context, is being called in another thread. + * + * @par Concepts: + * Dispatcher. + * + * @par Synchronous and asynchronous operations + * + * Synchronous operations on I/O objects implicitly run the io_context object + * for an individual operation. The io_context functions run(), run_one(), + * run_for(), run_until(), poll() or poll_one() must be called for the + * io_context to perform asynchronous operations on behalf of a C++ program. + * Notification that an asynchronous operation has completed is delivered by + * invocation of the associated handler. Handlers are invoked only by a thread + * that is currently calling any overload of run(), run_one(), run_for(), + * run_until(), poll() or poll_one() for the io_context. + * + * @par Effect of exceptions thrown from handlers + * + * If an exception is thrown from a handler, the exception is allowed to + * propagate through the throwing thread's invocation of run(), run_one(), + * run_for(), run_until(), poll() or poll_one(). No other threads that are + * calling any of these functions are affected. It is then the responsibility + * of the application to catch the exception. + * + * After the exception has been caught, the run(), run_one(), run_for(), + * run_until(), poll() or poll_one() call may be restarted @em without the need + * for an intervening call to restart(). This allows the thread to rejoin the + * io_context object's thread pool without impacting any other threads in the + * pool. + * + * For example: + * + * @code + * asio::io_context io_context; + * ... + * for (;;) + * { + * try + * { + * io_context.run(); + * break; // run() exited normally + * } + * catch (my_exception& e) + * { + * // Deal with exception as appropriate. + * } + * } + * @endcode + * + * @par Submitting arbitrary tasks to the io_context + * + * To submit functions to the io_context, use the @ref asio::dispatch, + * @ref asio::post or @ref asio::defer free functions. + * + * For example: + * + * @code void my_task() + * { + * ... + * } + * + * ... + * + * asio::io_context io_context; + * + * // Submit a function to the io_context. + * asio::post(io_context, my_task); + * + * // Submit a lambda object to the io_context. + * asio::post(io_context, + * []() + * { + * ... + * }); + * + * // Run the io_context until it runs out of work. + * io_context.run(); @endcode + * + * @par Stopping the io_context from running out of work + * + * Some applications may need to prevent an io_context object's run() call from + * returning when there is no more work to do. For example, the io_context may + * be being run in a background thread that is launched prior to the + * application's asynchronous operations. The run() call may be kept running by + * creating an object of type + * asio::executor_work_guard: + * + * @code asio::io_context io_context; + * asio::executor_work_guard + * = asio::make_work_guard(io_context); + * ... @endcode + * + * To effect a shutdown, the application will then need to call the io_context + * object's stop() member function. This will cause the io_context run() call + * to return as soon as possible, abandoning unfinished operations and without + * permitting ready handlers to be dispatched. + * + * Alternatively, if the application requires that all operations and handlers + * be allowed to finish normally, the work object may be explicitly reset. + * + * @code asio::io_context io_context; + * asio::executor_work_guard + * = asio::make_work_guard(io_context); + * ... + * work.reset(); // Allow run() to exit. @endcode + */ +class io_context + : public execution_context +{ +private: + typedef detail::io_context_impl impl_type; +#if defined(ASIO_HAS_IOCP) + friend class detail::win_iocp_overlapped_ptr; +#endif + +public: + class executor_type; + friend class executor_type; + +#if !defined(ASIO_NO_DEPRECATED) + class work; + friend class work; +#endif // !defined(ASIO_NO_DEPRECATED) + + class service; + +#if !defined(ASIO_NO_EXTENSIONS) + class strand; +#endif // !defined(ASIO_NO_EXTENSIONS) + + /// The type used to count the number of handlers executed by the context. + typedef std::size_t count_type; + + /// Constructor. + ASIO_DECL io_context(); + + /// Constructor. + /** + * Construct with a hint about the required level of concurrency. + * + * @param concurrency_hint A suggestion to the implementation on how many + * threads it should allow to run simultaneously. + */ + ASIO_DECL explicit io_context(int concurrency_hint); + + /// Destructor. + /** + * On destruction, the io_context performs the following sequence of + * operations: + * + * @li For each service object @c svc in the io_context set, in reverse order + * of the beginning of service object lifetime, performs + * @c svc->shutdown(). + * + * @li Uninvoked handler objects that were scheduled for deferred invocation + * on the io_context, or any associated strand, are destroyed. + * + * @li For each service object @c svc in the io_context set, in reverse order + * of the beginning of service object lifetime, performs + * delete static_cast(svc). + * + * @note The destruction sequence described above permits programs to + * simplify their resource management by using @c shared_ptr<>. Where an + * object's lifetime is tied to the lifetime of a connection (or some other + * sequence of asynchronous operations), a @c shared_ptr to the object would + * be bound into the handlers for all asynchronous operations associated with + * it. This works as follows: + * + * @li When a single connection ends, all associated asynchronous operations + * complete. The corresponding handler objects are destroyed, and all + * @c shared_ptr references to the objects are destroyed. + * + * @li To shut down the whole program, the io_context function stop() is + * called to terminate any run() calls as soon as possible. The io_context + * destructor defined above destroys all handlers, causing all @c shared_ptr + * references to all connection objects to be destroyed. + */ + ASIO_DECL ~io_context(); + + /// Obtains the executor associated with the io_context. + executor_type get_executor() ASIO_NOEXCEPT; + + /// Run the io_context object's event processing loop. + /** + * The run() function blocks until all work has finished and there are no + * more handlers to be dispatched, or until the io_context has been stopped. + * + * Multiple threads may call the run() function to set up a pool of threads + * from which the io_context may execute handlers. All threads that are + * waiting in the pool are equivalent and the io_context may choose any one + * of them to invoke a handler. + * + * A normal exit from the run() function implies that the io_context object + * is stopped (the stopped() function returns @c true). Subsequent calls to + * run(), run_one(), poll() or poll_one() will return immediately unless there + * is a prior call to restart(). + * + * @return The number of handlers that were executed. + * + * @note Calling the run() function from a thread that is currently calling + * one of run(), run_one(), run_for(), run_until(), poll() or poll_one() on + * the same io_context object may introduce the potential for deadlock. It is + * the caller's reponsibility to avoid this. + * + * The poll() function may also be used to dispatch ready handlers, but + * without blocking. + */ + ASIO_DECL count_type run(); + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use non-error_code overload.) Run the io_context object's + /// event processing loop. + /** + * The run() function blocks until all work has finished and there are no + * more handlers to be dispatched, or until the io_context has been stopped. + * + * Multiple threads may call the run() function to set up a pool of threads + * from which the io_context may execute handlers. All threads that are + * waiting in the pool are equivalent and the io_context may choose any one + * of them to invoke a handler. + * + * A normal exit from the run() function implies that the io_context object + * is stopped (the stopped() function returns @c true). Subsequent calls to + * run(), run_one(), poll() or poll_one() will return immediately unless there + * is a prior call to restart(). + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of handlers that were executed. + * + * @note Calling the run() function from a thread that is currently calling + * one of run(), run_one(), run_for(), run_until(), poll() or poll_one() on + * the same io_context object may introduce the potential for deadlock. It is + * the caller's reponsibility to avoid this. + * + * The poll() function may also be used to dispatch ready handlers, but + * without blocking. + */ + ASIO_DECL count_type run(asio::error_code& ec); +#endif // !defined(ASIO_NO_DEPRECATED) + +#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) + /// Run the io_context object's event processing loop for a specified + /// duration. + /** + * The run_for() function blocks until all work has finished and there are no + * more handlers to be dispatched, until the io_context has been stopped, or + * until the specified duration has elapsed. + * + * @param rel_time The duration for which the call may block. + * + * @return The number of handlers that were executed. + */ + template + std::size_t run_for(const chrono::duration& rel_time); + + /// Run the io_context object's event processing loop until a specified time. + /** + * The run_until() function blocks until all work has finished and there are + * no more handlers to be dispatched, until the io_context has been stopped, + * or until the specified time has been reached. + * + * @param abs_time The time point until which the call may block. + * + * @return The number of handlers that were executed. + */ + template + std::size_t run_until(const chrono::time_point& abs_time); +#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) + + /// Run the io_context object's event processing loop to execute at most one + /// handler. + /** + * The run_one() function blocks until one handler has been dispatched, or + * until the io_context has been stopped. + * + * @return The number of handlers that were executed. A zero return value + * implies that the io_context object is stopped (the stopped() function + * returns @c true). Subsequent calls to run(), run_one(), poll() or + * poll_one() will return immediately unless there is a prior call to + * restart(). + * + * @note Calling the run_one() function from a thread that is currently + * calling one of run(), run_one(), run_for(), run_until(), poll() or + * poll_one() on the same io_context object may introduce the potential for + * deadlock. It is the caller's reponsibility to avoid this. + */ + ASIO_DECL count_type run_one(); + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use non-error_code overlaod.) Run the io_context object's + /// event processing loop to execute at most one handler. + /** + * The run_one() function blocks until one handler has been dispatched, or + * until the io_context has been stopped. + * + * @return The number of handlers that were executed. A zero return value + * implies that the io_context object is stopped (the stopped() function + * returns @c true). Subsequent calls to run(), run_one(), poll() or + * poll_one() will return immediately unless there is a prior call to + * restart(). + * + * @return The number of handlers that were executed. + * + * @note Calling the run_one() function from a thread that is currently + * calling one of run(), run_one(), run_for(), run_until(), poll() or + * poll_one() on the same io_context object may introduce the potential for + * deadlock. It is the caller's reponsibility to avoid this. + */ + ASIO_DECL count_type run_one(asio::error_code& ec); +#endif // !defined(ASIO_NO_DEPRECATED) + +#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) + /// Run the io_context object's event processing loop for a specified duration + /// to execute at most one handler. + /** + * The run_one_for() function blocks until one handler has been dispatched, + * until the io_context has been stopped, or until the specified duration has + * elapsed. + * + * @param rel_time The duration for which the call may block. + * + * @return The number of handlers that were executed. + */ + template + std::size_t run_one_for(const chrono::duration& rel_time); + + /// Run the io_context object's event processing loop until a specified time + /// to execute at most one handler. + /** + * The run_one_until() function blocks until one handler has been dispatched, + * until the io_context has been stopped, or until the specified time has + * been reached. + * + * @param abs_time The time point until which the call may block. + * + * @return The number of handlers that were executed. + */ + template + std::size_t run_one_until( + const chrono::time_point& abs_time); +#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) + + /// Run the io_context object's event processing loop to execute ready + /// handlers. + /** + * The poll() function runs handlers that are ready to run, without blocking, + * until the io_context has been stopped or there are no more ready handlers. + * + * @return The number of handlers that were executed. + */ + ASIO_DECL count_type poll(); + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use non-error_code overload.) Run the io_context object's + /// event processing loop to execute ready handlers. + /** + * The poll() function runs handlers that are ready to run, without blocking, + * until the io_context has been stopped or there are no more ready handlers. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of handlers that were executed. + */ + ASIO_DECL count_type poll(asio::error_code& ec); +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Run the io_context object's event processing loop to execute one ready + /// handler. + /** + * The poll_one() function runs at most one handler that is ready to run, + * without blocking. + * + * @return The number of handlers that were executed. + */ + ASIO_DECL count_type poll_one(); + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use non-error_code overload.) Run the io_context object's + /// event processing loop to execute one ready handler. + /** + * The poll_one() function runs at most one handler that is ready to run, + * without blocking. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of handlers that were executed. + */ + ASIO_DECL count_type poll_one(asio::error_code& ec); +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Stop the io_context object's event processing loop. + /** + * This function does not block, but instead simply signals the io_context to + * stop. All invocations of its run() or run_one() member functions should + * return as soon as possible. Subsequent calls to run(), run_one(), poll() + * or poll_one() will return immediately until restart() is called. + */ + ASIO_DECL void stop(); + + /// Determine whether the io_context object has been stopped. + /** + * This function is used to determine whether an io_context object has been + * stopped, either through an explicit call to stop(), or due to running out + * of work. When an io_context object is stopped, calls to run(), run_one(), + * poll() or poll_one() will return immediately without invoking any + * handlers. + * + * @return @c true if the io_context object is stopped, otherwise @c false. + */ + ASIO_DECL bool stopped() const; + + /// Restart the io_context in preparation for a subsequent run() invocation. + /** + * This function must be called prior to any second or later set of + * invocations of the run(), run_one(), poll() or poll_one() functions when a + * previous invocation of these functions returned due to the io_context + * being stopped or running out of work. After a call to restart(), the + * io_context object's stopped() function will return @c false. + * + * This function must not be called while there are any unfinished calls to + * the run(), run_one(), poll() or poll_one() functions. + */ + ASIO_DECL void restart(); + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use restart().) Reset the io_context in preparation for a + /// subsequent run() invocation. + /** + * This function must be called prior to any second or later set of + * invocations of the run(), run_one(), poll() or poll_one() functions when a + * previous invocation of these functions returned due to the io_context + * being stopped or running out of work. After a call to restart(), the + * io_context object's stopped() function will return @c false. + * + * This function must not be called while there are any unfinished calls to + * the run(), run_one(), poll() or poll_one() functions. + */ + void reset(); + + /// (Deprecated: Use asio::dispatch().) Request the io_context to + /// invoke the given handler. + /** + * This function is used to ask the io_context to execute the given handler. + * + * The io_context guarantees that the handler will only be called in a thread + * in which the run(), run_one(), poll() or poll_one() member functions is + * currently being invoked. The handler may be executed inside this function + * if the guarantee can be met. + * + * @param handler The handler to be called. The io_context will make + * a copy of the handler object as required. The function signature of the + * handler must be: @code void handler(); @endcode + * + * @note This function throws an exception only if: + * + * @li the handler's @c asio_handler_allocate function; or + * + * @li the handler's copy constructor + * + * throws an exception. + */ + template + ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ()) + dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler); + + /// (Deprecated: Use asio::post().) Request the io_context to invoke + /// the given handler and return immediately. + /** + * This function is used to ask the io_context to execute the given handler, + * but without allowing the io_context to call the handler from inside this + * function. + * + * The io_context guarantees that the handler will only be called in a thread + * in which the run(), run_one(), poll() or poll_one() member functions is + * currently being invoked. + * + * @param handler The handler to be called. The io_context will make + * a copy of the handler object as required. The function signature of the + * handler must be: @code void handler(); @endcode + * + * @note This function throws an exception only if: + * + * @li the handler's @c asio_handler_allocate function; or + * + * @li the handler's copy constructor + * + * throws an exception. + */ + template + ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ()) + post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler); + + /// (Deprecated: Use asio::bind_executor().) Create a new handler that + /// automatically dispatches the wrapped handler on the io_context. + /** + * This function is used to create a new handler function object that, when + * invoked, will automatically pass the wrapped handler to the io_context + * object's dispatch function. + * + * @param handler The handler to be wrapped. The io_context will make a copy + * of the handler object as required. The function signature of the handler + * must be: @code void handler(A1 a1, ... An an); @endcode + * + * @return A function object that, when invoked, passes the wrapped handler to + * the io_context object's dispatch function. Given a function object with the + * signature: + * @code R f(A1 a1, ... An an); @endcode + * If this function object is passed to the wrap function like so: + * @code io_context.wrap(f); @endcode + * then the return value is a function object with the signature + * @code void g(A1 a1, ... An an); @endcode + * that, when invoked, executes code equivalent to: + * @code io_context.dispatch(boost::bind(f, a1, ... an)); @endcode + */ + template +#if defined(GENERATING_DOCUMENTATION) + unspecified +#else + detail::wrapped_handler +#endif + wrap(Handler handler); +#endif // !defined(ASIO_NO_DEPRECATED) + +private: + // Helper function to add the implementation. + ASIO_DECL impl_type& add_impl(impl_type* impl); + + // Backwards compatible overload for use with services derived from + // io_context::service. + template + friend Service& use_service(io_context& ioc); + +#if defined(ASIO_WINDOWS) || defined(__CYGWIN__) + detail::winsock_init<> init_; +#elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \ + || defined(__osf__) + detail::signal_init<> init_; +#endif + + // The implementation. + impl_type& impl_; +}; + +/// Executor used to submit functions to an io_context. +class io_context::executor_type +{ +public: + /// Obtain the underlying execution context. + io_context& context() const ASIO_NOEXCEPT; + + /// Inform the io_context that it has some outstanding work to do. + /** + * This function is used to inform the io_context that some work has begun. + * This ensures that the io_context's run() and run_one() functions do not + * exit while the work is underway. + */ + void on_work_started() const ASIO_NOEXCEPT; + + /// Inform the io_context that some work is no longer outstanding. + /** + * This function is used to inform the io_context that some work has + * finished. Once the count of unfinished work reaches zero, the io_context + * is stopped and the run() and run_one() functions may exit. + */ + void on_work_finished() const ASIO_NOEXCEPT; + + /// Request the io_context to invoke the given function object. + /** + * This function is used to ask the io_context to execute the given function + * object. If the current thread is running the io_context, @c dispatch() + * executes the function before returning. Otherwise, the function will be + * scheduled to run on the io_context. + * + * @param f The function object to be called. The executor will make a copy + * of the handler object as required. The function signature of the function + * object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; + + /// Request the io_context to invoke the given function object. + /** + * This function is used to ask the io_context to execute the given function + * object. The function object will never be executed inside @c post(). + * Instead, it will be scheduled to run on the io_context. + * + * @param f The function object to be called. The executor will make a copy + * of the handler object as required. The function signature of the function + * object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; + + /// Request the io_context to invoke the given function object. + /** + * This function is used to ask the io_context to execute the given function + * object. The function object will never be executed inside @c defer(). + * Instead, it will be scheduled to run on the io_context. + * + * If the current thread belongs to the io_context, @c defer() will delay + * scheduling the function object until the current thread returns control to + * the pool. + * + * @param f The function object to be called. The executor will make a copy + * of the handler object as required. The function signature of the function + * object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; + + /// Determine whether the io_context is running in the current thread. + /** + * @return @c true if the current thread is running the io_context. Otherwise + * returns @c false. + */ + bool running_in_this_thread() const ASIO_NOEXCEPT; + + /// Compare two executors for equality. + /** + * Two executors are equal if they refer to the same underlying io_context. + */ + friend bool operator==(const executor_type& a, + const executor_type& b) ASIO_NOEXCEPT + { + return &a.io_context_ == &b.io_context_; + } + + /// Compare two executors for inequality. + /** + * Two executors are equal if they refer to the same underlying io_context. + */ + friend bool operator!=(const executor_type& a, + const executor_type& b) ASIO_NOEXCEPT + { + return &a.io_context_ != &b.io_context_; + } + +private: + friend class io_context; + + // Constructor. + explicit executor_type(io_context& i) : io_context_(i) {} + + // The underlying io_context. + io_context& io_context_; +}; + +#if !defined(ASIO_NO_DEPRECATED) +/// (Deprecated: Use executor_work_guard.) Class to inform the io_context when +/// it has work to do. +/** + * The work class is used to inform the io_context when work starts and + * finishes. This ensures that the io_context object's run() function will not + * exit while work is underway, and that it does exit when there is no + * unfinished work remaining. + * + * The work class is copy-constructible so that it may be used as a data member + * in a handler class. It is not assignable. + */ +class io_context::work +{ +public: + /// Constructor notifies the io_context that work is starting. + /** + * The constructor is used to inform the io_context that some work has begun. + * This ensures that the io_context object's run() function will not exit + * while the work is underway. + */ + explicit work(asio::io_context& io_context); + + /// Copy constructor notifies the io_context that work is starting. + /** + * The constructor is used to inform the io_context that some work has begun. + * This ensures that the io_context object's run() function will not exit + * while the work is underway. + */ + work(const work& other); + + /// Destructor notifies the io_context that the work is complete. + /** + * The destructor is used to inform the io_context that some work has + * finished. Once the count of unfinished work reaches zero, the io_context + * object's run() function is permitted to exit. + */ + ~work(); + + /// Get the io_context associated with the work. + asio::io_context& get_io_context(); + + /// (Deprecated: Use get_io_context().) Get the io_context associated with the + /// work. + asio::io_context& get_io_service(); + +private: + // Prevent assignment. + void operator=(const work& other); + + // The io_context implementation. + detail::io_context_impl& io_context_impl_; +}; +#endif // !defined(ASIO_NO_DEPRECATED) + +/// Base class for all io_context services. +class io_context::service + : public execution_context::service +{ +public: + /// Get the io_context object that owns the service. + asio::io_context& get_io_context(); + +#if !defined(ASIO_NO_DEPRECATED) + /// Get the io_context object that owns the service. + asio::io_context& get_io_service(); +#endif // !defined(ASIO_NO_DEPRECATED) + +private: + /// Destroy all user-defined handler objects owned by the service. + ASIO_DECL virtual void shutdown(); + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use shutdown().) Destroy all user-defined handler objects + /// owned by the service. + ASIO_DECL virtual void shutdown_service(); +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Handle notification of a fork-related event to perform any necessary + /// housekeeping. + /** + * This function is not a pure virtual so that services only have to + * implement it if necessary. The default implementation does nothing. + */ + ASIO_DECL virtual void notify_fork( + execution_context::fork_event event); + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use notify_fork().) Handle notification of a fork-related + /// event to perform any necessary housekeeping. + /** + * This function is not a pure virtual so that services only have to + * implement it if necessary. The default implementation does nothing. + */ + ASIO_DECL virtual void fork_service( + execution_context::fork_event event); +#endif // !defined(ASIO_NO_DEPRECATED) + +protected: + /// Constructor. + /** + * @param owner The io_context object that owns the service. + */ + ASIO_DECL service(asio::io_context& owner); + + /// Destructor. + ASIO_DECL virtual ~service(); +}; + +namespace detail { + +// Special service base class to keep classes header-file only. +template +class service_base + : public asio::io_context::service +{ +public: + static asio::detail::service_id id; + + // Constructor. + service_base(asio::io_context& io_context) + : asio::io_context::service(io_context) + { + } +}; + +template +asio::detail::service_id service_base::id; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/io_context.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/impl/io_context.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +// If both io_context.hpp and strand.hpp have been included, automatically +// include the header file needed for the io_context::strand class. +#if !defined(ASIO_NO_EXTENSIONS) +# if defined(ASIO_STRAND_HPP) +# include "asio/io_context_strand.hpp" +# endif // defined(ASIO_STRAND_HPP) +#endif // !defined(ASIO_NO_EXTENSIONS) + +#endif // ASIO_IO_CONTEXT_HPP diff --git a/tools/sdk/include/asio/asio/io_context_strand.hpp b/tools/sdk/include/asio/asio/io_context_strand.hpp new file mode 100644 index 00000000..3c596f12 --- /dev/null +++ b/tools/sdk/include/asio/asio/io_context_strand.hpp @@ -0,0 +1,384 @@ +// +// io_context_strand.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IO_CONTEXT_STRAND_HPP +#define ASIO_IO_CONTEXT_STRAND_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_NO_EXTENSIONS) + +#include "asio/async_result.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/strand_service.hpp" +#include "asio/detail/wrapped_handler.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Provides serialised handler execution. +/** + * The io_context::strand class provides the ability to post and dispatch + * handlers with the guarantee that none of those handlers will execute + * concurrently. + * + * @par Order of handler invocation + * Given: + * + * @li a strand object @c s + * + * @li an object @c a meeting completion handler requirements + * + * @li an object @c a1 which is an arbitrary copy of @c a made by the + * implementation + * + * @li an object @c b meeting completion handler requirements + * + * @li an object @c b1 which is an arbitrary copy of @c b made by the + * implementation + * + * if any of the following conditions are true: + * + * @li @c s.post(a) happens-before @c s.post(b) + * + * @li @c s.post(a) happens-before @c s.dispatch(b), where the latter is + * performed outside the strand + * + * @li @c s.dispatch(a) happens-before @c s.post(b), where the former is + * performed outside the strand + * + * @li @c s.dispatch(a) happens-before @c s.dispatch(b), where both are + * performed outside the strand + * + * then @c asio_handler_invoke(a1, &a1) happens-before + * @c asio_handler_invoke(b1, &b1). + * + * Note that in the following case: + * @code async_op_1(..., s.wrap(a)); + * async_op_2(..., s.wrap(b)); @endcode + * the completion of the first async operation will perform @c s.dispatch(a), + * and the second will perform @c s.dispatch(b), but the order in which those + * are performed is unspecified. That is, you cannot state whether one + * happens-before the other. Therefore none of the above conditions are met and + * no ordering guarantee is made. + * + * @note The implementation makes no guarantee that handlers posted or + * dispatched through different @c strand objects will be invoked concurrently. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Dispatcher. + */ +class io_context::strand +{ +public: + /// Constructor. + /** + * Constructs the strand. + * + * @param io_context The io_context object that the strand will use to + * dispatch handlers that are ready to be run. + */ + explicit strand(asio::io_context& io_context) + : service_(asio::use_service< + asio::detail::strand_service>(io_context)) + { + service_.construct(impl_); + } + + /// Destructor. + /** + * Destroys a strand. + * + * Handlers posted through the strand that have not yet been invoked will + * still be dispatched in a way that meets the guarantee of non-concurrency. + */ + ~strand() + { + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use context().) Get the io_context associated with the + /// strand. + /** + * This function may be used to obtain the io_context object that the strand + * uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_context object that the strand will use to + * dispatch handlers. Ownership is not transferred to the caller. + */ + asio::io_context& get_io_context() + { + return service_.get_io_context(); + } + + /// (Deprecated: Use context().) Get the io_context associated with the + /// strand. + /** + * This function may be used to obtain the io_context object that the strand + * uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_context object that the strand will use to + * dispatch handlers. Ownership is not transferred to the caller. + */ + asio::io_context& get_io_service() + { + return service_.get_io_context(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Obtain the underlying execution context. + asio::io_context& context() const ASIO_NOEXCEPT + { + return service_.get_io_context(); + } + + /// Inform the strand that it has some outstanding work to do. + /** + * The strand delegates this call to its underlying io_context. + */ + void on_work_started() const ASIO_NOEXCEPT + { + context().get_executor().on_work_started(); + } + + /// Inform the strand that some work is no longer outstanding. + /** + * The strand delegates this call to its underlying io_context. + */ + void on_work_finished() const ASIO_NOEXCEPT + { + context().get_executor().on_work_finished(); + } + + /// Request the strand to invoke the given function object. + /** + * This function is used to ask the strand to execute the given function + * object on its underlying io_context. The function object will be executed + * inside this function if the strand is not otherwise busy and if the + * underlying io_context's executor's @c dispatch() function is also able to + * execute the function before returning. + * + * @param f The function object to be called. The executor will make + * a copy of the handler object as required. The function signature of the + * function object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const + { + typename decay::type tmp(ASIO_MOVE_CAST(Function)(f)); + service_.dispatch(impl_, tmp); + (void)a; + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use asio::dispatch().) Request the strand to invoke + /// the given handler. + /** + * This function is used to ask the strand to execute the given handler. + * + * The strand object guarantees that handlers posted or dispatched through + * the strand will not be executed concurrently. The handler may be executed + * inside this function if the guarantee can be met. If this function is + * called from within a handler that was posted or dispatched through the same + * strand, then the new handler will be executed immediately. + * + * The strand's guarantee is in addition to the guarantee provided by the + * underlying io_context. The io_context guarantees that the handler will only + * be called in a thread in which the io_context's run member function is + * currently being invoked. + * + * @param handler The handler to be called. The strand will make a copy of the + * handler object as required. The function signature of the handler must be: + * @code void handler(); @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ()) + dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a LegacyCompletionHandler. + ASIO_LEGACY_COMPLETION_HANDLER_CHECK( + LegacyCompletionHandler, handler) type_check; + + async_completion init(handler); + + service_.dispatch(impl_, init.completion_handler); + + return init.result.get(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Request the strand to invoke the given function object. + /** + * This function is used to ask the executor to execute the given function + * object. The function object will never be executed inside this function. + * Instead, it will be scheduled to run by the underlying io_context. + * + * @param f The function object to be called. The executor will make + * a copy of the handler object as required. The function signature of the + * function object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const + { + typename decay::type tmp(ASIO_MOVE_CAST(Function)(f)); + service_.post(impl_, tmp); + (void)a; + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use asio::post().) Request the strand to invoke the + /// given handler and return immediately. + /** + * This function is used to ask the strand to execute the given handler, but + * without allowing the strand to call the handler from inside this function. + * + * The strand object guarantees that handlers posted or dispatched through + * the strand will not be executed concurrently. The strand's guarantee is in + * addition to the guarantee provided by the underlying io_context. The + * io_context guarantees that the handler will only be called in a thread in + * which the io_context's run member function is currently being invoked. + * + * @param handler The handler to be called. The strand will make a copy of the + * handler object as required. The function signature of the handler must be: + * @code void handler(); @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ()) + post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a LegacyCompletionHandler. + ASIO_LEGACY_COMPLETION_HANDLER_CHECK( + LegacyCompletionHandler, handler) type_check; + + async_completion init(handler); + + service_.post(impl_, init.completion_handler); + + return init.result.get(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Request the strand to invoke the given function object. + /** + * This function is used to ask the executor to execute the given function + * object. The function object will never be executed inside this function. + * Instead, it will be scheduled to run by the underlying io_context. + * + * @param f The function object to be called. The executor will make + * a copy of the handler object as required. The function signature of the + * function object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const + { + typename decay::type tmp(ASIO_MOVE_CAST(Function)(f)); + service_.post(impl_, tmp); + (void)a; + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use asio::bind_executor().) Create a new handler that + /// automatically dispatches the wrapped handler on the strand. + /** + * This function is used to create a new handler function object that, when + * invoked, will automatically pass the wrapped handler to the strand's + * dispatch function. + * + * @param handler The handler to be wrapped. The strand will make a copy of + * the handler object as required. The function signature of the handler must + * be: @code void handler(A1 a1, ... An an); @endcode + * + * @return A function object that, when invoked, passes the wrapped handler to + * the strand's dispatch function. Given a function object with the signature: + * @code R f(A1 a1, ... An an); @endcode + * If this function object is passed to the wrap function like so: + * @code strand.wrap(f); @endcode + * then the return value is a function object with the signature + * @code void g(A1 a1, ... An an); @endcode + * that, when invoked, executes code equivalent to: + * @code strand.dispatch(boost::bind(f, a1, ... an)); @endcode + */ + template +#if defined(GENERATING_DOCUMENTATION) + unspecified +#else + detail::wrapped_handler +#endif + wrap(Handler handler) + { + return detail::wrapped_handler(*this, handler); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Determine whether the strand is running in the current thread. + /** + * @return @c true if the current thread is executing a handler that was + * submitted to the strand using post(), dispatch() or wrap(). Otherwise + * returns @c false. + */ + bool running_in_this_thread() const ASIO_NOEXCEPT + { + return service_.running_in_this_thread(impl_); + } + + /// Compare two strands for equality. + /** + * Two strands are equal if they refer to the same ordered, non-concurrent + * state. + */ + friend bool operator==(const strand& a, const strand& b) ASIO_NOEXCEPT + { + return a.impl_ == b.impl_; + } + + /// Compare two strands for inequality. + /** + * Two strands are equal if they refer to the same ordered, non-concurrent + * state. + */ + friend bool operator!=(const strand& a, const strand& b) ASIO_NOEXCEPT + { + return a.impl_ != b.impl_; + } + +private: + asio::detail::strand_service& service_; + mutable asio::detail::strand_service::implementation_type impl_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_NO_EXTENSIONS) + +#endif // ASIO_IO_CONTEXT_STRAND_HPP diff --git a/tools/sdk/include/asio/asio/io_service.hpp b/tools/sdk/include/asio/asio/io_service.hpp new file mode 100644 index 00000000..ed05c834 --- /dev/null +++ b/tools/sdk/include/asio/asio/io_service.hpp @@ -0,0 +1,33 @@ +// +// io_service.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IO_SERVICE_HPP +#define ASIO_IO_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +#if !defined(ASIO_NO_DEPRECATED) +/// Typedef for backwards compatibility. +typedef io_context io_service; +#endif // !defined(ASIO_NO_DEPRECATED) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IO_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/io_service_strand.hpp b/tools/sdk/include/asio/asio/io_service_strand.hpp new file mode 100644 index 00000000..7093f0e9 --- /dev/null +++ b/tools/sdk/include/asio/asio/io_service_strand.hpp @@ -0,0 +1,20 @@ +// +// io_service_strand.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IO_SERVICE_STRAND_HPP +#define ASIO_IO_SERVICE_STRAND_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/io_context_strand.hpp" + +#endif // ASIO_IO_SERVICE_STRAND_HPP diff --git a/tools/sdk/include/asio/asio/ip/address.hpp b/tools/sdk/include/asio/asio/ip/address.hpp new file mode 100644 index 00000000..cf852a6d --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/address.hpp @@ -0,0 +1,260 @@ +// +// ip/address.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_ADDRESS_HPP +#define ASIO_IP_ADDRESS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/detail/throw_exception.hpp" +#include "asio/detail/string_view.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error_code.hpp" +#include "asio/ip/address_v4.hpp" +#include "asio/ip/address_v6.hpp" +#include "asio/ip/bad_address_cast.hpp" + +#if !defined(ASIO_NO_IOSTREAM) +# include +#endif // !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Implements version-independent IP addresses. +/** + * The asio::ip::address class provides the ability to use either IP + * version 4 or version 6 addresses. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class address +{ +public: + /// Default constructor. + ASIO_DECL address(); + + /// Construct an address from an IPv4 address. + ASIO_DECL address(const asio::ip::address_v4& ipv4_address); + + /// Construct an address from an IPv6 address. + ASIO_DECL address(const asio::ip::address_v6& ipv6_address); + + /// Copy constructor. + ASIO_DECL address(const address& other); + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + ASIO_DECL address(address&& other); +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from another address. + ASIO_DECL address& operator=(const address& other); + +#if defined(ASIO_HAS_MOVE) + /// Move-assign from another address. + ASIO_DECL address& operator=(address&& other); +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from an IPv4 address. + ASIO_DECL address& operator=( + const asio::ip::address_v4& ipv4_address); + + /// Assign from an IPv6 address. + ASIO_DECL address& operator=( + const asio::ip::address_v6& ipv6_address); + + /// Get whether the address is an IP version 4 address. + bool is_v4() const + { + return type_ == ipv4; + } + + /// Get whether the address is an IP version 6 address. + bool is_v6() const + { + return type_ == ipv6; + } + + /// Get the address as an IP version 4 address. + ASIO_DECL asio::ip::address_v4 to_v4() const; + + /// Get the address as an IP version 6 address. + ASIO_DECL asio::ip::address_v6 to_v6() const; + + /// Get the address as a string. + ASIO_DECL std::string to_string() const; + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use other overload.) Get the address as a string. + ASIO_DECL std::string to_string(asio::error_code& ec) const; + + /// (Deprecated: Use make_address().) Create an address from an IPv4 address + /// string in dotted decimal form, or from an IPv6 address in hexadecimal + /// notation. + static address from_string(const char* str); + + /// (Deprecated: Use make_address().) Create an address from an IPv4 address + /// string in dotted decimal form, or from an IPv6 address in hexadecimal + /// notation. + static address from_string(const char* str, asio::error_code& ec); + + /// (Deprecated: Use make_address().) Create an address from an IPv4 address + /// string in dotted decimal form, or from an IPv6 address in hexadecimal + /// notation. + static address from_string(const std::string& str); + + /// (Deprecated: Use make_address().) Create an address from an IPv4 address + /// string in dotted decimal form, or from an IPv6 address in hexadecimal + /// notation. + static address from_string( + const std::string& str, asio::error_code& ec); +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Determine whether the address is a loopback address. + ASIO_DECL bool is_loopback() const; + + /// Determine whether the address is unspecified. + ASIO_DECL bool is_unspecified() const; + + /// Determine whether the address is a multicast address. + ASIO_DECL bool is_multicast() const; + + /// Compare two addresses for equality. + ASIO_DECL friend bool operator==(const address& a1, const address& a2); + + /// Compare two addresses for inequality. + friend bool operator!=(const address& a1, const address& a2) + { + return !(a1 == a2); + } + + /// Compare addresses for ordering. + ASIO_DECL friend bool operator<(const address& a1, const address& a2); + + /// Compare addresses for ordering. + friend bool operator>(const address& a1, const address& a2) + { + return a2 < a1; + } + + /// Compare addresses for ordering. + friend bool operator<=(const address& a1, const address& a2) + { + return !(a2 < a1); + } + + /// Compare addresses for ordering. + friend bool operator>=(const address& a1, const address& a2) + { + return !(a1 < a2); + } + +private: + // The type of the address. + enum { ipv4, ipv6 } type_; + + // The underlying IPv4 address. + asio::ip::address_v4 ipv4_address_; + + // The underlying IPv6 address. + asio::ip::address_v6 ipv6_address_; +}; + +/// Create an address from an IPv4 address string in dotted decimal form, +/// or from an IPv6 address in hexadecimal notation. +/** + * @relates address + */ +ASIO_DECL address make_address(const char* str); + +/// Create an address from an IPv4 address string in dotted decimal form, +/// or from an IPv6 address in hexadecimal notation. +/** + * @relates address + */ +ASIO_DECL address make_address( + const char* str, asio::error_code& ec); + +/// Create an address from an IPv4 address string in dotted decimal form, +/// or from an IPv6 address in hexadecimal notation. +/** + * @relates address + */ +ASIO_DECL address make_address(const std::string& str); + +/// Create an address from an IPv4 address string in dotted decimal form, +/// or from an IPv6 address in hexadecimal notation. +/** + * @relates address + */ +ASIO_DECL address make_address( + const std::string& str, asio::error_code& ec); + +#if defined(ASIO_HAS_STRING_VIEW) \ + || defined(GENERATING_DOCUMENTATION) + +/// Create an address from an IPv4 address string in dotted decimal form, +/// or from an IPv6 address in hexadecimal notation. +/** + * @relates address + */ +ASIO_DECL address make_address(string_view str); + +/// Create an address from an IPv4 address string in dotted decimal form, +/// or from an IPv6 address in hexadecimal notation. +/** + * @relates address + */ +ASIO_DECL address make_address( + string_view str, asio::error_code& ec); + +#endif // defined(ASIO_HAS_STRING_VIEW) + // || defined(GENERATING_DOCUMENTATION) + +#if !defined(ASIO_NO_IOSTREAM) + +/// Output an address as a string. +/** + * Used to output a human-readable string for a specified address. + * + * @param os The output stream to which the string will be written. + * + * @param addr The address to be written. + * + * @return The output stream. + * + * @relates asio::ip::address + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const address& addr); + +#endif // !defined(ASIO_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/impl/address.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/ip/impl/address.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_IP_ADDRESS_HPP diff --git a/tools/sdk/include/asio/asio/ip/address_v4.hpp b/tools/sdk/include/asio/asio/ip/address_v4.hpp new file mode 100644 index 00000000..4e1cc9a3 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/address_v4.hpp @@ -0,0 +1,329 @@ +// +// ip/address_v4.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_ADDRESS_V4_HPP +#define ASIO_IP_ADDRESS_V4_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/detail/array.hpp" +#include "asio/detail/cstdint.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/string_view.hpp" +#include "asio/detail/winsock_init.hpp" +#include "asio/error_code.hpp" + +#if !defined(ASIO_NO_IOSTREAM) +# include +#endif // !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Implements IP version 4 style addresses. +/** + * The asio::ip::address_v4 class provides the ability to use and + * manipulate IP version 4 addresses. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class address_v4 +{ +public: + /// The type used to represent an address as an unsigned integer. + typedef uint_least32_t uint_type; + + /// The type used to represent an address as an array of bytes. + /** + * @note This type is defined in terms of the C++0x template @c std::array + * when it is available. Otherwise, it uses @c boost:array. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef array bytes_type; +#else + typedef asio::detail::array bytes_type; +#endif + + /// Default constructor. + address_v4() + { + addr_.s_addr = 0; + } + + /// Construct an address from raw bytes. + ASIO_DECL explicit address_v4(const bytes_type& bytes); + + /// Construct an address from an unsigned integer in host byte order. + ASIO_DECL explicit address_v4(uint_type addr); + + /// Copy constructor. + address_v4(const address_v4& other) + : addr_(other.addr_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + address_v4(address_v4&& other) + : addr_(other.addr_) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from another address. + address_v4& operator=(const address_v4& other) + { + addr_ = other.addr_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move-assign from another address. + address_v4& operator=(address_v4&& other) + { + addr_ = other.addr_; + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// Get the address in bytes, in network byte order. + ASIO_DECL bytes_type to_bytes() const; + + /// Get the address as an unsigned integer in host byte order + ASIO_DECL uint_type to_uint() const; + +#if !defined(ASIO_NO_DEPRECATED) + /// Get the address as an unsigned long in host byte order + ASIO_DECL unsigned long to_ulong() const; +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the address as a string in dotted decimal format. + ASIO_DECL std::string to_string() const; + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use other overload.) Get the address as a string in dotted + /// decimal format. + ASIO_DECL std::string to_string(asio::error_code& ec) const; + + /// (Deprecated: Use make_address_v4().) Create an address from an IP address + /// string in dotted decimal form. + static address_v4 from_string(const char* str); + + /// (Deprecated: Use make_address_v4().) Create an address from an IP address + /// string in dotted decimal form. + static address_v4 from_string( + const char* str, asio::error_code& ec); + + /// (Deprecated: Use make_address_v4().) Create an address from an IP address + /// string in dotted decimal form. + static address_v4 from_string(const std::string& str); + + /// (Deprecated: Use make_address_v4().) Create an address from an IP address + /// string in dotted decimal form. + static address_v4 from_string( + const std::string& str, asio::error_code& ec); +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Determine whether the address is a loopback address. + ASIO_DECL bool is_loopback() const; + + /// Determine whether the address is unspecified. + ASIO_DECL bool is_unspecified() const; + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use network_v4 class.) Determine whether the address is a + /// class A address. + ASIO_DECL bool is_class_a() const; + + /// (Deprecated: Use network_v4 class.) Determine whether the address is a + /// class B address. + ASIO_DECL bool is_class_b() const; + + /// (Deprecated: Use network_v4 class.) Determine whether the address is a + /// class C address. + ASIO_DECL bool is_class_c() const; +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Determine whether the address is a multicast address. + ASIO_DECL bool is_multicast() const; + + /// Compare two addresses for equality. + friend bool operator==(const address_v4& a1, const address_v4& a2) + { + return a1.addr_.s_addr == a2.addr_.s_addr; + } + + /// Compare two addresses for inequality. + friend bool operator!=(const address_v4& a1, const address_v4& a2) + { + return a1.addr_.s_addr != a2.addr_.s_addr; + } + + /// Compare addresses for ordering. + friend bool operator<(const address_v4& a1, const address_v4& a2) + { + return a1.to_uint() < a2.to_uint(); + } + + /// Compare addresses for ordering. + friend bool operator>(const address_v4& a1, const address_v4& a2) + { + return a1.to_uint() > a2.to_uint(); + } + + /// Compare addresses for ordering. + friend bool operator<=(const address_v4& a1, const address_v4& a2) + { + return a1.to_uint() <= a2.to_uint(); + } + + /// Compare addresses for ordering. + friend bool operator>=(const address_v4& a1, const address_v4& a2) + { + return a1.to_uint() >= a2.to_uint(); + } + + /// Obtain an address object that represents any address. + static address_v4 any() + { + return address_v4(); + } + + /// Obtain an address object that represents the loopback address. + static address_v4 loopback() + { + return address_v4(0x7F000001); + } + + /// Obtain an address object that represents the broadcast address. + static address_v4 broadcast() + { + return address_v4(0xFFFFFFFF); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use network_v4 class.) Obtain an address object that + /// represents the broadcast address that corresponds to the specified + /// address and netmask. + ASIO_DECL static address_v4 broadcast( + const address_v4& addr, const address_v4& mask); + + /// (Deprecated: Use network_v4 class.) Obtain the netmask that corresponds + /// to the address, based on its address class. + ASIO_DECL static address_v4 netmask(const address_v4& addr); +#endif // !defined(ASIO_NO_DEPRECATED) + +private: + // The underlying IPv4 address. + asio::detail::in4_addr_type addr_; +}; + +/// Create an IPv4 address from raw bytes in network order. +/** + * @relates address_v4 + */ +inline address_v4 make_address_v4(const address_v4::bytes_type& bytes) +{ + return address_v4(bytes); +} + +/// Create an IPv4 address from an unsigned integer in host byte order. +/** + * @relates address_v4 + */ +inline address_v4 make_address_v4(address_v4::uint_type addr) +{ + return address_v4(addr); +} + +/// Create an IPv4 address from an IP address string in dotted decimal form. +/** + * @relates address_v4 + */ +ASIO_DECL address_v4 make_address_v4(const char* str); + +/// Create an IPv4 address from an IP address string in dotted decimal form. +/** + * @relates address_v4 + */ +ASIO_DECL address_v4 make_address_v4( + const char* str, asio::error_code& ec); + +/// Create an IPv4 address from an IP address string in dotted decimal form. +/** + * @relates address_v4 + */ +ASIO_DECL address_v4 make_address_v4(const std::string& str); + +/// Create an IPv4 address from an IP address string in dotted decimal form. +/** + * @relates address_v4 + */ +ASIO_DECL address_v4 make_address_v4( + const std::string& str, asio::error_code& ec); + +#if defined(ASIO_HAS_STRING_VIEW) \ + || defined(GENERATING_DOCUMENTATION) + +/// Create an IPv4 address from an IP address string in dotted decimal form. +/** + * @relates address_v4 + */ +ASIO_DECL address_v4 make_address_v4(string_view str); + +/// Create an IPv4 address from an IP address string in dotted decimal form. +/** + * @relates address_v4 + */ +ASIO_DECL address_v4 make_address_v4( + string_view str, asio::error_code& ec); + +#endif // defined(ASIO_HAS_STRING_VIEW) + // || defined(GENERATING_DOCUMENTATION) + +#if !defined(ASIO_NO_IOSTREAM) + +/// Output an address as a string. +/** + * Used to output a human-readable string for a specified address. + * + * @param os The output stream to which the string will be written. + * + * @param addr The address to be written. + * + * @return The output stream. + * + * @relates asio::ip::address_v4 + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const address_v4& addr); + +#endif // !defined(ASIO_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/impl/address_v4.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/ip/impl/address_v4.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_IP_ADDRESS_V4_HPP diff --git a/tools/sdk/include/asio/asio/ip/address_v4_iterator.hpp b/tools/sdk/include/asio/asio/ip/address_v4_iterator.hpp new file mode 100644 index 00000000..e2ef3937 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/address_v4_iterator.hpp @@ -0,0 +1,162 @@ +// +// ip/address_v4_iterator.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_ADDRESS_V4_ITERATOR_HPP +#define ASIO_IP_ADDRESS_V4_ITERATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/ip/address_v4.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template class basic_address_iterator; + +/// An input iterator that can be used for traversing IPv4 addresses. +/** + * In addition to satisfying the input iterator requirements, this iterator + * also supports decrement. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <> class basic_address_iterator +{ +public: + /// The type of the elements pointed to by the iterator. + typedef address_v4 value_type; + + /// Distance between two iterators. + typedef std::ptrdiff_t difference_type; + + /// The type of a pointer to an element pointed to by the iterator. + typedef const address_v4* pointer; + + /// The type of a reference to an element pointed to by the iterator. + typedef const address_v4& reference; + + /// Denotes that the iterator satisfies the input iterator requirements. + typedef std::input_iterator_tag iterator_category; + + /// Construct an iterator that points to the specified address. + basic_address_iterator(const address_v4& addr) ASIO_NOEXCEPT + : address_(addr) + { + } + + /// Copy constructor. + basic_address_iterator( + const basic_address_iterator& other) ASIO_NOEXCEPT + : address_(other.address_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + basic_address_iterator(basic_address_iterator&& other) ASIO_NOEXCEPT + : address_(ASIO_MOVE_CAST(address_v4)(other.address_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assignment operator. + basic_address_iterator& operator=( + const basic_address_iterator& other) ASIO_NOEXCEPT + { + address_ = other.address_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move assignment operator. + basic_address_iterator& operator=( + basic_address_iterator&& other) ASIO_NOEXCEPT + { + address_ = ASIO_MOVE_CAST(address_v4)(other.address_); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// Dereference the iterator. + const address_v4& operator*() const ASIO_NOEXCEPT + { + return address_; + } + + /// Dereference the iterator. + const address_v4* operator->() const ASIO_NOEXCEPT + { + return &address_; + } + + /// Pre-increment operator. + basic_address_iterator& operator++() ASIO_NOEXCEPT + { + address_ = address_v4((address_.to_uint() + 1) & 0xFFFFFFFF); + return *this; + } + + /// Post-increment operator. + basic_address_iterator operator++(int) ASIO_NOEXCEPT + { + basic_address_iterator tmp(*this); + ++*this; + return tmp; + } + + /// Pre-decrement operator. + basic_address_iterator& operator--() ASIO_NOEXCEPT + { + address_ = address_v4((address_.to_uint() - 1) & 0xFFFFFFFF); + return *this; + } + + /// Post-decrement operator. + basic_address_iterator operator--(int) + { + basic_address_iterator tmp(*this); + --*this; + return tmp; + } + + /// Compare two addresses for equality. + friend bool operator==(const basic_address_iterator& a, + const basic_address_iterator& b) + { + return a.address_ == b.address_; + } + + /// Compare two addresses for inequality. + friend bool operator!=(const basic_address_iterator& a, + const basic_address_iterator& b) + { + return a.address_ != b.address_; + } + +private: + address_v4 address_; +}; + +/// An input iterator that can be used for traversing IPv4 addresses. +typedef basic_address_iterator address_v4_iterator; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ADDRESS_V4_ITERATOR_HPP diff --git a/tools/sdk/include/asio/asio/ip/address_v4_range.hpp b/tools/sdk/include/asio/asio/ip/address_v4_range.hpp new file mode 100644 index 00000000..a4028420 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/address_v4_range.hpp @@ -0,0 +1,134 @@ +// +// ip/address_v4_range.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_ADDRESS_V4_RANGE_HPP +#define ASIO_IP_ADDRESS_V4_RANGE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/ip/address_v4_iterator.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template class basic_address_range; + +/// Represents a range of IPv4 addresses. +/** + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <> class basic_address_range +{ +public: + /// The type of an iterator that points into the range. + typedef basic_address_iterator iterator; + + /// Construct an empty range. + basic_address_range() ASIO_NOEXCEPT + : begin_(address_v4()), + end_(address_v4()) + { + } + + /// Construct an range that represents the given range of addresses. + explicit basic_address_range(const iterator& first, + const iterator& last) ASIO_NOEXCEPT + : begin_(first), + end_(last) + { + } + + /// Copy constructor. + basic_address_range(const basic_address_range& other) ASIO_NOEXCEPT + : begin_(other.begin_), + end_(other.end_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + basic_address_range(basic_address_range&& other) ASIO_NOEXCEPT + : begin_(ASIO_MOVE_CAST(iterator)(other.begin_)), + end_(ASIO_MOVE_CAST(iterator)(other.end_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assignment operator. + basic_address_range& operator=( + const basic_address_range& other) ASIO_NOEXCEPT + { + begin_ = other.begin_; + end_ = other.end_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move assignment operator. + basic_address_range& operator=( + basic_address_range&& other) ASIO_NOEXCEPT + { + begin_ = ASIO_MOVE_CAST(iterator)(other.begin_); + end_ = ASIO_MOVE_CAST(iterator)(other.end_); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// Obtain an iterator that points to the start of the range. + iterator begin() const ASIO_NOEXCEPT + { + return begin_; + } + + /// Obtain an iterator that points to the end of the range. + iterator end() const ASIO_NOEXCEPT + { + return end_; + } + + /// Determine whether the range is empty. + bool empty() const ASIO_NOEXCEPT + { + return size() == 0; + } + + /// Return the size of the range. + std::size_t size() const ASIO_NOEXCEPT + { + return end_->to_uint() - begin_->to_uint(); + } + + /// Find an address in the range. + iterator find(const address_v4& addr) const ASIO_NOEXCEPT + { + return addr >= *begin_ && addr < *end_ ? iterator(addr) : end_; + } + +private: + iterator begin_; + iterator end_; +}; + +/// Represents a range of IPv4 addresses. +typedef basic_address_range address_v4_range; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ADDRESS_V4_RANGE_HPP diff --git a/tools/sdk/include/asio/asio/ip/address_v6.hpp b/tools/sdk/include/asio/asio/ip/address_v6.hpp new file mode 100644 index 00000000..fece3329 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/address_v6.hpp @@ -0,0 +1,336 @@ +// +// ip/address_v6.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_ADDRESS_V6_HPP +#define ASIO_IP_ADDRESS_V6_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/detail/array.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/string_view.hpp" +#include "asio/detail/winsock_init.hpp" +#include "asio/error_code.hpp" +#include "asio/ip/address_v4.hpp" + +#if !defined(ASIO_NO_IOSTREAM) +# include +#endif // !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template class basic_address_iterator; + +/// Implements IP version 6 style addresses. +/** + * The asio::ip::address_v6 class provides the ability to use and + * manipulate IP version 6 addresses. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class address_v6 +{ +public: + /// The type used to represent an address as an array of bytes. + /** + * @note This type is defined in terms of the C++0x template @c std::array + * when it is available. Otherwise, it uses @c boost:array. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef array bytes_type; +#else + typedef asio::detail::array bytes_type; +#endif + + /// Default constructor. + ASIO_DECL address_v6(); + + /// Construct an address from raw bytes and scope ID. + ASIO_DECL explicit address_v6(const bytes_type& bytes, + unsigned long scope_id = 0); + + /// Copy constructor. + ASIO_DECL address_v6(const address_v6& other); + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + ASIO_DECL address_v6(address_v6&& other); +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from another address. + ASIO_DECL address_v6& operator=(const address_v6& other); + +#if defined(ASIO_HAS_MOVE) + /// Move-assign from another address. + ASIO_DECL address_v6& operator=(address_v6&& other); +#endif // defined(ASIO_HAS_MOVE) + + /// The scope ID of the address. + /** + * Returns the scope ID associated with the IPv6 address. + */ + unsigned long scope_id() const + { + return scope_id_; + } + + /// The scope ID of the address. + /** + * Modifies the scope ID associated with the IPv6 address. + */ + void scope_id(unsigned long id) + { + scope_id_ = id; + } + + /// Get the address in bytes, in network byte order. + ASIO_DECL bytes_type to_bytes() const; + + /// Get the address as a string. + ASIO_DECL std::string to_string() const; + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use other overload.) Get the address as a string. + ASIO_DECL std::string to_string(asio::error_code& ec) const; + + /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP + /// address string. + static address_v6 from_string(const char* str); + + /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP + /// address string. + static address_v6 from_string( + const char* str, asio::error_code& ec); + + /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP + /// address string. + static address_v6 from_string(const std::string& str); + + /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP + /// address string. + static address_v6 from_string( + const std::string& str, asio::error_code& ec); + + /// (Deprecated: Use make_address_v4().) Converts an IPv4-mapped or + /// IPv4-compatible address to an IPv4 address. + ASIO_DECL address_v4 to_v4() const; +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Determine whether the address is a loopback address. + ASIO_DECL bool is_loopback() const; + + /// Determine whether the address is unspecified. + ASIO_DECL bool is_unspecified() const; + + /// Determine whether the address is link local. + ASIO_DECL bool is_link_local() const; + + /// Determine whether the address is site local. + ASIO_DECL bool is_site_local() const; + + /// Determine whether the address is a mapped IPv4 address. + ASIO_DECL bool is_v4_mapped() const; + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: No replacement.) Determine whether the address is an + /// IPv4-compatible address. + ASIO_DECL bool is_v4_compatible() const; +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Determine whether the address is a multicast address. + ASIO_DECL bool is_multicast() const; + + /// Determine whether the address is a global multicast address. + ASIO_DECL bool is_multicast_global() const; + + /// Determine whether the address is a link-local multicast address. + ASIO_DECL bool is_multicast_link_local() const; + + /// Determine whether the address is a node-local multicast address. + ASIO_DECL bool is_multicast_node_local() const; + + /// Determine whether the address is a org-local multicast address. + ASIO_DECL bool is_multicast_org_local() const; + + /// Determine whether the address is a site-local multicast address. + ASIO_DECL bool is_multicast_site_local() const; + + /// Compare two addresses for equality. + ASIO_DECL friend bool operator==( + const address_v6& a1, const address_v6& a2); + + /// Compare two addresses for inequality. + friend bool operator!=(const address_v6& a1, const address_v6& a2) + { + return !(a1 == a2); + } + + /// Compare addresses for ordering. + ASIO_DECL friend bool operator<( + const address_v6& a1, const address_v6& a2); + + /// Compare addresses for ordering. + friend bool operator>(const address_v6& a1, const address_v6& a2) + { + return a2 < a1; + } + + /// Compare addresses for ordering. + friend bool operator<=(const address_v6& a1, const address_v6& a2) + { + return !(a2 < a1); + } + + /// Compare addresses for ordering. + friend bool operator>=(const address_v6& a1, const address_v6& a2) + { + return !(a1 < a2); + } + + /// Obtain an address object that represents any address. + static address_v6 any() + { + return address_v6(); + } + + /// Obtain an address object that represents the loopback address. + ASIO_DECL static address_v6 loopback(); + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use make_address_v6().) Create an IPv4-mapped IPv6 address. + ASIO_DECL static address_v6 v4_mapped(const address_v4& addr); + + /// (Deprecated: No replacement.) Create an IPv4-compatible IPv6 address. + ASIO_DECL static address_v6 v4_compatible(const address_v4& addr); +#endif // !defined(ASIO_NO_DEPRECATED) + +private: + friend class basic_address_iterator; + + // The underlying IPv6 address. + asio::detail::in6_addr_type addr_; + + // The scope ID associated with the address. + unsigned long scope_id_; +}; + +/// Create an IPv6 address from raw bytes and scope ID. +/** + * @relates address_v6 + */ +inline address_v6 make_address_v6(const address_v6::bytes_type& bytes, + unsigned long scope_id = 0) +{ + return address_v6(bytes, scope_id); +} + +/// Create an IPv6 address from an IP address string. +/** + * @relates address_v6 + */ +ASIO_DECL address_v6 make_address_v6(const char* str); + +/// Create an IPv6 address from an IP address string. +/** + * @relates address_v6 + */ +ASIO_DECL address_v6 make_address_v6( + const char* str, asio::error_code& ec); + +/// Createan IPv6 address from an IP address string. +/** + * @relates address_v6 + */ +ASIO_DECL address_v6 make_address_v6(const std::string& str); + +/// Create an IPv6 address from an IP address string. +/** + * @relates address_v6 + */ +ASIO_DECL address_v6 make_address_v6( + const std::string& str, asio::error_code& ec); + +#if defined(ASIO_HAS_STRING_VIEW) \ + || defined(GENERATING_DOCUMENTATION) + +/// Create an IPv6 address from an IP address string. +/** + * @relates address_v6 + */ +ASIO_DECL address_v6 make_address_v6(string_view str); + +/// Create an IPv6 address from an IP address string. +/** + * @relates address_v6 + */ +ASIO_DECL address_v6 make_address_v6( + string_view str, asio::error_code& ec); + +#endif // defined(ASIO_HAS_STRING_VIEW) + // || defined(GENERATING_DOCUMENTATION) + +/// Tag type used for distinguishing overloads that deal in IPv4-mapped IPv6 +/// addresses. +enum v4_mapped_t { v4_mapped }; + +/// Create an IPv4 address from a IPv4-mapped IPv6 address. +/** + * @relates address_v4 + */ +ASIO_DECL address_v4 make_address_v4( + v4_mapped_t, const address_v6& v6_addr); + +/// Create an IPv4-mapped IPv6 address from an IPv4 address. +/** + * @relates address_v6 + */ +ASIO_DECL address_v6 make_address_v6( + v4_mapped_t, const address_v4& v4_addr); + +#if !defined(ASIO_NO_IOSTREAM) + +/// Output an address as a string. +/** + * Used to output a human-readable string for a specified address. + * + * @param os The output stream to which the string will be written. + * + * @param addr The address to be written. + * + * @return The output stream. + * + * @relates asio::ip::address_v6 + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const address_v6& addr); + +#endif // !defined(ASIO_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/impl/address_v6.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/ip/impl/address_v6.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_IP_ADDRESS_V6_HPP diff --git a/tools/sdk/include/asio/asio/ip/address_v6_iterator.hpp b/tools/sdk/include/asio/asio/ip/address_v6_iterator.hpp new file mode 100644 index 00000000..0a1fb3fe --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/address_v6_iterator.hpp @@ -0,0 +1,183 @@ +// +// ip/address_v6_iterator.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Oliver Kowalke (oliver dot kowalke at gmail dot com) +// +// 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 ASIO_IP_ADDRESS_V6_ITERATOR_HPP +#define ASIO_IP_ADDRESS_V6_ITERATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/ip/address_v6.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template class basic_address_iterator; + +/// An input iterator that can be used for traversing IPv6 addresses. +/** + * In addition to satisfying the input iterator requirements, this iterator + * also supports decrement. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <> class basic_address_iterator +{ +public: + /// The type of the elements pointed to by the iterator. + typedef address_v6 value_type; + + /// Distance between two iterators. + typedef std::ptrdiff_t difference_type; + + /// The type of a pointer to an element pointed to by the iterator. + typedef const address_v6* pointer; + + /// The type of a reference to an element pointed to by the iterator. + typedef const address_v6& reference; + + /// Denotes that the iterator satisfies the input iterator requirements. + typedef std::input_iterator_tag iterator_category; + + /// Construct an iterator that points to the specified address. + basic_address_iterator(const address_v6& addr) ASIO_NOEXCEPT + : address_(addr) + { + } + + /// Copy constructor. + basic_address_iterator( + const basic_address_iterator& other) ASIO_NOEXCEPT + : address_(other.address_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + basic_address_iterator(basic_address_iterator&& other) ASIO_NOEXCEPT + : address_(ASIO_MOVE_CAST(address_v6)(other.address_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assignment operator. + basic_address_iterator& operator=( + const basic_address_iterator& other) ASIO_NOEXCEPT + { + address_ = other.address_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move assignment operator. + basic_address_iterator& operator=( + basic_address_iterator&& other) ASIO_NOEXCEPT + { + address_ = ASIO_MOVE_CAST(address_v6)(other.address_); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// Dereference the iterator. + const address_v6& operator*() const ASIO_NOEXCEPT + { + return address_; + } + + /// Dereference the iterator. + const address_v6* operator->() const ASIO_NOEXCEPT + { + return &address_; + } + + /// Pre-increment operator. + basic_address_iterator& operator++() ASIO_NOEXCEPT + { + for (int i = 15; i >= 0; --i) + { + if (address_.addr_.s6_addr[i] < 0xFF) + { + ++address_.addr_.s6_addr[i]; + break; + } + + address_.addr_.s6_addr[i] = 0; + } + + return *this; + } + + /// Post-increment operator. + basic_address_iterator operator++(int) ASIO_NOEXCEPT + { + basic_address_iterator tmp(*this); + ++*this; + return tmp; + } + + /// Pre-decrement operator. + basic_address_iterator& operator--() ASIO_NOEXCEPT + { + for (int i = 15; i >= 0; --i) + { + if (address_.addr_.s6_addr[i] > 0) + { + --address_.addr_.s6_addr[i]; + break; + } + + address_.addr_.s6_addr[i] = 0xFF; + } + + return *this; + } + + /// Post-decrement operator. + basic_address_iterator operator--(int) + { + basic_address_iterator tmp(*this); + --*this; + return tmp; + } + + /// Compare two addresses for equality. + friend bool operator==(const basic_address_iterator& a, + const basic_address_iterator& b) + { + return a.address_ == b.address_; + } + + /// Compare two addresses for inequality. + friend bool operator!=(const basic_address_iterator& a, + const basic_address_iterator& b) + { + return a.address_ != b.address_; + } + +private: + address_v6 address_; +}; + +/// An input iterator that can be used for traversing IPv6 addresses. +typedef basic_address_iterator address_v6_iterator; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ADDRESS_V6_ITERATOR_HPP diff --git a/tools/sdk/include/asio/asio/ip/address_v6_range.hpp b/tools/sdk/include/asio/asio/ip/address_v6_range.hpp new file mode 100644 index 00000000..9d7062ef --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/address_v6_range.hpp @@ -0,0 +1,129 @@ +// +// ip/address_v6_range.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Oliver Kowalke (oliver dot kowalke at gmail dot com) +// +// 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 ASIO_IP_ADDRESS_V6_RANGE_HPP +#define ASIO_IP_ADDRESS_V6_RANGE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/ip/address_v6_iterator.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template class basic_address_range; + +/// Represents a range of IPv6 addresses. +/** + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <> class basic_address_range +{ +public: + /// The type of an iterator that points into the range. + typedef basic_address_iterator iterator; + + /// Construct an empty range. + basic_address_range() ASIO_NOEXCEPT + : begin_(address_v6()), + end_(address_v6()) + { + } + + /// Construct an range that represents the given range of addresses. + explicit basic_address_range(const iterator& first, + const iterator& last) ASIO_NOEXCEPT + : begin_(first), + end_(last) + { + } + + /// Copy constructor. + basic_address_range(const basic_address_range& other) ASIO_NOEXCEPT + : begin_(other.begin_), + end_(other.end_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + basic_address_range(basic_address_range&& other) ASIO_NOEXCEPT + : begin_(ASIO_MOVE_CAST(iterator)(other.begin_)), + end_(ASIO_MOVE_CAST(iterator)(other.end_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assignment operator. + basic_address_range& operator=( + const basic_address_range& other) ASIO_NOEXCEPT + { + begin_ = other.begin_; + end_ = other.end_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move assignment operator. + basic_address_range& operator=( + basic_address_range&& other) ASIO_NOEXCEPT + { + begin_ = ASIO_MOVE_CAST(iterator)(other.begin_); + end_ = ASIO_MOVE_CAST(iterator)(other.end_); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// Obtain an iterator that points to the start of the range. + iterator begin() const ASIO_NOEXCEPT + { + return begin_; + } + + /// Obtain an iterator that points to the end of the range. + iterator end() const ASIO_NOEXCEPT + { + return end_; + } + + /// Determine whether the range is empty. + bool empty() const ASIO_NOEXCEPT + { + return begin_ == end_; + } + + /// Find an address in the range. + iterator find(const address_v6& addr) const ASIO_NOEXCEPT + { + return addr >= *begin_ && addr < *end_ ? iterator(addr) : end_; + } + +private: + iterator begin_; + iterator end_; +}; + +/// Represents a range of IPv6 addresses. +typedef basic_address_range address_v6_range; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ADDRESS_V6_RANGE_HPP diff --git a/tools/sdk/include/asio/asio/ip/bad_address_cast.hpp b/tools/sdk/include/asio/asio/ip/bad_address_cast.hpp new file mode 100644 index 00000000..8c71f704 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/bad_address_cast.hpp @@ -0,0 +1,48 @@ +// +// ip/bad_address_cast.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_BAD_ADDRESS_CAST_HPP +#define ASIO_IP_BAD_ADDRESS_CAST_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Thrown to indicate a failed address conversion. +class bad_address_cast : public std::bad_cast +{ +public: + /// Default constructor. + bad_address_cast() {} + + /// Destructor. + virtual ~bad_address_cast() ASIO_NOEXCEPT_OR_NOTHROW {} + + /// Get the message associated with the exception. + virtual const char* what() const ASIO_NOEXCEPT_OR_NOTHROW + { + return "bad address cast"; + } +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ADDRESS_HPP diff --git a/tools/sdk/include/asio/asio/ip/basic_endpoint.hpp b/tools/sdk/include/asio/asio/ip/basic_endpoint.hpp new file mode 100644 index 00000000..4418ee77 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/basic_endpoint.hpp @@ -0,0 +1,263 @@ +// +// ip/basic_endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_BASIC_ENDPOINT_HPP +#define ASIO_IP_BASIC_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/ip/address.hpp" +#include "asio/ip/detail/endpoint.hpp" + +#if !defined(ASIO_NO_IOSTREAM) +# include +#endif // !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Describes an endpoint for a version-independent IP socket. +/** + * The asio::ip::basic_endpoint class template describes an endpoint that + * may be associated with a particular socket. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * Endpoint. + */ +template +class basic_endpoint +{ +public: + /// The protocol type associated with the endpoint. + typedef InternetProtocol protocol_type; + + /// The type of the endpoint structure. This type is dependent on the + /// underlying implementation of the socket layer. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined data_type; +#else + typedef asio::detail::socket_addr_type data_type; +#endif + + /// Default constructor. + basic_endpoint() + : impl_() + { + } + + /// Construct an endpoint using a port number, specified in the host's byte + /// order. The IP address will be the any address (i.e. INADDR_ANY or + /// in6addr_any). This constructor would typically be used for accepting new + /// connections. + /** + * @par Examples + * To initialise an IPv4 TCP endpoint for port 1234, use: + * @code + * asio::ip::tcp::endpoint ep(asio::ip::tcp::v4(), 1234); + * @endcode + * + * To specify an IPv6 UDP endpoint for port 9876, use: + * @code + * asio::ip::udp::endpoint ep(asio::ip::udp::v6(), 9876); + * @endcode + */ + basic_endpoint(const InternetProtocol& internet_protocol, + unsigned short port_num) + : impl_(internet_protocol.family(), port_num) + { + } + + /// Construct an endpoint using a port number and an IP address. This + /// constructor may be used for accepting connections on a specific interface + /// or for making a connection to a remote endpoint. + basic_endpoint(const asio::ip::address& addr, unsigned short port_num) + : impl_(addr, port_num) + { + } + + /// Copy constructor. + basic_endpoint(const basic_endpoint& other) + : impl_(other.impl_) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move constructor. + basic_endpoint(basic_endpoint&& other) + : impl_(other.impl_) + { + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Assign from another endpoint. + basic_endpoint& operator=(const basic_endpoint& other) + { + impl_ = other.impl_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-assign from another endpoint. + basic_endpoint& operator=(basic_endpoint&& other) + { + impl_ = other.impl_; + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// The protocol associated with the endpoint. + protocol_type protocol() const + { + if (impl_.is_v4()) + return InternetProtocol::v4(); + return InternetProtocol::v6(); + } + + /// Get the underlying endpoint in the native type. + data_type* data() + { + return impl_.data(); + } + + /// Get the underlying endpoint in the native type. + const data_type* data() const + { + return impl_.data(); + } + + /// Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + return impl_.size(); + } + + /// Set the underlying size of the endpoint in the native type. + void resize(std::size_t new_size) + { + impl_.resize(new_size); + } + + /// Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return impl_.capacity(); + } + + /// Get the port associated with the endpoint. The port number is always in + /// the host's byte order. + unsigned short port() const + { + return impl_.port(); + } + + /// Set the port associated with the endpoint. The port number is always in + /// the host's byte order. + void port(unsigned short port_num) + { + impl_.port(port_num); + } + + /// Get the IP address associated with the endpoint. + asio::ip::address address() const + { + return impl_.address(); + } + + /// Set the IP address associated with the endpoint. + void address(const asio::ip::address& addr) + { + impl_.address(addr); + } + + /// Compare two endpoints for equality. + friend bool operator==(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e1.impl_ == e2.impl_; + } + + /// Compare two endpoints for inequality. + friend bool operator!=(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return !(e1 == e2); + } + + /// Compare endpoints for ordering. + friend bool operator<(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e1.impl_ < e2.impl_; + } + + /// Compare endpoints for ordering. + friend bool operator>(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e2.impl_ < e1.impl_; + } + + /// Compare endpoints for ordering. + friend bool operator<=(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return !(e2 < e1); + } + + /// Compare endpoints for ordering. + friend bool operator>=(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return !(e1 < e2); + } + +private: + // The underlying IP endpoint. + asio::ip::detail::endpoint impl_; +}; + +#if !defined(ASIO_NO_IOSTREAM) + +/// Output an endpoint as a string. +/** + * Used to output a human-readable string for a specified endpoint. + * + * @param os The output stream to which the string will be written. + * + * @param endpoint The endpoint to be written. + * + * @return The output stream. + * + * @relates asio::ip::basic_endpoint + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const basic_endpoint& endpoint); + +#endif // !defined(ASIO_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/impl/basic_endpoint.hpp" + +#endif // ASIO_IP_BASIC_ENDPOINT_HPP diff --git a/tools/sdk/include/asio/asio/ip/basic_resolver.hpp b/tools/sdk/include/asio/asio/ip/basic_resolver.hpp new file mode 100644 index 00000000..812dbec5 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/basic_resolver.hpp @@ -0,0 +1,1018 @@ +// +// ip/basic_resolver.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_BASIC_RESOLVER_HPP +#define ASIO_IP_BASIC_RESOLVER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/async_result.hpp" +#include "asio/basic_io_object.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/string_view.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/ip/basic_resolver_results.hpp" +#include "asio/ip/resolver_base.hpp" + +#if defined(ASIO_HAS_MOVE) +# include +#endif // defined(ASIO_HAS_MOVE) + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/ip/resolver_service.hpp" +#else // defined(ASIO_ENABLE_OLD_SERVICES) +# if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/winrt_resolver_service.hpp" +# define ASIO_SVC_T \ + asio::detail::winrt_resolver_service +# else +# include "asio/detail/resolver_service.hpp" +# define ASIO_SVC_T \ + asio::detail::resolver_service +# endif +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Provides endpoint resolution functionality. +/** + * The basic_resolver class template provides the ability to resolve a query + * to a list of endpoints. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template )> +class basic_resolver + : ASIO_SVC_ACCESS basic_io_object, + public resolver_base +{ +public: + /// The type of the executor associated with the object. + typedef io_context::executor_type executor_type; + + /// The protocol type. + typedef InternetProtocol protocol_type; + + /// The endpoint type. + typedef typename InternetProtocol::endpoint endpoint_type; + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated.) The query type. + typedef basic_resolver_query query; + + /// (Deprecated.) The iterator type. + typedef basic_resolver_iterator iterator; +#endif // !defined(ASIO_NO_DEPRECATED) + + /// The results type. + typedef basic_resolver_results results_type; + + /// Constructor. + /** + * This constructor creates a basic_resolver. + * + * @param io_context The io_context object that the resolver will use to + * dispatch handlers for any asynchronous operations performed on the + * resolver. + */ + explicit basic_resolver(asio::io_context& io_context) + : basic_io_object(io_context) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_resolver from another. + /** + * This constructor moves a resolver from one object to another. + * + * @param other The other basic_resolver 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_resolver(io_context&) constructor. + */ + basic_resolver(basic_resolver&& other) + : basic_io_object(std::move(other)) + { + } + + /// Move-assign a basic_resolver from another. + /** + * This assignment operator moves a resolver from one object to another. + * Cancels any outstanding asynchronous operations associated with the target + * object. + * + * @param other The other basic_resolver 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_resolver(io_context&) constructor. + */ + basic_resolver& operator=(basic_resolver&& other) + { + basic_io_object::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroys the resolver. + /** + * This function destroys the resolver, cancelling any outstanding + * asynchronous wait operations associated with the resolver as if by calling + * @c cancel. + */ + ~basic_resolver() + { + } + +#if defined(ASIO_ENABLE_OLD_SERVICES) + // These functions are provided by basic_io_object<>. +#else // defined(ASIO_ENABLE_OLD_SERVICES) +#if !defined(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. + */ + 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. + */ + asio::io_context& get_io_service() + { + return basic_io_object::get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return basic_io_object::get_executor(); + } +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + + /// Cancel any asynchronous operations that are waiting on the resolver. + /** + * This function forces the completion of any pending asynchronous + * operations on the host resolver. The handler for each cancelled operation + * will be invoked with the asio::error::operation_aborted error code. + */ + void cancel() + { + return this->get_service().cancel(this->get_implementation()); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated.) Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve a query into a list of endpoint entries. + * + * @param q A query object that determines what endpoints will be returned. + * + * @returns A range object representing the list of endpoint entries. A + * successful call to this function is guaranteed to return a non-empty + * range. + * + * @throws asio::system_error Thrown on failure. + */ + results_type resolve(const query& q) + { + asio::error_code ec; + results_type r = this->get_service().resolve( + this->get_implementation(), q, ec); + asio::detail::throw_error(ec, "resolve"); + return r; + } + + /// (Deprecated.) Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve a query into a list of endpoint entries. + * + * @param q A query object that determines what endpoints will be returned. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A range object representing the list of endpoint entries. An + * empty range is returned if an error occurs. A successful call to this + * function is guaranteed to return a non-empty range. + */ + results_type resolve(const query& q, asio::error_code& ec) + { + return this->get_service().resolve(this->get_implementation(), q, ec); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @returns A range object representing the list of endpoint entries. A + * successful call to this function is guaranteed to return a non-empty + * range. + * + * @throws asio::system_error Thrown on failure. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(ASIO_STRING_VIEW_PARAM host, + ASIO_STRING_VIEW_PARAM service) + { + return resolve(host, service, resolver_base::flags()); + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A range object representing the list of endpoint entries. An + * empty range is returned if an error occurs. A successful call to this + * function is guaranteed to return a non-empty range. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(ASIO_STRING_VIEW_PARAM host, + ASIO_STRING_VIEW_PARAM service, asio::error_code& ec) + { + return resolve(host, service, resolver_base::flags(), ec); + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @returns A range object representing the list of endpoint entries. A + * successful call to this function is guaranteed to return a non-empty + * range. + * + * @throws asio::system_error Thrown on failure. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(ASIO_STRING_VIEW_PARAM host, + ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags) + { + asio::error_code ec; + basic_resolver_query q(static_cast(host), + static_cast(service), resolve_flags); + results_type r = this->get_service().resolve( + this->get_implementation(), q, ec); + asio::detail::throw_error(ec, "resolve"); + return r; + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A range object representing the list of endpoint entries. An + * empty range is returned if an error occurs. A successful call to this + * function is guaranteed to return a non-empty range. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(ASIO_STRING_VIEW_PARAM host, + ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags, + asio::error_code& ec) + { + basic_resolver_query q(static_cast(host), + static_cast(service), resolve_flags); + return this->get_service().resolve(this->get_implementation(), q, ec); + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @returns A range object representing the list of endpoint entries. A + * successful call to this function is guaranteed to return a non-empty + * range. + * + * @throws asio::system_error Thrown on failure. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(const protocol_type& protocol, + ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service) + { + return resolve(protocol, host, service, resolver_base::flags()); + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A range object representing the list of endpoint entries. An + * empty range is returned if an error occurs. A successful call to this + * function is guaranteed to return a non-empty range. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(const protocol_type& protocol, + ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, + asio::error_code& ec) + { + return resolve(protocol, host, service, resolver_base::flags(), ec); + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @returns A range object representing the list of endpoint entries. A + * successful call to this function is guaranteed to return a non-empty + * range. + * + * @throws asio::system_error Thrown on failure. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(const protocol_type& protocol, + ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, + resolver_base::flags resolve_flags) + { + asio::error_code ec; + basic_resolver_query q( + protocol, static_cast(host), + static_cast(service), resolve_flags); + results_type r = this->get_service().resolve( + this->get_implementation(), q, ec); + asio::detail::throw_error(ec, "resolve"); + return r; + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A range object representing the list of endpoint entries. An + * empty range is returned if an error occurs. A successful call to this + * function is guaranteed to return a non-empty range. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(const protocol_type& protocol, + ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, + resolver_base::flags resolve_flags, asio::error_code& ec) + { + basic_resolver_query q( + protocol, static_cast(host), + static_cast(service), resolve_flags); + return this->get_service().resolve(this->get_implementation(), q, ec); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated.) Asynchronously perform forward resolution of a query to a + /// list of entries. + /** + * This function is used to asynchronously resolve a query into a list of + * endpoint entries. + * + * @param q A query object that determines what endpoints will be returned. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * resolver::results_type results // Resolved endpoints as a range. + * ); @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 + * asio::io_context::post(). + * + * A successful resolve operation is guaranteed to pass a non-empty range to + * the handler. + */ + template + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(const query& q, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ResolveHandler. + ASIO_RESOLVE_HANDLER_CHECK( + ResolveHandler, handler, results_type) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_resolve(this->get_implementation(), q, + ASIO_MOVE_CAST(ResolveHandler)(handler)); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + asio::async_completion init(handler); + + this->get_service().async_resolve( + this->get_implementation(), q, init.completion_handler); + + return init.result.get(); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Asynchronously perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * resolver::results_type results // Resolved endpoints as a range. + * ); @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 + * asio::io_context::post(). + * + * A successful resolve operation is guaranteed to pass a non-empty range to + * the handler. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + template + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(ASIO_STRING_VIEW_PARAM host, + ASIO_STRING_VIEW_PARAM service, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + return async_resolve(host, service, resolver_base::flags(), + ASIO_MOVE_CAST(ResolveHandler)(handler)); + } + + /// Asynchronously perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * resolver::results_type results // Resolved endpoints as a range. + * ); @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 + * asio::io_context::post(). + * + * A successful resolve operation is guaranteed to pass a non-empty range to + * the handler. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + template + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(ASIO_STRING_VIEW_PARAM host, + ASIO_STRING_VIEW_PARAM service, + resolver_base::flags resolve_flags, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ResolveHandler. + ASIO_RESOLVE_HANDLER_CHECK( + ResolveHandler, handler, results_type) type_check; + + basic_resolver_query q(static_cast(host), + static_cast(service), resolve_flags); + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_resolve(this->get_implementation(), q, + ASIO_MOVE_CAST(ResolveHandler)(handler)); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + asio::async_completion init(handler); + + this->get_service().async_resolve( + this->get_implementation(), q, init.completion_handler); + + return init.result.get(); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + } + + /// Asynchronously perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * resolver::results_type results // Resolved endpoints as a range. + * ); @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 + * asio::io_context::post(). + * + * A successful resolve operation is guaranteed to pass a non-empty range to + * the handler. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + template + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(const protocol_type& protocol, + ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + return async_resolve(protocol, host, service, resolver_base::flags(), + ASIO_MOVE_CAST(ResolveHandler)(handler)); + } + + /// Asynchronously perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * resolver::results_type results // Resolved endpoints as a range. + * ); @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 + * asio::io_context::post(). + * + * A successful resolve operation is guaranteed to pass a non-empty range to + * the handler. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + template + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(const protocol_type& protocol, + ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, + resolver_base::flags resolve_flags, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ResolveHandler. + ASIO_RESOLVE_HANDLER_CHECK( + ResolveHandler, handler, results_type) type_check; + + basic_resolver_query q( + protocol, static_cast(host), + static_cast(service), resolve_flags); + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_resolve(this->get_implementation(), q, + ASIO_MOVE_CAST(ResolveHandler)(handler)); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + asio::async_completion init(handler); + + this->get_service().async_resolve( + this->get_implementation(), q, init.completion_handler); + + return init.result.get(); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + } + + /// Perform reverse resolution of an endpoint to a list of entries. + /** + * This function is used to resolve an endpoint into a list of endpoint + * entries. + * + * @param e An endpoint object that determines what endpoints will be + * returned. + * + * @returns A range object representing the list of endpoint entries. A + * successful call to this function is guaranteed to return a non-empty + * range. + * + * @throws asio::system_error Thrown on failure. + */ + results_type resolve(const endpoint_type& e) + { + asio::error_code ec; + results_type i = this->get_service().resolve( + this->get_implementation(), e, ec); + asio::detail::throw_error(ec, "resolve"); + return i; + } + + /// Perform reverse resolution of an endpoint to a list of entries. + /** + * This function is used to resolve an endpoint into a list of endpoint + * entries. + * + * @param e An endpoint object that determines what endpoints will be + * returned. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A range object representing the list of endpoint entries. An + * empty range is returned if an error occurs. A successful call to this + * function is guaranteed to return a non-empty range. + */ + results_type resolve(const endpoint_type& e, asio::error_code& ec) + { + return this->get_service().resolve(this->get_implementation(), e, ec); + } + + /// Asynchronously perform reverse resolution of an endpoint to a list of + /// entries. + /** + * This function is used to asynchronously resolve an endpoint into a list of + * endpoint entries. + * + * @param e An endpoint object that determines what endpoints will be + * returned. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * resolver::results_type results // Resolved endpoints as a range. + * ); @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 + * asio::io_context::post(). + * + * A successful resolve operation is guaranteed to pass a non-empty range to + * the handler. + */ + template + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(const endpoint_type& e, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ResolveHandler. + ASIO_RESOLVE_HANDLER_CHECK( + ResolveHandler, handler, results_type) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_resolve(this->get_implementation(), e, + ASIO_MOVE_CAST(ResolveHandler)(handler)); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + asio::async_completion init(handler); + + this->get_service().async_resolve( + this->get_implementation(), e, init.completion_handler); + + return init.result.get(); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + } +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if !defined(ASIO_ENABLE_OLD_SERVICES) +# undef ASIO_SVC_T +#endif // !defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_IP_BASIC_RESOLVER_HPP diff --git a/tools/sdk/include/asio/asio/ip/basic_resolver_entry.hpp b/tools/sdk/include/asio/asio/ip/basic_resolver_entry.hpp new file mode 100644 index 00000000..99bcbd29 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/basic_resolver_entry.hpp @@ -0,0 +1,113 @@ +// +// ip/basic_resolver_entry.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_BASIC_RESOLVER_ENTRY_HPP +#define ASIO_IP_BASIC_RESOLVER_ENTRY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/detail/string_view.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// An entry produced by a resolver. +/** + * The asio::ip::basic_resolver_entry class template describes an entry + * as returned by a resolver. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_resolver_entry +{ +public: + /// The protocol type associated with the endpoint entry. + typedef InternetProtocol protocol_type; + + /// The endpoint type associated with the endpoint entry. + typedef typename InternetProtocol::endpoint endpoint_type; + + /// Default constructor. + basic_resolver_entry() + { + } + + /// Construct with specified endpoint, host name and service name. + basic_resolver_entry(const endpoint_type& ep, + ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service) + : endpoint_(ep), + host_name_(static_cast(host)), + service_name_(static_cast(service)) + { + } + + /// Get the endpoint associated with the entry. + endpoint_type endpoint() const + { + return endpoint_; + } + + /// Convert to the endpoint associated with the entry. + operator endpoint_type() const + { + return endpoint_; + } + + /// Get the host name associated with the entry. + std::string host_name() const + { + return host_name_; + } + + /// Get the host name associated with the entry. + template + std::basic_string, Allocator> host_name( + const Allocator& alloc = Allocator()) const + { + return std::basic_string, Allocator>( + host_name_.c_str(), alloc); + } + + /// Get the service name associated with the entry. + std::string service_name() const + { + return service_name_; + } + + /// Get the service name associated with the entry. + template + std::basic_string, Allocator> service_name( + const Allocator& alloc = Allocator()) const + { + return std::basic_string, Allocator>( + service_name_.c_str(), alloc); + } + +private: + endpoint_type endpoint_; + std::string host_name_; + std::string service_name_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_BASIC_RESOLVER_ENTRY_HPP diff --git a/tools/sdk/include/asio/asio/ip/basic_resolver_iterator.hpp b/tools/sdk/include/asio/asio/ip/basic_resolver_iterator.hpp new file mode 100644 index 00000000..ec5412cf --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/basic_resolver_iterator.hpp @@ -0,0 +1,192 @@ +// +// ip/basic_resolver_iterator.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP +#define ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include +#include +#include +#include +#include "asio/detail/memory.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/ip/basic_resolver_entry.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/winrt_utils.hpp" +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// An iterator over the entries produced by a resolver. +/** + * The asio::ip::basic_resolver_iterator class template is used to define + * iterators over the results returned by a resolver. + * + * The iterator's value_type, obtained when the iterator is dereferenced, is: + * @code const basic_resolver_entry @endcode + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_resolver_iterator +{ +public: + /// The type used for the distance between two iterators. + typedef std::ptrdiff_t difference_type; + + /// The type of the value pointed to by the iterator. + typedef basic_resolver_entry value_type; + + /// The type of the result of applying operator->() to the iterator. + typedef const basic_resolver_entry* pointer; + + /// The type of the result of applying operator*() to the iterator. + typedef const basic_resolver_entry& reference; + + /// The iterator category. + typedef std::forward_iterator_tag iterator_category; + + /// Default constructor creates an end iterator. + basic_resolver_iterator() + : index_(0) + { + } + + /// Copy constructor. + basic_resolver_iterator(const basic_resolver_iterator& other) + : values_(other.values_), + index_(other.index_) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move constructor. + basic_resolver_iterator(basic_resolver_iterator&& other) + : values_(ASIO_MOVE_CAST(values_ptr_type)(other.values_)), + index_(other.index_) + { + other.index_ = 0; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Assignment operator. + basic_resolver_iterator& operator=(const basic_resolver_iterator& other) + { + values_ = other.values_; + index_ = other.index_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-assignment operator. + basic_resolver_iterator& operator=(basic_resolver_iterator&& other) + { + if (this != &other) + { + values_ = ASIO_MOVE_CAST(values_ptr_type)(other.values_); + index_ = other.index_; + other.index_ = 0; + } + + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Dereference an iterator. + const basic_resolver_entry& operator*() const + { + return dereference(); + } + + /// Dereference an iterator. + const basic_resolver_entry* operator->() const + { + return &dereference(); + } + + /// Increment operator (prefix). + basic_resolver_iterator& operator++() + { + increment(); + return *this; + } + + /// Increment operator (postfix). + basic_resolver_iterator operator++(int) + { + basic_resolver_iterator tmp(*this); + ++*this; + return tmp; + } + + /// Test two iterators for equality. + friend bool operator==(const basic_resolver_iterator& a, + const basic_resolver_iterator& b) + { + return a.equal(b); + } + + /// Test two iterators for inequality. + friend bool operator!=(const basic_resolver_iterator& a, + const basic_resolver_iterator& b) + { + return !a.equal(b); + } + +protected: + void increment() + { + if (++index_ == values_->size()) + { + // Reset state to match a default constructed end iterator. + values_.reset(); + index_ = 0; + } + } + + bool equal(const basic_resolver_iterator& other) const + { + if (!values_ && !other.values_) + return true; + if (values_ != other.values_) + return false; + return index_ == other.index_; + } + + const basic_resolver_entry& dereference() const + { + return (*values_)[index_]; + } + + typedef std::vector > values_type; + typedef asio::detail::shared_ptr values_ptr_type; + values_ptr_type values_; + std::size_t index_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP diff --git a/tools/sdk/include/asio/asio/ip/basic_resolver_query.hpp b/tools/sdk/include/asio/asio/ip/basic_resolver_query.hpp new file mode 100644 index 00000000..84cd98d5 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/basic_resolver_query.hpp @@ -0,0 +1,244 @@ +// +// ip/basic_resolver_query.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_BASIC_RESOLVER_QUERY_HPP +#define ASIO_IP_BASIC_RESOLVER_QUERY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/detail/socket_ops.hpp" +#include "asio/ip/resolver_query_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// An query to be passed to a resolver. +/** + * The asio::ip::basic_resolver_query class template describes a query + * that can be passed to a resolver. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_resolver_query + : public resolver_query_base +{ +public: + /// The protocol type associated with the endpoint query. + typedef InternetProtocol protocol_type; + + /// Construct with specified service name for any protocol. + /** + * This constructor is typically used to perform name resolution for local + * service binding. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for local service + * binding. + * + * @note On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + basic_resolver_query(const std::string& service, + resolver_query_base::flags resolve_flags = passive | address_configured) + : hints_(), + host_name_(), + service_name_(service) + { + typename InternetProtocol::endpoint endpoint; + hints_.ai_flags = static_cast(resolve_flags); + hints_.ai_family = PF_UNSPEC; + hints_.ai_socktype = endpoint.protocol().type(); + hints_.ai_protocol = endpoint.protocol().protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Construct with specified service name for a given protocol. + /** + * This constructor is typically used to perform name resolution for local + * service binding with a specific protocol version. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for local service + * binding. + * + * @note On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + basic_resolver_query(const protocol_type& protocol, + const std::string& service, + resolver_query_base::flags resolve_flags = passive | address_configured) + : hints_(), + host_name_(), + service_name_(service) + { + hints_.ai_flags = static_cast(resolve_flags); + hints_.ai_family = protocol.family(); + hints_.ai_socktype = protocol.type(); + hints_.ai_protocol = protocol.protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Construct with specified host name and service name for any protocol. + /** + * This constructor is typically used to perform name resolution for + * communication with remote hosts. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + basic_resolver_query(const std::string& host, const std::string& service, + resolver_query_base::flags resolve_flags = address_configured) + : hints_(), + host_name_(host), + service_name_(service) + { + typename InternetProtocol::endpoint endpoint; + hints_.ai_flags = static_cast(resolve_flags); + hints_.ai_family = ASIO_OS_DEF(AF_UNSPEC); + hints_.ai_socktype = endpoint.protocol().type(); + hints_.ai_protocol = endpoint.protocol().protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Construct with specified host name and service name for a given protocol. + /** + * This constructor is typically used to perform name resolution for + * communication with remote hosts. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + basic_resolver_query(const protocol_type& protocol, + const std::string& host, const std::string& service, + resolver_query_base::flags resolve_flags = address_configured) + : hints_(), + host_name_(host), + service_name_(service) + { + hints_.ai_flags = static_cast(resolve_flags); + hints_.ai_family = protocol.family(); + hints_.ai_socktype = protocol.type(); + hints_.ai_protocol = protocol.protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Get the hints associated with the query. + const asio::detail::addrinfo_type& hints() const + { + return hints_; + } + + /// Get the host name associated with the query. + std::string host_name() const + { + return host_name_; + } + + /// Get the service name associated with the query. + std::string service_name() const + { + return service_name_; + } + +private: + asio::detail::addrinfo_type hints_; + std::string host_name_; + std::string service_name_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_BASIC_RESOLVER_QUERY_HPP diff --git a/tools/sdk/include/asio/asio/ip/basic_resolver_results.hpp b/tools/sdk/include/asio/asio/ip/basic_resolver_results.hpp new file mode 100644 index 00000000..185075f0 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/basic_resolver_results.hpp @@ -0,0 +1,311 @@ +// +// ip/basic_resolver_results.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_BASIC_RESOLVER_RESULTS_HPP +#define ASIO_IP_BASIC_RESOLVER_RESULTS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/winrt_utils.hpp" +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// A range of entries produced by a resolver. +/** + * The asio::ip::basic_resolver_results class template is used to define + * a range over the results returned by a resolver. + * + * The iterator's value_type, obtained when a results iterator is dereferenced, + * is: @code const basic_resolver_entry @endcode + * + * @note For backward compatibility, basic_resolver_results is derived from + * basic_resolver_iterator. This derivation is deprecated. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_resolver_results +#if !defined(ASIO_NO_DEPRECATED) + : public basic_resolver_iterator +#else // !defined(ASIO_NO_DEPRECATED) + : private basic_resolver_iterator +#endif // !defined(ASIO_NO_DEPRECATED) +{ +public: + /// The protocol type associated with the results. + typedef InternetProtocol protocol_type; + + /// The endpoint type associated with the results. + typedef typename protocol_type::endpoint endpoint_type; + + /// The type of a value in the results range. + typedef basic_resolver_entry value_type; + + /// The type of a const reference to a value in the range. + typedef const value_type& const_reference; + + /// The type of a non-const reference to a value in the range. + typedef value_type& reference; + + /// The type of an iterator into the range. + typedef basic_resolver_iterator const_iterator; + + /// The type of an iterator into the range. + typedef const_iterator iterator; + + /// Type used to represent the distance between two iterators in the range. + typedef std::ptrdiff_t difference_type; + + /// Type used to represent a count of the elements in the range. + typedef std::size_t size_type; + + /// Default constructor creates an empty range. + basic_resolver_results() + { + } + + /// Copy constructor. + basic_resolver_results(const basic_resolver_results& other) + : basic_resolver_iterator(other) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move constructor. + basic_resolver_results(basic_resolver_results&& other) + : basic_resolver_iterator( + ASIO_MOVE_CAST(basic_resolver_results)(other)) + { + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Assignment operator. + basic_resolver_results& operator=(const basic_resolver_results& other) + { + basic_resolver_iterator::operator=(other); + return *this; + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-assignment operator. + basic_resolver_results& operator=(basic_resolver_results&& other) + { + basic_resolver_iterator::operator=( + ASIO_MOVE_CAST(basic_resolver_results)(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + +#if !defined(GENERATING_DOCUMENTATION) + // Create results from an addrinfo list returned by getaddrinfo. + static basic_resolver_results create( + asio::detail::addrinfo_type* address_info, + const std::string& host_name, const std::string& service_name) + { + basic_resolver_results results; + if (!address_info) + return results; + + std::string actual_host_name = host_name; + if (address_info->ai_canonname) + actual_host_name = address_info->ai_canonname; + + results.values_.reset(new values_type); + + while (address_info) + { + if (address_info->ai_family == ASIO_OS_DEF(AF_INET) + || address_info->ai_family == ASIO_OS_DEF(AF_INET6)) + { + using namespace std; // For memcpy. + typename InternetProtocol::endpoint endpoint; + endpoint.resize(static_cast(address_info->ai_addrlen)); + memcpy(endpoint.data(), address_info->ai_addr, + address_info->ai_addrlen); + results.values_->push_back( + basic_resolver_entry(endpoint, + actual_host_name, service_name)); + } + address_info = address_info->ai_next; + } + + return results; + } + + // Create results from an endpoint, host name and service name. + static basic_resolver_results create(const endpoint_type& endpoint, + const std::string& host_name, const std::string& service_name) + { + basic_resolver_results results; + results.values_.reset(new values_type); + results.values_->push_back( + basic_resolver_entry( + endpoint, host_name, service_name)); + return results; + } + + // Create results from a sequence of endpoints, host and service name. + template + static basic_resolver_results create( + EndpointIterator begin, EndpointIterator end, + const std::string& host_name, const std::string& service_name) + { + basic_resolver_results results; + if (begin != end) + { + results.values_.reset(new values_type); + for (EndpointIterator ep_iter = begin; ep_iter != end; ++ep_iter) + { + results.values_->push_back( + basic_resolver_entry( + *ep_iter, host_name, service_name)); + } + } + return results; + } + +# if defined(ASIO_WINDOWS_RUNTIME) + // Create results from a Windows Runtime list of EndpointPair objects. + static basic_resolver_results create( + Windows::Foundation::Collections::IVectorView< + Windows::Networking::EndpointPair^>^ endpoints, + const asio::detail::addrinfo_type& hints, + const std::string& host_name, const std::string& service_name) + { + basic_resolver_results results; + if (endpoints->Size) + { + results.values_.reset(new values_type); + for (unsigned int i = 0; i < endpoints->Size; ++i) + { + auto pair = endpoints->GetAt(i); + + if (hints.ai_family == ASIO_OS_DEF(AF_INET) + && pair->RemoteHostName->Type + != Windows::Networking::HostNameType::Ipv4) + continue; + + if (hints.ai_family == ASIO_OS_DEF(AF_INET6) + && pair->RemoteHostName->Type + != Windows::Networking::HostNameType::Ipv6) + continue; + + results.values_->push_back( + basic_resolver_entry( + typename InternetProtocol::endpoint( + ip::make_address( + asio::detail::winrt_utils::string( + pair->RemoteHostName->CanonicalName)), + asio::detail::winrt_utils::integer( + pair->RemoteServiceName)), + host_name, service_name)); + } + } + return results; + } +# endif // defined(ASIO_WINDOWS_RUNTIME) +#endif // !defined(GENERATING_DOCUMENTATION) + + /// Get the number of entries in the results range. + size_type size() const ASIO_NOEXCEPT + { + return this->values_->size(); + } + + /// Get the maximum number of entries permitted in a results range. + size_type max_size() const ASIO_NOEXCEPT + { + return this->values_->max_size(); + } + + /// Determine whether the results range is empty. + bool empty() const ASIO_NOEXCEPT + { + return this->values_->empty(); + } + + /// Obtain a begin iterator for the results range. + const_iterator begin() const + { + basic_resolver_results tmp(*this); + tmp.index_ = 0; + return tmp; + } + + /// Obtain an end iterator for the results range. + const_iterator end() const + { + return const_iterator(); + } + + /// Obtain a begin iterator for the results range. + const_iterator cbegin() const + { + return begin(); + } + + /// Obtain an end iterator for the results range. + const_iterator cend() const + { + return end(); + } + + /// Swap the results range with another. + void swap(basic_resolver_results& that) ASIO_NOEXCEPT + { + if (this != &that) + { + this->values_.swap(that.values_); + std::size_t index = this->index_; + this->index_ = that.index_; + that.index_ = index; + } + } + + /// Test two iterators for equality. + friend bool operator==(const basic_resolver_results& a, + const basic_resolver_results& b) + { + return a.equal(b); + } + + /// Test two iterators for inequality. + friend bool operator!=(const basic_resolver_results& a, + const basic_resolver_results& b) + { + return !a.equal(b); + } + +private: + typedef std::vector > values_type; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_BASIC_RESOLVER_RESULTS_HPP diff --git a/tools/sdk/include/asio/asio/ip/detail/endpoint.hpp b/tools/sdk/include/asio/asio/ip/detail/endpoint.hpp new file mode 100644 index 00000000..9acefe5f --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/detail/endpoint.hpp @@ -0,0 +1,139 @@ +// +// ip/detail/endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_DETAIL_ENDPOINT_HPP +#define ASIO_IP_DETAIL_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/detail/socket_types.hpp" +#include "asio/detail/winsock_init.hpp" +#include "asio/error_code.hpp" +#include "asio/ip/address.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { +namespace detail { + +// Helper class for implementating an IP endpoint. +class endpoint +{ +public: + // Default constructor. + ASIO_DECL endpoint(); + + // Construct an endpoint using a family and port number. + ASIO_DECL endpoint(int family, unsigned short port_num); + + // Construct an endpoint using an address and port number. + ASIO_DECL endpoint(const asio::ip::address& addr, + unsigned short port_num); + + // Copy constructor. + endpoint(const endpoint& other) + : data_(other.data_) + { + } + + // Assign from another endpoint. + endpoint& operator=(const endpoint& other) + { + data_ = other.data_; + return *this; + } + + // Get the underlying endpoint in the native type. + asio::detail::socket_addr_type* data() + { + return &data_.base; + } + + // Get the underlying endpoint in the native type. + const asio::detail::socket_addr_type* data() const + { + return &data_.base; + } + + // Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + if (is_v4()) + return sizeof(asio::detail::sockaddr_in4_type); + else + return sizeof(asio::detail::sockaddr_in6_type); + } + + // Set the underlying size of the endpoint in the native type. + ASIO_DECL void resize(std::size_t new_size); + + // Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return sizeof(data_); + } + + // Get the port associated with the endpoint. + ASIO_DECL unsigned short port() const; + + // Set the port associated with the endpoint. + ASIO_DECL void port(unsigned short port_num); + + // Get the IP address associated with the endpoint. + ASIO_DECL asio::ip::address address() const; + + // Set the IP address associated with the endpoint. + ASIO_DECL void address(const asio::ip::address& addr); + + // Compare two endpoints for equality. + ASIO_DECL friend bool operator==( + const endpoint& e1, const endpoint& e2); + + // Compare endpoints for ordering. + ASIO_DECL friend bool operator<( + const endpoint& e1, const endpoint& e2); + + // Determine whether the endpoint is IPv4. + bool is_v4() const + { + return data_.base.sa_family == ASIO_OS_DEF(AF_INET); + } + +#if !defined(ASIO_NO_IOSTREAM) + // Convert to a string. + ASIO_DECL std::string to_string() const; +#endif // !defined(ASIO_NO_IOSTREAM) + +private: + // The underlying IP socket address. + union data_union + { + asio::detail::socket_addr_type base; + asio::detail::sockaddr_in4_type v4; + asio::detail::sockaddr_in6_type v6; + } data_; +}; + +} // namespace detail +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/ip/detail/impl/endpoint.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_IP_DETAIL_ENDPOINT_HPP diff --git a/tools/sdk/include/asio/asio/ip/detail/socket_option.hpp b/tools/sdk/include/asio/asio/ip/detail/socket_option.hpp new file mode 100644 index 00000000..051ef30d --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/detail/socket_option.hpp @@ -0,0 +1,566 @@ +// +// detail/socket_option.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_DETAIL_SOCKET_OPTION_HPP +#define ASIO_IP_DETAIL_SOCKET_OPTION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include +#include +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/ip/address.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { +namespace detail { +namespace socket_option { + +// Helper template for implementing multicast enable loopback options. +template +class multicast_enable_loopback +{ +public: +#if defined(__sun) || defined(__osf__) + typedef unsigned char ipv4_value_type; + typedef unsigned char ipv6_value_type; +#elif defined(_AIX) || defined(__hpux) || defined(__QNXNTO__) + typedef unsigned char ipv4_value_type; + typedef unsigned int ipv6_value_type; +#else + typedef int ipv4_value_type; + typedef int ipv6_value_type; +#endif + + // Default constructor. + multicast_enable_loopback() + : ipv4_value_(0), + ipv6_value_(0) + { + } + + // Construct with a specific option value. + explicit multicast_enable_loopback(bool v) + : ipv4_value_(v ? 1 : 0), + ipv6_value_(v ? 1 : 0) + { + } + + // Set the value of the boolean. + multicast_enable_loopback& operator=(bool v) + { + ipv4_value_ = v ? 1 : 0; + ipv6_value_ = v ? 1 : 0; + return *this; + } + + // Get the current value of the boolean. + bool value() const + { + return !!ipv4_value_; + } + + // Convert to bool. + operator bool() const + { + return !!ipv4_value_; + } + + // Test for false. + bool operator!() const + { + return !ipv4_value_; + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the boolean data. + template + void* data(const Protocol& protocol) + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the address of the boolean data. + template + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the boolean data. + template + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + + // Set the size of the boolean data. + template + void resize(const Protocol& protocol, std::size_t s) + { + if (protocol.family() == PF_INET6) + { + if (s != sizeof(ipv6_value_)) + { + std::length_error ex("multicast_enable_loopback socket option resize"); + asio::detail::throw_exception(ex); + } + ipv4_value_ = ipv6_value_ ? 1 : 0; + } + else + { + if (s != sizeof(ipv4_value_)) + { + std::length_error ex("multicast_enable_loopback socket option resize"); + asio::detail::throw_exception(ex); + } + ipv6_value_ = ipv4_value_ ? 1 : 0; + } + } + +private: + ipv4_value_type ipv4_value_; + ipv6_value_type ipv6_value_; +}; + +// Helper template for implementing unicast hops options. +template +class unicast_hops +{ +public: + // Default constructor. + unicast_hops() + : value_(0) + { + } + + // Construct with a specific option value. + explicit unicast_hops(int v) + : value_(v) + { + } + + // Set the value of the option. + unicast_hops& operator=(int v) + { + value_ = v; + return *this; + } + + // Get the current value of the option. + int value() const + { + return value_; + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the data. + template + int* data(const Protocol&) + { + return &value_; + } + + // Get the address of the data. + template + const int* data(const Protocol&) const + { + return &value_; + } + + // Get the size of the data. + template + std::size_t size(const Protocol&) const + { + return sizeof(value_); + } + + // Set the size of the data. + template + void resize(const Protocol&, std::size_t s) + { + if (s != sizeof(value_)) + { + std::length_error ex("unicast hops socket option resize"); + asio::detail::throw_exception(ex); + } +#if defined(__hpux) + if (value_ < 0) + value_ = value_ & 0xFF; +#endif + } + +private: + int value_; +}; + +// Helper template for implementing multicast hops options. +template +class multicast_hops +{ +public: +#if defined(ASIO_WINDOWS) && defined(UNDER_CE) + typedef int ipv4_value_type; +#else + typedef unsigned char ipv4_value_type; +#endif + typedef int ipv6_value_type; + + // Default constructor. + multicast_hops() + : ipv4_value_(0), + ipv6_value_(0) + { + } + + // Construct with a specific option value. + explicit multicast_hops(int v) + { + if (v < 0 || v > 255) + { + std::out_of_range ex("multicast hops value out of range"); + asio::detail::throw_exception(ex); + } + ipv4_value_ = (ipv4_value_type)v; + ipv6_value_ = v; + } + + // Set the value of the option. + multicast_hops& operator=(int v) + { + if (v < 0 || v > 255) + { + std::out_of_range ex("multicast hops value out of range"); + asio::detail::throw_exception(ex); + } + ipv4_value_ = (ipv4_value_type)v; + ipv6_value_ = v; + return *this; + } + + // Get the current value of the option. + int value() const + { + return ipv6_value_; + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the data. + template + void* data(const Protocol& protocol) + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the address of the data. + template + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the data. + template + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + + // Set the size of the data. + template + void resize(const Protocol& protocol, std::size_t s) + { + if (protocol.family() == PF_INET6) + { + if (s != sizeof(ipv6_value_)) + { + std::length_error ex("multicast hops socket option resize"); + asio::detail::throw_exception(ex); + } + if (ipv6_value_ < 0) + ipv4_value_ = 0; + else if (ipv6_value_ > 255) + ipv4_value_ = 255; + else + ipv4_value_ = (ipv4_value_type)ipv6_value_; + } + else + { + if (s != sizeof(ipv4_value_)) + { + std::length_error ex("multicast hops socket option resize"); + asio::detail::throw_exception(ex); + } + ipv6_value_ = ipv4_value_; + } + } + +private: + ipv4_value_type ipv4_value_; + ipv6_value_type ipv6_value_; +}; + +// Helper template for implementing ip_mreq-based options. +template +class multicast_request +{ +public: + // Default constructor. + multicast_request() + : ipv4_value_(), // Zero-initialisation gives the "any" address. + ipv6_value_() // Zero-initialisation gives the "any" address. + { + } + + // Construct with multicast address only. + explicit multicast_request(const address& multicast_address) + : ipv4_value_(), // Zero-initialisation gives the "any" address. + ipv6_value_() // Zero-initialisation gives the "any" address. + { + if (multicast_address.is_v6()) + { + using namespace std; // For memcpy. + address_v6 ipv6_address = multicast_address.to_v6(); + address_v6::bytes_type bytes = ipv6_address.to_bytes(); + memcpy(ipv6_value_.ipv6mr_multiaddr.s6_addr, bytes.data(), 16); + ipv6_value_.ipv6mr_interface = ipv6_address.scope_id(); + } + else + { + ipv4_value_.imr_multiaddr.s_addr = + asio::detail::socket_ops::host_to_network_long( + multicast_address.to_v4().to_uint()); + ipv4_value_.imr_interface.s_addr = + asio::detail::socket_ops::host_to_network_long( + address_v4::any().to_uint()); + } + } + + // Construct with multicast address and IPv4 address specifying an interface. + explicit multicast_request(const address_v4& multicast_address, + const address_v4& network_interface = address_v4::any()) + : ipv6_value_() // Zero-initialisation gives the "any" address. + { + ipv4_value_.imr_multiaddr.s_addr = + asio::detail::socket_ops::host_to_network_long( + multicast_address.to_uint()); + ipv4_value_.imr_interface.s_addr = + asio::detail::socket_ops::host_to_network_long( + network_interface.to_uint()); + } + + // Construct with multicast address and IPv6 network interface index. + explicit multicast_request( + const address_v6& multicast_address, + unsigned long network_interface = 0) + : ipv4_value_() // Zero-initialisation gives the "any" address. + { + using namespace std; // For memcpy. + address_v6::bytes_type bytes = multicast_address.to_bytes(); + memcpy(ipv6_value_.ipv6mr_multiaddr.s6_addr, bytes.data(), 16); + if (network_interface) + ipv6_value_.ipv6mr_interface = network_interface; + else + ipv6_value_.ipv6mr_interface = multicast_address.scope_id(); + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the option data. + template + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the option data. + template + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + +private: + asio::detail::in4_mreq_type ipv4_value_; + asio::detail::in6_mreq_type ipv6_value_; +}; + +// Helper template for implementing options that specify a network interface. +template +class network_interface +{ +public: + // Default constructor. + network_interface() + { + ipv4_value_.s_addr = + asio::detail::socket_ops::host_to_network_long( + address_v4::any().to_uint()); + ipv6_value_ = 0; + } + + // Construct with IPv4 interface. + explicit network_interface(const address_v4& ipv4_interface) + { + ipv4_value_.s_addr = + asio::detail::socket_ops::host_to_network_long( + ipv4_interface.to_uint()); + ipv6_value_ = 0; + } + + // Construct with IPv6 interface. + explicit network_interface(unsigned int ipv6_interface) + { + ipv4_value_.s_addr = + asio::detail::socket_ops::host_to_network_long( + address_v4::any().to_uint()); + ipv6_value_ = ipv6_interface; + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the option data. + template + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the option data. + template + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + +private: + asio::detail::in4_addr_type ipv4_value_; + unsigned int ipv6_value_; +}; + +} // namespace socket_option +} // namespace detail +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_DETAIL_SOCKET_OPTION_HPP diff --git a/tools/sdk/include/asio/asio/ip/host_name.hpp b/tools/sdk/include/asio/asio/ip/host_name.hpp new file mode 100644 index 00000000..d06de508 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/host_name.hpp @@ -0,0 +1,42 @@ +// +// ip/host_name.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_HOST_NAME_HPP +#define ASIO_IP_HOST_NAME_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/error_code.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Get the current host name. +ASIO_DECL std::string host_name(); + +/// Get the current host name. +ASIO_DECL std::string host_name(asio::error_code& ec); + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/ip/impl/host_name.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_IP_HOST_NAME_HPP diff --git a/tools/sdk/include/asio/asio/ip/icmp.hpp b/tools/sdk/include/asio/asio/ip/icmp.hpp new file mode 100644 index 00000000..92e1953f --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/icmp.hpp @@ -0,0 +1,115 @@ +// +// ip/icmp.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_ICMP_HPP +#define ASIO_IP_ICMP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/basic_raw_socket.hpp" +#include "asio/ip/basic_endpoint.hpp" +#include "asio/ip/basic_resolver.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Encapsulates the flags needed for ICMP. +/** + * The asio::ip::icmp class contains flags necessary for ICMP sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol, InternetProtocol. + */ +class icmp +{ +public: + /// The type of a ICMP endpoint. + typedef basic_endpoint endpoint; + + /// Construct to represent the IPv4 ICMP protocol. + static icmp v4() + { + return icmp(ASIO_OS_DEF(IPPROTO_ICMP), + ASIO_OS_DEF(AF_INET)); + } + + /// Construct to represent the IPv6 ICMP protocol. + static icmp v6() + { + return icmp(ASIO_OS_DEF(IPPROTO_ICMPV6), + ASIO_OS_DEF(AF_INET6)); + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return ASIO_OS_DEF(SOCK_RAW); + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return protocol_; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// The ICMP socket type. + typedef basic_raw_socket socket; + + /// The ICMP resolver type. + typedef basic_resolver resolver; + + /// Compare two protocols for equality. + friend bool operator==(const icmp& p1, const icmp& p2) + { + return p1.protocol_ == p2.protocol_ && p1.family_ == p2.family_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const icmp& p1, const icmp& p2) + { + return p1.protocol_ != p2.protocol_ || p1.family_ != p2.family_; + } + +private: + // Construct with a specific family. + explicit icmp(int protocol_id, int protocol_family) + : protocol_(protocol_id), + family_(protocol_family) + { + } + + int protocol_; + int family_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ICMP_HPP diff --git a/tools/sdk/include/asio/asio/ip/impl/address.hpp b/tools/sdk/include/asio/asio/ip/impl/address.hpp new file mode 100644 index 00000000..085b93f7 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/impl/address.hpp @@ -0,0 +1,67 @@ +// +// ip/impl/address.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_IMPL_ADDRESS_HPP +#define ASIO_IP_IMPL_ADDRESS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +#if !defined(ASIO_NO_DEPRECATED) + +inline address address::from_string(const char* str) +{ + return asio::ip::make_address(str); +} + +inline address address::from_string( + const char* str, asio::error_code& ec) +{ + return asio::ip::make_address(str, ec); +} + +inline address address::from_string(const std::string& str) +{ + return asio::ip::make_address(str); +} + +inline address address::from_string( + const std::string& str, asio::error_code& ec) +{ + return asio::ip::make_address(str, ec); +} + +#endif // !defined(ASIO_NO_DEPRECATED) + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const address& addr) +{ + return os << addr.to_string().c_str(); +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_IP_IMPL_ADDRESS_HPP diff --git a/tools/sdk/include/asio/asio/ip/impl/address_v4.hpp b/tools/sdk/include/asio/asio/ip/impl/address_v4.hpp new file mode 100644 index 00000000..d1cf407c --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/impl/address_v4.hpp @@ -0,0 +1,67 @@ +// +// ip/impl/address_v4.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_IMPL_ADDRESS_V4_HPP +#define ASIO_IP_IMPL_ADDRESS_V4_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +#if !defined(ASIO_NO_DEPRECATED) + +inline address_v4 address_v4::from_string(const char* str) +{ + return asio::ip::make_address_v4(str); +} + +inline address_v4 address_v4::from_string( + const char* str, asio::error_code& ec) +{ + return asio::ip::make_address_v4(str, ec); +} + +inline address_v4 address_v4::from_string(const std::string& str) +{ + return asio::ip::make_address_v4(str); +} + +inline address_v4 address_v4::from_string( + const std::string& str, asio::error_code& ec) +{ + return asio::ip::make_address_v4(str, ec); +} + +#endif // !defined(ASIO_NO_DEPRECATED) + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const address_v4& addr) +{ + return os << addr.to_string().c_str(); +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_IP_IMPL_ADDRESS_V4_HPP diff --git a/tools/sdk/include/asio/asio/ip/impl/address_v6.hpp b/tools/sdk/include/asio/asio/ip/impl/address_v6.hpp new file mode 100644 index 00000000..330eafd1 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/impl/address_v6.hpp @@ -0,0 +1,67 @@ +// +// ip/impl/address_v6.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_IMPL_ADDRESS_V6_HPP +#define ASIO_IP_IMPL_ADDRESS_V6_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +#if !defined(ASIO_NO_DEPRECATED) + +inline address_v6 address_v6::from_string(const char* str) +{ + return asio::ip::make_address_v6(str); +} + +inline address_v6 address_v6::from_string( + const char* str, asio::error_code& ec) +{ + return asio::ip::make_address_v6(str, ec); +} + +inline address_v6 address_v6::from_string(const std::string& str) +{ + return asio::ip::make_address_v6(str); +} + +inline address_v6 address_v6::from_string( + const std::string& str, asio::error_code& ec) +{ + return asio::ip::make_address_v6(str, ec); +} + +#endif // !defined(ASIO_NO_DEPRECATED) + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const address_v6& addr) +{ + return os << addr.to_string().c_str(); +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_IP_IMPL_ADDRESS_V6_HPP diff --git a/tools/sdk/include/asio/asio/ip/impl/basic_endpoint.hpp b/tools/sdk/include/asio/asio/ip/impl/basic_endpoint.hpp new file mode 100644 index 00000000..5680a438 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/impl/basic_endpoint.hpp @@ -0,0 +1,43 @@ +// +// ip/impl/basic_endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_IMPL_BASIC_ENDPOINT_HPP +#define ASIO_IP_IMPL_BASIC_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const basic_endpoint& endpoint) +{ + asio::ip::detail::endpoint tmp_ep(endpoint.address(), endpoint.port()); + return os << tmp_ep.to_string().c_str(); +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_IP_IMPL_BASIC_ENDPOINT_HPP diff --git a/tools/sdk/include/asio/asio/ip/impl/network_v4.hpp b/tools/sdk/include/asio/asio/ip/impl/network_v4.hpp new file mode 100644 index 00000000..911a45c3 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/impl/network_v4.hpp @@ -0,0 +1,54 @@ +// +// ip/impl/network_v4.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) +// +// 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 ASIO_IP_IMPL_NETWORK_V4_HPP +#define ASIO_IP_IMPL_NETWORK_V4_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const network_v4& addr) +{ + asio::error_code ec; + std::string s = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::basic_ostream::failbit) + asio::detail::throw_error(ec); + else + os.setstate(std::basic_ostream::failbit); + } + else + for (std::string::iterator i = s.begin(); i != s.end(); ++i) + os << os.widen(*i); + return os; +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_IP_IMPL_NETWORK_V4_HPP diff --git a/tools/sdk/include/asio/asio/ip/impl/network_v6.hpp b/tools/sdk/include/asio/asio/ip/impl/network_v6.hpp new file mode 100644 index 00000000..b0eedade --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/impl/network_v6.hpp @@ -0,0 +1,53 @@ +// +// ip/impl/network_v6.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_IMPL_NETWORK_V6_HPP +#define ASIO_IP_IMPL_NETWORK_V6_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const network_v6& addr) +{ + asio::error_code ec; + std::string s = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::basic_ostream::failbit) + asio::detail::throw_error(ec); + else + os.setstate(std::basic_ostream::failbit); + } + else + for (std::string::iterator i = s.begin(); i != s.end(); ++i) + os << os.widen(*i); + return os; +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_IP_IMPL_NETWORK_V6_HPP diff --git a/tools/sdk/include/asio/asio/ip/multicast.hpp b/tools/sdk/include/asio/asio/ip/multicast.hpp new file mode 100644 index 00000000..ea624e14 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/multicast.hpp @@ -0,0 +1,191 @@ +// +// ip/multicast.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_MULTICAST_HPP +#define ASIO_IP_MULTICAST_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/ip/detail/socket_option.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { +namespace multicast { + +/// Socket option to join a multicast group on a specified interface. +/** + * Implements the IPPROTO_IP/IP_ADD_MEMBERSHIP socket option. + * + * @par Examples + * Setting the option to join a multicast group: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::address multicast_address = + * asio::ip::address::from_string("225.0.0.1"); + * asio::ip::multicast::join_group option(multicast_address); + * socket.set_option(option); + * @endcode + * + * @par Concepts: + * SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined join_group; +#else +typedef asio::ip::detail::socket_option::multicast_request< + ASIO_OS_DEF(IPPROTO_IP), + ASIO_OS_DEF(IP_ADD_MEMBERSHIP), + ASIO_OS_DEF(IPPROTO_IPV6), + ASIO_OS_DEF(IPV6_JOIN_GROUP)> join_group; +#endif + +/// Socket option to leave a multicast group on a specified interface. +/** + * Implements the IPPROTO_IP/IP_DROP_MEMBERSHIP socket option. + * + * @par Examples + * Setting the option to leave a multicast group: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::address multicast_address = + * asio::ip::address::from_string("225.0.0.1"); + * asio::ip::multicast::leave_group option(multicast_address); + * socket.set_option(option); + * @endcode + * + * @par Concepts: + * SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined leave_group; +#else +typedef asio::ip::detail::socket_option::multicast_request< + ASIO_OS_DEF(IPPROTO_IP), + ASIO_OS_DEF(IP_DROP_MEMBERSHIP), + ASIO_OS_DEF(IPPROTO_IPV6), + ASIO_OS_DEF(IPV6_LEAVE_GROUP)> leave_group; +#endif + +/// Socket option for local interface to use for outgoing multicast packets. +/** + * Implements the IPPROTO_IP/IP_MULTICAST_IF socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::address_v4 local_interface = + * asio::ip::address_v4::from_string("1.2.3.4"); + * asio::ip::multicast::outbound_interface option(local_interface); + * socket.set_option(option); + * @endcode + * + * @par Concepts: + * SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined outbound_interface; +#else +typedef asio::ip::detail::socket_option::network_interface< + ASIO_OS_DEF(IPPROTO_IP), + ASIO_OS_DEF(IP_MULTICAST_IF), + ASIO_OS_DEF(IPPROTO_IPV6), + ASIO_OS_DEF(IPV6_MULTICAST_IF)> outbound_interface; +#endif + +/// Socket option for time-to-live associated with outgoing multicast packets. +/** + * Implements the IPPROTO_IP/IP_MULTICAST_TTL socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::multicast::hops option(4); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::multicast::hops option; + * socket.get_option(option); + * int ttl = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined hops; +#else +typedef asio::ip::detail::socket_option::multicast_hops< + ASIO_OS_DEF(IPPROTO_IP), + ASIO_OS_DEF(IP_MULTICAST_TTL), + ASIO_OS_DEF(IPPROTO_IPV6), + ASIO_OS_DEF(IPV6_MULTICAST_HOPS)> hops; +#endif + +/// Socket option determining whether outgoing multicast packets will be +/// received on the same socket if it is a member of the multicast group. +/** + * Implements the IPPROTO_IP/IP_MULTICAST_LOOP socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::multicast::enable_loopback option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::multicast::enable_loopback option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined enable_loopback; +#else +typedef asio::ip::detail::socket_option::multicast_enable_loopback< + ASIO_OS_DEF(IPPROTO_IP), + ASIO_OS_DEF(IP_MULTICAST_LOOP), + ASIO_OS_DEF(IPPROTO_IPV6), + ASIO_OS_DEF(IPV6_MULTICAST_LOOP)> enable_loopback; +#endif + +} // namespace multicast +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_MULTICAST_HPP diff --git a/tools/sdk/include/asio/asio/ip/network_v4.hpp b/tools/sdk/include/asio/asio/ip/network_v4.hpp new file mode 100644 index 00000000..e38f60fe --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/network_v4.hpp @@ -0,0 +1,261 @@ +// +// ip/network_v4.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) +// +// 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 ASIO_IP_NETWORK_V4_HPP +#define ASIO_IP_NETWORK_V4_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/detail/string_view.hpp" +#include "asio/error_code.hpp" +#include "asio/ip/address_v4_range.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Represents an IPv4 network. +/** + * The asio::ip::network_v4 class provides the ability to use and + * manipulate IP version 4 networks. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class network_v4 +{ +public: + /// Default constructor. + network_v4() ASIO_NOEXCEPT + : address_(), + prefix_length_(0) + { + } + + /// Construct a network based on the specified address and prefix length. + ASIO_DECL network_v4(const address_v4& addr, + unsigned short prefix_len); + + /// Construct network based on the specified address and netmask. + ASIO_DECL network_v4(const address_v4& addr, + const address_v4& mask); + + /// Copy constructor. + network_v4(const network_v4& other) ASIO_NOEXCEPT + : address_(other.address_), + prefix_length_(other.prefix_length_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + network_v4(network_v4&& other) ASIO_NOEXCEPT + : address_(ASIO_MOVE_CAST(address_v4)(other.address_)), + prefix_length_(other.prefix_length_) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from another network. + network_v4& operator=(const network_v4& other) ASIO_NOEXCEPT + { + address_ = other.address_; + prefix_length_ = other.prefix_length_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move-assign from another network. + network_v4& operator=(network_v4&& other) ASIO_NOEXCEPT + { + address_ = ASIO_MOVE_CAST(address_v4)(other.address_); + prefix_length_ = other.prefix_length_; + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// Obtain the address object specified when the network object was created. + address_v4 address() const ASIO_NOEXCEPT + { + return address_; + } + + /// Obtain the prefix length that was specified when the network object was + /// created. + unsigned short prefix_length() const ASIO_NOEXCEPT + { + return prefix_length_; + } + + /// Obtain the netmask that was specified when the network object was created. + ASIO_DECL address_v4 netmask() const ASIO_NOEXCEPT; + + /// Obtain an address object that represents the network address. + address_v4 network() const ASIO_NOEXCEPT + { + return address_v4(address_.to_uint() & netmask().to_uint()); + } + + /// Obtain an address object that represents the network's broadcast address. + address_v4 broadcast() const ASIO_NOEXCEPT + { + return address_v4(network().to_uint() | (netmask().to_uint() ^ 0xFFFFFFFF)); + } + + /// Obtain an address range corresponding to the hosts in the network. + ASIO_DECL address_v4_range hosts() const ASIO_NOEXCEPT; + + /// Obtain the true network address, omitting any host bits. + network_v4 canonical() const ASIO_NOEXCEPT + { + return network_v4(network(), netmask()); + } + + /// Test if network is a valid host address. + bool is_host() const ASIO_NOEXCEPT + { + return prefix_length_ == 32; + } + + /// Test if a network is a real subnet of another network. + ASIO_DECL bool is_subnet_of(const network_v4& other) const; + + /// Get the network as an address in dotted decimal format. + ASIO_DECL std::string to_string() const; + + /// Get the network as an address in dotted decimal format. + ASIO_DECL std::string to_string(asio::error_code& ec) const; + + /// Compare two networks for equality. + friend bool operator==(const network_v4& a, const network_v4& b) + { + return a.address_ == b.address_ && a.prefix_length_ == b.prefix_length_; + } + + /// Compare two networks for inequality. + friend bool operator!=(const network_v4& a, const network_v4& b) + { + return !(a == b); + } + +private: + address_v4 address_; + unsigned short prefix_length_; +}; + +/// Create an IPv4 network from an address and prefix length. +/** + * @relates address_v4 + */ +inline network_v4 make_network_v4( + const address_v4& addr, unsigned short prefix_len) +{ + return network_v4(addr, prefix_len); +} + +/// Create an IPv4 network from an address and netmask. +/** + * @relates address_v4 + */ +inline network_v4 make_network_v4( + const address_v4& addr, const address_v4& mask) +{ + return network_v4(addr, mask); +} + +/// Create an IPv4 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v4 + */ +ASIO_DECL network_v4 make_network_v4(const char* str); + +/// Create an IPv4 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v4 + */ +ASIO_DECL network_v4 make_network_v4( + const char* str, asio::error_code& ec); + +/// Create an IPv4 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v4 + */ +ASIO_DECL network_v4 make_network_v4(const std::string& str); + +/// Create an IPv4 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v4 + */ +ASIO_DECL network_v4 make_network_v4( + const std::string& str, asio::error_code& ec); + +#if defined(ASIO_HAS_STRING_VIEW) \ + || defined(GENERATING_DOCUMENTATION) + +/// Create an IPv4 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v4 + */ +ASIO_DECL network_v4 make_network_v4(string_view str); + +/// Create an IPv4 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v4 + */ +ASIO_DECL network_v4 make_network_v4( + string_view str, asio::error_code& ec); + +#endif // defined(ASIO_HAS_STRING_VIEW) + // || defined(GENERATING_DOCUMENTATION) + +#if !defined(ASIO_NO_IOSTREAM) + +/// Output a network as a string. +/** + * Used to output a human-readable string for a specified network. + * + * @param os The output stream to which the string will be written. + * + * @param net The network to be written. + * + * @return The output stream. + * + * @relates asio::ip::address_v4 + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const network_v4& net); + +#endif // !defined(ASIO_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/impl/network_v4.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/ip/impl/network_v4.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_IP_NETWORK_V4_HPP diff --git a/tools/sdk/include/asio/asio/ip/network_v6.hpp b/tools/sdk/include/asio/asio/ip/network_v6.hpp new file mode 100644 index 00000000..7b6b7e61 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/network_v6.hpp @@ -0,0 +1,235 @@ +// +// ip/network_v6.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) +// +// 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 ASIO_IP_NETWORK_V6_HPP +#define ASIO_IP_NETWORK_V6_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/detail/string_view.hpp" +#include "asio/error_code.hpp" +#include "asio/ip/address_v6_range.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Represents an IPv6 network. +/** + * The asio::ip::network_v6 class provides the ability to use and + * manipulate IP version 6 networks. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class network_v6 +{ +public: + /// Default constructor. + network_v6() ASIO_NOEXCEPT + : address_(), + prefix_length_(0) + { + } + + /// Construct a network based on the specified address and prefix length. + ASIO_DECL network_v6(const address_v6& addr, + unsigned short prefix_len); + + /// Copy constructor. + network_v6(const network_v6& other) ASIO_NOEXCEPT + : address_(other.address_), + prefix_length_(other.prefix_length_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + network_v6(network_v6&& other) ASIO_NOEXCEPT + : address_(ASIO_MOVE_CAST(address_v6)(other.address_)), + prefix_length_(other.prefix_length_) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from another network. + network_v6& operator=(const network_v6& other) ASIO_NOEXCEPT + { + address_ = other.address_; + prefix_length_ = other.prefix_length_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move-assign from another network. + network_v6& operator=(network_v6&& other) ASIO_NOEXCEPT + { + address_ = ASIO_MOVE_CAST(address_v6)(other.address_); + prefix_length_ = other.prefix_length_; + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// Obtain the address object specified when the network object was created. + address_v6 address() const ASIO_NOEXCEPT + { + return address_; + } + + /// Obtain the prefix length that was specified when the network object was + /// created. + unsigned short prefix_length() const ASIO_NOEXCEPT + { + return prefix_length_; + } + + /// Obtain an address object that represents the network address. + ASIO_DECL address_v6 network() const ASIO_NOEXCEPT; + + /// Obtain an address range corresponding to the hosts in the network. + ASIO_DECL address_v6_range hosts() const ASIO_NOEXCEPT; + + /// Obtain the true network address, omitting any host bits. + network_v6 canonical() const ASIO_NOEXCEPT + { + return network_v6(network(), prefix_length()); + } + + /// Test if network is a valid host address. + bool is_host() const ASIO_NOEXCEPT + { + return prefix_length_ == 128; + } + + /// Test if a network is a real subnet of another network. + ASIO_DECL bool is_subnet_of(const network_v6& other) const; + + /// Get the network as an address in dotted decimal format. + ASIO_DECL std::string to_string() const; + + /// Get the network as an address in dotted decimal format. + ASIO_DECL std::string to_string(asio::error_code& ec) const; + + /// Compare two networks for equality. + friend bool operator==(const network_v6& a, const network_v6& b) + { + return a.address_ == b.address_ && a.prefix_length_ == b.prefix_length_; + } + + /// Compare two networks for inequality. + friend bool operator!=(const network_v6& a, const network_v6& b) + { + return !(a == b); + } + +private: + address_v6 address_; + unsigned short prefix_length_; +}; + +/// Create an IPv6 network from an address and prefix length. +/** + * @relates address_v6 + */ +inline network_v6 make_network_v6( + const address_v6& addr, unsigned short prefix_len) +{ + return network_v6(addr, prefix_len); +} + +/// Create an IPv6 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v6 + */ +ASIO_DECL network_v6 make_network_v6(const char* str); + +/// Create an IPv6 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v6 + */ +ASIO_DECL network_v6 make_network_v6( + const char* str, asio::error_code& ec); + +/// Create an IPv6 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v6 + */ +ASIO_DECL network_v6 make_network_v6(const std::string& str); + +/// Create an IPv6 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v6 + */ +ASIO_DECL network_v6 make_network_v6( + const std::string& str, asio::error_code& ec); + +#if defined(ASIO_HAS_STRING_VIEW) \ + || defined(GENERATING_DOCUMENTATION) + +/// Create an IPv6 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v6 + */ +ASIO_DECL network_v6 make_network_v6(string_view str); + +/// Create an IPv6 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v6 + */ +ASIO_DECL network_v6 make_network_v6( + string_view str, asio::error_code& ec); + +#endif // defined(ASIO_HAS_STRING_VIEW) + // || defined(GENERATING_DOCUMENTATION) + +#if !defined(ASIO_NO_IOSTREAM) + +/// Output a network as a string. +/** + * Used to output a human-readable string for a specified network. + * + * @param os The output stream to which the string will be written. + * + * @param net The network to be written. + * + * @return The output stream. + * + * @relates asio::ip::address_v6 + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const network_v6& net); + +#endif // !defined(ASIO_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/impl/network_v6.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/ip/impl/network_v6.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_IP_NETWORK_V6_HPP diff --git a/tools/sdk/include/asio/asio/ip/resolver_base.hpp b/tools/sdk/include/asio/asio/ip/resolver_base.hpp new file mode 100644 index 00000000..d32c9110 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/resolver_base.hpp @@ -0,0 +1,129 @@ +// +// ip/resolver_base.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_RESOLVER_BASE_HPP +#define ASIO_IP_RESOLVER_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// The resolver_base class is used as a base for the basic_resolver class +/// templates to provide a common place to define the flag constants. +class resolver_base +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// A bitmask type (C++ Std [lib.bitmask.types]). + typedef unspecified flags; + + /// Determine the canonical name of the host specified in the query. + static const flags canonical_name = implementation_defined; + + /// Indicate that returned endpoint is intended for use as a locally bound + /// socket endpoint. + static const flags passive = implementation_defined; + + /// Host name should be treated as a numeric string defining an IPv4 or IPv6 + /// address and no name resolution should be attempted. + static const flags numeric_host = implementation_defined; + + /// Service name should be treated as a numeric string defining a port number + /// and no name resolution should be attempted. + static const flags numeric_service = implementation_defined; + + /// If the query protocol family is specified as IPv6, return IPv4-mapped + /// IPv6 addresses on finding no IPv6 addresses. + static const flags v4_mapped = implementation_defined; + + /// If used with v4_mapped, return all matching IPv6 and IPv4 addresses. + static const flags all_matching = implementation_defined; + + /// Only return IPv4 addresses if a non-loopback IPv4 address is configured + /// for the system. Only return IPv6 addresses if a non-loopback IPv6 address + /// is configured for the system. + static const flags address_configured = implementation_defined; +#else + enum flags + { + canonical_name = ASIO_OS_DEF(AI_CANONNAME), + passive = ASIO_OS_DEF(AI_PASSIVE), + numeric_host = ASIO_OS_DEF(AI_NUMERICHOST), + numeric_service = ASIO_OS_DEF(AI_NUMERICSERV), + v4_mapped = ASIO_OS_DEF(AI_V4MAPPED), + all_matching = ASIO_OS_DEF(AI_ALL), + address_configured = ASIO_OS_DEF(AI_ADDRCONFIG) + }; + + // Implement bitmask operations as shown in C++ Std [lib.bitmask.types]. + + friend flags operator&(flags x, flags y) + { + return static_cast( + static_cast(x) & static_cast(y)); + } + + friend flags operator|(flags x, flags y) + { + return static_cast( + static_cast(x) | static_cast(y)); + } + + friend flags operator^(flags x, flags y) + { + return static_cast( + static_cast(x) ^ static_cast(y)); + } + + friend flags operator~(flags x) + { + return static_cast(~static_cast(x)); + } + + friend flags& operator&=(flags& x, flags y) + { + x = x & y; + return x; + } + + friend flags& operator|=(flags& x, flags y) + { + x = x | y; + return x; + } + + friend flags& operator^=(flags& x, flags y) + { + x = x ^ y; + return x; + } +#endif + +protected: + /// Protected destructor to prevent deletion through this type. + ~resolver_base() + { + } +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_RESOLVER_BASE_HPP diff --git a/tools/sdk/include/asio/asio/ip/resolver_query_base.hpp b/tools/sdk/include/asio/asio/ip/resolver_query_base.hpp new file mode 100644 index 00000000..be368589 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/resolver_query_base.hpp @@ -0,0 +1,43 @@ +// +// ip/resolver_query_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_RESOLVER_QUERY_BASE_HPP +#define ASIO_IP_RESOLVER_QUERY_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/ip/resolver_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// The resolver_query_base class is used as a base for the +/// basic_resolver_query class templates to provide a common place to define +/// the flag constants. +class resolver_query_base : public resolver_base +{ +protected: + /// Protected destructor to prevent deletion through this type. + ~resolver_query_base() + { + } +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_RESOLVER_QUERY_BASE_HPP diff --git a/tools/sdk/include/asio/asio/ip/resolver_service.hpp b/tools/sdk/include/asio/asio/ip/resolver_service.hpp new file mode 100644 index 00000000..519d72db --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/resolver_service.hpp @@ -0,0 +1,200 @@ +// +// ip/resolver_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_RESOLVER_SERVICE_HPP +#define ASIO_IP_RESOLVER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/async_result.hpp" +#include "asio/error_code.hpp" +#include "asio/io_context.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/ip/basic_resolver_results.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/winrt_resolver_service.hpp" +#else +# include "asio/detail/resolver_service.hpp" +#endif + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Default service implementation for a resolver. +template +class resolver_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base< + resolver_service > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_context::id id; +#endif + + /// The protocol type. + typedef InternetProtocol protocol_type; + + /// The endpoint type. + typedef typename InternetProtocol::endpoint endpoint_type; + + /// The query type. + typedef basic_resolver_query query_type; + + /// The iterator type. + typedef basic_resolver_iterator iterator_type; + + /// The results type. + typedef basic_resolver_results results_type; + +private: + // The type of the platform-specific implementation. +#if defined(ASIO_WINDOWS_RUNTIME) + typedef asio::detail::winrt_resolver_service + service_impl_type; +#else + typedef asio::detail::resolver_service + service_impl_type; +#endif + +public: + /// The type of a resolver implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// Construct a new resolver service for the specified io_context. + explicit resolver_service(asio::io_context& io_context) + : asio::detail::service_base< + resolver_service >(io_context), + service_impl_(io_context) + { + } + + /// Construct a new resolver implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new resolver implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another resolver implementation. + void move_assign(implementation_type& impl, + resolver_service& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy a resolver implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Cancel pending asynchronous operations. + void cancel(implementation_type& impl) + { + service_impl_.cancel(impl); + } + + /// Resolve a query to a list of entries. + results_type resolve(implementation_type& impl, const query_type& query, + asio::error_code& ec) + { + return service_impl_.resolve(impl, query, ec); + } + + /// Asynchronously resolve a query to a list of entries. + template + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(implementation_type& impl, const query_type& query, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + asio::async_completion init(handler); + + service_impl_.async_resolve(impl, query, init.completion_handler); + + return init.result.get(); + } + + /// Resolve an endpoint to a list of entries. + results_type resolve(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + return service_impl_.resolve(impl, endpoint, ec); + } + + /// Asynchronously resolve an endpoint to a list of entries. + template + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(implementation_type& impl, const endpoint_type& endpoint, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + asio::async_completion init(handler); + + service_impl_.async_resolve(impl, endpoint, init.completion_handler); + + return init.result.get(); + } + +private: + // Destroy all user-defined handler objects owned by the service. + void shutdown() + { + service_impl_.shutdown(); + } + + // Perform any fork-related housekeeping. + void notify_fork(asio::io_context::fork_event event) + { + service_impl_.notify_fork(event); + } + + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_IP_RESOLVER_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/ip/tcp.hpp b/tools/sdk/include/asio/asio/ip/tcp.hpp new file mode 100644 index 00000000..f1adeb02 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/tcp.hpp @@ -0,0 +1,155 @@ +// +// ip/tcp.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_TCP_HPP +#define ASIO_IP_TCP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/basic_socket_acceptor.hpp" +#include "asio/basic_socket_iostream.hpp" +#include "asio/basic_stream_socket.hpp" +#include "asio/detail/socket_option.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/ip/basic_endpoint.hpp" +#include "asio/ip/basic_resolver.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Encapsulates the flags needed for TCP. +/** + * The asio::ip::tcp class contains flags necessary for TCP sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol, InternetProtocol. + */ +class tcp +{ +public: + /// The type of a TCP endpoint. + typedef basic_endpoint endpoint; + + /// Construct to represent the IPv4 TCP protocol. + static tcp v4() + { + return tcp(ASIO_OS_DEF(AF_INET)); + } + + /// Construct to represent the IPv6 TCP protocol. + static tcp v6() + { + return tcp(ASIO_OS_DEF(AF_INET6)); + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return ASIO_OS_DEF(SOCK_STREAM); + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return ASIO_OS_DEF(IPPROTO_TCP); + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// The TCP socket type. + typedef basic_stream_socket socket; + + /// The TCP acceptor type. + typedef basic_socket_acceptor acceptor; + + /// The TCP resolver type. + typedef basic_resolver resolver; + +#if !defined(ASIO_NO_IOSTREAM) + /// The TCP iostream type. + typedef basic_socket_iostream iostream; +#endif // !defined(ASIO_NO_IOSTREAM) + + /// Socket option for disabling the Nagle algorithm. + /** + * Implements the IPPROTO_TCP/TCP_NODELAY socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::tcp::no_delay option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::tcp::no_delay option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined no_delay; +#else + typedef asio::detail::socket_option::boolean< + ASIO_OS_DEF(IPPROTO_TCP), ASIO_OS_DEF(TCP_NODELAY)> no_delay; +#endif + + /// Compare two protocols for equality. + friend bool operator==(const tcp& p1, const tcp& p2) + { + return p1.family_ == p2.family_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const tcp& p1, const tcp& p2) + { + return p1.family_ != p2.family_; + } + +private: + // Construct with a specific family. + explicit tcp(int protocol_family) + : family_(protocol_family) + { + } + + int family_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_TCP_HPP diff --git a/tools/sdk/include/asio/asio/ip/udp.hpp b/tools/sdk/include/asio/asio/ip/udp.hpp new file mode 100644 index 00000000..1c93f9b0 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/udp.hpp @@ -0,0 +1,111 @@ +// +// ip/udp.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_UDP_HPP +#define ASIO_IP_UDP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/basic_datagram_socket.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/ip/basic_endpoint.hpp" +#include "asio/ip/basic_resolver.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Encapsulates the flags needed for UDP. +/** + * The asio::ip::udp 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 +{ +public: + /// The type of a UDP endpoint. + typedef basic_endpoint endpoint; + + /// Construct to represent the IPv4 UDP protocol. + static udp v4() + { + return udp(ASIO_OS_DEF(AF_INET)); + } + + /// Construct to represent the IPv6 UDP protocol. + static udp v6() + { + return udp(ASIO_OS_DEF(AF_INET6)); + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return ASIO_OS_DEF(SOCK_DGRAM); + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return 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 socket; + + /// The UDP resolver type. + typedef basic_resolver resolver; + + /// Compare two protocols for equality. + friend bool operator==(const udp& p1, const udp& p2) + { + return p1.family_ == p2.family_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const udp& p1, const udp& p2) + { + return p1.family_ != p2.family_; + } + +private: + // Construct with a specific family. + explicit udp(int protocol_family) + : family_(protocol_family) + { + } + + int family_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_UDP_HPP diff --git a/tools/sdk/include/asio/asio/ip/unicast.hpp b/tools/sdk/include/asio/asio/ip/unicast.hpp new file mode 100644 index 00000000..14e3e489 --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/unicast.hpp @@ -0,0 +1,70 @@ +// +// ip/unicast.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_UNICAST_HPP +#define ASIO_IP_UNICAST_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/ip/detail/socket_option.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { +namespace unicast { + +/// Socket option for time-to-live associated with outgoing unicast packets. +/** + * Implements the IPPROTO_IP/IP_UNICAST_TTL socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::unicast::hops option(4); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::unicast::hops option; + * socket.get_option(option); + * int ttl = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined hops; +#else +typedef asio::ip::detail::socket_option::unicast_hops< + ASIO_OS_DEF(IPPROTO_IP), + ASIO_OS_DEF(IP_TTL), + ASIO_OS_DEF(IPPROTO_IPV6), + ASIO_OS_DEF(IPV6_UNICAST_HOPS)> hops; +#endif + +} // namespace unicast +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_UNICAST_HPP diff --git a/tools/sdk/include/asio/asio/ip/v6_only.hpp b/tools/sdk/include/asio/asio/ip/v6_only.hpp new file mode 100644 index 00000000..ac7234ed --- /dev/null +++ b/tools/sdk/include/asio/asio/ip/v6_only.hpp @@ -0,0 +1,69 @@ +// +// ip/v6_only.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IP_V6_ONLY_HPP +#define ASIO_IP_V6_ONLY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/socket_option.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Socket option for determining whether an IPv6 socket supports IPv6 +/// communication only. +/** + * Implements the IPPROTO_IPV6/IP_V6ONLY socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::v6_only option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::v6_only option; + * socket.get_option(option); + * bool v6_only = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined v6_only; +#elif defined(IPV6_V6ONLY) +typedef asio::detail::socket_option::boolean< + IPPROTO_IPV6, IPV6_V6ONLY> v6_only; +#else +typedef asio::detail::socket_option::boolean< + asio::detail::custom_socket_option_level, + asio::detail::always_fail_option> v6_only; +#endif + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_V6_ONLY_HPP diff --git a/tools/sdk/include/asio/asio/is_executor.hpp b/tools/sdk/include/asio/asio/is_executor.hpp new file mode 100644 index 00000000..a1661ec4 --- /dev/null +++ b/tools/sdk/include/asio/asio/is_executor.hpp @@ -0,0 +1,46 @@ +// +// is_executor.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IS_EXECUTOR_HPP +#define ASIO_IS_EXECUTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/is_executor.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// The is_executor trait detects whether a type T meets the Executor type +/// requirements. +/** + * Class template @c is_executor is a UnaryTypeTrait that is derived from @c + * true_type if the type @c T meets the syntactic requirements for Executor, + * otherwise @c false_type. + */ +template +struct is_executor +#if defined(GENERATING_DOCUMENTATION) + : integral_constant +#else // defined(GENERATING_DOCUMENTATION) + : asio::detail::is_executor +#endif // defined(GENERATING_DOCUMENTATION) +{ +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IS_EXECUTOR_HPP diff --git a/tools/sdk/include/asio/asio/is_read_buffered.hpp b/tools/sdk/include/asio/asio/is_read_buffered.hpp new file mode 100644 index 00000000..c5a67b2d --- /dev/null +++ b/tools/sdk/include/asio/asio/is_read_buffered.hpp @@ -0,0 +1,59 @@ +// +// is_read_buffered.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IS_READ_BUFFERED_HPP +#define ASIO_IS_READ_BUFFERED_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/buffered_read_stream_fwd.hpp" +#include "asio/buffered_stream_fwd.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +namespace detail { + +template +char is_read_buffered_helper(buffered_stream* s); + +template +char is_read_buffered_helper(buffered_read_stream* s); + +struct is_read_buffered_big_type { char data[10]; }; +is_read_buffered_big_type is_read_buffered_helper(...); + +} // namespace detail + +/// The is_read_buffered class is a traits class that may be used to determine +/// whether a stream type supports buffering of read data. +template +class is_read_buffered +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The value member is true only if the Stream type supports buffering of + /// read data. + static const bool value; +#else + ASIO_STATIC_CONSTANT(bool, + value = sizeof(detail::is_read_buffered_helper((Stream*)0)) == 1); +#endif +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IS_READ_BUFFERED_HPP diff --git a/tools/sdk/include/asio/asio/is_write_buffered.hpp b/tools/sdk/include/asio/asio/is_write_buffered.hpp new file mode 100644 index 00000000..e237dd6f --- /dev/null +++ b/tools/sdk/include/asio/asio/is_write_buffered.hpp @@ -0,0 +1,59 @@ +// +// is_write_buffered.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_IS_WRITE_BUFFERED_HPP +#define ASIO_IS_WRITE_BUFFERED_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/buffered_stream_fwd.hpp" +#include "asio/buffered_write_stream_fwd.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +namespace detail { + +template +char is_write_buffered_helper(buffered_stream* s); + +template +char is_write_buffered_helper(buffered_write_stream* s); + +struct is_write_buffered_big_type { char data[10]; }; +is_write_buffered_big_type is_write_buffered_helper(...); + +} // namespace detail + +/// The is_write_buffered class is a traits class that may be used to determine +/// whether a stream type supports buffering of written data. +template +class is_write_buffered +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The value member is true only if the Stream type supports buffering of + /// written data. + static const bool value; +#else + ASIO_STATIC_CONSTANT(bool, + value = sizeof(detail::is_write_buffered_helper((Stream*)0)) == 1); +#endif +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IS_WRITE_BUFFERED_HPP diff --git a/tools/sdk/include/asio/asio/local/basic_endpoint.hpp b/tools/sdk/include/asio/asio/local/basic_endpoint.hpp new file mode 100644 index 00000000..94e470a4 --- /dev/null +++ b/tools/sdk/include/asio/asio/local/basic_endpoint.hpp @@ -0,0 +1,239 @@ +// +// local/basic_endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Derived from a public domain implementation written by Daniel Casimiro. +// +// 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 ASIO_LOCAL_BASIC_ENDPOINT_HPP +#define ASIO_LOCAL_BASIC_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_LOCAL_SOCKETS) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/local/detail/endpoint.hpp" + +#if !defined(ASIO_NO_IOSTREAM) +# include +#endif // !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace local { + +/// Describes an endpoint for a UNIX socket. +/** + * The asio::local::basic_endpoint class template describes an endpoint + * that may be associated with a particular UNIX socket. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * Endpoint. + */ +template +class basic_endpoint +{ +public: + /// The protocol type associated with the endpoint. + typedef Protocol protocol_type; + + /// The type of the endpoint structure. This type is dependent on the + /// underlying implementation of the socket layer. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined data_type; +#else + typedef asio::detail::socket_addr_type data_type; +#endif + + /// Default constructor. + basic_endpoint() + { + } + + /// Construct an endpoint using the specified path name. + basic_endpoint(const char* path_name) + : impl_(path_name) + { + } + + /// Construct an endpoint using the specified path name. + basic_endpoint(const std::string& path_name) + : impl_(path_name) + { + } + + /// Copy constructor. + basic_endpoint(const basic_endpoint& other) + : impl_(other.impl_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + basic_endpoint(basic_endpoint&& other) + : impl_(other.impl_) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from another endpoint. + basic_endpoint& operator=(const basic_endpoint& other) + { + impl_ = other.impl_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move-assign from another endpoint. + basic_endpoint& operator=(basic_endpoint&& other) + { + impl_ = other.impl_; + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// The protocol associated with the endpoint. + protocol_type protocol() const + { + return protocol_type(); + } + + /// Get the underlying endpoint in the native type. + data_type* data() + { + return impl_.data(); + } + + /// Get the underlying endpoint in the native type. + const data_type* data() const + { + return impl_.data(); + } + + /// Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + return impl_.size(); + } + + /// Set the underlying size of the endpoint in the native type. + void resize(std::size_t new_size) + { + impl_.resize(new_size); + } + + /// Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return impl_.capacity(); + } + + /// Get the path associated with the endpoint. + std::string path() const + { + return impl_.path(); + } + + /// Set the path associated with the endpoint. + void path(const char* p) + { + impl_.path(p); + } + + /// Set the path associated with the endpoint. + void path(const std::string& p) + { + impl_.path(p); + } + + /// Compare two endpoints for equality. + friend bool operator==(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e1.impl_ == e2.impl_; + } + + /// Compare two endpoints for inequality. + friend bool operator!=(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return !(e1.impl_ == e2.impl_); + } + + /// Compare endpoints for ordering. + friend bool operator<(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e1.impl_ < e2.impl_; + } + + /// Compare endpoints for ordering. + friend bool operator>(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e2.impl_ < e1.impl_; + } + + /// Compare endpoints for ordering. + friend bool operator<=(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return !(e2 < e1); + } + + /// Compare endpoints for ordering. + friend bool operator>=(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return !(e1 < e2); + } + +private: + // The underlying UNIX domain endpoint. + asio::local::detail::endpoint impl_; +}; + +/// Output an endpoint as a string. +/** + * Used to output a human-readable string for a specified endpoint. + * + * @param os The output stream to which the string will be written. + * + * @param endpoint The endpoint to be written. + * + * @return The output stream. + * + * @relates asio::local::basic_endpoint + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const basic_endpoint& endpoint) +{ + os << endpoint.path(); + return os; +} + +} // namespace local +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_LOCAL_SOCKETS) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_LOCAL_BASIC_ENDPOINT_HPP diff --git a/tools/sdk/include/asio/asio/local/connect_pair.hpp b/tools/sdk/include/asio/asio/local/connect_pair.hpp new file mode 100644 index 00000000..2f7c090e --- /dev/null +++ b/tools/sdk/include/asio/asio/local/connect_pair.hpp @@ -0,0 +1,106 @@ +// +// local/connect_pair.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_LOCAL_CONNECT_PAIR_HPP +#define ASIO_LOCAL_CONNECT_PAIR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_LOCAL_SOCKETS) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/basic_socket.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/local/basic_endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace local { + +/// Create a pair of connected sockets. +template +void connect_pair( + basic_socket& socket1, + basic_socket& socket2); + +/// Create a pair of connected sockets. +template +ASIO_SYNC_OP_VOID connect_pair( + basic_socket& socket1, + basic_socket& socket2, + asio::error_code& ec); + +template +inline void connect_pair( + basic_socket& socket1, + basic_socket& socket2) +{ + asio::error_code ec; + connect_pair(socket1, socket2, ec); + asio::detail::throw_error(ec, "connect_pair"); +} + +template +inline ASIO_SYNC_OP_VOID connect_pair( + basic_socket& socket1, + basic_socket& socket2, + asio::error_code& ec) +{ + // Check that this function is only being used with a UNIX domain socket. + asio::local::basic_endpoint* tmp + = static_cast(0); + (void)tmp; + + Protocol protocol; + asio::detail::socket_type sv[2]; + if (asio::detail::socket_ops::socketpair(protocol.family(), + protocol.type(), protocol.protocol(), sv, ec) + == asio::detail::socket_error_retval) + ASIO_SYNC_OP_VOID_RETURN(ec); + + socket1.assign(protocol, sv[0], ec); + if (ec) + { + asio::error_code temp_ec; + asio::detail::socket_ops::state_type state[2] = { 0, 0 }; + asio::detail::socket_ops::close(sv[0], state[0], true, temp_ec); + asio::detail::socket_ops::close(sv[1], state[1], true, temp_ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + socket2.assign(protocol, sv[1], ec); + if (ec) + { + asio::error_code temp_ec; + socket1.close(temp_ec); + asio::detail::socket_ops::state_type state = 0; + asio::detail::socket_ops::close(sv[1], state, true, temp_ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + ASIO_SYNC_OP_VOID_RETURN(ec); +} + +} // namespace local +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_LOCAL_SOCKETS) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_LOCAL_CONNECT_PAIR_HPP diff --git a/tools/sdk/include/asio/asio/local/datagram_protocol.hpp b/tools/sdk/include/asio/asio/local/datagram_protocol.hpp new file mode 100644 index 00000000..b87df2e5 --- /dev/null +++ b/tools/sdk/include/asio/asio/local/datagram_protocol.hpp @@ -0,0 +1,80 @@ +// +// local/datagram_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_LOCAL_DATAGRAM_PROTOCOL_HPP +#define ASIO_LOCAL_DATAGRAM_PROTOCOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_LOCAL_SOCKETS) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/basic_datagram_socket.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/local/basic_endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace local { + +/// Encapsulates the flags needed for datagram-oriented UNIX sockets. +/** + * The asio::local::datagram_protocol class contains flags necessary for + * datagram-oriented UNIX domain sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol. + */ +class datagram_protocol +{ +public: + /// Obtain an identifier for the type of the protocol. + int type() const + { + return SOCK_DGRAM; + } + + /// 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_datagram_socket socket; +}; + +} // namespace local +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_LOCAL_SOCKETS) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_LOCAL_DATAGRAM_PROTOCOL_HPP diff --git a/tools/sdk/include/asio/asio/local/detail/endpoint.hpp b/tools/sdk/include/asio/asio/local/detail/endpoint.hpp new file mode 100644 index 00000000..4870f3b9 --- /dev/null +++ b/tools/sdk/include/asio/asio/local/detail/endpoint.hpp @@ -0,0 +1,133 @@ +// +// local/detail/endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Derived from a public domain implementation written by Daniel Casimiro. +// +// 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 ASIO_LOCAL_DETAIL_ENDPOINT_HPP +#define ASIO_LOCAL_DETAIL_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_LOCAL_SOCKETS) + +#include +#include +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace local { +namespace detail { + +// Helper class for implementing a UNIX domain endpoint. +class endpoint +{ +public: + // Default constructor. + ASIO_DECL endpoint(); + + // Construct an endpoint using the specified path name. + ASIO_DECL endpoint(const char* path_name); + + // Construct an endpoint using the specified path name. + ASIO_DECL endpoint(const std::string& path_name); + + // Copy constructor. + endpoint(const endpoint& other) + : data_(other.data_), + path_length_(other.path_length_) + { + } + + // Assign from another endpoint. + endpoint& operator=(const endpoint& other) + { + data_ = other.data_; + path_length_ = other.path_length_; + return *this; + } + + // Get the underlying endpoint in the native type. + asio::detail::socket_addr_type* data() + { + return &data_.base; + } + + // Get the underlying endpoint in the native type. + const asio::detail::socket_addr_type* data() const + { + return &data_.base; + } + + // Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + return path_length_ + + offsetof(asio::detail::sockaddr_un_type, sun_path); + } + + // Set the underlying size of the endpoint in the native type. + ASIO_DECL void resize(std::size_t size); + + // Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return sizeof(asio::detail::sockaddr_un_type); + } + + // Get the path associated with the endpoint. + ASIO_DECL std::string path() const; + + // Set the path associated with the endpoint. + ASIO_DECL void path(const char* p); + + // Set the path associated with the endpoint. + ASIO_DECL void path(const std::string& p); + + // Compare two endpoints for equality. + ASIO_DECL friend bool operator==( + const endpoint& e1, const endpoint& e2); + + // Compare endpoints for ordering. + ASIO_DECL friend bool operator<( + const endpoint& e1, const endpoint& e2); + +private: + // The underlying UNIX socket address. + union data_union + { + asio::detail::socket_addr_type base; + asio::detail::sockaddr_un_type local; + } data_; + + // The length of the path associated with the endpoint. + std::size_t path_length_; + + // Initialise with a specified path. + ASIO_DECL void init(const char* path, std::size_t path_length); +}; + +} // namespace detail +} // namespace local +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/local/detail/impl/endpoint.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_LOCAL_SOCKETS) + +#endif // ASIO_LOCAL_DETAIL_ENDPOINT_HPP diff --git a/tools/sdk/include/asio/asio/local/stream_protocol.hpp b/tools/sdk/include/asio/asio/local/stream_protocol.hpp new file mode 100644 index 00000000..e2ef5f3b --- /dev/null +++ b/tools/sdk/include/asio/asio/local/stream_protocol.hpp @@ -0,0 +1,90 @@ +// +// local/stream_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_LOCAL_STREAM_PROTOCOL_HPP +#define ASIO_LOCAL_STREAM_PROTOCOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_LOCAL_SOCKETS) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/basic_socket_acceptor.hpp" +#include "asio/basic_socket_iostream.hpp" +#include "asio/basic_stream_socket.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/local/basic_endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace local { + +/// Encapsulates the flags needed for stream-oriented UNIX sockets. +/** + * The 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 +{ +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 socket; + + /// The UNIX domain acceptor type. + typedef basic_socket_acceptor acceptor; + +#if !defined(ASIO_NO_IOSTREAM) + /// The UNIX domain iostream type. + typedef basic_socket_iostream iostream; +#endif // !defined(ASIO_NO_IOSTREAM) +}; + +} // namespace local +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_LOCAL_SOCKETS) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_LOCAL_STREAM_PROTOCOL_HPP diff --git a/tools/sdk/include/asio/asio/packaged_task.hpp b/tools/sdk/include/asio/asio/packaged_task.hpp new file mode 100644 index 00000000..1e20b42e --- /dev/null +++ b/tools/sdk/include/asio/asio/packaged_task.hpp @@ -0,0 +1,126 @@ +// +// packaged_task.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_PACKAGED_TASK_HPP +#define ASIO_PACKAGED_TASK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_STD_FUTURE) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/async_result.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/detail/variadic_templates.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \ + || defined(GENERATING_DOCUMENTATION) + +/// Partial specialisation of @c async_result for @c std::packaged_task. +template +class async_result, Signature> +{ +public: + /// The packaged task is the concrete completion handler type. + typedef std::packaged_task completion_handler_type; + + /// The return type of the initiating function is the future obtained from + /// the packaged task. + typedef std::future return_type; + + /// The constructor extracts the future from the packaged task. + explicit async_result(completion_handler_type& h) + : future_(h.get_future()) + { + } + + /// Returns the packaged task's future. + return_type get() + { + return std::move(future_); + } + +private: + return_type future_; +}; + +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + // || defined(GENERATING_DOCUMENTATION) + +template +struct async_result, Signature> +{ + typedef std::packaged_task completion_handler_type; + typedef std::future return_type; + + explicit async_result(completion_handler_type& h) + : future_(h.get_future()) + { + } + + return_type get() + { + return std::move(future_); + } + +private: + return_type future_; +}; + +#define ASIO_PRIVATE_ASYNC_RESULT_DEF(n) \ + template \ + class async_result< \ + std::packaged_task, Signature> \ + { \ + public: \ + typedef std::packaged_task< \ + Result(ASIO_VARIADIC_TARGS(n))> \ + completion_handler_type; \ + \ + typedef std::future return_type; \ + \ + explicit async_result(completion_handler_type& h) \ + : future_(h.get_future()) \ + { \ + } \ + \ + return_type get() \ + { \ + return std::move(future_); \ + } \ + \ + private: \ + return_type future_; \ + }; \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_RESULT_DEF) +#undef ASIO_PRIVATE_ASYNC_RESULT_DEF + +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) + // || defined(GENERATING_DOCUMENTATION) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_STD_FUTURE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_PACKAGED_TASK_HPP diff --git a/tools/sdk/include/asio/asio/placeholders.hpp b/tools/sdk/include/asio/asio/placeholders.hpp new file mode 100644 index 00000000..e71a21e7 --- /dev/null +++ b/tools/sdk/include/asio/asio/placeholders.hpp @@ -0,0 +1,151 @@ +// +// placeholders.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_PLACEHOLDERS_HPP +#define ASIO_PLACEHOLDERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_BOOST_BIND) +# include +#endif // defined(ASIO_HAS_BOOST_BIND) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace placeholders { + +#if defined(GENERATING_DOCUMENTATION) + +/// An argument placeholder, for use with boost::bind(), that corresponds to +/// the error argument of a handler for any of the asynchronous functions. +unspecified error; + +/// An argument placeholder, for use with boost::bind(), that corresponds to +/// the bytes_transferred argument of a handler for asynchronous functions such +/// as asio::basic_stream_socket::async_write_some or +/// asio::async_write. +unspecified bytes_transferred; + +/// An argument placeholder, for use with boost::bind(), that corresponds to +/// the iterator argument of a handler for asynchronous functions such as +/// asio::async_connect. +unspecified iterator; + +/// An argument placeholder, for use with boost::bind(), that corresponds to +/// the results argument of a handler for asynchronous functions such as +/// asio::basic_resolver::async_resolve. +unspecified results; + +/// An argument placeholder, for use with boost::bind(), that corresponds to +/// the results argument of a handler for asynchronous functions such as +/// asio::async_connect. +unspecified endpoint; + +/// An argument placeholder, for use with boost::bind(), that corresponds to +/// the signal_number argument of a handler for asynchronous functions such as +/// asio::signal_set::async_wait. +unspecified signal_number; + +#elif defined(ASIO_HAS_BOOST_BIND) +# if defined(__BORLANDC__) || defined(__GNUC__) + +inline boost::arg<1> error() +{ + return boost::arg<1>(); +} + +inline boost::arg<2> bytes_transferred() +{ + return boost::arg<2>(); +} + +inline boost::arg<2> iterator() +{ + return boost::arg<2>(); +} + +inline boost::arg<2> results() +{ + return boost::arg<2>(); +} + +inline boost::arg<2> endpoint() +{ + return boost::arg<2>(); +} + +inline boost::arg<2> signal_number() +{ + return boost::arg<2>(); +} + +# else + +namespace detail +{ + template + struct placeholder + { + static boost::arg& get() + { + static boost::arg result; + return result; + } + }; +} + +# if defined(ASIO_MSVC) && (ASIO_MSVC < 1400) + +static boost::arg<1>& error + = asio::placeholders::detail::placeholder<1>::get(); +static boost::arg<2>& bytes_transferred + = asio::placeholders::detail::placeholder<2>::get(); +static boost::arg<2>& iterator + = asio::placeholders::detail::placeholder<2>::get(); +static boost::arg<2>& results + = asio::placeholders::detail::placeholder<2>::get(); +static boost::arg<2>& endpoint + = asio::placeholders::detail::placeholder<2>::get(); +static boost::arg<2>& signal_number + = asio::placeholders::detail::placeholder<2>::get(); + +# else + +namespace +{ + boost::arg<1>& error + = asio::placeholders::detail::placeholder<1>::get(); + boost::arg<2>& bytes_transferred + = asio::placeholders::detail::placeholder<2>::get(); + boost::arg<2>& iterator + = asio::placeholders::detail::placeholder<2>::get(); + boost::arg<2>& results + = asio::placeholders::detail::placeholder<2>::get(); + boost::arg<2>& endpoint + = asio::placeholders::detail::placeholder<2>::get(); + boost::arg<2>& signal_number + = asio::placeholders::detail::placeholder<2>::get(); +} // namespace + +# endif +# endif +#endif + +} // namespace placeholders +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_PLACEHOLDERS_HPP diff --git a/tools/sdk/include/asio/asio/posix/basic_descriptor.hpp b/tools/sdk/include/asio/asio/posix/basic_descriptor.hpp new file mode 100644 index 00000000..c15da632 --- /dev/null +++ b/tools/sdk/include/asio/asio/posix/basic_descriptor.hpp @@ -0,0 +1,582 @@ +// +// posix/basic_descriptor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_POSIX_BASIC_DESCRIPTOR_HPP +#define ASIO_POSIX_BASIC_DESCRIPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/basic_io_object.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/posix/descriptor_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace posix { + +/// Provides POSIX descriptor functionality. +/** + * The posix::basic_descriptor class template provides the ability to wrap a + * POSIX descriptor. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_descriptor + : public basic_io_object, + public descriptor_base +{ +public: + /// The native representation of a descriptor. + typedef typename DescriptorService::native_handle_type native_handle_type; + + /// A basic_descriptor is always the lowest layer. + typedef basic_descriptor lowest_layer_type; + + /// Construct a basic_descriptor without opening it. + /** + * This constructor creates a descriptor without opening it. + * + * @param io_context The io_context object that the descriptor will use to + * dispatch handlers for any asynchronous operations performed on the + * descriptor. + */ + explicit basic_descriptor(asio::io_context& io_context) + : basic_io_object(io_context) + { + } + + /// Construct a basic_descriptor on an existing native descriptor. + /** + * This constructor creates a descriptor object to hold an existing native + * descriptor. + * + * @param io_context The io_context object that the descriptor will use to + * dispatch handlers for any asynchronous operations performed on the + * descriptor. + * + * @param native_descriptor A native descriptor. + * + * @throws asio::system_error Thrown on failure. + */ + basic_descriptor(asio::io_context& io_context, + const native_handle_type& native_descriptor) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), + native_descriptor, ec); + asio::detail::throw_error(ec, "assign"); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_descriptor from another. + /** + * This constructor moves a descriptor from one object to another. + * + * @param other The other basic_descriptor 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_descriptor(io_context&) constructor. + */ + basic_descriptor(basic_descriptor&& other) + : basic_io_object( + ASIO_MOVE_CAST(basic_descriptor)(other)) + { + } + + /// Move-assign a basic_descriptor from another. + /** + * This assignment operator moves a descriptor from one object to another. + * + * @param other The other basic_descriptor 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_descriptor(io_context&) constructor. + */ + basic_descriptor& operator=(basic_descriptor&& other) + { + basic_io_object::operator=( + ASIO_MOVE_CAST(basic_descriptor)(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since a basic_descriptor 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_descriptor 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; + } + + /// Assign an existing native descriptor to the descriptor. + /* + * This function opens the descriptor to hold an existing native descriptor. + * + * @param native_descriptor A native descriptor. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const native_handle_type& native_descriptor) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), + native_descriptor, ec); + asio::detail::throw_error(ec, "assign"); + } + + /// Assign an existing native descriptor to the descriptor. + /* + * This function opens the descriptor to hold an existing native descriptor. + * + * @param native_descriptor A native descriptor. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID assign(const native_handle_type& native_descriptor, + asio::error_code& ec) + { + this->get_service().assign( + this->get_implementation(), native_descriptor, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the descriptor is open. + bool is_open() const + { + return this->get_service().is_open(this->get_implementation()); + } + + /// Close the descriptor. + /** + * This function is used to close the descriptor. Any asynchronous read or + * write operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. Note that, even if + * the function indicates an error, the underlying descriptor is closed. + */ + void close() + { + asio::error_code ec; + this->get_service().close(this->get_implementation(), ec); + asio::detail::throw_error(ec, "close"); + } + + /// Close the descriptor. + /** + * This function is used to close the descriptor. Any asynchronous read or + * write operations will be cancelled immediately, and will complete with the + * 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. + */ + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + this->get_service().close(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native descriptor representation. + /** + * This function may be used to obtain the underlying representation of the + * descriptor. This is intended to allow access to native descriptor + * functionality that is not otherwise provided. + */ + native_handle_type native_handle() + { + return this->get_service().native_handle(this->get_implementation()); + } + + /// Release ownership of the native descriptor implementation. + /** + * This function may be used to obtain the underlying representation of the + * descriptor. After calling this function, @c is_open() returns false. The + * caller is responsible for closing the descriptor. + * + * All outstanding asynchronous read or write operations will finish + * immediately, and the handlers for cancelled operations will be passed the + * asio::error::operation_aborted error. + */ + native_handle_type release() + { + return this->get_service().release(this->get_implementation()); + } + + /// Cancel all asynchronous operations associated with the descriptor. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel"); + } + + /// Cancel all asynchronous operations associated with the descriptor. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) + { + this->get_service().cancel(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Perform an IO control command on the descriptor. + /** + * This function is used to execute an IO control command on the descriptor. + * + * @param command The IO control command to be performed on the descriptor. + * + * @throws asio::system_error Thrown on failure. + * + * @sa IoControlCommand @n + * asio::posix::descriptor_base::bytes_readable @n + * asio::posix::descriptor_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * asio::posix::stream_descriptor descriptor(io_context); + * ... + * asio::posix::stream_descriptor::bytes_readable command; + * descriptor.io_control(command); + * std::size_t bytes_readable = command.get(); + * @endcode + */ + template + void io_control(IoControlCommand& command) + { + asio::error_code ec; + this->get_service().io_control(this->get_implementation(), command, ec); + asio::detail::throw_error(ec, "io_control"); + } + + /// Perform an IO control command on the descriptor. + /** + * This function is used to execute an IO control command on the descriptor. + * + * @param command The IO control command to be performed on the descriptor. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa IoControlCommand @n + * asio::posix::descriptor_base::bytes_readable @n + * asio::posix::descriptor_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * asio::posix::stream_descriptor descriptor(io_context); + * ... + * asio::posix::stream_descriptor::bytes_readable command; + * asio::error_code ec; + * descriptor.io_control(command, ec); + * if (ec) + * { + * // An error occurred. + * } + * std::size_t bytes_readable = command.get(); + * @endcode + */ + template + ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, + asio::error_code& ec) + { + this->get_service().io_control(this->get_implementation(), command, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Gets the non-blocking mode of the descriptor. + /** + * @returns @c true if the descriptor's synchronous operations will fail with + * 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 + * asio::error::would_block. + */ + bool non_blocking() const + { + return this->get_service().non_blocking(this->get_implementation()); + } + + /// Sets the non-blocking mode of the descriptor. + /** + * @param mode If @c true, the descriptor's synchronous operations will fail + * with asio::error::would_block if they are unable to perform the + * requested operation immediately. If @c false, synchronous operations will + * block until complete. + * + * @throws asio::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 + * asio::error::would_block. + */ + void non_blocking(bool mode) + { + asio::error_code ec; + this->get_service().non_blocking(this->get_implementation(), mode, ec); + asio::detail::throw_error(ec, "non_blocking"); + } + + /// Sets the non-blocking mode of the descriptor. + /** + * @param mode If @c true, the descriptor's synchronous operations will fail + * with 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 + * asio::error::would_block. + */ + ASIO_SYNC_OP_VOID non_blocking( + bool mode, asio::error_code& ec) + { + this->get_service().non_blocking(this->get_implementation(), mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Gets the non-blocking mode of the native descriptor implementation. + /** + * This function is used to retrieve the non-blocking mode of the underlying + * native descriptor. This mode has no effect on the behaviour of the + * descriptor object's synchronous operations. + * + * @returns @c true if the underlying descriptor is in non-blocking mode and + * direct system calls may fail with asio::error::would_block (or the + * equivalent system error). + * + * @note The current non-blocking mode is cached by the descriptor object. + * Consequently, the return value may be incorrect if the non-blocking mode + * was set directly on the native descriptor. + */ + bool native_non_blocking() const + { + return this->get_service().native_non_blocking( + this->get_implementation()); + } + + /// Sets the non-blocking mode of the native descriptor implementation. + /** + * This function is used to modify the non-blocking mode of the underlying + * native descriptor. It has no effect on the behaviour of the descriptor + * object's synchronous operations. + * + * @param mode If @c true, the underlying descriptor is put into non-blocking + * mode and direct system calls may fail with asio::error::would_block + * (or the equivalent system error). + * + * @throws asio::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 asio::error::invalid_argument, as the + * combination does not make sense. + */ + void native_non_blocking(bool mode) + { + asio::error_code ec; + this->get_service().native_non_blocking( + this->get_implementation(), mode, ec); + asio::detail::throw_error(ec, "native_non_blocking"); + } + + /// Sets the non-blocking mode of the native descriptor implementation. + /** + * This function is used to modify the non-blocking mode of the underlying + * native descriptor. It has no effect on the behaviour of the descriptor + * object's synchronous operations. + * + * @param mode If @c true, the underlying descriptor is put into non-blocking + * mode and direct system calls may fail with 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 asio::error::invalid_argument, as the + * combination does not make sense. + */ + ASIO_SYNC_OP_VOID native_non_blocking( + bool mode, asio::error_code& ec) + { + this->get_service().native_non_blocking( + this->get_implementation(), mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Wait for the descriptor 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 descriptor to enter + * a ready to read, write or error condition state. + * + * @param w Specifies the desired descriptor state. + * + * @par Example + * Waiting for a descriptor to become readable. + * @code + * asio::posix::stream_descriptor descriptor(io_context); + * ... + * descriptor.wait(asio::posix::stream_descriptor::wait_read); + * @endcode + */ + void wait(wait_type w) + { + asio::error_code ec; + this->get_service().wait(this->get_implementation(), w, ec); + asio::detail::throw_error(ec, "wait"); + } + + /// Wait for the descriptor 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 descriptor to enter + * a ready to read, write or error condition state. + * + * @param w Specifies the desired descriptor state. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * Waiting for a descriptor to become readable. + * @code + * asio::posix::stream_descriptor descriptor(io_context); + * ... + * asio::error_code ec; + * descriptor.wait(asio::posix::stream_descriptor::wait_read, ec); + * @endcode + */ + ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec) + { + this->get_service().wait(this->get_implementation(), w, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Asynchronously wait for the descriptor 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 descriptor to + * enter a ready to read, write or error condition state. + * + * @param w Specifies the desired descriptor 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 asio::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 + * asio::io_context::post(). + * + * @par Example + * @code + * void wait_handler(const asio::error_code& error) + * { + * if (!error) + * { + * // Wait succeeded. + * } + * } + * + * ... + * + * asio::posix::stream_descriptor descriptor(io_context); + * ... + * descriptor.async_wait( + * asio::posix::stream_descriptor::wait_read, + * wait_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(wait_type w, 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. + ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; + + return this->get_service().async_wait(this->get_implementation(), + w, ASIO_MOVE_CAST(WaitHandler)(handler)); + } + +protected: + /// Protected destructor to prevent deletion through this type. + ~basic_descriptor() + { + } +}; + +} // namespace posix +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_POSIX_BASIC_DESCRIPTOR_HPP diff --git a/tools/sdk/include/asio/asio/posix/basic_stream_descriptor.hpp b/tools/sdk/include/asio/asio/posix/basic_stream_descriptor.hpp new file mode 100644 index 00000000..acd5cb6a --- /dev/null +++ b/tools/sdk/include/asio/asio/posix/basic_stream_descriptor.hpp @@ -0,0 +1,362 @@ +// +// posix/basic_stream_descriptor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP +#define ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/posix/basic_descriptor.hpp" +#include "asio/posix/stream_descriptor_service.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace posix { + +/// Provides stream-oriented descriptor functionality. +/** + * The posix::basic_stream_descriptor class template provides asynchronous and + * blocking stream-oriented descriptor 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_descriptor + : public basic_descriptor +{ +public: + /// The native representation of a descriptor. + typedef typename StreamDescriptorService::native_handle_type + native_handle_type; + + /// Construct a basic_stream_descriptor without opening it. + /** + * This constructor creates a stream descriptor without opening it. The + * descriptor 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 descriptor will + * use to dispatch handlers for any asynchronous operations performed on the + * descriptor. + */ + explicit basic_stream_descriptor(asio::io_context& io_context) + : basic_descriptor(io_context) + { + } + + /// Construct a basic_stream_descriptor on an existing native descriptor. + /** + * This constructor creates a stream descriptor object to hold an existing + * native descriptor. + * + * @param io_context The io_context object that the stream descriptor will + * use to dispatch handlers for any asynchronous operations performed on the + * descriptor. + * + * @param native_descriptor The new underlying descriptor implementation. + * + * @throws asio::system_error Thrown on failure. + */ + basic_stream_descriptor(asio::io_context& io_context, + const native_handle_type& native_descriptor) + : basic_descriptor(io_context, native_descriptor) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_stream_descriptor from another. + /** + * This constructor moves a stream descriptor from one object to another. + * + * @param other The other basic_stream_descriptor 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_descriptor(io_context&) constructor. + */ + basic_stream_descriptor(basic_stream_descriptor&& other) + : basic_descriptor( + ASIO_MOVE_CAST(basic_stream_descriptor)(other)) + { + } + + /// Move-assign a basic_stream_descriptor from another. + /** + * This assignment operator moves a stream descriptor from one object to + * another. + * + * @param other The other basic_stream_descriptor 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_descriptor(io_context&) constructor. + */ + basic_stream_descriptor& operator=(basic_stream_descriptor&& other) + { + basic_descriptor::operator=( + ASIO_MOVE_CAST(basic_stream_descriptor)(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Write some data to the descriptor. + /** + * This function is used to write data to the stream descriptor. 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 descriptor. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * 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 + * descriptor.write_some(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) + { + asio::error_code ec; + std::size_t s = this->get_service().write_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "write_some"); + return s; + } + + /// Write some data to the descriptor. + /** + * This function is used to write data to the stream descriptor. 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 descriptor. + * + * @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, + asio::error_code& ec) + { + return this->get_service().write_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write data to the stream + * descriptor. The function call always returns immediately. + * + * @param buffers One or more data buffers to be written to the descriptor. + * 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 asio::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 + * 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 + * descriptor.async_write_some(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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + return this->get_service().async_write_some(this->get_implementation(), + buffers, ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Read some data from the descriptor. + /** + * This function is used to read data from the stream descriptor. 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 asio::system_error Thrown on failure. An error code of + * 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 + * descriptor.read_some(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) + { + asio::error_code ec; + std::size_t s = this->get_service().read_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "read_some"); + return s; + } + + /// Read some data from the descriptor. + /** + * This function is used to read data from the stream descriptor. 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, + asio::error_code& ec) + { + return this->get_service().read_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read data from the stream + * descriptor. 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 asio::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 + * 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 + * descriptor.async_read_some(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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + return this->get_service().async_read_some(this->get_implementation(), + buffers, ASIO_MOVE_CAST(ReadHandler)(handler)); + } +}; + +} // namespace posix +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP diff --git a/tools/sdk/include/asio/asio/posix/descriptor.hpp b/tools/sdk/include/asio/asio/posix/descriptor.hpp new file mode 100644 index 00000000..d0cee1a2 --- /dev/null +++ b/tools/sdk/include/asio/asio/posix/descriptor.hpp @@ -0,0 +1,644 @@ +// +// posix/descriptor.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_POSIX_DESCRIPTOR_HPP +#define ASIO_POSIX_DESCRIPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/async_result.hpp" +#include "asio/basic_io_object.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/reactive_descriptor_service.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/posix/descriptor_base.hpp" + +#if defined(ASIO_HAS_MOVE) +# include +#endif // defined(ASIO_HAS_MOVE) + +#define ASIO_SVC_T asio::detail::reactive_descriptor_service + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace posix { + +/// Provides POSIX descriptor functionality. +/** + * The posix::descriptor class template provides the ability to wrap a + * POSIX descriptor. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class descriptor + : ASIO_SVC_ACCESS basic_io_object, + public descriptor_base +{ +public: + /// The type of the executor associated with the object. + typedef io_context::executor_type executor_type; + + /// The native representation of a descriptor. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef ASIO_SVC_T::native_handle_type native_handle_type; +#endif + + /// A descriptor is always the lowest layer. + typedef descriptor lowest_layer_type; + + /// Construct a descriptor without opening it. + /** + * This constructor creates a descriptor without opening it. + * + * @param io_context The io_context object that the descriptor will use to + * dispatch handlers for any asynchronous operations performed on the + * descriptor. + */ + explicit descriptor(asio::io_context& io_context) + : basic_io_object(io_context) + { + } + + /// Construct a descriptor on an existing native descriptor. + /** + * This constructor creates a descriptor object to hold an existing native + * descriptor. + * + * @param io_context The io_context object that the descriptor will use to + * dispatch handlers for any asynchronous operations performed on the + * descriptor. + * + * @param native_descriptor A native descriptor. + * + * @throws asio::system_error Thrown on failure. + */ + descriptor(asio::io_context& io_context, + const native_handle_type& native_descriptor) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), + native_descriptor, ec); + asio::detail::throw_error(ec, "assign"); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a descriptor from another. + /** + * This constructor moves a descriptor from one object to another. + * + * @param other The other descriptor 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 descriptor(io_context&) constructor. + */ + descriptor(descriptor&& other) + : basic_io_object(std::move(other)) + { + } + + /// Move-assign a descriptor from another. + /** + * This assignment operator moves a descriptor from one object to another. + * + * @param other The other descriptor 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 descriptor(io_context&) constructor. + */ + descriptor& operator=(descriptor&& other) + { + basic_io_object::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + +#if !defined(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. + */ + 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. + */ + asio::io_context& get_io_service() + { + return basic_io_object::get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return basic_io_object::get_executor(); + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since a descriptor 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 descriptor 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; + } + + /// Assign an existing native descriptor to the descriptor. + /* + * This function opens the descriptor to hold an existing native descriptor. + * + * @param native_descriptor A native descriptor. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const native_handle_type& native_descriptor) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), + native_descriptor, ec); + asio::detail::throw_error(ec, "assign"); + } + + /// Assign an existing native descriptor to the descriptor. + /* + * This function opens the descriptor to hold an existing native descriptor. + * + * @param native_descriptor A native descriptor. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID assign(const native_handle_type& native_descriptor, + asio::error_code& ec) + { + this->get_service().assign( + this->get_implementation(), native_descriptor, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the descriptor is open. + bool is_open() const + { + return this->get_service().is_open(this->get_implementation()); + } + + /// Close the descriptor. + /** + * This function is used to close the descriptor. Any asynchronous read or + * write operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. Note that, even if + * the function indicates an error, the underlying descriptor is closed. + */ + void close() + { + asio::error_code ec; + this->get_service().close(this->get_implementation(), ec); + asio::detail::throw_error(ec, "close"); + } + + /// Close the descriptor. + /** + * This function is used to close the descriptor. Any asynchronous read or + * write operations will be cancelled immediately, and will complete with the + * 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. + */ + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + this->get_service().close(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native descriptor representation. + /** + * This function may be used to obtain the underlying representation of the + * descriptor. This is intended to allow access to native descriptor + * functionality that is not otherwise provided. + */ + native_handle_type native_handle() + { + return this->get_service().native_handle(this->get_implementation()); + } + + /// Release ownership of the native descriptor implementation. + /** + * This function may be used to obtain the underlying representation of the + * descriptor. After calling this function, @c is_open() returns false. The + * caller is responsible for closing the descriptor. + * + * All outstanding asynchronous read or write operations will finish + * immediately, and the handlers for cancelled operations will be passed the + * asio::error::operation_aborted error. + */ + native_handle_type release() + { + return this->get_service().release(this->get_implementation()); + } + + /// Cancel all asynchronous operations associated with the descriptor. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel"); + } + + /// Cancel all asynchronous operations associated with the descriptor. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) + { + this->get_service().cancel(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Perform an IO control command on the descriptor. + /** + * This function is used to execute an IO control command on the descriptor. + * + * @param command The IO control command to be performed on the descriptor. + * + * @throws asio::system_error Thrown on failure. + * + * @sa IoControlCommand @n + * asio::posix::descriptor_base::bytes_readable @n + * asio::posix::descriptor_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * asio::posix::stream_descriptor descriptor(io_context); + * ... + * asio::posix::stream_descriptor::bytes_readable command; + * descriptor.io_control(command); + * std::size_t bytes_readable = command.get(); + * @endcode + */ + template + void io_control(IoControlCommand& command) + { + asio::error_code ec; + this->get_service().io_control(this->get_implementation(), command, ec); + asio::detail::throw_error(ec, "io_control"); + } + + /// Perform an IO control command on the descriptor. + /** + * This function is used to execute an IO control command on the descriptor. + * + * @param command The IO control command to be performed on the descriptor. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa IoControlCommand @n + * asio::posix::descriptor_base::bytes_readable @n + * asio::posix::descriptor_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * asio::posix::stream_descriptor descriptor(io_context); + * ... + * asio::posix::stream_descriptor::bytes_readable command; + * asio::error_code ec; + * descriptor.io_control(command, ec); + * if (ec) + * { + * // An error occurred. + * } + * std::size_t bytes_readable = command.get(); + * @endcode + */ + template + ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, + asio::error_code& ec) + { + this->get_service().io_control(this->get_implementation(), command, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Gets the non-blocking mode of the descriptor. + /** + * @returns @c true if the descriptor's synchronous operations will fail with + * 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 + * asio::error::would_block. + */ + bool non_blocking() const + { + return this->get_service().non_blocking(this->get_implementation()); + } + + /// Sets the non-blocking mode of the descriptor. + /** + * @param mode If @c true, the descriptor's synchronous operations will fail + * with asio::error::would_block if they are unable to perform the + * requested operation immediately. If @c false, synchronous operations will + * block until complete. + * + * @throws asio::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 + * asio::error::would_block. + */ + void non_blocking(bool mode) + { + asio::error_code ec; + this->get_service().non_blocking(this->get_implementation(), mode, ec); + asio::detail::throw_error(ec, "non_blocking"); + } + + /// Sets the non-blocking mode of the descriptor. + /** + * @param mode If @c true, the descriptor's synchronous operations will fail + * with 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 + * asio::error::would_block. + */ + ASIO_SYNC_OP_VOID non_blocking( + bool mode, asio::error_code& ec) + { + this->get_service().non_blocking(this->get_implementation(), mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Gets the non-blocking mode of the native descriptor implementation. + /** + * This function is used to retrieve the non-blocking mode of the underlying + * native descriptor. This mode has no effect on the behaviour of the + * descriptor object's synchronous operations. + * + * @returns @c true if the underlying descriptor is in non-blocking mode and + * direct system calls may fail with asio::error::would_block (or the + * equivalent system error). + * + * @note The current non-blocking mode is cached by the descriptor object. + * Consequently, the return value may be incorrect if the non-blocking mode + * was set directly on the native descriptor. + */ + bool native_non_blocking() const + { + return this->get_service().native_non_blocking( + this->get_implementation()); + } + + /// Sets the non-blocking mode of the native descriptor implementation. + /** + * This function is used to modify the non-blocking mode of the underlying + * native descriptor. It has no effect on the behaviour of the descriptor + * object's synchronous operations. + * + * @param mode If @c true, the underlying descriptor is put into non-blocking + * mode and direct system calls may fail with asio::error::would_block + * (or the equivalent system error). + * + * @throws asio::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 asio::error::invalid_argument, as the + * combination does not make sense. + */ + void native_non_blocking(bool mode) + { + asio::error_code ec; + this->get_service().native_non_blocking( + this->get_implementation(), mode, ec); + asio::detail::throw_error(ec, "native_non_blocking"); + } + + /// Sets the non-blocking mode of the native descriptor implementation. + /** + * This function is used to modify the non-blocking mode of the underlying + * native descriptor. It has no effect on the behaviour of the descriptor + * object's synchronous operations. + * + * @param mode If @c true, the underlying descriptor is put into non-blocking + * mode and direct system calls may fail with 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 asio::error::invalid_argument, as the + * combination does not make sense. + */ + ASIO_SYNC_OP_VOID native_non_blocking( + bool mode, asio::error_code& ec) + { + this->get_service().native_non_blocking( + this->get_implementation(), mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Wait for the descriptor 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 descriptor to enter + * a ready to read, write or error condition state. + * + * @param w Specifies the desired descriptor state. + * + * @par Example + * Waiting for a descriptor to become readable. + * @code + * asio::posix::stream_descriptor descriptor(io_context); + * ... + * descriptor.wait(asio::posix::stream_descriptor::wait_read); + * @endcode + */ + void wait(wait_type w) + { + asio::error_code ec; + this->get_service().wait(this->get_implementation(), w, ec); + asio::detail::throw_error(ec, "wait"); + } + + /// Wait for the descriptor 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 descriptor to enter + * a ready to read, write or error condition state. + * + * @param w Specifies the desired descriptor state. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * Waiting for a descriptor to become readable. + * @code + * asio::posix::stream_descriptor descriptor(io_context); + * ... + * asio::error_code ec; + * descriptor.wait(asio::posix::stream_descriptor::wait_read, ec); + * @endcode + */ + ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec) + { + this->get_service().wait(this->get_implementation(), w, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Asynchronously wait for the descriptor 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 descriptor to + * enter a ready to read, write or error condition state. + * + * @param w Specifies the desired descriptor 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 asio::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 + * asio::io_context::post(). + * + * @par Example + * @code + * void wait_handler(const asio::error_code& error) + * { + * if (!error) + * { + * // Wait succeeded. + * } + * } + * + * ... + * + * asio::posix::stream_descriptor descriptor(io_context); + * ... + * descriptor.async_wait( + * asio::posix::stream_descriptor::wait_read, + * wait_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(wait_type w, 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. + ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; + + async_completion init(handler); + + this->get_service().async_wait( + this->get_implementation(), w, init.completion_handler); + + return init.result.get(); + } + +protected: + /// Protected destructor to prevent deletion through this type. + /** + * This function destroys the descriptor, cancelling any outstanding + * asynchronous wait operations associated with the descriptor as if by + * calling @c cancel. + */ + ~descriptor() + { + } +}; + +} // namespace posix +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#undef ASIO_SVC_T + +#endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) + // || defined(GENERATING_DOCUMENTATION) + +#endif // !defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_POSIX_DESCRIPTOR_HPP diff --git a/tools/sdk/include/asio/asio/posix/descriptor_base.hpp b/tools/sdk/include/asio/asio/posix/descriptor_base.hpp new file mode 100644 index 00000000..4aac04f1 --- /dev/null +++ b/tools/sdk/include/asio/asio/posix/descriptor_base.hpp @@ -0,0 +1,90 @@ +// +// posix/descriptor_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_POSIX_DESCRIPTOR_BASE_HPP +#define ASIO_POSIX_DESCRIPTOR_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/io_control.hpp" +#include "asio/detail/socket_option.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace posix { + +/// The descriptor_base class is used as a base for the descriptor class as a +/// place to define the associated IO control commands. +class descriptor_base +{ +public: + /// Wait types. + /** + * For use with descriptor::wait() and descriptor::async_wait(). + */ + enum wait_type + { + /// Wait for a descriptor to become ready to read. + wait_read, + + /// Wait for a descriptor to become ready to write. + wait_write, + + /// Wait for a descriptor to have error conditions pending. + wait_error + }; + + /// IO control command to get the amount of data that can be read without + /// blocking. + /** + * Implements the FIONREAD IO control command. + * + * @par Example + * @code + * asio::posix::stream_descriptor descriptor(io_context); + * ... + * asio::descriptor_base::bytes_readable command(true); + * descriptor.io_control(command); + * std::size_t bytes_readable = command.get(); + * @endcode + * + * @par Concepts: + * IoControlCommand. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined bytes_readable; +#else + typedef asio::detail::io_control::bytes_readable bytes_readable; +#endif + +protected: + /// Protected destructor to prevent deletion through this type. + ~descriptor_base() + { + } +}; + +} // namespace posix +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_POSIX_DESCRIPTOR_BASE_HPP diff --git a/tools/sdk/include/asio/asio/posix/stream_descriptor.hpp b/tools/sdk/include/asio/asio/posix/stream_descriptor.hpp new file mode 100644 index 00000000..abb426a3 --- /dev/null +++ b/tools/sdk/include/asio/asio/posix/stream_descriptor.hpp @@ -0,0 +1,360 @@ +// +// posix/stream_descriptor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_POSIX_STREAM_DESCRIPTOR_HPP +#define ASIO_POSIX_STREAM_DESCRIPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/posix/descriptor.hpp" + +#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ + || defined(GENERATING_DOCUMENTATION) + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/posix/basic_stream_descriptor.hpp" +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +namespace asio { +namespace posix { + +#if defined(ASIO_ENABLE_OLD_SERVICES) +// Typedef for the typical usage of a stream-oriented descriptor. +typedef basic_stream_descriptor<> stream_descriptor; +#else // defined(ASIO_ENABLE_OLD_SERVICES) +/// Provides stream-oriented descriptor functionality. +/** + * The posix::stream_descriptor class template provides asynchronous and + * blocking stream-oriented descriptor functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +class stream_descriptor + : public descriptor +{ +public: + /// Construct a stream_descriptor without opening it. + /** + * This constructor creates a stream descriptor without opening it. The + * descriptor 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 descriptor will + * use to dispatch handlers for any asynchronous operations performed on the + * descriptor. + */ + explicit stream_descriptor(asio::io_context& io_context) + : descriptor(io_context) + { + } + + /// Construct a stream_descriptor on an existing native descriptor. + /** + * This constructor creates a stream descriptor object to hold an existing + * native descriptor. + * + * @param io_context The io_context object that the stream descriptor will + * use to dispatch handlers for any asynchronous operations performed on the + * descriptor. + * + * @param native_descriptor The new underlying descriptor implementation. + * + * @throws asio::system_error Thrown on failure. + */ + stream_descriptor(asio::io_context& io_context, + const native_handle_type& native_descriptor) + : descriptor(io_context, native_descriptor) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a stream_descriptor from another. + /** + * This constructor moves a stream descriptor from one object to another. + * + * @param other The other stream_descriptor 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 stream_descriptor(io_context&) constructor. + */ + stream_descriptor(stream_descriptor&& other) + : descriptor(std::move(other)) + { + } + + /// Move-assign a stream_descriptor from another. + /** + * This assignment operator moves a stream descriptor from one object to + * another. + * + * @param other The other stream_descriptor 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 stream_descriptor(io_context&) constructor. + */ + stream_descriptor& operator=(stream_descriptor&& other) + { + descriptor::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Write some data to the descriptor. + /** + * This function is used to write data to the stream descriptor. 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 descriptor. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * 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 + * descriptor.write_some(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) + { + asio::error_code ec; + std::size_t s = this->get_service().write_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "write_some"); + return s; + } + + /// Write some data to the descriptor. + /** + * This function is used to write data to the stream descriptor. 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 descriptor. + * + * @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, + asio::error_code& ec) + { + return this->get_service().write_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write data to the stream + * descriptor. The function call always returns immediately. + * + * @param buffers One or more data buffers to be written to the descriptor. + * 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 asio::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 + * 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 + * descriptor.async_write_some(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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + asio::async_completion init(handler); + + this->get_service().async_write_some( + this->get_implementation(), buffers, init.completion_handler); + + return init.result.get(); + } + + /// Read some data from the descriptor. + /** + * This function is used to read data from the stream descriptor. 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 asio::system_error Thrown on failure. An error code of + * 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 + * descriptor.read_some(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) + { + asio::error_code ec; + std::size_t s = this->get_service().read_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "read_some"); + return s; + } + + /// Read some data from the descriptor. + /** + * This function is used to read data from the stream descriptor. 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, + asio::error_code& ec) + { + return this->get_service().read_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read data from the stream + * descriptor. 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 asio::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 + * 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 + * descriptor.async_read_some(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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + asio::async_completion init(handler); + + this->get_service().async_read_some( + this->get_implementation(), buffers, init.completion_handler); + + return init.result.get(); + } +}; +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +} // namespace posix +} // namespace asio + +#endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_POSIX_STREAM_DESCRIPTOR_HPP diff --git a/tools/sdk/include/asio/asio/posix/stream_descriptor_service.hpp b/tools/sdk/include/asio/asio/posix/stream_descriptor_service.hpp new file mode 100644 index 00000000..4ffbb960 --- /dev/null +++ b/tools/sdk/include/asio/asio/posix/stream_descriptor_service.hpp @@ -0,0 +1,279 @@ +// +// posix/stream_descriptor_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_POSIX_STREAM_DESCRIPTOR_SERVICE_HPP +#define ASIO_POSIX_STREAM_DESCRIPTOR_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/async_result.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/detail/reactive_descriptor_service.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace posix { + +/// Default service implementation for a stream descriptor. +class stream_descriptor_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_context::id id; +#endif + +private: + // The type of the platform-specific implementation. + typedef detail::reactive_descriptor_service service_impl_type; + +public: + /// The type of a stream descriptor implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef service_impl_type::implementation_type implementation_type; +#endif + + /// The native descriptor type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef service_impl_type::native_handle_type native_handle_type; +#endif + + /// Construct a new stream descriptor service for the specified io_context. + explicit stream_descriptor_service(asio::io_context& io_context) + : asio::detail::service_base(io_context), + service_impl_(io_context) + { + } + + /// Construct a new stream descriptor implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new stream descriptor implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another stream descriptor implementation. + void move_assign(implementation_type& impl, + stream_descriptor_service& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy a stream descriptor implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Assign an existing native descriptor to a stream descriptor. + ASIO_SYNC_OP_VOID assign(implementation_type& impl, + const native_handle_type& native_descriptor, + asio::error_code& ec) + { + service_impl_.assign(impl, native_descriptor, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the descriptor is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a stream descriptor implementation. + ASIO_SYNC_OP_VOID close(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.close(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native descriptor implementation. + native_handle_type native_handle(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Release ownership of the native descriptor implementation. + native_handle_type release(implementation_type& impl) + { + return service_impl_.release(impl); + } + + /// Cancel all asynchronous operations associated with the descriptor. + ASIO_SYNC_OP_VOID cancel(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.cancel(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Perform an IO control command on the descriptor. + template + ASIO_SYNC_OP_VOID io_control(implementation_type& impl, + IoControlCommand& command, asio::error_code& ec) + { + service_impl_.io_control(impl, command, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Gets the non-blocking mode of the descriptor. + bool non_blocking(const implementation_type& impl) const + { + return service_impl_.non_blocking(impl); + } + + /// Sets the non-blocking mode of the descriptor. + ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl, + bool mode, asio::error_code& ec) + { + service_impl_.non_blocking(impl, mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Gets the non-blocking mode of the native descriptor 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 descriptor implementation. + ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl, + bool mode, asio::error_code& ec) + { + service_impl_.native_non_blocking(impl, mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Wait for the descriptor to become ready to read, ready to write, or to + /// have pending error conditions. + ASIO_SYNC_OP_VOID wait(implementation_type& impl, + descriptor_base::wait_type w, asio::error_code& ec) + { + service_impl_.wait(impl, w, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Asynchronously wait for the descriptor to become ready to read, ready to + /// write, or to have pending error conditions. + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(implementation_type& impl, descriptor_base::wait_type w, + ASIO_MOVE_ARG(WaitHandler) handler) + { + async_completion init(handler); + + service_impl_.async_wait(impl, w, init.completion_handler); + + return init.result.get(); + } + + /// Write the given data to the stream. + template + std::size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.write_some(impl, buffers, ec); + } + + /// Start an asynchronous write. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) + { + asio::async_completion init(handler); + + service_impl_.async_write_some(impl, buffers, init.completion_handler); + + return init.result.get(); + } + + /// Read some data from the stream. + template + std::size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.read_some(impl, buffers, ec); + } + + /// Start an asynchronous read. + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) + { + asio::async_completion init(handler); + + service_impl_.async_read_some(impl, buffers, 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 posix +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_POSIX_STREAM_DESCRIPTOR_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/post.hpp b/tools/sdk/include/asio/asio/post.hpp new file mode 100644 index 00000000..87d7b96d --- /dev/null +++ b/tools/sdk/include/asio/asio/post.hpp @@ -0,0 +1,107 @@ +// +// post.hpp +// ~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_POST_HPP +#define ASIO_POST_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/async_result.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/execution_context.hpp" +#include "asio/is_executor.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Submits a completion token or function object for execution. +/** + * This function submits an object for execution using the object's associated + * executor. The function object is queued for execution, and is never called + * from the current thread prior to returning from post(). + * + * This function has the following effects: + * + * @li Constructs a function object handler of type @c Handler, initialized + * with handler(forward(token)). + * + * @li Constructs an object @c result of type async_result, + * initializing the object as result(handler). + * + * @li Obtains the handler's associated executor object @c ex by performing + * get_associated_executor(handler). + * + * @li Obtains the handler's associated allocator object @c alloc by performing + * get_associated_allocator(handler). + * + * @li Performs ex.post(std::move(handler), alloc). + * + * @li Returns result.get(). + */ +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post( + ASIO_MOVE_ARG(CompletionToken) token); + +/// Submits a completion token or function object for execution. +/** + * This function submits an object for execution using the specified executor. + * The function object is queued for execution, and is never called from the + * current thread prior to returning from post(). + * + * This function has the following effects: + * + * @li Constructs a function object handler of type @c Handler, initialized + * with handler(forward(token)). + * + * @li Constructs an object @c result of type async_result, + * initializing the object as result(handler). + * + * @li Obtains the handler's associated executor object @c ex1 by performing + * get_associated_executor(handler). + * + * @li Creates a work object @c w by performing make_work(ex1). + * + * @li Obtains the handler's associated allocator object @c alloc by performing + * get_associated_allocator(handler). + * + * @li Constructs a function object @c f with a function call operator that + * performs ex1.dispatch(std::move(handler), alloc) followed by + * w.reset(). + * + * @li Performs Executor(ex).post(std::move(f), alloc). + * + * @li Returns result.get(). + */ +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post( + const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token, + typename enable_if::value>::type* = 0); + +/// Submits a completion token or function object for execution. +/** + * @returns post(ctx.get_executor(), forward(token)). + */ +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post( + ExecutionContext& ctx, ASIO_MOVE_ARG(CompletionToken) token, + typename enable_if::value>::type* = 0); + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/post.hpp" + +#endif // ASIO_POST_HPP diff --git a/tools/sdk/include/asio/asio/raw_socket_service.hpp b/tools/sdk/include/asio/asio/raw_socket_service.hpp new file mode 100644 index 00000000..2bccf032 --- /dev/null +++ b/tools/sdk/include/asio/asio/raw_socket_service.hpp @@ -0,0 +1,466 @@ +// +// raw_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_RAW_SOCKET_SERVICE_HPP +#define ASIO_RAW_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#include +#include "asio/async_result.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/null_socket_service.hpp" +#elif defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_socket_service.hpp" +#else +# include "asio/detail/reactive_socket_service.hpp" +#endif + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Default service implementation for a raw socket. +template +class raw_socket_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static 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(ASIO_WINDOWS_RUNTIME) + typedef detail::null_socket_service service_impl_type; +#elif defined(ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service service_impl_type; +#else + typedef detail::reactive_socket_service service_impl_type; +#endif + +public: + /// The type of a raw socket. +#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 raw socket service for the specified io_context. + explicit raw_socket_service(asio::io_context& io_context) + : asio::detail::service_base< + raw_socket_service >(io_context), + service_impl_(io_context) + { + } + + /// Construct a new raw socket implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new raw socket implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another raw socket implementation. + void move_assign(implementation_type& impl, + raw_socket_service& 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 raw_socket_service; + + /// Move-construct a new raw socket implementation from another protocol + /// type. + template + void converting_move_construct(implementation_type& impl, + raw_socket_service& other_service, + typename raw_socket_service< + 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(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy a raw socket implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + // Open a new raw socket implementation. + ASIO_SYNC_OP_VOID open(implementation_type& impl, + const protocol_type& protocol, asio::error_code& ec) + { + if (protocol.type() == ASIO_OS_DEF(SOCK_RAW)) + service_impl_.open(impl, protocol, ec); + else + ec = asio::error::invalid_argument; + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Assign an existing native socket to a raw socket. + ASIO_SYNC_OP_VOID assign(implementation_type& impl, + const protocol_type& protocol, const native_handle_type& native_socket, + asio::error_code& ec) + { + service_impl_.assign(impl, protocol, native_socket, ec); + 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 raw socket implementation. + ASIO_SYNC_OP_VOID close(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.close(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Release ownership of the underlying socket. + native_handle_type release(implementation_type& impl, + asio::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. + ASIO_SYNC_OP_VOID cancel(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.cancel(impl, ec); + 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, + asio::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, + asio::error_code& ec) const + { + return service_impl_.available(impl, ec); + } + + // Bind the raw socket to the specified local endpoint. + ASIO_SYNC_OP_VOID bind(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + service_impl_.bind(impl, endpoint, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Connect the raw socket to the specified endpoint. + ASIO_SYNC_OP_VOID connect(implementation_type& impl, + const endpoint_type& peer_endpoint, asio::error_code& ec) + { + service_impl_.connect(impl, peer_endpoint, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Start an asynchronous connect. + template + ASIO_INITFN_RESULT_TYPE(ConnectHandler, + void (asio::error_code)) + async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, + 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 + ASIO_SYNC_OP_VOID set_option(implementation_type& impl, + const SettableSocketOption& option, asio::error_code& ec) + { + service_impl_.set_option(impl, option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get a socket option. + template + ASIO_SYNC_OP_VOID get_option(const implementation_type& impl, + GettableSocketOption& option, asio::error_code& ec) const + { + service_impl_.get_option(impl, option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Perform an IO control command on the socket. + template + ASIO_SYNC_OP_VOID io_control(implementation_type& impl, + IoControlCommand& command, asio::error_code& ec) + { + service_impl_.io_control(impl, command, ec); + 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. + ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl, + bool mode, asio::error_code& ec) + { + service_impl_.non_blocking(impl, mode, ec); + 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. + ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl, + bool mode, asio::error_code& ec) + { + service_impl_.native_non_blocking(impl, mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.remote_endpoint(impl, ec); + } + + /// Disable sends or receives on the socket. + ASIO_SYNC_OP_VOID shutdown(implementation_type& impl, + socket_base::shutdown_type what, asio::error_code& ec) + { + service_impl_.shutdown(impl, what, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Wait for the socket to become ready to read, ready to write, or to have + /// pending error conditions. + ASIO_SYNC_OP_VOID wait(implementation_type& impl, + socket_base::wait_type w, asio::error_code& ec) + { + service_impl_.wait(impl, w, ec); + 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 + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(implementation_type& impl, socket_base::wait_type w, + 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, asio::error_code& ec) + { + return service_impl_.send(impl, buffers, flags, ec); + } + + /// Start an asynchronous send. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send(implementation_type& impl, const ConstBufferSequence& buffers, + socket_base::message_flags flags, + ASIO_MOVE_ARG(WriteHandler) handler) + { + async_completion init(handler); + + service_impl_.async_send(impl, buffers, flags, init.completion_handler); + + return init.result.get(); + } + + /// Send raw data 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, asio::error_code& ec) + { + return service_impl_.send_to(impl, buffers, destination, flags, ec); + } + + /// Start an asynchronous send. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send_to(implementation_type& impl, + const ConstBufferSequence& buffers, const endpoint_type& destination, + socket_base::message_flags flags, + ASIO_MOVE_ARG(WriteHandler) handler) + { + async_completion init(handler); + + service_impl_.async_send_to(impl, buffers, + destination, 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, asio::error_code& ec) + { + return service_impl_.receive(impl, buffers, flags, ec); + } + + /// Start an asynchronous receive. + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, + ASIO_MOVE_ARG(ReadHandler) handler) + { + async_completion init(handler); + + service_impl_.async_receive(impl, buffers, flags, init.completion_handler); + + return init.result.get(); + } + + /// Receive raw data 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, asio::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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, + socket_base::message_flags flags, + ASIO_MOVE_ARG(ReadHandler) handler) + { + async_completion init(handler); + + service_impl_.async_receive_from(impl, buffers, + sender_endpoint, 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 + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_RAW_SOCKET_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/read.hpp b/tools/sdk/include/asio/asio/read.hpp new file mode 100644 index 00000000..e77206a8 --- /dev/null +++ b/tools/sdk/include/asio/asio/read.hpp @@ -0,0 +1,947 @@ +// +// read.hpp +// ~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_READ_HPP +#define ASIO_READ_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/async_result.hpp" +#include "asio/buffer.hpp" +#include "asio/error.hpp" + +#if !defined(ASIO_NO_EXTENSIONS) +# include "asio/basic_streambuf_fwd.hpp" +#endif // !defined(ASIO_NO_EXTENSIONS) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/** + * @defgroup read asio::read + * + * @brief Attempt to read a certain amount of data from a stream before + * returning. + */ +/*@{*/ + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code asio::read(s, 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. + * + * @note This overload is equivalent to calling: + * @code asio::read( + * s, buffers, + * asio::transfer_all()); @endcode + */ +template +std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + typename enable_if< + is_mutable_buffer_sequence::value + >::type* = 0); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes transferred. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code asio::read(s, asio::buffer(data, size), ec); @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. + * + * @note This overload is equivalent to calling: + * @code asio::read( + * s, buffers, + * asio::transfer_all(), ec); @endcode + */ +template +std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + asio::error_code& ec, + typename enable_if< + is_mutable_buffer_sequence::value + >::type* = 0); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's read_some function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code asio::read(s, asio::buffer(data, size), + * asio::transfer_at_least(32)); @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(SyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, + typename enable_if< + is_mutable_buffer_sequence::value + >::type* = 0); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's read_some function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec, + typename enable_if< + is_mutable_buffer_sequence::value + >::type* = 0); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The specified dynamic buffer sequence is full (that is, it has reached + * maximum size). + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers The dynamic buffer sequence into which the data will be read. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @note This overload is equivalent to calling: + * @code asio::read( + * s, buffers, + * asio::transfer_all()); @endcode + */ +template +std::size_t read(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + typename enable_if< + is_dynamic_buffer::type>::value + >::type* = 0); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffer is full (that is, it has reached maximum size). + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers The dynamic buffer sequence into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes transferred. + * + * @note This overload is equivalent to calling: + * @code asio::read( + * s, buffers, + * asio::transfer_all(), ec); @endcode + */ +template +std::size_t read(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + asio::error_code& ec, + typename enable_if< + is_dynamic_buffer::type>::value + >::type* = 0); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The specified dynamic buffer sequence is full (that is, it has reached + * maximum size). + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers The dynamic buffer sequence into which the data will be read. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's read_some function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + */ +template +std::size_t read(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + CompletionCondition completion_condition, + typename enable_if< + is_dynamic_buffer::type>::value + >::type* = 0); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The specified dynamic buffer sequence is full (that is, it has reached + * maximum size). + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers The dynamic buffer sequence into which the data will be read. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's read_some function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t read(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + CompletionCondition completion_condition, asio::error_code& ec, + typename enable_if< + is_dynamic_buffer::type>::value + >::type* = 0); + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffer is full (that is, it has reached maximum size). + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @note This overload is equivalent to calling: + * @code asio::read( + * s, b, + * asio::transfer_all()); @endcode + */ +template +std::size_t read(SyncReadStream& s, basic_streambuf& b); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffer is full (that is, it has reached maximum size). + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes transferred. + * + * @note This overload is equivalent to calling: + * @code asio::read( + * s, b, + * asio::transfer_all(), ec); @endcode + */ +template +std::size_t read(SyncReadStream& s, basic_streambuf& b, + asio::error_code& ec); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffer is full (that is, it has reached maximum size). + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's read_some function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + */ +template +std::size_t read(SyncReadStream& s, basic_streambuf& b, + CompletionCondition completion_condition); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffer is full (that is, it has reached maximum size). + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's read_some function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t read(SyncReadStream& s, basic_streambuf& b, + CompletionCondition completion_condition, asio::error_code& ec); + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +/*@}*/ +/** + * @defgroup async_read asio::async_read + * + * @brief Start an asynchronous operation to read a certain amount of data from + * a stream. + */ +/*@{*/ + +/// Start an asynchronous operation to read a certain amount of data from a +/// stream. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions is + * true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other read operations (such + * as async_read, the stream's async_read_some function, or any other composed + * operations that perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. 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 asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. + * ); @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 + * asio::io_context::post(). + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * asio::async_read(s, 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. + * + * @note This overload is equivalent to calling: + * @code asio::async_read( + * s, buffers, + * asio::transfer_all(), + * handler); @endcode + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler, + typename enable_if< + is_mutable_buffer_sequence::value + >::type* = 0); + +/// Start an asynchronous operation to read a certain amount of data from a +/// stream. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions is + * true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. 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 completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's async_read_some function. + * + * @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 asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. + * ); @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 + * asio::io_context::post(). + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code asio::async_read(s, + * asio::buffer(data, size), + * asio::transfer_at_least(32), + * 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 +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(ReadHandler) handler, + typename enable_if< + is_mutable_buffer_sequence::value + >::type* = 0); + +/// Start an asynchronous operation to read a certain amount of data from a +/// stream. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions is + * true: + * + * @li The specified dynamic buffer sequence is full (that is, it has reached + * maximum size). + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other read operations (such + * as async_read, the stream's async_read_some function, or any other composed + * operations that perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param buffers The dynamic buffer sequence 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 asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. + * ); @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 + * asio::io_context::post(). + * + * @note This overload is equivalent to calling: + * @code asio::async_read( + * s, buffers, + * asio::transfer_all(), + * handler); @endcode + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read(AsyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + ASIO_MOVE_ARG(ReadHandler) handler, + typename enable_if< + is_dynamic_buffer::type>::value + >::type* = 0); + +/// Start an asynchronous operation to read a certain amount of data from a +/// stream. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions is + * true: + * + * @li The specified dynamic buffer sequence is full (that is, it has reached + * maximum size). + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other read operations (such + * as async_read, the stream's async_read_some function, or any other composed + * operations that perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param buffers The dynamic buffer sequence 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 completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's async_read_some function. + * + * @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 asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. + * ); @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 + * asio::io_context::post(). + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read(AsyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(ReadHandler) handler, + typename enable_if< + is_dynamic_buffer::type>::value + >::type* = 0); + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +/// Start an asynchronous operation to read a certain amount of data from a +/// stream. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions is + * true: + * + * @li The supplied buffer is full (that is, it has reached maximum size). + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other read operations (such + * as async_read, the stream's async_read_some function, or any other composed + * operations that perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A basic_streambuf object into which the data will be read. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains 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 asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. + * ); @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 + * asio::io_context::post(). + * + * @note This overload is equivalent to calling: + * @code asio::async_read( + * s, b, + * asio::transfer_all(), + * handler); @endcode + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read(AsyncReadStream& s, basic_streambuf& b, + ASIO_MOVE_ARG(ReadHandler) handler); + +/// Start an asynchronous operation to read a certain amount of data from a +/// stream. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions is + * true: + * + * @li The supplied buffer is full (that is, it has reached maximum size). + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other read operations (such + * as async_read, the stream's async_read_some function, or any other composed + * operations that perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A basic_streambuf object into which the data will be read. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's async_read_some function. + * + * @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 asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. + * ); @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 + * asio::io_context::post(). + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read(AsyncReadStream& s, basic_streambuf& b, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(ReadHandler) handler); + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +/*@}*/ + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/read.hpp" + +#endif // ASIO_READ_HPP diff --git a/tools/sdk/include/asio/asio/read_at.hpp b/tools/sdk/include/asio/asio/read_at.hpp new file mode 100644 index 00000000..df2c6287 --- /dev/null +++ b/tools/sdk/include/asio/asio/read_at.hpp @@ -0,0 +1,671 @@ +// +// read_at.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_READ_AT_HPP +#define ASIO_READ_AT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/async_result.hpp" +#include "asio/detail/cstdint.hpp" +#include "asio/error.hpp" + +#if !defined(ASIO_NO_EXTENSIONS) +# include "asio/basic_streambuf_fwd.hpp" +#endif // !defined(ASIO_NO_EXTENSIONS) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/** + * @defgroup read_at asio::read_at + * + * @brief Attempt to read a certain amount of data at the specified offset + * before returning. + */ +/*@{*/ + +/// Attempt to read a certain amount of data at the specified offset before +/// returning. +/** + * This function is used to read a certain number of bytes of data from a + * random access device at the specified offset. The call will block until one + * of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the SyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * device. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code asio::read_at(d, 42, 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. + * + * @note This overload is equivalent to calling: + * @code asio::read_at( + * d, 42, buffers, + * asio::transfer_all()); @endcode + */ +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, const MutableBufferSequence& buffers); + +/// Attempt to read a certain amount of data at the specified offset before +/// returning. +/** + * This function is used to read a certain number of bytes of data from a + * random access device at the specified offset. The call will block until one + * of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the SyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * device. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes transferred. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code asio::read_at(d, 42, + * asio::buffer(data, size), ec); @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. + * + * @note This overload is equivalent to calling: + * @code asio::read_at( + * d, 42, buffers, + * asio::transfer_all(), ec); @endcode + */ +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, const MutableBufferSequence& buffers, + asio::error_code& ec); + +/// Attempt to read a certain amount of data at the specified offset before +/// returning. +/** + * This function is used to read a certain number of bytes of data from a + * random access device at the specified offset. The call will block until one + * of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the SyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * device. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the device's read_some_at function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code asio::read_at(d, 42, asio::buffer(data, size), + * asio::transfer_at_least(32)); @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_at(SyncRandomAccessReadDevice& d, + uint64_t offset, const MutableBufferSequence& buffers, + CompletionCondition completion_condition); + +/// Attempt to read a certain amount of data at the specified offset before +/// returning. +/** + * This function is used to read a certain number of bytes of data from a + * random access device at the specified offset. The call will block until one + * of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the SyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * device. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the device's read_some_at function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec); + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +/// Attempt to read a certain amount of data at the specified offset before +/// returning. +/** + * This function is used to read a certain number of bytes of data from a + * random access device at the specified offset. The call will block until one + * of the following conditions is true: + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the SyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @note This overload is equivalent to calling: + * @code asio::read_at( + * d, 42, b, + * asio::transfer_all()); @endcode + */ +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, basic_streambuf& b); + +/// Attempt to read a certain amount of data at the specified offset before +/// returning. +/** + * This function is used to read a certain number of bytes of data from a + * random access device at the specified offset. The call will block until one + * of the following conditions is true: + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the SyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes transferred. + * + * @note This overload is equivalent to calling: + * @code asio::read_at( + * d, 42, b, + * asio::transfer_all(), ec); @endcode + */ +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, basic_streambuf& b, + asio::error_code& ec); + +/// Attempt to read a certain amount of data at the specified offset before +/// returning. +/** + * This function is used to read a certain number of bytes of data from a + * random access device at the specified offset. The call will block until one + * of the following conditions is true: + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the SyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the device's read_some_at function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + */ +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, basic_streambuf& b, + CompletionCondition completion_condition); + +/// Attempt to read a certain amount of data at the specified offset before +/// returning. +/** + * This function is used to read a certain number of bytes of data from a + * random access device at the specified offset. The call will block until one + * of the following conditions is true: + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the SyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the device's read_some_at function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + uint64_t offset, basic_streambuf& b, + CompletionCondition completion_condition, asio::error_code& ec); + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +/*@}*/ +/** + * @defgroup async_read_at asio::async_read_at + * + * @brief Start an asynchronous operation to read a certain amount of data at + * the specified offset. + */ +/*@{*/ + +/// Start an asynchronous operation to read a certain amount of data at the +/// specified offset. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a random access device at the specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * async_read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the AsyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * device. 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( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes copied into the buffers. If an error + * // occurred, this will be the number of bytes successfully + * // transferred prior to the error. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * asio::async_read_at(d, 42, 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. + * + * @note This overload is equivalent to calling: + * @code asio::async_read_at( + * d, 42, buffers, + * asio::transfer_all(), + * handler); @endcode + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset, + const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler); + +/// Start an asynchronous operation to read a certain amount of data at the +/// specified offset. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a random access device at the specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * @param d The device from which the data is to be read. The type must support + * the AsyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * device. 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 completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_read_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the device's async_read_some_at function. + * + * @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( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes copied into the buffers. If an error + * // occurred, this will be the number of bytes successfully + * // transferred prior to the error. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code asio::async_read_at(d, 42, + * asio::buffer(data, size), + * asio::transfer_at_least(32), + * 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 +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_at(AsyncRandomAccessReadDevice& d, + uint64_t offset, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(ReadHandler) handler); + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +/// Start an asynchronous operation to read a certain amount of data at the +/// specified offset. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a random access device at the specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * async_read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the AsyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param b A basic_streambuf object into which the data will be read. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains 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( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes copied into the buffers. If an error + * // occurred, this will be the number of bytes successfully + * // transferred prior to the error. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + * + * @note This overload is equivalent to calling: + * @code asio::async_read_at( + * d, 42, b, + * asio::transfer_all(), + * handler); @endcode + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset, + basic_streambuf& b, ASIO_MOVE_ARG(ReadHandler) handler); + +/// Start an asynchronous operation to read a certain amount of data at the +/// specified offset. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a random access device at the specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * async_read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the AsyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param b A basic_streambuf object into which the data will be read. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_read_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the device's async_read_some_at function. + * + * @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( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes copied into the buffers. If an error + * // occurred, this will be the number of bytes successfully + * // transferred prior to the error. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_at(AsyncRandomAccessReadDevice& d, + uint64_t offset, basic_streambuf& b, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(ReadHandler) handler); + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +/*@}*/ + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/read_at.hpp" + +#endif // ASIO_READ_AT_HPP diff --git a/tools/sdk/include/asio/asio/read_until.hpp b/tools/sdk/include/asio/asio/read_until.hpp new file mode 100644 index 00000000..f413d987 --- /dev/null +++ b/tools/sdk/include/asio/asio/read_until.hpp @@ -0,0 +1,1824 @@ +// +// read_until.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_READ_UNTIL_HPP +#define ASIO_READ_UNTIL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include +#include "asio/async_result.hpp" +#include "asio/detail/regex_fwd.hpp" +#include "asio/detail/string_view.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error.hpp" + +#if !defined(ASIO_NO_EXTENSIONS) +# include "asio/basic_streambuf_fwd.hpp" +#endif // !defined(ASIO_NO_EXTENSIONS) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +namespace detail +{ + char (&has_result_type_helper(...))[2]; + + template + char has_result_type_helper(T*, typename T::result_type* = 0); + + template + struct has_result_type + { + enum { value = (sizeof((has_result_type_helper)((T*)(0))) == 1) }; + }; +} // namespace detail + +/// Type trait used to determine whether a type can be used as a match condition +/// function with read_until and async_read_until. +template +struct is_match_condition +{ +#if defined(GENERATING_DOCUMENTATION) + /// The value member is true if the type may be used as a match condition. + static const bool value; +#else + enum + { + value = asio::is_function< + typename asio::remove_pointer::type>::value + || detail::has_result_type::value + }; +#endif +}; + +/** + * @defgroup read_until asio::read_until + * + * @brief Read data into a dynamic buffer sequence, or into a streambuf, until + * it contains a delimiter, matches a regular expression, or a function object + * indicates a match. + */ +/*@{*/ + +/// Read data into a dynamic buffer sequence until it contains a specified +/// delimiter. +/** + * This function is used to read data into the specified dynamic buffer + * sequence until the dynamic buffer sequence's get area contains the specified + * delimiter. The call will block until one of the following conditions is + * true: + * + * @li The get area of the dynamic buffer sequence contains the specified + * delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the dynamic buffer sequence's get area already + * contains the delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers The dynamic buffer sequence into which the data will be read. + * + * @param delim The delimiter character. + * + * @returns The number of bytes in the dynamic buffer sequence's get area up to + * and including the delimiter. + * + * @throws asio::system_error Thrown on failure. + * + * @note After a successful read_until operation, the dynamic buffer sequence + * may contain additional data beyond the delimiter. An application will + * typically leave that data in the dynamic buffer sequence for a subsequent + * read_until operation to examine. + * + * @par Example + * To read data into a @c std::string until a newline is encountered: + * @code std::string data; + * std::string n = asio::read_until(s, + * asio::dynamic_buffer(data), '\n'); + * std::string line = data.substr(0, n); + * data.erase(0, n); @endcode + * After the @c read_until operation completes successfully, the string @c data + * contains the delimiter: + * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode + * The call to @c substr then extracts the data up to and including the + * delimiter, so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\n' } @endcode + * After the call to @c erase, the remaining data is left in the buffer @c b as + * follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c read_until operation. + */ +template +std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, char delim); + +/// Read data into a dynamic buffer sequence until it contains a specified +/// delimiter. +/** + * This function is used to read data into the specified dynamic buffer + * sequence until the dynamic buffer sequence's get area contains the specified + * delimiter. The call will block until one of the following conditions is + * true: + * + * @li The get area of the dynamic buffer sequence contains the specified + * delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the dynamic buffer sequence's get area already + * contains the delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers The dynamic buffer sequence into which the data will be read. + * + * @param delim The delimiter character. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the dynamic buffer sequence's get area up to + * and including the delimiter. Returns 0 if an error occurred. + * + * @note After a successful read_until operation, the dynamic buffer sequence + * may contain additional data beyond the delimiter. An application will + * typically leave that data in the dynamic buffer sequence for a subsequent + * read_until operation to examine. + */ +template +std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + char delim, asio::error_code& ec); + +/// Read data into a dynamic buffer sequence until it contains a specified +/// delimiter. +/** + * This function is used to read data into the specified dynamic buffer + * sequence until the dynamic buffer sequence's get area contains the specified + * delimiter. The call will block until one of the following conditions is + * true: + * + * @li The get area of the dynamic buffer sequence contains the specified + * delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the dynamic buffer sequence's get area already + * contains the delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers The dynamic buffer sequence into which the data will be read. + * + * @param delim The delimiter string. + * + * @returns The number of bytes in the dynamic buffer sequence's get area up to + * and including the delimiter. + * + * @note After a successful read_until operation, the dynamic buffer sequence + * may contain additional data beyond the delimiter. An application will + * typically leave that data in the dynamic buffer sequence for a subsequent + * read_until operation to examine. + * + * @par Example + * To read data into a @c std::string until a CR-LF sequence is encountered: + * @code std::string data; + * std::string n = asio::read_until(s, + * asio::dynamic_buffer(data), "\r\n"); + * std::string line = data.substr(0, n); + * data.erase(0, n); @endcode + * After the @c read_until operation completes successfully, the string @c data + * contains the delimiter: + * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode + * The call to @c substr then extracts the data up to and including the + * delimiter, so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode + * After the call to @c erase, the remaining data is left in the buffer @c b as + * follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c read_until operation. + */ +template +std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + ASIO_STRING_VIEW_PARAM delim); + +/// Read data into a dynamic buffer sequence until it contains a specified +/// delimiter. +/** + * This function is used to read data into the specified dynamic buffer + * sequence until the dynamic buffer sequence's get area contains the specified + * delimiter. The call will block until one of the following conditions is + * true: + * + * @li The get area of the dynamic buffer sequence contains the specified + * delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the dynamic buffer sequence's get area already + * contains the delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers The dynamic buffer sequence into which the data will be read. + * + * @param delim The delimiter string. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the dynamic buffer sequence's get area up to + * and including the delimiter. Returns 0 if an error occurred. + * + * @note After a successful read_until operation, the dynamic buffer sequence + * may contain additional data beyond the delimiter. An application will + * typically leave that data in the dynamic buffer sequence for a subsequent + * read_until operation to examine. + */ +template +std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + ASIO_STRING_VIEW_PARAM delim, + asio::error_code& ec); + +#if !defined(ASIO_NO_EXTENSIONS) +#if defined(ASIO_HAS_BOOST_REGEX) \ + || defined(GENERATING_DOCUMENTATION) + +/// Read data into a dynamic buffer sequence until some part of the data it +/// contains matches a regular expression. +/** + * This function is used to read data into the specified dynamic buffer + * sequence until the dynamic buffer sequence's get area contains some data + * that matches a regular expression. The call will block until one of the + * following conditions is true: + * + * @li A substring of the dynamic buffer sequence's get area matches the + * regular expression. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the dynamic buffer sequence's get area already + * contains data that matches the regular expression, the function returns + * immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers A dynamic buffer sequence into which the data will be read. + * + * @param expr The regular expression. + * + * @returns The number of bytes in the dynamic buffer sequence's get area up to + * and including the substring that matches the regular expression. + * + * @throws asio::system_error Thrown on failure. + * + * @note After a successful read_until operation, the dynamic buffer sequence + * may contain additional data beyond that which matched the regular + * expression. An application will typically leave that data in the dynamic + * buffer sequence for a subsequent read_until operation to examine. + * + * @par Example + * To read data into a @c std::string until a CR-LF sequence is encountered: + * @code std::string data; + * std::string n = asio::read_until(s, + * asio::dynamic_buffer(data), boost::regex("\r\n")); + * std::string line = data.substr(0, n); + * data.erase(0, n); @endcode + * After the @c read_until operation completes successfully, the string @c data + * contains the delimiter: + * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode + * The call to @c substr then extracts the data up to and including the + * delimiter, so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode + * After the call to @c erase, the remaining data is left in the buffer @c b as + * follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c read_until operation. + */ +template +std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + const boost::regex& expr); + +/// Read data into a dynamic buffer sequence until some part of the data it +/// contains matches a regular expression. +/** + * This function is used to read data into the specified dynamic buffer + * sequence until the dynamic buffer sequence's get area contains some data + * that matches a regular expression. The call will block until one of the + * following conditions is true: + * + * @li A substring of the dynamic buffer sequence's get area matches the + * regular expression. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the dynamic buffer sequence's get area already + * contains data that matches the regular expression, the function returns + * immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers A dynamic buffer sequence into which the data will be read. + * + * @param expr The regular expression. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the dynamic buffer sequence's get area up to + * and including the substring that matches the regular expression. Returns 0 + * if an error occurred. + * + * @note After a successful read_until operation, the dynamic buffer sequence + * may contain additional data beyond that which matched the regular + * expression. An application will typically leave that data in the dynamic + * buffer sequence for a subsequent read_until operation to examine. + */ +template +std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + const boost::regex& expr, asio::error_code& ec); + +#endif // defined(ASIO_HAS_BOOST_REGEX) + // || defined(GENERATING_DOCUMENTATION) + +/// Read data into a dynamic buffer sequence until a function object indicates a +/// match. + +/** + * This function is used to read data into the specified dynamic buffer + * sequence until a user-defined match condition function object, when applied + * to the data contained in the dynamic buffer sequence, indicates a successful + * match. The call will block until one of the following conditions is true: + * + * @li The match condition function object returns a std::pair where the second + * element evaluates to true. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the match condition function object already indicates + * a match, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers A dynamic buffer sequence into which the data will be read. + * + * @param match_condition The function object to be called to determine whether + * a match exists. The signature of the function object must be: + * @code pair match_condition(iterator begin, iterator end); + * @endcode + * where @c iterator represents the type: + * @code buffers_iterator + * @endcode + * The iterator parameters @c begin and @c end define the range of bytes to be + * scanned to determine whether there is a match. The @c first member of the + * return value is an iterator marking one-past-the-end of the bytes that have + * been consumed by the match function. This iterator is used to calculate the + * @c begin parameter for any subsequent invocation of the match condition. The + * @c second member of the return value is true if a match has been found, false + * otherwise. + * + * @returns The number of bytes in the dynamic_buffer's get area that + * have been fully consumed by the match function. + * + * @throws asio::system_error Thrown on failure. + * + * @note After a successful read_until operation, the dynamic buffer sequence + * may contain additional data beyond that which matched the function object. + * An application will typically leave that data in the dynamic buffer sequence + * for a subsequent read_until operation to examine. + + * @note The default implementation of the @c is_match_condition type trait + * evaluates to true for function pointers and function objects with a + * @c result_type typedef. It must be specialised for other user-defined + * function objects. + * + * @par Examples + * To read data into a dynamic buffer sequence until whitespace is encountered: + * @code typedef asio::buffers_iterator< + * asio::const_buffers_1> iterator; + * + * std::pair + * match_whitespace(iterator begin, iterator end) + * { + * iterator i = begin; + * while (i != end) + * if (std::isspace(*i++)) + * return std::make_pair(i, true); + * return std::make_pair(i, false); + * } + * ... + * std::string data; + * asio::read_until(s, data, match_whitespace); + * @endcode + * + * To read data into a @c std::string until a matching character is found: + * @code class match_char + * { + * public: + * explicit match_char(char c) : c_(c) {} + * + * template + * std::pair operator()( + * Iterator begin, Iterator end) const + * { + * Iterator i = begin; + * while (i != end) + * if (c_ == *i++) + * return std::make_pair(i, true); + * return std::make_pair(i, false); + * } + * + * private: + * char c_; + * }; + * + * namespace asio { + * template <> struct is_match_condition + * : public boost::true_type {}; + * } // namespace asio + * ... + * std::string data; + * asio::read_until(s, data, match_char('a')); + * @endcode + */ +template +std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + MatchCondition match_condition, + typename enable_if::value>::type* = 0); + +/// Read data into a dynamic buffer sequence until a function object indicates a +/// match. +/** + * This function is used to read data into the specified dynamic buffer + * sequence until a user-defined match condition function object, when applied + * to the data contained in the dynamic buffer sequence, indicates a successful + * match. The call will block until one of the following conditions is true: + * + * @li The match condition function object returns a std::pair where the second + * element evaluates to true. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the match condition function object already indicates + * a match, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers A dynamic buffer sequence into which the data will be read. + * + * @param match_condition The function object to be called to determine whether + * a match exists. The signature of the function object must be: + * @code pair match_condition(iterator begin, iterator end); + * @endcode + * where @c iterator represents the type: + * @code buffers_iterator + * @endcode + * The iterator parameters @c begin and @c end define the range of bytes to be + * scanned to determine whether there is a match. The @c first member of the + * return value is an iterator marking one-past-the-end of the bytes that have + * been consumed by the match function. This iterator is used to calculate the + * @c begin parameter for any subsequent invocation of the match condition. The + * @c second member of the return value is true if a match has been found, false + * otherwise. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the dynamic buffer sequence's get area that + * have been fully consumed by the match function. Returns 0 if an error + * occurred. + * + * @note After a successful read_until operation, the dynamic buffer sequence + * may contain additional data beyond that which matched the function object. + * An application will typically leave that data in the dynamic buffer sequence + * for a subsequent read_until operation to examine. + * + * @note The default implementation of the @c is_match_condition type trait + * evaluates to true for function pointers and function objects with a + * @c result_type typedef. It must be specialised for other user-defined + * function objects. + */ +template +std::size_t read_until(SyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + MatchCondition match_condition, asio::error_code& ec, + typename enable_if::value>::type* = 0); + +#if !defined(ASIO_NO_IOSTREAM) + +/// Read data into a streambuf until it contains a specified delimiter. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains the specified delimiter. The call will block + * until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains the + * delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param delim The delimiter character. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the delimiter. + * + * @throws asio::system_error Thrown on failure. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond the delimiter. An application will typically leave + * that data in the streambuf for a subsequent read_until operation to examine. + * + * @par Example + * To read data into a streambuf until a newline is encountered: + * @code asio::streambuf b; + * asio::read_until(s, b, '\n'); + * std::istream is(&b); + * std::string line; + * std::getline(is, line); @endcode + * After the @c read_until operation completes successfully, the buffer @c b + * contains the delimiter: + * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode + * The call to @c std::getline then extracts the data up to and including the + * newline (which is discarded), so that the string @c line contains: + * @code { 'a', 'b', ..., 'c' } @endcode + * The remaining data is left in the buffer @c b as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c read_until operation. + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, char delim); + +/// Read data into a streambuf until it contains a specified delimiter. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains the specified delimiter. The call will block + * until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains the + * delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param delim The delimiter character. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the delimiter. Returns 0 if an error occurred. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond the delimiter. An application will typically leave + * that data in the streambuf for a subsequent read_until operation to examine. + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, char delim, + asio::error_code& ec); + +/// Read data into a streambuf until it contains a specified delimiter. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains the specified delimiter. The call will block + * until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains the + * delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param delim The delimiter string. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the delimiter. + * + * @throws asio::system_error Thrown on failure. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond the delimiter. An application will typically leave + * that data in the streambuf for a subsequent read_until operation to examine. + * + * @par Example + * To read data into a streambuf until a newline is encountered: + * @code asio::streambuf b; + * asio::read_until(s, b, "\r\n"); + * std::istream is(&b); + * std::string line; + * std::getline(is, line); @endcode + * After the @c read_until operation completes successfully, the buffer @c b + * contains the delimiter: + * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode + * The call to @c std::getline then extracts the data up to and including the + * newline (which is discarded), so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\r' } @endcode + * The remaining data is left in the buffer @c b as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c read_until operation. + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, + ASIO_STRING_VIEW_PARAM delim); + +/// Read data into a streambuf until it contains a specified delimiter. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains the specified delimiter. The call will block + * until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains the + * delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param delim The delimiter string. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the delimiter. Returns 0 if an error occurred. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond the delimiter. An application will typically leave + * that data in the streambuf for a subsequent read_until operation to examine. + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, + ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec); + +#if defined(ASIO_HAS_BOOST_REGEX) \ + || defined(GENERATING_DOCUMENTATION) + +/// Read data into a streambuf until some part of the data it contains matches +/// a regular expression. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains some data that matches a regular expression. + * The call will block until one of the following conditions is true: + * + * @li A substring of the streambuf's get area matches the regular expression. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains data that + * matches the regular expression, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param expr The regular expression. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the substring that matches the regular expression. + * + * @throws asio::system_error Thrown on failure. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond that which matched the regular expression. An + * application will typically leave that data in the streambuf for a subsequent + * read_until operation to examine. + * + * @par Example + * To read data into a streambuf until a CR-LF sequence is encountered: + * @code asio::streambuf b; + * asio::read_until(s, b, boost::regex("\r\n")); + * std::istream is(&b); + * std::string line; + * std::getline(is, line); @endcode + * After the @c read_until operation completes successfully, the buffer @c b + * contains the data which matched the regular expression: + * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode + * The call to @c std::getline then extracts the data up to and including the + * newline (which is discarded), so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\r' } @endcode + * The remaining data is left in the buffer @c b as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c read_until operation. + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, const boost::regex& expr); + +/// Read data into a streambuf until some part of the data it contains matches +/// a regular expression. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains some data that matches a regular expression. + * The call will block until one of the following conditions is true: + * + * @li A substring of the streambuf's get area matches the regular expression. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains data that + * matches the regular expression, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param expr The regular expression. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the substring that matches the regular expression. Returns 0 if an error + * occurred. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond that which matched the regular expression. An + * application will typically leave that data in the streambuf for a subsequent + * read_until operation to examine. + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, const boost::regex& expr, + asio::error_code& ec); + +#endif // defined(ASIO_HAS_BOOST_REGEX) + // || defined(GENERATING_DOCUMENTATION) + +/// Read data into a streambuf until a function object indicates a match. +/** + * This function is used to read data into the specified streambuf until a + * user-defined match condition function object, when applied to the data + * contained in the streambuf, indicates a successful match. The call will + * block until one of the following conditions is true: + * + * @li The match condition function object returns a std::pair where the second + * element evaluates to true. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the match condition function object already indicates + * a match, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param match_condition The function object to be called to determine whether + * a match exists. The signature of the function object must be: + * @code pair match_condition(iterator begin, iterator end); + * @endcode + * where @c iterator represents the type: + * @code buffers_iterator::const_buffers_type> + * @endcode + * The iterator parameters @c begin and @c end define the range of bytes to be + * scanned to determine whether there is a match. The @c first member of the + * return value is an iterator marking one-past-the-end of the bytes that have + * been consumed by the match function. This iterator is used to calculate the + * @c begin parameter for any subsequent invocation of the match condition. The + * @c second member of the return value is true if a match has been found, false + * otherwise. + * + * @returns The number of bytes in the streambuf's get area that have been fully + * consumed by the match function. + * + * @throws asio::system_error Thrown on failure. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond that which matched the function object. An application + * will typically leave that data in the streambuf for a subsequent read_until + * operation to examine. + * + * @note The default implementation of the @c is_match_condition type trait + * evaluates to true for function pointers and function objects with a + * @c result_type typedef. It must be specialised for other user-defined + * function objects. + * + * @par Examples + * To read data into a streambuf until whitespace is encountered: + * @code typedef asio::buffers_iterator< + * asio::streambuf::const_buffers_type> iterator; + * + * std::pair + * match_whitespace(iterator begin, iterator end) + * { + * iterator i = begin; + * while (i != end) + * if (std::isspace(*i++)) + * return std::make_pair(i, true); + * return std::make_pair(i, false); + * } + * ... + * asio::streambuf b; + * asio::read_until(s, b, match_whitespace); + * @endcode + * + * To read data into a streambuf until a matching character is found: + * @code class match_char + * { + * public: + * explicit match_char(char c) : c_(c) {} + * + * template + * std::pair operator()( + * Iterator begin, Iterator end) const + * { + * Iterator i = begin; + * while (i != end) + * if (c_ == *i++) + * return std::make_pair(i, true); + * return std::make_pair(i, false); + * } + * + * private: + * char c_; + * }; + * + * namespace asio { + * template <> struct is_match_condition + * : public boost::true_type {}; + * } // namespace asio + * ... + * asio::streambuf b; + * asio::read_until(s, b, match_char('a')); + * @endcode + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, MatchCondition match_condition, + typename enable_if::value>::type* = 0); + +/// Read data into a streambuf until a function object indicates a match. +/** + * This function is used to read data into the specified streambuf until a + * user-defined match condition function object, when applied to the data + * contained in the streambuf, indicates a successful match. The call will + * block until one of the following conditions is true: + * + * @li The match condition function object returns a std::pair where the second + * element evaluates to true. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the match condition function object already indicates + * a match, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param match_condition The function object to be called to determine whether + * a match exists. The signature of the function object must be: + * @code pair match_condition(iterator begin, iterator end); + * @endcode + * where @c iterator represents the type: + * @code buffers_iterator::const_buffers_type> + * @endcode + * The iterator parameters @c begin and @c end define the range of bytes to be + * scanned to determine whether there is a match. The @c first member of the + * return value is an iterator marking one-past-the-end of the bytes that have + * been consumed by the match function. This iterator is used to calculate the + * @c begin parameter for any subsequent invocation of the match condition. The + * @c second member of the return value is true if a match has been found, false + * otherwise. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the streambuf's get area that have been fully + * consumed by the match function. Returns 0 if an error occurred. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond that which matched the function object. An application + * will typically leave that data in the streambuf for a subsequent read_until + * operation to examine. + * + * @note The default implementation of the @c is_match_condition type trait + * evaluates to true for function pointers and function objects with a + * @c result_type typedef. It must be specialised for other user-defined + * function objects. + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, + MatchCondition match_condition, asio::error_code& ec, + typename enable_if::value>::type* = 0); + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +/*@}*/ +/** + * @defgroup async_read_until asio::async_read_until + * + * @brief Start an asynchronous operation to read data into a dynamic buffer + * sequence, or into a streambuf, until it contains a delimiter, matches a + * regular expression, or a function object indicates a match. + */ +/*@{*/ + +/// Start an asynchronous operation to read data into a dynamic buffer sequence +/// until it contains a specified delimiter. +/** + * This function is used to asynchronously read data into the specified dynamic + * buffer sequence until the dynamic buffer sequence's get area contains the + * specified delimiter. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li The get area of the dynamic buffer sequence contains the specified + * delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. If + * the dynamic buffer sequence's get area already contains the delimiter, this + * asynchronous operation completes immediately. The program must ensure that + * the stream performs no other read operations (such as async_read, + * async_read_until, the stream's async_read_some function, or any other + * composed operations that perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param buffers The dynamic buffer sequence 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 delim The delimiter character. + * + * @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( + * // Result of operation. + * const asio::error_code& error, + * + * // The number of bytes in the dynamic buffer sequence's + * // get area up to and including the delimiter. + * // 0 if an error occurred. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + * + * @note After a successful async_read_until operation, the dynamic buffer + * sequence may contain additional data beyond the delimiter. An application + * will typically leave that data in the dynamic buffer sequence for a + * subsequent async_read_until operation to examine. + * + * @par Example + * To asynchronously read data into a @c std::string until a newline is + * encountered: + * @code std::string data; + * ... + * void handler(const asio::error_code& e, std::size_t size) + * { + * if (!e) + * { + * std::string line = data.substr(0, n); + * data.erase(0, n); + * ... + * } + * } + * ... + * asio::async_read_until(s, data, '\n', handler); @endcode + * After the @c async_read_until operation completes successfully, the buffer + * @c data contains the delimiter: + * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode + * The call to @c substr then extracts the data up to and including the + * delimiter, so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\n' } @endcode + * After the call to @c erase, the remaining data is left in the buffer @c data + * as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c async_read_until operation. + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + char delim, ASIO_MOVE_ARG(ReadHandler) handler); + +/// Start an asynchronous operation to read data into a dynamic buffer sequence +/// until it contains a specified delimiter. +/** + * This function is used to asynchronously read data into the specified dynamic + * buffer sequence until the dynamic buffer sequence's get area contains the + * specified delimiter. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li The get area of the dynamic buffer sequence contains the specified + * delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. If + * the dynamic buffer sequence's get area already contains the delimiter, this + * asynchronous operation completes immediately. The program must ensure that + * the stream performs no other read operations (such as async_read, + * async_read_until, the stream's async_read_some function, or any other + * composed operations that perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param buffers The dynamic buffer sequence 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 delim The delimiter string. + * + * @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( + * // Result of operation. + * const asio::error_code& error, + * + * // The number of bytes in the dynamic buffer sequence's + * // get area up to and including the delimiter. + * // 0 if an error occurred. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + * + * @note After a successful async_read_until operation, the dynamic buffer + * sequence may contain additional data beyond the delimiter. An application + * will typically leave that data in the dynamic buffer sequence for a + * subsequent async_read_until operation to examine. + * + * @par Example + * To asynchronously read data into a @c std::string until a CR-LF sequence is + * encountered: + * @code std::string data; + * ... + * void handler(const asio::error_code& e, std::size_t size) + * { + * if (!e) + * { + * std::string line = data.substr(0, n); + * data.erase(0, n); + * ... + * } + * } + * ... + * asio::async_read_until(s, data, "\r\n", handler); @endcode + * After the @c async_read_until operation completes successfully, the string + * @c data contains the delimiter: + * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode + * The call to @c substr then extracts the data up to and including the + * delimiter, so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode + * After the call to @c erase, the remaining data is left in the string @c data + * as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c async_read_until operation. + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + ASIO_STRING_VIEW_PARAM delim, + ASIO_MOVE_ARG(ReadHandler) handler); + +#if !defined(ASIO_NO_EXTENSIONS) +#if defined(ASIO_HAS_BOOST_REGEX) \ + || defined(GENERATING_DOCUMENTATION) + +/// Start an asynchronous operation to read data into a dynamic buffer sequence +/// until some part of its data matches a regular expression. +/** + * This function is used to asynchronously read data into the specified dynamic + * buffer sequence until the dynamic buffer sequence's get area contains some + * data that matches a regular expression. The function call always returns + * immediately. The asynchronous operation will continue until one of the + * following conditions is true: + * + * @li A substring of the dynamic buffer sequence's get area matches the regular + * expression. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. If + * the dynamic buffer sequence's get area already contains data that matches + * the regular expression, this asynchronous operation completes immediately. + * The program must ensure that the stream performs no other read operations + * (such as async_read, async_read_until, the stream's async_read_some + * function, or any other composed operations that perform reads) until this + * operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param buffers The dynamic buffer sequence 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 expr The regular expression. + * + * @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( + * // Result of operation. + * const asio::error_code& error, + * + * // The number of bytes in the dynamic buffer + * // sequence's get area up to and including the + * // substring that matches the regular expression. + * // 0 if an error occurred. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + * + * @note After a successful async_read_until operation, the dynamic buffer + * sequence may contain additional data beyond that which matched the regular + * expression. An application will typically leave that data in the dynamic + * buffer sequence for a subsequent async_read_until operation to examine. + * + * @par Example + * To asynchronously read data into a @c std::string until a CR-LF sequence is + * encountered: + * @code std::string data; + * ... + * void handler(const asio::error_code& e, std::size_t size) + * { + * if (!e) + * { + * std::string line = data.substr(0, n); + * data.erase(0, n); + * ... + * } + * } + * ... + * asio::async_read_until(s, data, + * boost::regex("\r\n"), handler); @endcode + * After the @c async_read_until operation completes successfully, the string + * @c data contains the data which matched the regular expression: + * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode + * The call to @c substr then extracts the data up to and including the match, + * so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode + * After the call to @c erase, the remaining data is left in the string @c data + * as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c async_read_until operation. + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + const boost::regex& expr, + ASIO_MOVE_ARG(ReadHandler) handler); + +#endif // defined(ASIO_HAS_BOOST_REGEX) + // || defined(GENERATING_DOCUMENTATION) + +/// Start an asynchronous operation to read data into a dynamic buffer sequence +/// until a function object indicates a match. +/** + * This function is used to asynchronously read data into the specified dynamic + * buffer sequence until a user-defined match condition function object, when + * applied to the data contained in the dynamic buffer sequence, indicates a + * successful match. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li The match condition function object returns a std::pair where the second + * element evaluates to true. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. If + * the match condition function object already indicates a match, this + * asynchronous operation completes immediately. The program must ensure that + * the stream performs no other read operations (such as async_read, + * async_read_until, the stream's async_read_some function, or any other + * composed operations that perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param buffers The dynamic buffer sequence 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 match_condition The function object to be called to determine whether + * a match exists. The signature of the function object must be: + * @code pair match_condition(iterator begin, iterator end); + * @endcode + * where @c iterator represents the type: + * @code buffers_iterator + * @endcode + * The iterator parameters @c begin and @c end define the range of bytes to be + * scanned to determine whether there is a match. The @c first member of the + * return value is an iterator marking one-past-the-end of the bytes that have + * been consumed by the match function. This iterator is used to calculate the + * @c begin parameter for any subsequent invocation of the match condition. The + * @c second member of the return value is true if a match has been found, false + * otherwise. + * + * @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( + * // Result of operation. + * const asio::error_code& error, + * + * // The number of bytes in the dynamic buffer sequence's + * // get area that have been fully consumed by the match + * // function. O if an error occurred. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + * + * @note After a successful async_read_until operation, the dynamic buffer + * sequence may contain additional data beyond that which matched the function + * object. An application will typically leave that data in the dynamic buffer + * sequence for a subsequent async_read_until operation to examine. + * + * @note The default implementation of the @c is_match_condition type trait + * evaluates to true for function pointers and function objects with a + * @c result_type typedef. It must be specialised for other user-defined + * function objects. + * + * @par Examples + * To asynchronously read data into a @c std::string until whitespace is + * encountered: + * @code typedef asio::buffers_iterator< + * asio::const_buffers_1> iterator; + * + * std::pair + * match_whitespace(iterator begin, iterator end) + * { + * iterator i = begin; + * while (i != end) + * if (std::isspace(*i++)) + * return std::make_pair(i, true); + * return std::make_pair(i, false); + * } + * ... + * void handler(const asio::error_code& e, std::size_t size); + * ... + * std::string data; + * asio::async_read_until(s, data, match_whitespace, handler); + * @endcode + * + * To asynchronously read data into a @c std::string until a matching character + * is found: + * @code class match_char + * { + * public: + * explicit match_char(char c) : c_(c) {} + * + * template + * std::pair operator()( + * Iterator begin, Iterator end) const + * { + * Iterator i = begin; + * while (i != end) + * if (c_ == *i++) + * return std::make_pair(i, true); + * return std::make_pair(i, false); + * } + * + * private: + * char c_; + * }; + * + * namespace asio { + * template <> struct is_match_condition + * : public boost::true_type {}; + * } // namespace asio + * ... + * void handler(const asio::error_code& e, std::size_t size); + * ... + * std::string data; + * asio::async_read_until(s, data, match_char('a'), handler); + * @endcode + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + MatchCondition match_condition, ASIO_MOVE_ARG(ReadHandler) handler, + typename enable_if::value>::type* = 0); + +#if !defined(ASIO_NO_IOSTREAM) + +/// Start an asynchronous operation to read data into a streambuf until it +/// contains a specified delimiter. +/** + * This function is used to asynchronously read data into the specified + * streambuf until the streambuf's get area contains the specified delimiter. + * The function call always returns immediately. The asynchronous operation + * will continue until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. If + * the streambuf's get area already contains the delimiter, this asynchronous + * operation completes immediately. The program must ensure that the stream + * performs no other read operations (such as async_read, async_read_until, the + * stream's async_read_some function, or any other composed operations that + * perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. Ownership of + * the streambuf is retained by the caller, which must guarantee that it remains + * valid until the handler is called. + * + * @param delim The delimiter character. + * + * @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( + * // Result of operation. + * const asio::error_code& error, + * + * // The number of bytes in the streambuf's get + * // area up to and including the delimiter. + * // 0 if an error occurred. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + * + * @note After a successful async_read_until operation, the streambuf may + * contain additional data beyond the delimiter. An application will typically + * leave that data in the streambuf for a subsequent async_read_until operation + * to examine. + * + * @par Example + * To asynchronously read data into a streambuf until a newline is encountered: + * @code asio::streambuf b; + * ... + * void handler(const asio::error_code& e, std::size_t size) + * { + * if (!e) + * { + * std::istream is(&b); + * std::string line; + * std::getline(is, line); + * ... + * } + * } + * ... + * asio::async_read_until(s, b, '\n', handler); @endcode + * After the @c async_read_until operation completes successfully, the buffer + * @c b contains the delimiter: + * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode + * The call to @c std::getline then extracts the data up to and including the + * newline (which is discarded), so that the string @c line contains: + * @code { 'a', 'b', ..., 'c' } @endcode + * The remaining data is left in the buffer @c b as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c async_read_until operation. + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, + char delim, ASIO_MOVE_ARG(ReadHandler) handler); + +/// Start an asynchronous operation to read data into a streambuf until it +/// contains a specified delimiter. +/** + * This function is used to asynchronously read data into the specified + * streambuf until the streambuf's get area contains the specified delimiter. + * The function call always returns immediately. The asynchronous operation + * will continue until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. If + * the streambuf's get area already contains the delimiter, this asynchronous + * operation completes immediately. The program must ensure that the stream + * performs no other read operations (such as async_read, async_read_until, the + * stream's async_read_some function, or any other composed operations that + * perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. Ownership of + * the streambuf is retained by the caller, which must guarantee that it remains + * valid until the handler is called. + * + * @param delim The delimiter string. + * + * @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( + * // Result of operation. + * const asio::error_code& error, + * + * // The number of bytes in the streambuf's get + * // area up to and including the delimiter. + * // 0 if an error occurred. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + * + * @note After a successful async_read_until operation, the streambuf may + * contain additional data beyond the delimiter. An application will typically + * leave that data in the streambuf for a subsequent async_read_until operation + * to examine. + * + * @par Example + * To asynchronously read data into a streambuf until a newline is encountered: + * @code asio::streambuf b; + * ... + * void handler(const asio::error_code& e, std::size_t size) + * { + * if (!e) + * { + * std::istream is(&b); + * std::string line; + * std::getline(is, line); + * ... + * } + * } + * ... + * asio::async_read_until(s, b, "\r\n", handler); @endcode + * After the @c async_read_until operation completes successfully, the buffer + * @c b contains the delimiter: + * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode + * The call to @c std::getline then extracts the data up to and including the + * newline (which is discarded), so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\r' } @endcode + * The remaining data is left in the buffer @c b as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c async_read_until operation. + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, + ASIO_STRING_VIEW_PARAM delim, + ASIO_MOVE_ARG(ReadHandler) handler); + +#if defined(ASIO_HAS_BOOST_REGEX) \ + || defined(GENERATING_DOCUMENTATION) + +/// Start an asynchronous operation to read data into a streambuf until some +/// part of its data matches a regular expression. +/** + * This function is used to asynchronously read data into the specified + * streambuf until the streambuf's get area contains some data that matches a + * regular expression. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li A substring of the streambuf's get area matches the regular expression. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. If + * the streambuf's get area already contains data that matches the regular + * expression, this asynchronous operation completes immediately. The program + * must ensure that the stream performs no other read operations (such as + * async_read, async_read_until, the stream's async_read_some function, or any + * other composed operations that perform reads) until this operation + * completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. Ownership of + * the streambuf is retained by the caller, which must guarantee that it remains + * valid until the handler is called. + * + * @param expr The regular expression. + * + * @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( + * // Result of operation. + * const asio::error_code& error, + * + * // The number of bytes in the streambuf's get + * // area up to and including the substring + * // that matches the regular. expression. + * // 0 if an error occurred. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + * + * @note After a successful async_read_until operation, the streambuf may + * contain additional data beyond that which matched the regular expression. An + * application will typically leave that data in the streambuf for a subsequent + * async_read_until operation to examine. + * + * @par Example + * To asynchronously read data into a streambuf until a CR-LF sequence is + * encountered: + * @code asio::streambuf b; + * ... + * void handler(const asio::error_code& e, std::size_t size) + * { + * if (!e) + * { + * std::istream is(&b); + * std::string line; + * std::getline(is, line); + * ... + * } + * } + * ... + * asio::async_read_until(s, b, boost::regex("\r\n"), handler); @endcode + * After the @c async_read_until operation completes successfully, the buffer + * @c b contains the data which matched the regular expression: + * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode + * The call to @c std::getline then extracts the data up to and including the + * newline (which is discarded), so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\r' } @endcode + * The remaining data is left in the buffer @c b as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c async_read_until operation. + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, const boost::regex& expr, + ASIO_MOVE_ARG(ReadHandler) handler); + +#endif // defined(ASIO_HAS_BOOST_REGEX) + // || defined(GENERATING_DOCUMENTATION) + +/// Start an asynchronous operation to read data into a streambuf until a +/// function object indicates a match. +/** + * This function is used to asynchronously read data into the specified + * streambuf until a user-defined match condition function object, when applied + * to the data contained in the streambuf, indicates a successful match. The + * function call always returns immediately. The asynchronous operation will + * continue until one of the following conditions is true: + * + * @li The match condition function object returns a std::pair where the second + * element evaluates to true. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. If + * the match condition function object already indicates a match, this + * asynchronous operation completes immediately. The program must ensure that + * the stream performs no other read operations (such as async_read, + * async_read_until, the stream's async_read_some function, or any other + * composed operations that perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param match_condition The function object to be called to determine whether + * a match exists. The signature of the function object must be: + * @code pair match_condition(iterator begin, iterator end); + * @endcode + * where @c iterator represents the type: + * @code buffers_iterator::const_buffers_type> + * @endcode + * The iterator parameters @c begin and @c end define the range of bytes to be + * scanned to determine whether there is a match. The @c first member of the + * return value is an iterator marking one-past-the-end of the bytes that have + * been consumed by the match function. This iterator is used to calculate the + * @c begin parameter for any subsequent invocation of the match condition. The + * @c second member of the return value is true if a match has been found, false + * otherwise. + * + * @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( + * // Result of operation. + * const asio::error_code& error, + * + * // The number of bytes in the streambuf's get + * // area that have been fully consumed by the + * // match function. O if an error occurred. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + * + * @note After a successful async_read_until operation, the streambuf may + * contain additional data beyond that which matched the function object. An + * application will typically leave that data in the streambuf for a subsequent + * async_read_until operation to examine. + * + * @note The default implementation of the @c is_match_condition type trait + * evaluates to true for function pointers and function objects with a + * @c result_type typedef. It must be specialised for other user-defined + * function objects. + * + * @par Examples + * To asynchronously read data into a streambuf until whitespace is encountered: + * @code typedef asio::buffers_iterator< + * asio::streambuf::const_buffers_type> iterator; + * + * std::pair + * match_whitespace(iterator begin, iterator end) + * { + * iterator i = begin; + * while (i != end) + * if (std::isspace(*i++)) + * return std::make_pair(i, true); + * return std::make_pair(i, false); + * } + * ... + * void handler(const asio::error_code& e, std::size_t size); + * ... + * asio::streambuf b; + * asio::async_read_until(s, b, match_whitespace, handler); + * @endcode + * + * To asynchronously read data into a streambuf until a matching character is + * found: + * @code class match_char + * { + * public: + * explicit match_char(char c) : c_(c) {} + * + * template + * std::pair operator()( + * Iterator begin, Iterator end) const + * { + * Iterator i = begin; + * while (i != end) + * if (c_ == *i++) + * return std::make_pair(i, true); + * return std::make_pair(i, false); + * } + * + * private: + * char c_; + * }; + * + * namespace asio { + * template <> struct is_match_condition + * : public boost::true_type {}; + * } // namespace asio + * ... + * void handler(const asio::error_code& e, std::size_t size); + * ... + * asio::streambuf b; + * asio::async_read_until(s, b, match_char('a'), handler); + * @endcode + */ +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, + MatchCondition match_condition, ASIO_MOVE_ARG(ReadHandler) handler, + typename enable_if::value>::type* = 0); + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +/*@}*/ + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/read_until.hpp" + +#endif // ASIO_READ_UNTIL_HPP diff --git a/tools/sdk/include/asio/asio/seq_packet_socket_service.hpp b/tools/sdk/include/asio/asio/seq_packet_socket_service.hpp new file mode 100644 index 00000000..7e6824d4 --- /dev/null +++ b/tools/sdk/include/asio/asio/seq_packet_socket_service.hpp @@ -0,0 +1,416 @@ +// +// seq_packet_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SEQ_PACKET_SOCKET_SERVICE_HPP +#define ASIO_SEQ_PACKET_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#include +#include "asio/async_result.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/null_socket_service.hpp" +#elif defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_socket_service.hpp" +#else +# include "asio/detail/reactive_socket_service.hpp" +#endif + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Default service implementation for a sequenced packet socket. +template +class seq_packet_socket_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base< + seq_packet_socket_service > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static 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(ASIO_WINDOWS_RUNTIME) + typedef detail::null_socket_service service_impl_type; +#elif defined(ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service service_impl_type; +#else + typedef detail::reactive_socket_service service_impl_type; +#endif + +public: + /// The type of a sequenced packet 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 sequenced packet socket service for the specified + /// io_context. + explicit seq_packet_socket_service(asio::io_context& io_context) + : asio::detail::service_base< + seq_packet_socket_service >(io_context), + service_impl_(io_context) + { + } + + /// Construct a new sequenced packet socket implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new sequenced packet socket implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another sequenced packet socket implementation. + void move_assign(implementation_type& impl, + seq_packet_socket_service& 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 seq_packet_socket_service; + + /// Move-construct a new sequenced packet socket implementation from another + /// protocol type. + template + void converting_move_construct(implementation_type& impl, + seq_packet_socket_service& other_service, + typename seq_packet_socket_service< + 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(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy a sequenced packet socket implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Open a sequenced packet socket. + ASIO_SYNC_OP_VOID open(implementation_type& impl, + const protocol_type& protocol, asio::error_code& ec) + { + if (protocol.type() == ASIO_OS_DEF(SOCK_SEQPACKET)) + service_impl_.open(impl, protocol, ec); + else + ec = asio::error::invalid_argument; + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Assign an existing native socket to a sequenced packet socket. + ASIO_SYNC_OP_VOID assign(implementation_type& impl, + const protocol_type& protocol, const native_handle_type& native_socket, + asio::error_code& ec) + { + service_impl_.assign(impl, protocol, native_socket, ec); + 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 sequenced packet socket implementation. + ASIO_SYNC_OP_VOID close(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.close(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Release ownership of the underlying socket. + native_handle_type release(implementation_type& impl, + asio::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. + ASIO_SYNC_OP_VOID cancel(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.cancel(impl, ec); + 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, + asio::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, + asio::error_code& ec) const + { + return service_impl_.available(impl, ec); + } + + /// Bind the sequenced packet socket to the specified local endpoint. + ASIO_SYNC_OP_VOID bind(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + service_impl_.bind(impl, endpoint, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Connect the sequenced packet socket to the specified endpoint. + ASIO_SYNC_OP_VOID connect(implementation_type& impl, + const endpoint_type& peer_endpoint, asio::error_code& ec) + { + service_impl_.connect(impl, peer_endpoint, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Start an asynchronous connect. + template + ASIO_INITFN_RESULT_TYPE(ConnectHandler, + void (asio::error_code)) + async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, + 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 + ASIO_SYNC_OP_VOID set_option(implementation_type& impl, + const SettableSocketOption& option, asio::error_code& ec) + { + service_impl_.set_option(impl, option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get a socket option. + template + ASIO_SYNC_OP_VOID get_option(const implementation_type& impl, + GettableSocketOption& option, asio::error_code& ec) const + { + service_impl_.get_option(impl, option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Perform an IO control command on the socket. + template + ASIO_SYNC_OP_VOID io_control(implementation_type& impl, + IoControlCommand& command, asio::error_code& ec) + { + service_impl_.io_control(impl, command, ec); + 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. + ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl, + bool mode, asio::error_code& ec) + { + service_impl_.non_blocking(impl, mode, ec); + 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. + ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl, + bool mode, asio::error_code& ec) + { + service_impl_.native_non_blocking(impl, mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.remote_endpoint(impl, ec); + } + + /// Disable sends or receives on the socket. + ASIO_SYNC_OP_VOID shutdown(implementation_type& impl, + socket_base::shutdown_type what, asio::error_code& ec) + { + service_impl_.shutdown(impl, what, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Wait for the socket to become ready to read, ready to write, or to have + /// pending error conditions. + ASIO_SYNC_OP_VOID wait(implementation_type& impl, + socket_base::wait_type w, asio::error_code& ec) + { + service_impl_.wait(impl, w, ec); + 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 + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(implementation_type& impl, socket_base::wait_type w, + 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, asio::error_code& ec) + { + return service_impl_.send(impl, buffers, flags, ec); + } + + /// Start an asynchronous send. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send(implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, + 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 in_flags, + socket_base::message_flags& out_flags, asio::error_code& ec) + { + return service_impl_.receive_with_flags(impl, + buffers, in_flags, out_flags, ec); + } + + /// Start an asynchronous receive. + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, socket_base::message_flags in_flags, + socket_base::message_flags& out_flags, + ASIO_MOVE_ARG(ReadHandler) handler) + { + async_completion init(handler); + + service_impl_.async_receive_with_flags(impl, + buffers, in_flags, out_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 + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_SEQ_PACKET_SOCKET_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/serial_port.hpp b/tools/sdk/include/asio/asio/serial_port.hpp new file mode 100644 index 00000000..27bb63ef --- /dev/null +++ b/tools/sdk/include/asio/asio/serial_port.hpp @@ -0,0 +1,769 @@ +// +// serial_port.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// 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 ASIO_SERIAL_PORT_HPP +#define ASIO_SERIAL_PORT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_SERIAL_PORT) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/async_result.hpp" +#include "asio/basic_io_object.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/serial_port_base.hpp" + +#if defined(ASIO_HAS_MOVE) +# include +#endif // defined(ASIO_HAS_MOVE) + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/basic_serial_port.hpp" +#else // defined(ASIO_ENABLE_OLD_SERVICES) +# if defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_serial_port_service.hpp" +# define ASIO_SVC_T detail::win_iocp_serial_port_service +# else +# include "asio/detail/reactive_serial_port_service.hpp" +# define ASIO_SVC_T detail::reactive_serial_port_service +# endif +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +#if defined(ASIO_ENABLE_OLD_SERVICES) +// Typedef for the typical usage of a serial port. +typedef basic_serial_port<> serial_port; +#else // defined(ASIO_ENABLE_OLD_SERVICES) +/// Provides serial port functionality. +/** + * The serial_port class provides a wrapper over serial port functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class serial_port + : ASIO_SVC_ACCESS basic_io_object, + public serial_port_base +{ +public: + /// The type of the executor associated with the object. + typedef io_context::executor_type executor_type; + + /// The native representation of a serial port. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef ASIO_SVC_T::native_handle_type native_handle_type; +#endif + + /// A basic_serial_port is always the lowest layer. + typedef serial_port lowest_layer_type; + + /// Construct a serial_port without opening it. + /** + * This constructor creates a serial port without opening it. + * + * @param io_context The io_context object that the serial port will use to + * dispatch handlers for any asynchronous operations performed on the port. + */ + explicit serial_port(asio::io_context& io_context) + : basic_io_object(io_context) + { + } + + /// Construct and open a serial_port. + /** + * This constructor creates and opens a serial port for the specified device + * name. + * + * @param io_context The io_context object that the serial port will use to + * dispatch handlers for any asynchronous operations performed on the port. + * + * @param device The platform-specific device name for this serial + * port. + */ + explicit serial_port(asio::io_context& io_context, + const char* device) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().open(this->get_implementation(), device, ec); + asio::detail::throw_error(ec, "open"); + } + + /// Construct and open a serial_port. + /** + * This constructor creates and opens a serial port for the specified device + * name. + * + * @param io_context The io_context object that the serial port will use to + * dispatch handlers for any asynchronous operations performed on the port. + * + * @param device The platform-specific device name for this serial + * port. + */ + explicit serial_port(asio::io_context& io_context, + const std::string& device) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().open(this->get_implementation(), device, ec); + asio::detail::throw_error(ec, "open"); + } + + /// Construct a serial_port on an existing native serial port. + /** + * This constructor creates a serial port object to hold an existing native + * serial port. + * + * @param io_context The io_context object that the serial port will use to + * dispatch handlers for any asynchronous operations performed on the port. + * + * @param native_serial_port A native serial port. + * + * @throws asio::system_error Thrown on failure. + */ + serial_port(asio::io_context& io_context, + const native_handle_type& native_serial_port) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), + native_serial_port, ec); + asio::detail::throw_error(ec, "assign"); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a serial_port from another. + /** + * This constructor moves a serial port from one object to another. + * + * @param other The other serial_port 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 serial_port(io_context&) constructor. + */ + serial_port(serial_port&& other) + : basic_io_object(std::move(other)) + { + } + + /// Move-assign a serial_port from another. + /** + * This assignment operator moves a serial port from one object to another. + * + * @param other The other serial_port 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 serial_port(io_context&) constructor. + */ + serial_port& operator=(serial_port&& other) + { + basic_io_object::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroys the serial port. + /** + * This function destroys the serial port, cancelling any outstanding + * asynchronous wait operations associated with the serial port as if by + * calling @c cancel. + */ + ~serial_port() + { + } + +#if !defined(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. + */ + 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. + */ + asio::io_context& get_io_service() + { + return basic_io_object::get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return basic_io_object::get_executor(); + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since a serial_port 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 serial_port 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; + } + + /// Open the serial port using the specified device name. + /** + * This function opens the serial port for the specified device name. + * + * @param device The platform-specific device name. + * + * @throws asio::system_error Thrown on failure. + */ + void open(const std::string& device) + { + asio::error_code ec; + this->get_service().open(this->get_implementation(), device, ec); + asio::detail::throw_error(ec, "open"); + } + + /// Open the serial port using the specified device name. + /** + * This function opens the serial port using the given platform-specific + * device name. + * + * @param device The platform-specific device name. + * + * @param ec Set the indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID open(const std::string& device, + asio::error_code& ec) + { + this->get_service().open(this->get_implementation(), device, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Assign an existing native serial port to the serial port. + /* + * This function opens the serial port to hold an existing native serial port. + * + * @param native_serial_port A native serial port. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const native_handle_type& native_serial_port) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), + native_serial_port, ec); + asio::detail::throw_error(ec, "assign"); + } + + /// Assign an existing native serial port to the serial port. + /* + * This function opens the serial port to hold an existing native serial port. + * + * @param native_serial_port A native serial port. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port, + asio::error_code& ec) + { + this->get_service().assign(this->get_implementation(), + native_serial_port, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the serial port is open. + bool is_open() const + { + return this->get_service().is_open(this->get_implementation()); + } + + /// Close the serial port. + /** + * This function is used to close the serial port. Any asynchronous read or + * write operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void close() + { + asio::error_code ec; + this->get_service().close(this->get_implementation(), ec); + asio::detail::throw_error(ec, "close"); + } + + /// Close the serial port. + /** + * This function is used to close the serial port. Any asynchronous read or + * write operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + this->get_service().close(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native serial port representation. + /** + * This function may be used to obtain the underlying representation of the + * serial port. This is intended to allow access to native serial port + * 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 serial port. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel"); + } + + /// Cancel all asynchronous operations associated with the serial port. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) + { + this->get_service().cancel(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Send a break sequence to the serial port. + /** + * This function causes a break sequence of platform-specific duration to be + * sent out the serial port. + * + * @throws asio::system_error Thrown on failure. + */ + void send_break() + { + asio::error_code ec; + this->get_service().send_break(this->get_implementation(), ec); + asio::detail::throw_error(ec, "send_break"); + } + + /// Send a break sequence to the serial port. + /** + * This function causes a break sequence of platform-specific duration to be + * sent out the serial port. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID send_break(asio::error_code& ec) + { + this->get_service().send_break(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Set an option on the serial port. + /** + * This function is used to set an option on the serial port. + * + * @param option The option value to be set on the serial port. + * + * @throws asio::system_error Thrown on failure. + * + * @sa SettableSerialPortOption @n + * asio::serial_port_base::baud_rate @n + * asio::serial_port_base::flow_control @n + * asio::serial_port_base::parity @n + * asio::serial_port_base::stop_bits @n + * asio::serial_port_base::character_size + */ + template + void set_option(const SettableSerialPortOption& option) + { + asio::error_code ec; + this->get_service().set_option(this->get_implementation(), option, ec); + asio::detail::throw_error(ec, "set_option"); + } + + /// Set an option on the serial port. + /** + * This function is used to set an option on the serial port. + * + * @param option The option value to be set on the serial port. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa SettableSerialPortOption @n + * asio::serial_port_base::baud_rate @n + * asio::serial_port_base::flow_control @n + * asio::serial_port_base::parity @n + * asio::serial_port_base::stop_bits @n + * asio::serial_port_base::character_size + */ + template + ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option, + asio::error_code& ec) + { + this->get_service().set_option(this->get_implementation(), option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get an option from the serial port. + /** + * This function is used to get the current value of an option on the serial + * port. + * + * @param option The option value to be obtained from the serial port. + * + * @throws asio::system_error Thrown on failure. + * + * @sa GettableSerialPortOption @n + * asio::serial_port_base::baud_rate @n + * asio::serial_port_base::flow_control @n + * asio::serial_port_base::parity @n + * asio::serial_port_base::stop_bits @n + * asio::serial_port_base::character_size + */ + template + void get_option(GettableSerialPortOption& option) + { + asio::error_code ec; + this->get_service().get_option(this->get_implementation(), option, ec); + asio::detail::throw_error(ec, "get_option"); + } + + /// Get an option from the serial port. + /** + * This function is used to get the current value of an option on the serial + * port. + * + * @param option The option value to be obtained from the serial port. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa GettableSerialPortOption @n + * asio::serial_port_base::baud_rate @n + * asio::serial_port_base::flow_control @n + * asio::serial_port_base::parity @n + * asio::serial_port_base::stop_bits @n + * asio::serial_port_base::character_size + */ + template + ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option, + asio::error_code& ec) + { + this->get_service().get_option(this->get_implementation(), option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Write some data to the serial port. + /** + * This function is used to write data to the serial port. 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 serial port. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * 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 + * serial_port.write_some(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) + { + asio::error_code ec; + std::size_t s = this->get_service().write_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "write_some"); + return s; + } + + /// Write some data to the serial port. + /** + * This function is used to write data to the serial port. 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 serial port. + * + * @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, + asio::error_code& ec) + { + return this->get_service().write_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write data to the serial port. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be written to the serial port. + * 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 asio::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 + * 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 + * serial_port.async_write_some(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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + async_completion init(handler); + + this->get_service().async_write_some( + this->get_implementation(), buffers, init.completion_handler); + + return init.result.get(); + } + + /// Read some data from the serial port. + /** + * This function is used to read data from the serial port. 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 asio::system_error Thrown on failure. An error code of + * 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 + * serial_port.read_some(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) + { + asio::error_code ec; + std::size_t s = this->get_service().read_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "read_some"); + return s; + } + + /// Read some data from the serial port. + /** + * This function is used to read data from the serial port. 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, + asio::error_code& ec) + { + return this->get_service().read_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read data from the serial port. + * 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 asio::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 + * 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 + * serial_port.async_read_some(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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + async_completion init(handler); + + this->get_service().async_read_some( + this->get_implementation(), buffers, init.completion_handler); + + return init.result.get(); + } +}; +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if !defined(ASIO_ENABLE_OLD_SERVICES) +# undef ASIO_SVC_T +#endif // !defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // defined(ASIO_HAS_SERIAL_PORT) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_SERIAL_PORT_HPP diff --git a/tools/sdk/include/asio/asio/serial_port_base.hpp b/tools/sdk/include/asio/asio/serial_port_base.hpp new file mode 100644 index 00000000..feb5b9df --- /dev/null +++ b/tools/sdk/include/asio/asio/serial_port_base.hpp @@ -0,0 +1,167 @@ +// +// serial_port_base.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// 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 ASIO_SERIAL_PORT_BASE_HPP +#define ASIO_SERIAL_PORT_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_SERIAL_PORT) \ + || defined(GENERATING_DOCUMENTATION) + +#if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) +# include +#endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) + +#include "asio/detail/socket_types.hpp" +#include "asio/error_code.hpp" + +#if defined(GENERATING_DOCUMENTATION) +# define ASIO_OPTION_STORAGE implementation_defined +#elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) +# define ASIO_OPTION_STORAGE DCB +#else +# define ASIO_OPTION_STORAGE termios +#endif + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// The serial_port_base class is used as a base for the basic_serial_port class +/// template so that we have a common place to define the serial port options. +class serial_port_base +{ +public: + /// Serial port option to permit changing the baud rate. + /** + * Implements changing the baud rate for a given serial port. + */ + class baud_rate + { + public: + explicit baud_rate(unsigned int rate = 0); + unsigned int value() const; + ASIO_DECL ASIO_SYNC_OP_VOID store( + ASIO_OPTION_STORAGE& storage, + asio::error_code& ec) const; + ASIO_DECL ASIO_SYNC_OP_VOID load( + const ASIO_OPTION_STORAGE& storage, + asio::error_code& ec); + private: + unsigned int value_; + }; + + /// Serial port option to permit changing the flow control. + /** + * Implements changing the flow control for a given serial port. + */ + class flow_control + { + public: + enum type { none, software, hardware }; + ASIO_DECL explicit flow_control(type t = none); + type value() const; + ASIO_DECL ASIO_SYNC_OP_VOID store( + ASIO_OPTION_STORAGE& storage, + asio::error_code& ec) const; + ASIO_DECL ASIO_SYNC_OP_VOID load( + const ASIO_OPTION_STORAGE& storage, + asio::error_code& ec); + private: + type value_; + }; + + /// Serial port option to permit changing the parity. + /** + * Implements changing the parity for a given serial port. + */ + class parity + { + public: + enum type { none, odd, even }; + ASIO_DECL explicit parity(type t = none); + type value() const; + ASIO_DECL ASIO_SYNC_OP_VOID store( + ASIO_OPTION_STORAGE& storage, + asio::error_code& ec) const; + ASIO_DECL ASIO_SYNC_OP_VOID load( + const ASIO_OPTION_STORAGE& storage, + asio::error_code& ec); + private: + type value_; + }; + + /// Serial port option to permit changing the number of stop bits. + /** + * Implements changing the number of stop bits for a given serial port. + */ + class stop_bits + { + public: + enum type { one, onepointfive, two }; + ASIO_DECL explicit stop_bits(type t = one); + type value() const; + ASIO_DECL ASIO_SYNC_OP_VOID store( + ASIO_OPTION_STORAGE& storage, + asio::error_code& ec) const; + ASIO_DECL ASIO_SYNC_OP_VOID load( + const ASIO_OPTION_STORAGE& storage, + asio::error_code& ec); + private: + type value_; + }; + + /// Serial port option to permit changing the character size. + /** + * Implements changing the character size for a given serial port. + */ + class character_size + { + public: + ASIO_DECL explicit character_size(unsigned int t = 8); + unsigned int value() const; + ASIO_DECL ASIO_SYNC_OP_VOID store( + ASIO_OPTION_STORAGE& storage, + asio::error_code& ec) const; + ASIO_DECL ASIO_SYNC_OP_VOID load( + const ASIO_OPTION_STORAGE& storage, + asio::error_code& ec); + private: + unsigned int value_; + }; + +protected: + /// Protected destructor to prevent deletion through this type. + ~serial_port_base() + { + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#undef ASIO_OPTION_STORAGE + +#include "asio/impl/serial_port_base.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/impl/serial_port_base.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // defined(ASIO_HAS_SERIAL_PORT) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_SERIAL_PORT_BASE_HPP diff --git a/tools/sdk/include/asio/asio/serial_port_service.hpp b/tools/sdk/include/asio/asio/serial_port_service.hpp new file mode 100644 index 00000000..0e20d96e --- /dev/null +++ b/tools/sdk/include/asio/asio/serial_port_service.hpp @@ -0,0 +1,249 @@ +// +// serial_port_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SERIAL_PORT_SERVICE_HPP +#define ASIO_SERIAL_PORT_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_SERIAL_PORT) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include +#include "asio/async_result.hpp" +#include "asio/detail/reactive_serial_port_service.hpp" +#include "asio/detail/win_iocp_serial_port_service.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/serial_port_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Default service implementation for a serial port. +class serial_port_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_context::id id; +#endif + +private: + // The type of the platform-specific implementation. +#if defined(ASIO_HAS_IOCP) + typedef detail::win_iocp_serial_port_service service_impl_type; +#else + typedef detail::reactive_serial_port_service service_impl_type; +#endif + +public: + /// The type of a serial port implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef service_impl_type::implementation_type implementation_type; +#endif + + /// The native handle type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef service_impl_type::native_handle_type native_handle_type; +#endif + + /// Construct a new serial port service for the specified io_context. + explicit serial_port_service(asio::io_context& io_context) + : asio::detail::service_base(io_context), + service_impl_(io_context) + { + } + + /// Construct a new serial port implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new serial port implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another serial port implementation. + void move_assign(implementation_type& impl, + serial_port_service& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy a serial port implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Open a serial port. + ASIO_SYNC_OP_VOID open(implementation_type& impl, + const std::string& device, asio::error_code& ec) + { + service_impl_.open(impl, device, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Assign an existing native handle to a serial port. + ASIO_SYNC_OP_VOID assign(implementation_type& impl, + const native_handle_type& handle, asio::error_code& ec) + { + service_impl_.assign(impl, handle, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a serial port implementation. + ASIO_SYNC_OP_VOID close(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.close(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native handle implementation. + native_handle_type native_handle(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Cancel all asynchronous operations associated with the handle. + ASIO_SYNC_OP_VOID cancel(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.cancel(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Set a serial port option. + template + ASIO_SYNC_OP_VOID set_option(implementation_type& impl, + const SettableSerialPortOption& option, asio::error_code& ec) + { + service_impl_.set_option(impl, option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get a serial port option. + template + ASIO_SYNC_OP_VOID get_option(const implementation_type& impl, + GettableSerialPortOption& option, asio::error_code& ec) const + { + service_impl_.get_option(impl, option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Send a break sequence to the serial port. + ASIO_SYNC_OP_VOID send_break(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.send_break(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Write the given data to the stream. + template + std::size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.write_some(impl, buffers, ec); + } + + /// Start an asynchronous write. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) + { + async_completion init(handler); + + service_impl_.async_write_some(impl, buffers, init.completion_handler); + + return init.result.get(); + } + + /// Read some data from the stream. + template + std::size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.read_some(impl, buffers, ec); + } + + /// Start an asynchronous read. + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) + { + async_completion init(handler); + + service_impl_.async_read_some(impl, buffers, 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 + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_SERIAL_PORT) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_SERIAL_PORT_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/signal_set.hpp b/tools/sdk/include/asio/asio/signal_set.hpp new file mode 100644 index 00000000..30e5c4e3 --- /dev/null +++ b/tools/sdk/include/asio/asio/signal_set.hpp @@ -0,0 +1,447 @@ +// +// signal_set.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SIGNAL_SET_HPP +#define ASIO_SIGNAL_SET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/async_result.hpp" +#include "asio/basic_io_object.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/basic_signal_set.hpp" +#else // defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/detail/signal_set_service.hpp" +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +namespace asio { + +#if defined(ASIO_ENABLE_OLD_SERVICES) +// Typedef for the typical usage of a signal set. +typedef basic_signal_set<> signal_set; +#else // defined(ASIO_ENABLE_OLD_SERVICES) +/// Provides signal functionality. +/** + * The signal_set class provides the ability to perform an asynchronous wait + * for one or more signals to occur. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Example + * Performing an asynchronous wait: + * @code + * void handler( + * const asio::error_code& error, + * int signal_number) + * { + * if (!error) + * { + * // A signal occurred. + * } + * } + * + * ... + * + * // Construct a signal set registered for process termination. + * asio::signal_set signals(io_context, SIGINT, SIGTERM); + * + * // Start an asynchronous wait for one of the signals to occur. + * signals.async_wait(handler); + * @endcode + * + * @par Queueing of signal notifications + * + * If a signal is registered with a signal_set, and the signal occurs when + * there are no waiting handlers, then the signal notification is queued. The + * next async_wait operation on that signal_set will dequeue the notification. + * If multiple notifications are queued, subsequent async_wait operations + * dequeue them one at a time. Signal notifications are dequeued in order of + * ascending signal number. + * + * If a signal number is removed from a signal_set (using the @c remove or @c + * erase member functions) then any queued notifications for that signal are + * discarded. + * + * @par Multiple registration of signals + * + * The same signal number may be registered with different signal_set objects. + * When the signal occurs, one handler is called for each signal_set object. + * + * Note that multiple registration only works for signals that are registered + * using Asio. The application must not also register a signal handler using + * functions such as @c signal() or @c sigaction(). + * + * @par Signal masking on POSIX platforms + * + * POSIX allows signals to be blocked using functions such as @c sigprocmask() + * and @c pthread_sigmask(). For signals to be delivered, programs must ensure + * that any signals registered using signal_set objects are unblocked in at + * least one thread. + */ +class signal_set + : ASIO_SVC_ACCESS basic_io_object +{ +public: + /// The type of the executor associated with the object. + typedef io_context::executor_type executor_type; + + /// Construct a signal set without adding any signals. + /** + * This constructor creates a signal set without registering for any signals. + * + * @param io_context The io_context object that the signal set will use to + * dispatch handlers for any asynchronous operations performed on the set. + */ + explicit signal_set(asio::io_context& io_context) + : basic_io_object(io_context) + { + } + + /// Construct a signal set and add one signal. + /** + * This constructor creates a signal set and registers for one signal. + * + * @param io_context The io_context object that the signal set will use to + * dispatch handlers for any asynchronous operations performed on the set. + * + * @param signal_number_1 The signal number to be added. + * + * @note This constructor is equivalent to performing: + * @code asio::signal_set signals(io_context); + * signals.add(signal_number_1); @endcode + */ + signal_set(asio::io_context& io_context, int signal_number_1) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().add(this->get_implementation(), signal_number_1, ec); + asio::detail::throw_error(ec, "add"); + } + + /// Construct a signal set and add two signals. + /** + * This constructor creates a signal set and registers for two signals. + * + * @param io_context The io_context object that the signal set will use to + * dispatch handlers for any asynchronous operations performed on the set. + * + * @param signal_number_1 The first signal number to be added. + * + * @param signal_number_2 The second signal number to be added. + * + * @note This constructor is equivalent to performing: + * @code asio::signal_set signals(io_context); + * signals.add(signal_number_1); + * signals.add(signal_number_2); @endcode + */ + signal_set(asio::io_context& io_context, int signal_number_1, + int signal_number_2) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().add(this->get_implementation(), signal_number_1, ec); + asio::detail::throw_error(ec, "add"); + this->get_service().add(this->get_implementation(), signal_number_2, ec); + asio::detail::throw_error(ec, "add"); + } + + /// Construct a signal set and add three signals. + /** + * This constructor creates a signal set and registers for three signals. + * + * @param io_context The io_context object that the signal set will use to + * dispatch handlers for any asynchronous operations performed on the set. + * + * @param signal_number_1 The first signal number to be added. + * + * @param signal_number_2 The second signal number to be added. + * + * @param signal_number_3 The third signal number to be added. + * + * @note This constructor is equivalent to performing: + * @code asio::signal_set signals(io_context); + * signals.add(signal_number_1); + * signals.add(signal_number_2); + * signals.add(signal_number_3); @endcode + */ + signal_set(asio::io_context& io_context, int signal_number_1, + int signal_number_2, int signal_number_3) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().add(this->get_implementation(), signal_number_1, ec); + asio::detail::throw_error(ec, "add"); + this->get_service().add(this->get_implementation(), signal_number_2, ec); + asio::detail::throw_error(ec, "add"); + this->get_service().add(this->get_implementation(), signal_number_3, ec); + asio::detail::throw_error(ec, "add"); + } + + /// Destroys the signal set. + /** + * This function destroys the signal set, cancelling any outstanding + * asynchronous wait operations associated with the signal set as if by + * calling @c cancel. + */ + ~signal_set() + { + } + +#if !defined(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. + */ + 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. + */ + asio::io_context& get_io_service() + { + return basic_io_object::get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return basic_io_object::get_executor(); + } + + /// Add a signal to a signal_set. + /** + * This function adds the specified signal to the set. It has no effect if the + * signal is already in the set. + * + * @param signal_number The signal to be added to the set. + * + * @throws asio::system_error Thrown on failure. + */ + void add(int signal_number) + { + asio::error_code ec; + this->get_service().add(this->get_implementation(), signal_number, ec); + asio::detail::throw_error(ec, "add"); + } + + /// Add a signal to a signal_set. + /** + * This function adds the specified signal to the set. It has no effect if the + * signal is already in the set. + * + * @param signal_number The signal to be added to the set. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID add(int signal_number, + asio::error_code& ec) + { + this->get_service().add(this->get_implementation(), signal_number, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Remove a signal from a signal_set. + /** + * This function removes the specified signal from the set. It has no effect + * if the signal is not in the set. + * + * @param signal_number The signal to be removed from the set. + * + * @throws asio::system_error Thrown on failure. + * + * @note Removes any notifications that have been queued for the specified + * signal number. + */ + void remove(int signal_number) + { + asio::error_code ec; + this->get_service().remove(this->get_implementation(), signal_number, ec); + asio::detail::throw_error(ec, "remove"); + } + + /// Remove a signal from a signal_set. + /** + * This function removes the specified signal from the set. It has no effect + * if the signal is not in the set. + * + * @param signal_number The signal to be removed from the set. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Removes any notifications that have been queued for the specified + * signal number. + */ + ASIO_SYNC_OP_VOID remove(int signal_number, + asio::error_code& ec) + { + this->get_service().remove(this->get_implementation(), signal_number, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Remove all signals from a signal_set. + /** + * This function removes all signals from the set. It has no effect if the set + * is already empty. + * + * @throws asio::system_error Thrown on failure. + * + * @note Removes all queued notifications. + */ + void clear() + { + asio::error_code ec; + this->get_service().clear(this->get_implementation(), ec); + asio::detail::throw_error(ec, "clear"); + } + + /// Remove all signals from a signal_set. + /** + * This function removes all signals from the set. It has no effect if the set + * is already empty. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Removes all queued notifications. + */ + ASIO_SYNC_OP_VOID clear(asio::error_code& ec) + { + this->get_service().clear(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Cancel all operations associated with the signal set. + /** + * This function forces the completion of any pending asynchronous wait + * operations against the signal set. The handler for each cancelled + * operation will be invoked with the asio::error::operation_aborted + * error code. + * + * Cancellation does not alter the set of registered signals. + * + * @throws asio::system_error Thrown on failure. + * + * @note If a registered signal occurred before cancel() is called, then the + * handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + void cancel() + { + asio::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel"); + } + + /// Cancel all operations associated with the signal set. + /** + * This function forces the completion of any pending asynchronous wait + * operations against the signal set. The handler for each cancelled + * operation will be invoked with the asio::error::operation_aborted + * error code. + * + * Cancellation does not alter the set of registered signals. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note If a registered signal occurred before cancel() is called, then the + * handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) + { + this->get_service().cancel(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Start an asynchronous operation to wait for a signal to be delivered. + /** + * This function may be used to initiate an asynchronous wait against the + * signal set. It always returns immediately. + * + * For each call to async_wait(), the supplied handler will be called exactly + * once. The handler will be called when: + * + * @li One of the registered signals in the signal set occurs; or + * + * @li The signal set was cancelled, in which case the handler is passed the + * error code asio::error::operation_aborted. + * + * @param handler The handler to be called when the signal occurs. Copies + * will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * int signal_number // Indicates which signal occurred. + * ); @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 + * asio::io_context::post(). + */ + template + ASIO_INITFN_RESULT_TYPE(SignalHandler, + void (asio::error_code, int)) + async_wait(ASIO_MOVE_ARG(SignalHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a SignalHandler. + ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check; + + async_completion init(handler); + + this->get_service().async_wait(this->get_implementation(), + init.completion_handler); + + return init.result.get(); + } +}; +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +} // namespace asio + +#endif // ASIO_SIGNAL_SET_HPP diff --git a/tools/sdk/include/asio/asio/signal_set_service.hpp b/tools/sdk/include/asio/asio/signal_set_service.hpp new file mode 100644 index 00000000..3285beb0 --- /dev/null +++ b/tools/sdk/include/asio/asio/signal_set_service.hpp @@ -0,0 +1,142 @@ +// +// signal_set_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SIGNAL_SET_SERVICE_HPP +#define ASIO_SIGNAL_SET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/async_result.hpp" +#include "asio/detail/signal_set_service.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Default service implementation for a signal set. +class signal_set_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_context::id id; +#endif + +public: + /// The type of a signal set implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef detail::signal_set_service::implementation_type implementation_type; +#endif + + /// Construct a new signal set service for the specified io_context. + explicit signal_set_service(asio::io_context& io_context) + : asio::detail::service_base(io_context), + service_impl_(io_context) + { + } + + /// Construct a new signal set implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a signal set implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Add a signal to a signal_set. + ASIO_SYNC_OP_VOID add(implementation_type& impl, + int signal_number, asio::error_code& ec) + { + service_impl_.add(impl, signal_number, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Remove a signal to a signal_set. + ASIO_SYNC_OP_VOID remove(implementation_type& impl, + int signal_number, asio::error_code& ec) + { + service_impl_.remove(impl, signal_number, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Remove all signals from a signal_set. + ASIO_SYNC_OP_VOID clear(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.clear(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Cancel all operations associated with the signal set. + ASIO_SYNC_OP_VOID cancel(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.cancel(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + // Start an asynchronous operation to wait for a signal to be delivered. + template + ASIO_INITFN_RESULT_TYPE(SignalHandler, + void (asio::error_code, int)) + async_wait(implementation_type& impl, + ASIO_MOVE_ARG(SignalHandler) handler) + { + async_completion init(handler); + + service_impl_.async_wait(impl, init.completion_handler); + + return init.result.get(); + } + +private: + // Destroy all user-defined handler objects owned by the service. + void shutdown() + { + service_impl_.shutdown(); + } + + // Perform any fork-related housekeeping. + void notify_fork(asio::io_context::fork_event event) + { + service_impl_.notify_fork(event); + } + + // The platform-specific implementation. + detail::signal_set_service service_impl_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_SIGNAL_SET_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/socket_acceptor_service.hpp b/tools/sdk/include/asio/asio/socket_acceptor_service.hpp new file mode 100644 index 00000000..cd40fe14 --- /dev/null +++ b/tools/sdk/include/asio/asio/socket_acceptor_service.hpp @@ -0,0 +1,372 @@ +// +// socket_acceptor_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SOCKET_ACCEPTOR_SERVICE_HPP +#define ASIO_SOCKET_ACCEPTOR_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/basic_socket.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/null_socket_service.hpp" +#elif defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_socket_service.hpp" +#else +# include "asio/detail/reactive_socket_service.hpp" +#endif + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Default service implementation for a socket acceptor. +template +class socket_acceptor_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_context::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(ASIO_WINDOWS_RUNTIME) + typedef detail::null_socket_service service_impl_type; +#elif defined(ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service service_impl_type; +#else + typedef detail::reactive_socket_service 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 + + /// 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_context. + explicit socket_acceptor_service(asio::io_context& io_context) + : asio::detail::service_base< + socket_acceptor_service >(io_context), + service_impl_(io_context) + { + } + + /// Construct a new socket acceptor implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(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& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } + + // All acceptor services have access to each other's implementations. + template friend class socket_acceptor_service; + + /// Move-construct a new socket acceptor implementation from another protocol + /// type. + template + void converting_move_construct(implementation_type& impl, + socket_acceptor_service& other_service, + typename socket_acceptor_service< + 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(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. + ASIO_SYNC_OP_VOID open(implementation_type& impl, + const protocol_type& protocol, asio::error_code& ec) + { + service_impl_.open(impl, protocol, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Assign an existing native acceptor to a socket acceptor. + ASIO_SYNC_OP_VOID assign(implementation_type& impl, + const protocol_type& protocol, const native_handle_type& native_acceptor, + asio::error_code& ec) + { + service_impl_.assign(impl, protocol, native_acceptor, ec); + ASIO_SYNC_OP_VOID_RETURN(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. + ASIO_SYNC_OP_VOID cancel(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.cancel(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Bind the socket acceptor to the specified local endpoint. + ASIO_SYNC_OP_VOID bind(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + service_impl_.bind(impl, endpoint, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Place the socket acceptor into the state where it will listen for new + /// connections. + ASIO_SYNC_OP_VOID listen(implementation_type& impl, int backlog, + asio::error_code& ec) + { + service_impl_.listen(impl, backlog, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Close a socket acceptor implementation. + ASIO_SYNC_OP_VOID close(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.close(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Release ownership of the underlying acceptor. + native_handle_type release(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.release(impl, ec); + } + + /// Get the native acceptor implementation. + native_handle_type native_handle(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Set a socket option. + template + ASIO_SYNC_OP_VOID set_option(implementation_type& impl, + const SettableSocketOption& option, asio::error_code& ec) + { + service_impl_.set_option(impl, option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get a socket option. + template + ASIO_SYNC_OP_VOID get_option(const implementation_type& impl, + GettableSocketOption& option, asio::error_code& ec) const + { + service_impl_.get_option(impl, option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Perform an IO control command on the socket. + template + ASIO_SYNC_OP_VOID io_control(implementation_type& impl, + IoControlCommand& command, asio::error_code& ec) + { + service_impl_.io_control(impl, command, ec); + ASIO_SYNC_OP_VOID_RETURN(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. + ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl, + bool mode, asio::error_code& ec) + { + service_impl_.non_blocking(impl, mode, ec); + ASIO_SYNC_OP_VOID_RETURN(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. + ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl, + bool mode, asio::error_code& ec) + { + service_impl_.native_non_blocking(impl, mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Wait for the acceptor to become ready to read, ready to write, or to have + /// pending error conditions. + ASIO_SYNC_OP_VOID wait(implementation_type& impl, + socket_base::wait_type w, asio::error_code& ec) + { + service_impl_.wait(impl, w, ec); + 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. + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(implementation_type& impl, socket_base::wait_type w, + ASIO_MOVE_ARG(WaitHandler) handler) + { + async_completion init(handler); + + service_impl_.async_wait(impl, w, init.completion_handler); + + return init.result.get(); + } + + /// Accept a new connection. + template + ASIO_SYNC_OP_VOID accept(implementation_type& impl, + basic_socket& peer, + endpoint_type* peer_endpoint, asio::error_code& ec, + typename enable_if::value>::type* = 0) + { + service_impl_.accept(impl, peer, peer_endpoint, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + +#if defined(ASIO_HAS_MOVE) + /// Accept a new connection. + typename Protocol::socket accept(implementation_type& impl, + io_context* peer_io_context, endpoint_type* peer_endpoint, + asio::error_code& ec) + { + return service_impl_.accept(impl, peer_io_context, peer_endpoint, ec); + } +#endif // defined(ASIO_HAS_MOVE) + + /// Start an asynchronous accept. + template + ASIO_INITFN_RESULT_TYPE(AcceptHandler, + void (asio::error_code)) + async_accept(implementation_type& impl, + basic_socket& peer, + endpoint_type* peer_endpoint, + ASIO_MOVE_ARG(AcceptHandler) handler, + typename enable_if::value>::type* = 0) + { + async_completion init(handler); + + service_impl_.async_accept(impl, + peer, peer_endpoint, init.completion_handler); + + return init.result.get(); + } + +#if defined(ASIO_HAS_MOVE) + /// Start an asynchronous accept. + template + ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (asio::error_code, typename Protocol::socket)) + async_accept(implementation_type& impl, + asio::io_context* peer_io_context, endpoint_type* peer_endpoint, + ASIO_MOVE_ARG(MoveAcceptHandler) handler) + { + async_completion init(handler); + + service_impl_.async_accept(impl, + peer_io_context, peer_endpoint, init.completion_handler); + + return init.result.get(); + } +#endif // defined(ASIO_HAS_MOVE) + +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 + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_SOCKET_ACCEPTOR_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/socket_base.hpp b/tools/sdk/include/asio/asio/socket_base.hpp new file mode 100644 index 00000000..87ed8408 --- /dev/null +++ b/tools/sdk/include/asio/asio/socket_base.hpp @@ -0,0 +1,559 @@ +// +// socket_base.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SOCKET_BASE_HPP +#define ASIO_SOCKET_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/io_control.hpp" +#include "asio/detail/socket_option.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// The socket_base class is used as a base for the basic_stream_socket and +/// basic_datagram_socket class templates so that we have a common place to +/// define the shutdown_type and enum. +class socket_base +{ +public: + /// Different ways a socket may be shutdown. + enum shutdown_type + { +#if defined(GENERATING_DOCUMENTATION) + /// Shutdown the receive side of the socket. + shutdown_receive = implementation_defined, + + /// Shutdown the send side of the socket. + shutdown_send = implementation_defined, + + /// Shutdown both send and receive on the socket. + shutdown_both = implementation_defined +#else + shutdown_receive = ASIO_OS_DEF(SHUT_RD), + shutdown_send = ASIO_OS_DEF(SHUT_WR), + shutdown_both = ASIO_OS_DEF(SHUT_RDWR) +#endif + }; + + /// Bitmask type for flags that can be passed to send and receive operations. + typedef int message_flags; + +#if defined(GENERATING_DOCUMENTATION) + /// Peek at incoming data without removing it from the input queue. + static const int message_peek = implementation_defined; + + /// Process out-of-band data. + static const int message_out_of_band = implementation_defined; + + /// Specify that the data should not be subject to routing. + static const int message_do_not_route = implementation_defined; + + /// Specifies that the data marks the end of a record. + static const int message_end_of_record = implementation_defined; +#else + ASIO_STATIC_CONSTANT(int, + message_peek = ASIO_OS_DEF(MSG_PEEK)); + ASIO_STATIC_CONSTANT(int, + message_out_of_band = ASIO_OS_DEF(MSG_OOB)); + ASIO_STATIC_CONSTANT(int, + message_do_not_route = ASIO_OS_DEF(MSG_DONTROUTE)); + ASIO_STATIC_CONSTANT(int, + message_end_of_record = ASIO_OS_DEF(MSG_EOR)); +#endif + + /// Wait types. + /** + * For use with basic_socket::wait() and basic_socket::async_wait(). + */ + enum wait_type + { + /// Wait for a socket to become ready to read. + wait_read, + + /// Wait for a socket to become ready to write. + wait_write, + + /// Wait for a socket to have error conditions pending. + wait_error + }; + + /// Socket option to permit sending of broadcast messages. + /** + * Implements the SOL_SOCKET/SO_BROADCAST socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::socket_base::broadcast option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::socket_base::broadcast option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined broadcast; +#else + typedef asio::detail::socket_option::boolean< + ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_BROADCAST)> + broadcast; +#endif + + /// Socket option to enable socket-level debugging. + /** + * Implements the SOL_SOCKET/SO_DEBUG socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::debug option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::debug option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined debug; +#else + typedef asio::detail::socket_option::boolean< + ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_DEBUG)> debug; +#endif + + /// Socket option to prevent routing, use local interfaces only. + /** + * Implements the SOL_SOCKET/SO_DONTROUTE socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::socket_base::do_not_route option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::socket_base::do_not_route option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined do_not_route; +#else + typedef asio::detail::socket_option::boolean< + ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_DONTROUTE)> + do_not_route; +#endif + + /// Socket option to send keep-alives. + /** + * Implements the SOL_SOCKET/SO_KEEPALIVE socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::keep_alive option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::keep_alive option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined keep_alive; +#else + typedef asio::detail::socket_option::boolean< + ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_KEEPALIVE)> keep_alive; +#endif + + /// Socket option for the send buffer size of a socket. + /** + * Implements the SOL_SOCKET/SO_SNDBUF socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::send_buffer_size option(8192); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::send_buffer_size option; + * socket.get_option(option); + * int size = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Integer_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined send_buffer_size; +#else + typedef asio::detail::socket_option::integer< + ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_SNDBUF)> + send_buffer_size; +#endif + + /// Socket option for the send low watermark. + /** + * Implements the SOL_SOCKET/SO_SNDLOWAT socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::send_low_watermark option(1024); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::send_low_watermark option; + * socket.get_option(option); + * int size = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Integer_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined send_low_watermark; +#else + typedef asio::detail::socket_option::integer< + ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_SNDLOWAT)> + send_low_watermark; +#endif + + /// Socket option for the receive buffer size of a socket. + /** + * Implements the SOL_SOCKET/SO_RCVBUF socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::receive_buffer_size option(8192); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::receive_buffer_size option; + * socket.get_option(option); + * int size = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Integer_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined receive_buffer_size; +#else + typedef asio::detail::socket_option::integer< + ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_RCVBUF)> + receive_buffer_size; +#endif + + /// Socket option for the receive low watermark. + /** + * Implements the SOL_SOCKET/SO_RCVLOWAT socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::receive_low_watermark option(1024); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::receive_low_watermark option; + * socket.get_option(option); + * int size = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Integer_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined receive_low_watermark; +#else + typedef asio::detail::socket_option::integer< + ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_RCVLOWAT)> + receive_low_watermark; +#endif + + /// Socket option to allow the socket to be bound to an address that is + /// already in use. + /** + * Implements the SOL_SOCKET/SO_REUSEADDR socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::socket_base::reuse_address option(true); + * acceptor.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::socket_base::reuse_address option; + * acceptor.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined reuse_address; +#else + typedef asio::detail::socket_option::boolean< + ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_REUSEADDR)> + reuse_address; +#endif + + /// Socket option to specify whether the socket lingers on close if unsent + /// data is present. + /** + * Implements the SOL_SOCKET/SO_LINGER socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::linger option(true, 30); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::linger option; + * socket.get_option(option); + * bool is_set = option.enabled(); + * unsigned short timeout = option.timeout(); + * @endcode + * + * @par Concepts: + * Socket_Option, Linger_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined linger; +#else + typedef asio::detail::socket_option::linger< + ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_LINGER)> + linger; +#endif + + /// Socket option for putting received out-of-band data inline. + /** + * Implements the SOL_SOCKET/SO_OOBINLINE socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::out_of_band_inline option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::out_of_band_inline option; + * socket.get_option(option); + * bool value = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined out_of_band_inline; +#else + typedef asio::detail::socket_option::boolean< + ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_OOBINLINE)> + out_of_band_inline; +#endif + + /// Socket option to report aborted connections on accept. + /** + * Implements a custom socket option that determines whether or not an accept + * operation is permitted to fail with asio::error::connection_aborted. + * By default the option is false. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::socket_base::enable_connection_aborted option(true); + * acceptor.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::acceptor acceptor(io_context); + * ... + * asio::socket_base::enable_connection_aborted option; + * acceptor.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined enable_connection_aborted; +#else + typedef asio::detail::socket_option::boolean< + asio::detail::custom_socket_option_level, + asio::detail::enable_connection_aborted_option> + enable_connection_aborted; +#endif + + /// IO control command to get the amount of data that can be read without + /// blocking. + /** + * Implements the FIONREAD IO control command. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::socket_base::bytes_readable command(true); + * socket.io_control(command); + * std::size_t bytes_readable = command.get(); + * @endcode + * + * @par Concepts: + * IO_Control_Command, Size_IO_Control_Command. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined bytes_readable; +#else + typedef asio::detail::io_control::bytes_readable bytes_readable; +#endif + + /// The maximum length of the queue of pending incoming connections. +#if defined(GENERATING_DOCUMENTATION) + static const int max_listen_connections = implementation_defined; +#else + ASIO_STATIC_CONSTANT(int, max_listen_connections + = ASIO_OS_DEF(SOMAXCONN)); +#endif + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use max_listen_connections.) The maximum length of the queue + /// of pending incoming connections. +#if defined(GENERATING_DOCUMENTATION) + static const int max_connections = implementation_defined; +#else + ASIO_STATIC_CONSTANT(int, max_connections + = ASIO_OS_DEF(SOMAXCONN)); +#endif +#endif // !defined(ASIO_NO_DEPRECATED) + +protected: + /// Protected destructor to prevent deletion through this type. + ~socket_base() + { + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SOCKET_BASE_HPP diff --git a/tools/sdk/include/asio/asio/spawn.hpp b/tools/sdk/include/asio/asio/spawn.hpp new file mode 100644 index 00000000..a91c5815 --- /dev/null +++ b/tools/sdk/include/asio/asio/spawn.hpp @@ -0,0 +1,336 @@ +// +// spawn.hpp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SPAWN_HPP +#define ASIO_SPAWN_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/bind_executor.hpp" +#include "asio/detail/memory.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/detail/wrapped_handler.hpp" +#include "asio/executor.hpp" +#include "asio/io_context.hpp" +#include "asio/is_executor.hpp" +#include "asio/strand.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Context object the represents the currently executing coroutine. +/** + * The basic_yield_context class is used to represent the currently executing + * stackful coroutine. A basic_yield_context may be passed as a handler to an + * asynchronous operation. For example: + * + * @code template + * void my_coroutine(basic_yield_context yield) + * { + * ... + * std::size_t n = my_socket.async_read_some(buffer, yield); + * ... + * } @endcode + * + * The initiating function (async_read_some in the above example) suspends the + * current coroutine. The coroutine is resumed when the asynchronous operation + * completes, and the result of the operation is returned. + */ +template +class basic_yield_context +{ +public: + /// The coroutine callee type, used by the implementation. + /** + * When using Boost.Coroutine v1, this type is: + * @code typename coroutine @endcode + * When using Boost.Coroutine v2 (unidirectional coroutines), this type is: + * @code push_coroutine @endcode + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined callee_type; +#elif defined(BOOST_COROUTINES_UNIDIRECT) || defined(BOOST_COROUTINES_V2) + typedef boost::coroutines::push_coroutine callee_type; +#else + typedef boost::coroutines::coroutine callee_type; +#endif + + /// The coroutine caller type, used by the implementation. + /** + * When using Boost.Coroutine v1, this type is: + * @code typename coroutine::caller_type @endcode + * When using Boost.Coroutine v2 (unidirectional coroutines), this type is: + * @code pull_coroutine @endcode + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined caller_type; +#elif defined(BOOST_COROUTINES_UNIDIRECT) || defined(BOOST_COROUTINES_V2) + typedef boost::coroutines::pull_coroutine caller_type; +#else + typedef boost::coroutines::coroutine::caller_type caller_type; +#endif + + /// Construct a yield context to represent the specified coroutine. + /** + * Most applications do not need to use this constructor. Instead, the + * spawn() function passes a yield context as an argument to the coroutine + * function. + */ + basic_yield_context( + const detail::weak_ptr& coro, + caller_type& ca, Handler& handler) + : coro_(coro), + ca_(ca), + handler_(handler), + ec_(0) + { + } + + /// Construct a yield context from another yield context type. + /** + * Requires that OtherHandler be convertible to Handler. + */ + template + basic_yield_context(const basic_yield_context& other) + : coro_(other.coro_), + ca_(other.ca_), + handler_(other.handler_), + ec_(other.ec_) + { + } + + /// Return a yield context that sets the specified error_code. + /** + * By default, when a yield context is used with an asynchronous operation, a + * non-success error_code is converted to system_error and thrown. This + * operator may be used to specify an error_code object that should instead be + * set with the asynchronous operation's result. For example: + * + * @code template + * void my_coroutine(basic_yield_context yield) + * { + * ... + * std::size_t n = my_socket.async_read_some(buffer, yield[ec]); + * if (ec) + * { + * // An error occurred. + * } + * ... + * } @endcode + */ + basic_yield_context operator[](asio::error_code& ec) const + { + basic_yield_context tmp(*this); + tmp.ec_ = &ec; + return tmp; + } + +#if defined(GENERATING_DOCUMENTATION) +private: +#endif // defined(GENERATING_DOCUMENTATION) + detail::weak_ptr coro_; + caller_type& ca_; + Handler handler_; + asio::error_code* ec_; +}; + +#if defined(GENERATING_DOCUMENTATION) +/// Context object that represents the currently executing coroutine. +typedef basic_yield_context yield_context; +#else // defined(GENERATING_DOCUMENTATION) +typedef basic_yield_context< + executor_binder > yield_context; +#endif // defined(GENERATING_DOCUMENTATION) + +/** + * @defgroup spawn asio::spawn + * + * @brief Start a new stackful coroutine. + * + * The spawn() function is a high-level wrapper over the Boost.Coroutine + * library. This function enables programs to implement asynchronous logic in a + * synchronous manner, as illustrated by the following example: + * + * @code asio::spawn(my_strand, do_echo); + * + * // ... + * + * void do_echo(asio::yield_context yield) + * { + * try + * { + * char data[128]; + * for (;;) + * { + * std::size_t length = + * my_socket.async_read_some( + * asio::buffer(data), yield); + * + * asio::async_write(my_socket, + * asio::buffer(data, length), yield); + * } + * } + * catch (std::exception& e) + * { + * // ... + * } + * } @endcode + */ +/*@{*/ + +/// Start a new stackful coroutine, calling the specified handler when it +/// completes. +/** + * This function is used to launch a new coroutine. + * + * @param function The coroutine function. The function must have the signature: + * @code void function(basic_yield_context yield); @endcode + * + * @param attributes Boost.Coroutine attributes used to customise the coroutine. + */ +template +void spawn(ASIO_MOVE_ARG(Function) function, + const boost::coroutines::attributes& attributes + = boost::coroutines::attributes()); + +/// Start a new stackful coroutine, calling the specified handler when it +/// completes. +/** + * This function is used to launch a new coroutine. + * + * @param handler A handler to be called when the coroutine exits. More + * importantly, the handler provides an execution context (via the the handler + * invocation hook) for the coroutine. The handler must have the signature: + * @code void handler(); @endcode + * + * @param function The coroutine function. The function must have the signature: + * @code void function(basic_yield_context yield); @endcode + * + * @param attributes Boost.Coroutine attributes used to customise the coroutine. + */ +template +void spawn(ASIO_MOVE_ARG(Handler) handler, + ASIO_MOVE_ARG(Function) function, + const boost::coroutines::attributes& attributes + = boost::coroutines::attributes(), + typename enable_if::type>::value && + !is_convertible::value>::type* = 0); + +/// Start a new stackful coroutine, inheriting the execution context of another. +/** + * This function is used to launch a new coroutine. + * + * @param ctx Identifies the current coroutine as a parent of the new + * coroutine. This specifies that the new coroutine should inherit the + * execution context of the parent. For example, if the parent coroutine is + * executing in a particular strand, then the new coroutine will execute in the + * same strand. + * + * @param function The coroutine function. The function must have the signature: + * @code void function(basic_yield_context yield); @endcode + * + * @param attributes Boost.Coroutine attributes used to customise the coroutine. + */ +template +void spawn(basic_yield_context ctx, + ASIO_MOVE_ARG(Function) function, + const boost::coroutines::attributes& attributes + = boost::coroutines::attributes()); + +/// Start a new stackful coroutine that executes on a given executor. +/** + * This function is used to launch a new coroutine. + * + * @param ex Identifies the executor that will run the coroutine. The new + * coroutine is implicitly given its own strand within this executor. + * + * @param function The coroutine function. The function must have the signature: + * @code void function(yield_context yield); @endcode + * + * @param attributes Boost.Coroutine attributes used to customise the coroutine. + */ +template +void spawn(const Executor& ex, + ASIO_MOVE_ARG(Function) function, + const boost::coroutines::attributes& attributes + = boost::coroutines::attributes(), + typename enable_if::value>::type* = 0); + +/// Start a new stackful coroutine that executes on a given strand. +/** + * This function is used to launch a new coroutine. + * + * @param ex Identifies the strand that will run the coroutine. + * + * @param function The coroutine function. The function must have the signature: + * @code void function(yield_context yield); @endcode + * + * @param attributes Boost.Coroutine attributes used to customise the coroutine. + */ +template +void spawn(const strand& ex, + ASIO_MOVE_ARG(Function) function, + const boost::coroutines::attributes& attributes + = boost::coroutines::attributes()); + +/// Start a new stackful coroutine that executes in the context of a strand. +/** + * This function is used to launch a new coroutine. + * + * @param s Identifies a strand. By starting multiple coroutines on the same + * strand, the implementation ensures that none of those coroutines can execute + * simultaneously. + * + * @param function The coroutine function. The function must have the signature: + * @code void function(yield_context yield); @endcode + * + * @param attributes Boost.Coroutine attributes used to customise the coroutine. + */ +template +void spawn(const asio::io_context::strand& s, + ASIO_MOVE_ARG(Function) function, + const boost::coroutines::attributes& attributes + = boost::coroutines::attributes()); + +/// Start a new stackful coroutine that executes on a given execution context. +/** + * This function is used to launch a new coroutine. + * + * @param ctx Identifies the execution context that will run the coroutine. The + * new coroutine is implicitly given its own strand within this execution + * context. + * + * @param function The coroutine function. The function must have the signature: + * @code void function(yield_context yield); @endcode + * + * @param attributes Boost.Coroutine attributes used to customise the coroutine. + */ +template +void spawn(ExecutionContext& ctx, + ASIO_MOVE_ARG(Function) function, + const boost::coroutines::attributes& attributes + = boost::coroutines::attributes(), + typename enable_if::value>::type* = 0); + +/*@}*/ + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/spawn.hpp" + +#endif // ASIO_SPAWN_HPP diff --git a/tools/sdk/include/asio/asio/ssl.hpp b/tools/sdk/include/asio/asio/ssl.hpp new file mode 100644 index 00000000..cbad19d8 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl.hpp @@ -0,0 +1,27 @@ +// +// ssl.hpp +// ~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_HPP +#define ASIO_SSL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/ssl/context.hpp" +#include "asio/ssl/context_base.hpp" +#include "asio/ssl/error.hpp" +#include "asio/ssl/rfc2818_verification.hpp" +#include "asio/ssl/stream.hpp" +#include "asio/ssl/stream_base.hpp" +#include "asio/ssl/verify_context.hpp" +#include "asio/ssl/verify_mode.hpp" + +#endif // ASIO_SSL_HPP diff --git a/tools/sdk/include/asio/asio/ssl/context.hpp b/tools/sdk/include/asio/asio/ssl/context.hpp new file mode 100644 index 00000000..9543aab6 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/context.hpp @@ -0,0 +1,758 @@ +// +// ssl/context.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_CONTEXT_HPP +#define ASIO_SSL_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include +#include "asio/buffer.hpp" +#include "asio/io_context.hpp" +#include "asio/ssl/context_base.hpp" +#include "asio/ssl/detail/openssl_types.hpp" +#include "asio/ssl/detail/openssl_init.hpp" +#include "asio/ssl/detail/password_callback.hpp" +#include "asio/ssl/detail/verify_callback.hpp" +#include "asio/ssl/verify_mode.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { + +class context + : public context_base, + private noncopyable +{ +public: + /// The native handle type of the SSL context. + typedef SSL_CTX* native_handle_type; + + /// Constructor. + ASIO_DECL explicit context(method m); + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a context from another. + /** + * This constructor moves an SSL context from one object to another. + * + * @param other The other context object from which the move will occur. + * + * @note Following the move, the following operations only are valid for the + * moved-from object: + * @li Destruction. + * @li As a target for move-assignment. + */ + ASIO_DECL context(context&& other); + + /// Move-assign a context from another. + /** + * This assignment operator moves an SSL context from one object to another. + * + * @param other The other context object from which the move will occur. + * + * @note Following the move, the following operations only are valid for the + * moved-from object: + * @li Destruction. + * @li As a target for move-assignment. + */ + ASIO_DECL context& operator=(context&& other); +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destructor. + ASIO_DECL ~context(); + + /// Get the underlying implementation in the native type. + /** + * This function may be used to obtain the underlying implementation of the + * context. This is intended to allow access to context functionality that is + * not otherwise provided. + */ + ASIO_DECL native_handle_type native_handle(); + + /// Clear options on the context. + /** + * This function may be used to configure the SSL options used by the context. + * + * @param o A bitmask of options. The available option values are defined in + * the context_base class. The specified options, if currently enabled on the + * context, are cleared. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_clear_options. + */ + ASIO_DECL void clear_options(options o); + + /// Clear options on the context. + /** + * This function may be used to configure the SSL options used by the context. + * + * @param o A bitmask of options. The available option values are defined in + * the context_base class. The specified options, if currently enabled on the + * context, are cleared. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_clear_options. + */ + ASIO_DECL ASIO_SYNC_OP_VOID clear_options(options o, + asio::error_code& ec); + + /// Set options on the context. + /** + * This function may be used to configure the SSL options used by the context. + * + * @param o A bitmask of options. The available option values are defined in + * the context_base class. The options are bitwise-ored with any existing + * value for the options. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_set_options. + */ + ASIO_DECL void set_options(options o); + + /// Set options on the context. + /** + * This function may be used to configure the SSL options used by the context. + * + * @param o A bitmask of options. The available option values are defined in + * the context_base class. The options are bitwise-ored with any existing + * value for the options. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_set_options. + */ + ASIO_DECL ASIO_SYNC_OP_VOID set_options(options o, + asio::error_code& ec); + + /// Set the peer verification mode. + /** + * This function may be used to configure the peer verification mode used by + * the context. + * + * @param v A bitmask of peer verification modes. See @ref verify_mode for + * available values. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_set_verify. + */ + ASIO_DECL void set_verify_mode(verify_mode v); + + /// Set the peer verification mode. + /** + * This function may be used to configure the peer verification mode used by + * the context. + * + * @param v A bitmask of peer verification modes. See @ref verify_mode for + * available values. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_set_verify. + */ + ASIO_DECL ASIO_SYNC_OP_VOID set_verify_mode( + verify_mode v, asio::error_code& ec); + + /// Set the peer verification depth. + /** + * This function may be used to configure the maximum verification depth + * allowed by the context. + * + * @param depth Maximum depth for the certificate chain verification that + * shall be allowed. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_set_verify_depth. + */ + ASIO_DECL void set_verify_depth(int depth); + + /// Set the peer verification depth. + /** + * This function may be used to configure the maximum verification depth + * allowed by the context. + * + * @param depth Maximum depth for the certificate chain verification that + * shall be allowed. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_set_verify_depth. + */ + ASIO_DECL ASIO_SYNC_OP_VOID set_verify_depth( + int depth, asio::error_code& ec); + + /// Set the callback used to verify peer certificates. + /** + * This function is used to specify a callback function that will be called + * by the implementation when it needs to verify a peer certificate. + * + * @param callback The function object to be used for verifying a certificate. + * The function signature of the handler must be: + * @code bool verify_callback( + * bool preverified, // True if the certificate passed pre-verification. + * verify_context& ctx // The peer certificate and other context. + * ); @endcode + * The return value of the callback is true if the certificate has passed + * verification, false otherwise. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_set_verify. + */ + template + void set_verify_callback(VerifyCallback callback); + + /// Set the callback used to verify peer certificates. + /** + * This function is used to specify a callback function that will be called + * by the implementation when it needs to verify a peer certificate. + * + * @param callback The function object to be used for verifying a certificate. + * The function signature of the handler must be: + * @code bool verify_callback( + * bool preverified, // True if the certificate passed pre-verification. + * verify_context& ctx // The peer certificate and other context. + * ); @endcode + * The return value of the callback is true if the certificate has passed + * verification, false otherwise. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_set_verify. + */ + template + ASIO_SYNC_OP_VOID set_verify_callback(VerifyCallback callback, + asio::error_code& ec); + + /// Load a certification authority file for performing verification. + /** + * This function is used to load one or more trusted certification authorities + * from a file. + * + * @param filename The name of a file containing certification authority + * certificates in PEM format. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_load_verify_locations. + */ + ASIO_DECL void load_verify_file(const std::string& filename); + + /// Load a certification authority file for performing verification. + /** + * This function is used to load the certificates for one or more trusted + * certification authorities from a file. + * + * @param filename The name of a file containing certification authority + * certificates in PEM format. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_load_verify_locations. + */ + ASIO_DECL ASIO_SYNC_OP_VOID load_verify_file( + const std::string& filename, asio::error_code& ec); + + /// Add certification authority for performing verification. + /** + * This function is used to add one trusted certification authority + * from a memory buffer. + * + * @param ca The buffer containing the certification authority certificate. + * The certificate must use the PEM format. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_get_cert_store and @c X509_STORE_add_cert. + */ + ASIO_DECL void add_certificate_authority(const const_buffer& ca); + + /// Add certification authority for performing verification. + /** + * This function is used to add one trusted certification authority + * from a memory buffer. + * + * @param ca The buffer containing the certification authority certificate. + * The certificate must use the PEM format. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_get_cert_store and @c X509_STORE_add_cert. + */ + ASIO_DECL ASIO_SYNC_OP_VOID add_certificate_authority( + const const_buffer& ca, asio::error_code& ec); + + /// Configures the context to use the default directories for finding + /// certification authority certificates. + /** + * This function specifies that the context should use the default, + * system-dependent directories for locating certification authority + * certificates. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_set_default_verify_paths. + */ + ASIO_DECL void set_default_verify_paths(); + + /// Configures the context to use the default directories for finding + /// certification authority certificates. + /** + * This function specifies that the context should use the default, + * system-dependent directories for locating certification authority + * certificates. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_set_default_verify_paths. + */ + ASIO_DECL ASIO_SYNC_OP_VOID set_default_verify_paths( + asio::error_code& ec); + + /// Add a directory containing certificate authority files to be used for + /// performing verification. + /** + * This function is used to specify the name of a directory containing + * certification authority certificates. Each file in the directory must + * contain a single certificate. The files must be named using the subject + * name's hash and an extension of ".0". + * + * @param path The name of a directory containing the certificates. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_load_verify_locations. + */ + ASIO_DECL void add_verify_path(const std::string& path); + + /// Add a directory containing certificate authority files to be used for + /// performing verification. + /** + * This function is used to specify the name of a directory containing + * certification authority certificates. Each file in the directory must + * contain a single certificate. The files must be named using the subject + * name's hash and an extension of ".0". + * + * @param path The name of a directory containing the certificates. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_load_verify_locations. + */ + ASIO_DECL ASIO_SYNC_OP_VOID add_verify_path( + const std::string& path, asio::error_code& ec); + + /// Use a certificate from a memory buffer. + /** + * This function is used to load a certificate into the context from a buffer. + * + * @param certificate The buffer containing the certificate. + * + * @param format The certificate format (ASN.1 or PEM). + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_use_certificate or SSL_CTX_use_certificate_ASN1. + */ + ASIO_DECL void use_certificate( + const const_buffer& certificate, file_format format); + + /// Use a certificate from a memory buffer. + /** + * This function is used to load a certificate into the context from a buffer. + * + * @param certificate The buffer containing the certificate. + * + * @param format The certificate format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_use_certificate or SSL_CTX_use_certificate_ASN1. + */ + ASIO_DECL ASIO_SYNC_OP_VOID use_certificate( + const const_buffer& certificate, file_format format, + asio::error_code& ec); + + /// Use a certificate from a file. + /** + * This function is used to load a certificate into the context from a file. + * + * @param filename The name of the file containing the certificate. + * + * @param format The file format (ASN.1 or PEM). + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_use_certificate_file. + */ + ASIO_DECL void use_certificate_file( + const std::string& filename, file_format format); + + /// Use a certificate from a file. + /** + * This function is used to load a certificate into the context from a file. + * + * @param filename The name of the file containing the certificate. + * + * @param format The file format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_use_certificate_file. + */ + ASIO_DECL ASIO_SYNC_OP_VOID use_certificate_file( + const std::string& filename, file_format format, + asio::error_code& ec); + + /// Use a certificate chain from a memory buffer. + /** + * This function is used to load a certificate chain into the context from a + * buffer. + * + * @param chain The buffer containing the certificate chain. The certificate + * chain must use the PEM format. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_use_certificate and SSL_CTX_add_extra_chain_cert. + */ + ASIO_DECL void use_certificate_chain(const const_buffer& chain); + + /// Use a certificate chain from a memory buffer. + /** + * This function is used to load a certificate chain into the context from a + * buffer. + * + * @param chain The buffer containing the certificate chain. The certificate + * chain must use the PEM format. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_use_certificate and SSL_CTX_add_extra_chain_cert. + */ + ASIO_DECL ASIO_SYNC_OP_VOID use_certificate_chain( + const const_buffer& chain, asio::error_code& ec); + + /// Use a certificate chain from a file. + /** + * This function is used to load a certificate chain into the context from a + * file. + * + * @param filename The name of the file containing the certificate. The file + * must use the PEM format. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_use_certificate_chain_file. + */ + ASIO_DECL void use_certificate_chain_file(const std::string& filename); + + /// Use a certificate chain from a file. + /** + * This function is used to load a certificate chain into the context from a + * file. + * + * @param filename The name of the file containing the certificate. The file + * must use the PEM format. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_use_certificate_chain_file. + */ + ASIO_DECL ASIO_SYNC_OP_VOID use_certificate_chain_file( + const std::string& filename, asio::error_code& ec); + + /// Use a private key from a memory buffer. + /** + * This function is used to load a private key into the context from a buffer. + * + * @param private_key The buffer containing the private key. + * + * @param format The private key format (ASN.1 or PEM). + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_use_PrivateKey or SSL_CTX_use_PrivateKey_ASN1. + */ + ASIO_DECL void use_private_key( + const const_buffer& private_key, file_format format); + + /// Use a private key from a memory buffer. + /** + * This function is used to load a private key into the context from a buffer. + * + * @param private_key The buffer containing the private key. + * + * @param format The private key format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_use_PrivateKey or SSL_CTX_use_PrivateKey_ASN1. + */ + ASIO_DECL ASIO_SYNC_OP_VOID use_private_key( + const const_buffer& private_key, file_format format, + asio::error_code& ec); + + /// Use a private key from a file. + /** + * This function is used to load a private key into the context from a file. + * + * @param filename The name of the file containing the private key. + * + * @param format The file format (ASN.1 or PEM). + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_use_PrivateKey_file. + */ + ASIO_DECL void use_private_key_file( + const std::string& filename, file_format format); + + /// Use a private key from a file. + /** + * This function is used to load a private key into the context from a file. + * + * @param filename The name of the file containing the private key. + * + * @param format The file format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_use_PrivateKey_file. + */ + ASIO_DECL ASIO_SYNC_OP_VOID use_private_key_file( + const std::string& filename, file_format format, + asio::error_code& ec); + + /// Use an RSA private key from a memory buffer. + /** + * This function is used to load an RSA private key into the context from a + * buffer. + * + * @param private_key The buffer containing the RSA private key. + * + * @param format The private key format (ASN.1 or PEM). + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_use_RSAPrivateKey or SSL_CTX_use_RSAPrivateKey_ASN1. + */ + ASIO_DECL void use_rsa_private_key( + const const_buffer& private_key, file_format format); + + /// Use an RSA private key from a memory buffer. + /** + * This function is used to load an RSA private key into the context from a + * buffer. + * + * @param private_key The buffer containing the RSA private key. + * + * @param format The private key format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_use_RSAPrivateKey or SSL_CTX_use_RSAPrivateKey_ASN1. + */ + ASIO_DECL ASIO_SYNC_OP_VOID use_rsa_private_key( + const const_buffer& private_key, file_format format, + asio::error_code& ec); + + /// Use an RSA private key from a file. + /** + * This function is used to load an RSA private key into the context from a + * file. + * + * @param filename The name of the file containing the RSA private key. + * + * @param format The file format (ASN.1 or PEM). + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_use_RSAPrivateKey_file. + */ + ASIO_DECL void use_rsa_private_key_file( + const std::string& filename, file_format format); + + /// Use an RSA private key from a file. + /** + * This function is used to load an RSA private key into the context from a + * file. + * + * @param filename The name of the file containing the RSA private key. + * + * @param format The file format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_use_RSAPrivateKey_file. + */ + ASIO_DECL ASIO_SYNC_OP_VOID use_rsa_private_key_file( + const std::string& filename, file_format format, + asio::error_code& ec); + + /// Use the specified memory buffer to obtain the temporary Diffie-Hellman + /// parameters. + /** + * This function is used to load Diffie-Hellman parameters into the context + * from a buffer. + * + * @param dh The memory buffer containing the Diffie-Hellman parameters. The + * buffer must use the PEM format. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_set_tmp_dh. + */ + ASIO_DECL void use_tmp_dh(const const_buffer& dh); + + /// Use the specified memory buffer to obtain the temporary Diffie-Hellman + /// parameters. + /** + * This function is used to load Diffie-Hellman parameters into the context + * from a buffer. + * + * @param dh The memory buffer containing the Diffie-Hellman parameters. The + * buffer must use the PEM format. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_set_tmp_dh. + */ + ASIO_DECL ASIO_SYNC_OP_VOID use_tmp_dh( + const const_buffer& dh, asio::error_code& ec); + + /// Use the specified file to obtain the temporary Diffie-Hellman parameters. + /** + * This function is used to load Diffie-Hellman parameters into the context + * from a file. + * + * @param filename The name of the file containing the Diffie-Hellman + * parameters. The file must use the PEM format. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_set_tmp_dh. + */ + ASIO_DECL void use_tmp_dh_file(const std::string& filename); + + /// Use the specified file to obtain the temporary Diffie-Hellman parameters. + /** + * This function is used to load Diffie-Hellman parameters into the context + * from a file. + * + * @param filename The name of the file containing the Diffie-Hellman + * parameters. The file must use the PEM format. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_set_tmp_dh. + */ + ASIO_DECL ASIO_SYNC_OP_VOID use_tmp_dh_file( + const std::string& filename, asio::error_code& ec); + + /// Set the password callback. + /** + * This function is used to specify a callback function to obtain password + * information about an encrypted key in PEM format. + * + * @param callback The function object to be used for obtaining the password. + * The function signature of the handler must be: + * @code std::string password_callback( + * std::size_t max_length, // The maximum size for a password. + * password_purpose purpose // Whether password is for reading or writing. + * ); @endcode + * The return value of the callback is a string containing the password. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_set_default_passwd_cb. + */ + template + void set_password_callback(PasswordCallback callback); + + /// Set the password callback. + /** + * This function is used to specify a callback function to obtain password + * information about an encrypted key in PEM format. + * + * @param callback The function object to be used for obtaining the password. + * The function signature of the handler must be: + * @code std::string password_callback( + * std::size_t max_length, // The maximum size for a password. + * password_purpose purpose // Whether password is for reading or writing. + * ); @endcode + * The return value of the callback is a string containing the password. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_set_default_passwd_cb. + */ + template + ASIO_SYNC_OP_VOID set_password_callback(PasswordCallback callback, + asio::error_code& ec); + +private: + struct bio_cleanup; + struct x509_cleanup; + struct evp_pkey_cleanup; + struct rsa_cleanup; + struct dh_cleanup; + + // Helper function used to set a peer certificate verification callback. + ASIO_DECL ASIO_SYNC_OP_VOID do_set_verify_callback( + detail::verify_callback_base* callback, asio::error_code& ec); + + // Callback used when the SSL implementation wants to verify a certificate. + ASIO_DECL static int verify_callback_function( + int preverified, X509_STORE_CTX* ctx); + + // Helper function used to set a password callback. + ASIO_DECL ASIO_SYNC_OP_VOID do_set_password_callback( + detail::password_callback_base* callback, asio::error_code& ec); + + // Callback used when the SSL implementation wants a password. + ASIO_DECL static int password_callback_function( + char* buf, int size, int purpose, void* data); + + // Helper function to set the temporary Diffie-Hellman parameters from a BIO. + ASIO_DECL ASIO_SYNC_OP_VOID do_use_tmp_dh( + BIO* bio, asio::error_code& ec); + + // Helper function to make a BIO from a memory buffer. + ASIO_DECL BIO* make_buffer_bio(const const_buffer& b); + + // The underlying native implementation. + native_handle_type handle_; + + // Ensure openssl is initialised. + asio::ssl::detail::openssl_init<> init_; +}; + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/ssl/impl/context.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/ssl/impl/context.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_SSL_CONTEXT_HPP diff --git a/tools/sdk/include/asio/asio/ssl/context_base.hpp b/tools/sdk/include/asio/asio/ssl/context_base.hpp new file mode 100644 index 00000000..56c76936 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/context_base.hpp @@ -0,0 +1,192 @@ +// +// ssl/context_base.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_CONTEXT_BASE_HPP +#define ASIO_SSL_CONTEXT_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/ssl/detail/openssl_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { + +/// The context_base class is used as a base for the basic_context class +/// template so that we have a common place to define various enums. +class context_base +{ +public: + /// Different methods supported by a context. + enum method + { + /// Generic SSL version 2. + sslv2, + + /// SSL version 2 client. + sslv2_client, + + /// SSL version 2 server. + sslv2_server, + + /// Generic SSL version 3. + sslv3, + + /// SSL version 3 client. + sslv3_client, + + /// SSL version 3 server. + sslv3_server, + + /// Generic TLS version 1. + tlsv1, + + /// TLS version 1 client. + tlsv1_client, + + /// TLS version 1 server. + tlsv1_server, + + /// Generic SSL/TLS. + sslv23, + + /// SSL/TLS client. + sslv23_client, + + /// SSL/TLS server. + sslv23_server, + + /// Generic TLS version 1.1. + tlsv11, + + /// TLS version 1.1 client. + tlsv11_client, + + /// TLS version 1.1 server. + tlsv11_server, + + /// Generic TLS version 1.2. + tlsv12, + + /// TLS version 1.2 client. + tlsv12_client, + + /// TLS version 1.2 server. + tlsv12_server, + + /// Generic TLS. + tls, + + /// TLS client. + tls_client, + + /// TLS server. + tls_server + }; + + /// Bitmask type for SSL options. + typedef long options; + +#if defined(GENERATING_DOCUMENTATION) + /// Implement various bug workarounds. + static const long default_workarounds = implementation_defined; + + /// Always create a new key when using tmp_dh parameters. + static const long single_dh_use = implementation_defined; + + /// Disable SSL v2. + static const long no_sslv2 = implementation_defined; + + /// Disable SSL v3. + static const long no_sslv3 = implementation_defined; + + /// Disable TLS v1. + static const long no_tlsv1 = implementation_defined; + + /// Disable TLS v1.1. + static const long no_tlsv1_1 = implementation_defined; + + /// Disable TLS v1.2. + static const long no_tlsv1_2 = implementation_defined; + + /// Disable compression. Compression is disabled by default. + static const long no_compression = implementation_defined; +#else + ASIO_STATIC_CONSTANT(long, default_workarounds = SSL_OP_ALL); + ASIO_STATIC_CONSTANT(long, single_dh_use = SSL_OP_SINGLE_DH_USE); + ASIO_STATIC_CONSTANT(long, no_sslv2 = SSL_OP_NO_SSLv2); + ASIO_STATIC_CONSTANT(long, no_sslv3 = SSL_OP_NO_SSLv3); + ASIO_STATIC_CONSTANT(long, no_tlsv1 = SSL_OP_NO_TLSv1); +# if defined(SSL_OP_NO_TLSv1_1) + ASIO_STATIC_CONSTANT(long, no_tlsv1_1 = SSL_OP_NO_TLSv1_1); +# else // defined(SSL_OP_NO_TLSv1_1) + ASIO_STATIC_CONSTANT(long, no_tlsv1_1 = 0x10000000L); +# endif // defined(SSL_OP_NO_TLSv1_1) +# if defined(SSL_OP_NO_TLSv1_2) + ASIO_STATIC_CONSTANT(long, no_tlsv1_2 = SSL_OP_NO_TLSv1_2); +# else // defined(SSL_OP_NO_TLSv1_2) + ASIO_STATIC_CONSTANT(long, no_tlsv1_2 = 0x08000000L); +# endif // defined(SSL_OP_NO_TLSv1_2) +# if defined(SSL_OP_NO_COMPRESSION) + ASIO_STATIC_CONSTANT(long, no_compression = SSL_OP_NO_COMPRESSION); +# else // defined(SSL_OP_NO_COMPRESSION) + ASIO_STATIC_CONSTANT(long, no_compression = 0x20000L); +# endif // defined(SSL_OP_NO_COMPRESSION) +#endif + + /// File format types. + enum file_format + { + /// ASN.1 file. + asn1, + + /// PEM file. + pem + }; + +#if !defined(GENERATING_DOCUMENTATION) + // The following types and constants are preserved for backward compatibility. + // New programs should use the equivalents of the same names that are defined + // in the asio::ssl namespace. + typedef int verify_mode; + ASIO_STATIC_CONSTANT(int, verify_none = SSL_VERIFY_NONE); + ASIO_STATIC_CONSTANT(int, verify_peer = SSL_VERIFY_PEER); + ASIO_STATIC_CONSTANT(int, + verify_fail_if_no_peer_cert = SSL_VERIFY_FAIL_IF_NO_PEER_CERT); + ASIO_STATIC_CONSTANT(int, verify_client_once = SSL_VERIFY_CLIENT_ONCE); +#endif + + /// Purpose of PEM password. + enum password_purpose + { + /// The password is needed for reading/decryption. + for_reading, + + /// The password is needed for writing/encryption. + for_writing + }; + +protected: + /// Protected destructor to prevent deletion through this type. + ~context_base() + { + } +}; + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_CONTEXT_BASE_HPP diff --git a/tools/sdk/include/asio/asio/ssl/detail/buffered_handshake_op.hpp b/tools/sdk/include/asio/asio/ssl/detail/buffered_handshake_op.hpp new file mode 100644 index 00000000..38a03fcc --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/detail/buffered_handshake_op.hpp @@ -0,0 +1,114 @@ +// +// ssl/detail/buffered_handshake_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_DETAIL_BUFFERED_HANDSHAKE_OP_HPP +#define ASIO_SSL_DETAIL_BUFFERED_HANDSHAKE_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/ssl/detail/engine.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +template +class buffered_handshake_op +{ +public: + buffered_handshake_op(stream_base::handshake_type type, + const ConstBufferSequence& buffers) + : type_(type), + buffers_(buffers), + total_buffer_size_(asio::buffer_size(buffers_)) + { + } + + engine::want operator()(engine& eng, + asio::error_code& ec, + std::size_t& bytes_transferred) const + { + return this->process(eng, ec, bytes_transferred, + asio::buffer_sequence_begin(buffers_), + asio::buffer_sequence_end(buffers_)); + } + + template + void call_handler(Handler& handler, + const asio::error_code& ec, + const std::size_t& bytes_transferred) const + { + handler(ec, bytes_transferred); + } + +private: + template + engine::want process(engine& eng, + asio::error_code& ec, + std::size_t& bytes_transferred, + Iterator begin, Iterator end) const + { + Iterator iter = begin; + std::size_t accumulated_size = 0; + + for (;;) + { + engine::want want = eng.handshake(type_, ec); + if (want != engine::want_input_and_retry + || bytes_transferred == total_buffer_size_) + return want; + + // Find the next buffer piece to be fed to the engine. + while (iter != end) + { + const_buffer buffer(*iter); + + // Skip over any buffers which have already been consumed by the engine. + if (bytes_transferred >= accumulated_size + buffer.size()) + { + accumulated_size += buffer.size(); + ++iter; + continue; + } + + // The current buffer may have been partially consumed by the engine on + // a previous iteration. If so, adjust the buffer to point to the + // unused portion. + if (bytes_transferred > accumulated_size) + buffer = buffer + (bytes_transferred - accumulated_size); + + // Pass the buffer to the engine, and update the bytes transferred to + // reflect the total number of bytes consumed so far. + bytes_transferred += buffer.size(); + buffer = eng.put_input(buffer); + bytes_transferred -= buffer.size(); + break; + } + } + } + + stream_base::handshake_type type_; + ConstBufferSequence buffers_; + std::size_t total_buffer_size_; +}; + +} // namespace detail +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_DETAIL_BUFFERED_HANDSHAKE_OP_HPP diff --git a/tools/sdk/include/asio/asio/ssl/detail/engine.hpp b/tools/sdk/include/asio/asio/ssl/detail/engine.hpp new file mode 100644 index 00000000..2f033d66 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/detail/engine.hpp @@ -0,0 +1,160 @@ +// +// ssl/detail/engine.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_DETAIL_ENGINE_HPP +#define ASIO_SSL_DETAIL_ENGINE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/buffer.hpp" +#include "asio/detail/static_mutex.hpp" +#include "asio/ssl/detail/openssl_types.hpp" +#include "asio/ssl/detail/verify_callback.hpp" +#include "asio/ssl/stream_base.hpp" +#include "asio/ssl/verify_mode.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +class engine +{ +public: + enum want + { + // Returned by functions to indicate that the engine wants input. The input + // buffer should be updated to point to the data. The engine then needs to + // be called again to retry the operation. + want_input_and_retry = -2, + + // Returned by functions to indicate that the engine wants to write output. + // The output buffer points to the data to be written. The engine then + // needs to be called again to retry the operation. + want_output_and_retry = -1, + + // Returned by functions to indicate that the engine doesn't need input or + // output. + want_nothing = 0, + + // Returned by functions to indicate that the engine wants to write output. + // The output buffer points to the data to be written. After that the + // operation is complete, and the engine does not need to be called again. + want_output = 1 + }; + + // Construct a new engine for the specified context. + ASIO_DECL explicit engine(SSL_CTX* context); + + // Destructor. + ASIO_DECL ~engine(); + + // Get the underlying implementation in the native type. + ASIO_DECL SSL* native_handle(); + + // Set the peer verification mode. + ASIO_DECL asio::error_code set_verify_mode( + verify_mode v, asio::error_code& ec); + + // Set the peer verification depth. + ASIO_DECL asio::error_code set_verify_depth( + int depth, asio::error_code& ec); + + // Set a peer certificate verification callback. + ASIO_DECL asio::error_code set_verify_callback( + verify_callback_base* callback, asio::error_code& ec); + + // Perform an SSL handshake using either SSL_connect (client-side) or + // SSL_accept (server-side). + ASIO_DECL want handshake( + stream_base::handshake_type type, asio::error_code& ec); + + // Perform a graceful shutdown of the SSL session. + ASIO_DECL want shutdown(asio::error_code& ec); + + // Write bytes to the SSL session. + ASIO_DECL want write(const asio::const_buffer& data, + asio::error_code& ec, std::size_t& bytes_transferred); + + // Read bytes from the SSL session. + ASIO_DECL want read(const asio::mutable_buffer& data, + asio::error_code& ec, std::size_t& bytes_transferred); + + // Get output data to be written to the transport. + ASIO_DECL asio::mutable_buffer get_output( + const asio::mutable_buffer& data); + + // Put input data that was read from the transport. + ASIO_DECL asio::const_buffer put_input( + const asio::const_buffer& data); + + // Map an error::eof code returned by the underlying transport according to + // the type and state of the SSL session. Returns a const reference to the + // error code object, suitable for passing to a completion handler. + ASIO_DECL const asio::error_code& map_error_code( + asio::error_code& ec) const; + +private: + // Disallow copying and assignment. + engine(const engine&); + engine& operator=(const engine&); + + // Callback used when the SSL implementation wants to verify a certificate. + ASIO_DECL static int verify_callback_function( + int preverified, X509_STORE_CTX* ctx); + +#if (OPENSSL_VERSION_NUMBER < 0x10000000L) + // The SSL_accept function may not be thread safe. This mutex is used to + // protect all calls to the SSL_accept function. + ASIO_DECL static asio::detail::static_mutex& accept_mutex(); +#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) + + // Perform one operation. Returns >= 0 on success or error, want_read if the + // operation needs more input, or want_write if it needs to write some output + // before the operation can complete. + ASIO_DECL want perform(int (engine::* op)(void*, std::size_t), + void* data, std::size_t length, asio::error_code& ec, + std::size_t* bytes_transferred); + + // Adapt the SSL_accept function to the signature needed for perform(). + ASIO_DECL int do_accept(void*, std::size_t); + + // Adapt the SSL_connect function to the signature needed for perform(). + ASIO_DECL int do_connect(void*, std::size_t); + + // Adapt the SSL_shutdown function to the signature needed for perform(). + ASIO_DECL int do_shutdown(void*, std::size_t); + + // Adapt the SSL_read function to the signature needed for perform(). + ASIO_DECL int do_read(void* data, std::size_t length); + + // Adapt the SSL_write function to the signature needed for perform(). + ASIO_DECL int do_write(void* data, std::size_t length); + + SSL* ssl_; + BIO* ext_bio_; +}; + +} // namespace detail +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/ssl/detail/impl/engine.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_SSL_DETAIL_ENGINE_HPP diff --git a/tools/sdk/include/asio/asio/ssl/detail/handshake_op.hpp b/tools/sdk/include/asio/asio/ssl/detail/handshake_op.hpp new file mode 100644 index 00000000..f782023a --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/detail/handshake_op.hpp @@ -0,0 +1,62 @@ +// +// ssl/detail/handshake_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP +#define ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/ssl/detail/engine.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +class handshake_op +{ +public: + handshake_op(stream_base::handshake_type type) + : type_(type) + { + } + + engine::want operator()(engine& eng, + asio::error_code& ec, + std::size_t& bytes_transferred) const + { + bytes_transferred = 0; + return eng.handshake(type_, ec); + } + + template + void call_handler(Handler& handler, + const asio::error_code& ec, + const std::size_t&) const + { + handler(ec); + } + +private: + stream_base::handshake_type type_; +}; + +} // namespace detail +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP diff --git a/tools/sdk/include/asio/asio/ssl/detail/io.hpp b/tools/sdk/include/asio/asio/ssl/detail/io.hpp new file mode 100644 index 00000000..0b0e51a2 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/detail/io.hpp @@ -0,0 +1,372 @@ +// +// ssl/detail/io.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_DETAIL_IO_HPP +#define ASIO_SSL_DETAIL_IO_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/ssl/detail/engine.hpp" +#include "asio/ssl/detail/stream_core.hpp" +#include "asio/write.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +template +std::size_t io(Stream& next_layer, stream_core& core, + const Operation& op, asio::error_code& ec) +{ + std::size_t bytes_transferred = 0; + do switch (op(core.engine_, ec, bytes_transferred)) + { + case engine::want_input_and_retry: + + // If the input buffer is empty then we need to read some more data from + // the underlying transport. + if (core.input_.size() == 0) + core.input_ = asio::buffer(core.input_buffer_, + next_layer.read_some(core.input_buffer_, ec)); + + // Pass the new input data to the engine. + core.input_ = core.engine_.put_input(core.input_); + + // Try the operation again. + continue; + + case engine::want_output_and_retry: + + // Get output data from the engine and write it to the underlying + // transport. + asio::write(next_layer, + core.engine_.get_output(core.output_buffer_), ec); + + // Try the operation again. + continue; + + case engine::want_output: + + // Get output data from the engine and write it to the underlying + // transport. + asio::write(next_layer, + core.engine_.get_output(core.output_buffer_), ec); + + // Operation is complete. Return result to caller. + core.engine_.map_error_code(ec); + return bytes_transferred; + + default: + + // Operation is complete. Return result to caller. + core.engine_.map_error_code(ec); + return bytes_transferred; + + } while (!ec); + + // Operation failed. Return result to caller. + core.engine_.map_error_code(ec); + return 0; +} + +template +class io_op +{ +public: + io_op(Stream& next_layer, stream_core& core, + const Operation& op, Handler& handler) + : next_layer_(next_layer), + core_(core), + op_(op), + start_(0), + want_(engine::want_nothing), + bytes_transferred_(0), + handler_(ASIO_MOVE_CAST(Handler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + io_op(const io_op& other) + : next_layer_(other.next_layer_), + core_(other.core_), + op_(other.op_), + start_(other.start_), + want_(other.want_), + ec_(other.ec_), + bytes_transferred_(other.bytes_transferred_), + handler_(other.handler_) + { + } + + io_op(io_op&& other) + : next_layer_(other.next_layer_), + core_(other.core_), + op_(ASIO_MOVE_CAST(Operation)(other.op_)), + start_(other.start_), + want_(other.want_), + ec_(other.ec_), + bytes_transferred_(other.bytes_transferred_), + handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(asio::error_code ec, + std::size_t bytes_transferred = ~std::size_t(0), int start = 0) + { + switch (start_ = start) + { + case 1: // Called after at least one async operation. + do + { + switch (want_ = op_(core_.engine_, ec_, bytes_transferred_)) + { + case engine::want_input_and_retry: + + // If the input buffer already has data in it we can pass it to the + // engine and then retry the operation immediately. + if (core_.input_.size() != 0) + { + core_.input_ = core_.engine_.put_input(core_.input_); + continue; + } + + // The engine wants more data to be read from input. However, we + // cannot allow more than one read operation at a time on the + // underlying transport. The pending_read_ timer's expiry is set to + // pos_infin if a read is in progress, and neg_infin otherwise. + if (core_.expiry(core_.pending_read_) == core_.neg_infin()) + { + // Prevent other read operations from being started. + core_.pending_read_.expires_at(core_.pos_infin()); + + // Start reading some data from the underlying transport. + next_layer_.async_read_some( + asio::buffer(core_.input_buffer_), + ASIO_MOVE_CAST(io_op)(*this)); + } + else + { + // Wait until the current read operation completes. + core_.pending_read_.async_wait(ASIO_MOVE_CAST(io_op)(*this)); + } + + // Yield control until asynchronous operation completes. Control + // resumes at the "default:" label below. + return; + + case engine::want_output_and_retry: + case engine::want_output: + + // The engine wants some data to be written to the output. However, we + // cannot allow more than one write operation at a time on the + // underlying transport. The pending_write_ timer's expiry is set to + // pos_infin if a write is in progress, and neg_infin otherwise. + if (core_.expiry(core_.pending_write_) == core_.neg_infin()) + { + // Prevent other write operations from being started. + core_.pending_write_.expires_at(core_.pos_infin()); + + // Start writing all the data to the underlying transport. + asio::async_write(next_layer_, + core_.engine_.get_output(core_.output_buffer_), + ASIO_MOVE_CAST(io_op)(*this)); + } + else + { + // Wait until the current write operation completes. + core_.pending_write_.async_wait(ASIO_MOVE_CAST(io_op)(*this)); + } + + // Yield control until asynchronous operation completes. Control + // resumes at the "default:" label below. + return; + + default: + + // The SSL operation is done and we can invoke the handler, but we + // have to keep in mind that this function might be being called from + // the async operation's initiating function. In this case we're not + // allowed to call the handler directly. Instead, issue a zero-sized + // read so the handler runs "as-if" posted using io_context::post(). + if (start) + { + next_layer_.async_read_some( + asio::buffer(core_.input_buffer_, 0), + ASIO_MOVE_CAST(io_op)(*this)); + + // Yield control until asynchronous operation completes. Control + // resumes at the "default:" label below. + return; + } + else + { + // Continue on to run handler directly. + break; + } + } + + default: + if (bytes_transferred == ~std::size_t(0)) + bytes_transferred = 0; // Timer cancellation, no data transferred. + else if (!ec_) + ec_ = ec; + + switch (want_) + { + case engine::want_input_and_retry: + + // Add received data to the engine's input. + core_.input_ = asio::buffer( + core_.input_buffer_, bytes_transferred); + core_.input_ = core_.engine_.put_input(core_.input_); + + // Release any waiting read operations. + core_.pending_read_.expires_at(core_.neg_infin()); + + // Try the operation again. + continue; + + case engine::want_output_and_retry: + + // Release any waiting write operations. + core_.pending_write_.expires_at(core_.neg_infin()); + + // Try the operation again. + continue; + + case engine::want_output: + + // Release any waiting write operations. + core_.pending_write_.expires_at(core_.neg_infin()); + + // Fall through to call handler. + + default: + + // Pass the result to the handler. + op_.call_handler(handler_, + core_.engine_.map_error_code(ec_), + ec_ ? 0 : bytes_transferred_); + + // Our work here is done. + return; + } + } while (!ec_); + + // Operation failed. Pass the result to the handler. + op_.call_handler(handler_, core_.engine_.map_error_code(ec_), 0); + } + } + +//private: + Stream& next_layer_; + stream_core& core_; + Operation op_; + int start_; + engine::want want_; + asio::error_code ec_; + std::size_t bytes_transferred_; + Handler handler_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + io_op* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + io_op* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline bool asio_handler_is_continuation( + io_op* this_handler) +{ + return this_handler->start_ == 0 ? true + : asio_handler_cont_helpers::is_continuation(this_handler->handler_); +} + +template +inline void asio_handler_invoke(Function& function, + io_op* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + io_op* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline void async_io(Stream& next_layer, stream_core& core, + const Operation& op, Handler& handler) +{ + io_op( + next_layer, core, op, handler)( + asio::error_code(), 0, 1); +} + +} // namespace detail +} // namespace ssl + +template +struct associated_allocator< + ssl::detail::io_op, Allocator> +{ + typedef typename associated_allocator::type type; + + static type get(const ssl::detail::io_op& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return associated_allocator::get(h.handler_, a); + } +}; + +template +struct associated_executor< + ssl::detail::io_op, Executor> +{ + typedef typename associated_executor::type type; + + static type get(const ssl::detail::io_op& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return associated_executor::get(h.handler_, ex); + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_DETAIL_IO_HPP diff --git a/tools/sdk/include/asio/asio/ssl/detail/openssl_init.hpp b/tools/sdk/include/asio/asio/ssl/detail/openssl_init.hpp new file mode 100644 index 00000000..c3e47278 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/detail/openssl_init.hpp @@ -0,0 +1,101 @@ +// +// ssl/detail/openssl_init.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_DETAIL_OPENSSL_INIT_HPP +#define ASIO_SSL_DETAIL_OPENSSL_INIT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/detail/memory.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/ssl/detail/openssl_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +class openssl_init_base + : private noncopyable +{ +protected: + // Class that performs the actual initialisation. + class do_init; + + // Helper function to manage a do_init singleton. The static instance of the + // openssl_init object ensures that this function is always called before + // main, and therefore before any other threads can get started. The do_init + // instance must be static in this function to ensure that it gets + // initialised before any other global objects try to use it. + ASIO_DECL static asio::detail::shared_ptr instance(); + +#if !defined(SSL_OP_NO_COMPRESSION) \ + && (OPENSSL_VERSION_NUMBER >= 0x00908000L) + // Get an empty stack of compression methods, to be used when disabling + // compression. + ASIO_DECL static STACK_OF(SSL_COMP)* get_null_compression_methods(); +#endif // !defined(SSL_OP_NO_COMPRESSION) + // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) +}; + +template +class openssl_init : private openssl_init_base +{ +public: + // Constructor. + openssl_init() + : ref_(instance()) + { + using namespace std; // For memmove. + + // Ensure openssl_init::instance_ is linked in. + openssl_init* tmp = &instance_; + memmove(&tmp, &tmp, sizeof(openssl_init*)); + } + + // Destructor. + ~openssl_init() + { + } + +#if !defined(SSL_OP_NO_COMPRESSION) \ + && (OPENSSL_VERSION_NUMBER >= 0x00908000L) + using openssl_init_base::get_null_compression_methods; +#endif // !defined(SSL_OP_NO_COMPRESSION) + // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) + +private: + // Instance to force initialisation of openssl at global scope. + static openssl_init instance_; + + // Reference to singleton do_init object to ensure that openssl does not get + // cleaned up until the last user has finished with it. + asio::detail::shared_ptr ref_; +}; + +template +openssl_init openssl_init::instance_; + +} // namespace detail +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/ssl/detail/impl/openssl_init.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_SSL_DETAIL_OPENSSL_INIT_HPP diff --git a/tools/sdk/include/asio/asio/ssl/detail/openssl_types.hpp b/tools/sdk/include/asio/asio/ssl/detail/openssl_types.hpp new file mode 100644 index 00000000..a044af30 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/detail/openssl_types.hpp @@ -0,0 +1,30 @@ +// +// ssl/detail/openssl_types.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP +#define ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/socket_types.hpp" +#include +#include +#if !defined(OPENSSL_NO_ENGINE) +# include +#endif // !defined(OPENSSL_NO_ENGINE) +#include +#include +#include +#include + +#endif // ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP diff --git a/tools/sdk/include/asio/asio/ssl/detail/password_callback.hpp b/tools/sdk/include/asio/asio/ssl/detail/password_callback.hpp new file mode 100644 index 00000000..9b1dbeeb --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/detail/password_callback.hpp @@ -0,0 +1,66 @@ +// +// ssl/detail/password_callback.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP +#define ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include +#include +#include "asio/ssl/context_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +class password_callback_base +{ +public: + virtual ~password_callback_base() + { + } + + virtual std::string call(std::size_t size, + context_base::password_purpose purpose) = 0; +}; + +template +class password_callback : public password_callback_base +{ +public: + explicit password_callback(PasswordCallback callback) + : callback_(callback) + { + } + + virtual std::string call(std::size_t size, + context_base::password_purpose purpose) + { + return callback_(size, purpose); + } + +private: + PasswordCallback callback_; +}; + +} // namespace detail +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP diff --git a/tools/sdk/include/asio/asio/ssl/detail/read_op.hpp b/tools/sdk/include/asio/asio/ssl/detail/read_op.hpp new file mode 100644 index 00000000..b0d6de26 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/detail/read_op.hpp @@ -0,0 +1,67 @@ +// +// ssl/detail/read_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_DETAIL_READ_OP_HPP +#define ASIO_SSL_DETAIL_READ_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/ssl/detail/engine.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +template +class read_op +{ +public: + read_op(const MutableBufferSequence& buffers) + : buffers_(buffers) + { + } + + engine::want operator()(engine& eng, + asio::error_code& ec, + std::size_t& bytes_transferred) const + { + asio::mutable_buffer buffer = + asio::detail::buffer_sequence_adapter::first(buffers_); + + return eng.read(buffer, ec, bytes_transferred); + } + + template + void call_handler(Handler& handler, + const asio::error_code& ec, + const std::size_t& bytes_transferred) const + { + handler(ec, bytes_transferred); + } + +private: + MutableBufferSequence buffers_; +}; + +} // namespace detail +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_DETAIL_READ_OP_HPP diff --git a/tools/sdk/include/asio/asio/ssl/detail/shutdown_op.hpp b/tools/sdk/include/asio/asio/ssl/detail/shutdown_op.hpp new file mode 100644 index 00000000..d20b4309 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/detail/shutdown_op.hpp @@ -0,0 +1,54 @@ +// +// ssl/detail/shutdown_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP +#define ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/ssl/detail/engine.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +class shutdown_op +{ +public: + engine::want operator()(engine& eng, + asio::error_code& ec, + std::size_t& bytes_transferred) const + { + bytes_transferred = 0; + return eng.shutdown(ec); + } + + template + void call_handler(Handler& handler, + const asio::error_code& ec, + const std::size_t&) const + { + handler(ec); + } +}; + +} // namespace detail +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP diff --git a/tools/sdk/include/asio/asio/ssl/detail/stream_core.hpp b/tools/sdk/include/asio/asio/ssl/detail/stream_core.hpp new file mode 100644 index 00000000..13fde74b --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/detail/stream_core.hpp @@ -0,0 +1,134 @@ +// +// ssl/detail/stream_core.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_DETAIL_STREAM_CORE_HPP +#define ASIO_SSL_DETAIL_STREAM_CORE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_BOOST_DATE_TIME) +# include "asio/deadline_timer.hpp" +#else // defined(ASIO_HAS_BOOST_DATE_TIME) +# include "asio/steady_timer.hpp" +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) +#include "asio/ssl/detail/engine.hpp" +#include "asio/buffer.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +struct stream_core +{ + // According to the OpenSSL documentation, this is the buffer size that is + // sufficient to hold the largest possible TLS record. + enum { max_tls_record_size = 17 * 1024 }; + + stream_core(SSL_CTX* context, asio::io_context& io_context) + : engine_(context), + pending_read_(io_context), + pending_write_(io_context), + output_buffer_space_(max_tls_record_size), + output_buffer_(asio::buffer(output_buffer_space_)), + input_buffer_space_(max_tls_record_size), + input_buffer_(asio::buffer(input_buffer_space_)) + { + pending_read_.expires_at(neg_infin()); + pending_write_.expires_at(neg_infin()); + } + + ~stream_core() + { + } + + // The SSL engine. + engine engine_; + +#if defined(ASIO_HAS_BOOST_DATE_TIME) + // Timer used for storing queued read operations. + asio::deadline_timer pending_read_; + + // Timer used for storing queued write operations. + asio::deadline_timer pending_write_; + + // Helper function for obtaining a time value that always fires. + static asio::deadline_timer::time_type neg_infin() + { + return boost::posix_time::neg_infin; + } + + // Helper function for obtaining a time value that never fires. + static asio::deadline_timer::time_type pos_infin() + { + return boost::posix_time::pos_infin; + } + + // Helper function to get a timer's expiry time. + static asio::deadline_timer::time_type expiry( + const asio::deadline_timer& timer) + { + return timer.expires_at(); + } +#else // defined(ASIO_HAS_BOOST_DATE_TIME) + // Timer used for storing queued read operations. + asio::steady_timer pending_read_; + + // Timer used for storing queued write operations. + asio::steady_timer pending_write_; + + // Helper function for obtaining a time value that always fires. + static asio::steady_timer::time_point neg_infin() + { + return (asio::steady_timer::time_point::min)(); + } + + // Helper function for obtaining a time value that never fires. + static asio::steady_timer::time_point pos_infin() + { + return (asio::steady_timer::time_point::max)(); + } + + // Helper function to get a timer's expiry time. + static asio::steady_timer::time_point expiry( + const asio::steady_timer& timer) + { + return timer.expiry(); + } +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + + // Buffer space used to prepare output intended for the transport. + std::vector output_buffer_space_; + + // A buffer that may be used to prepare output intended for the transport. + const asio::mutable_buffer output_buffer_; + + // Buffer space used to read input intended for the engine. + std::vector input_buffer_space_; + + // A buffer that may be used to read input intended for the engine. + const asio::mutable_buffer input_buffer_; + + // The buffer pointing to the engine's unconsumed input. + asio::const_buffer input_; +}; + +} // namespace detail +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_DETAIL_STREAM_CORE_HPP diff --git a/tools/sdk/include/asio/asio/ssl/detail/verify_callback.hpp b/tools/sdk/include/asio/asio/ssl/detail/verify_callback.hpp new file mode 100644 index 00000000..1c56a27d --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/detail/verify_callback.hpp @@ -0,0 +1,62 @@ +// +// ssl/detail/verify_callback.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_DETAIL_VERIFY_CALLBACK_HPP +#define ASIO_SSL_DETAIL_VERIFY_CALLBACK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/ssl/verify_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +class verify_callback_base +{ +public: + virtual ~verify_callback_base() + { + } + + virtual bool call(bool preverified, verify_context& ctx) = 0; +}; + +template +class verify_callback : public verify_callback_base +{ +public: + explicit verify_callback(VerifyCallback callback) + : callback_(callback) + { + } + + virtual bool call(bool preverified, verify_context& ctx) + { + return callback_(preverified, ctx); + } + +private: + VerifyCallback callback_; +}; + +} // namespace detail +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_DETAIL_VERIFY_CALLBACK_HPP diff --git a/tools/sdk/include/asio/asio/ssl/detail/write_op.hpp b/tools/sdk/include/asio/asio/ssl/detail/write_op.hpp new file mode 100644 index 00000000..1d341c09 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/detail/write_op.hpp @@ -0,0 +1,67 @@ +// +// ssl/detail/write_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_DETAIL_WRITE_OP_HPP +#define ASIO_SSL_DETAIL_WRITE_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/ssl/detail/engine.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +template +class write_op +{ +public: + write_op(const ConstBufferSequence& buffers) + : buffers_(buffers) + { + } + + engine::want operator()(engine& eng, + asio::error_code& ec, + std::size_t& bytes_transferred) const + { + asio::const_buffer buffer = + asio::detail::buffer_sequence_adapter::first(buffers_); + + return eng.write(buffer, ec, bytes_transferred); + } + + template + void call_handler(Handler& handler, + const asio::error_code& ec, + const std::size_t& bytes_transferred) const + { + handler(ec, bytes_transferred); + } + +private: + ConstBufferSequence buffers_; +}; + +} // namespace detail +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_DETAIL_WRITE_OP_HPP diff --git a/tools/sdk/include/asio/asio/ssl/error.hpp b/tools/sdk/include/asio/asio/ssl/error.hpp new file mode 100644 index 00000000..6165c5cf --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/error.hpp @@ -0,0 +1,111 @@ +// +// ssl/error.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_ERROR_HPP +#define ASIO_SSL_ERROR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/error_code.hpp" +#include "asio/ssl/detail/openssl_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace error { + +enum ssl_errors +{ + // Error numbers are those produced by openssl. +}; + +extern ASIO_DECL +const asio::error_category& get_ssl_category(); + +static const asio::error_category& + ssl_category ASIO_UNUSED_VARIABLE + = asio::error::get_ssl_category(); + +} // namespace error +namespace ssl { +namespace error { + +enum stream_errors +{ +#if defined(GENERATING_DOCUMENTATION) + /// The underlying stream closed before the ssl stream gracefully shut down. + stream_truncated +#elif (OPENSSL_VERSION_NUMBER < 0x10100000L) && !defined(OPENSSL_IS_BORINGSSL) + stream_truncated = ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ) +#else + stream_truncated = 1 +#endif +}; + +extern ASIO_DECL +const asio::error_category& get_stream_category(); + +static const asio::error_category& + stream_category ASIO_UNUSED_VARIABLE + = asio::ssl::error::get_stream_category(); + +} // namespace error +} // namespace ssl +} // namespace asio + +#if defined(ASIO_HAS_STD_SYSTEM_ERROR) +namespace std { + +template<> struct is_error_code_enum +{ + static const bool value = true; +}; + +template<> struct is_error_code_enum +{ + static const bool value = true; +}; + +} // namespace std +#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) + +namespace asio { +namespace error { + +inline asio::error_code make_error_code(ssl_errors e) +{ + return asio::error_code( + static_cast(e), get_ssl_category()); +} + +} // namespace error +namespace ssl { +namespace error { + +inline asio::error_code make_error_code(stream_errors e) +{ + return asio::error_code( + static_cast(e), get_stream_category()); +} + +} // namespace error +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/ssl/impl/error.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_SSL_ERROR_HPP diff --git a/tools/sdk/include/asio/asio/ssl/impl/context.hpp b/tools/sdk/include/asio/asio/ssl/impl/context.hpp new file mode 100644 index 00000000..40199c14 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/impl/context.hpp @@ -0,0 +1,67 @@ +// +// ssl/impl/context.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_IMPL_CONTEXT_HPP +#define ASIO_SSL_IMPL_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { + +template +void context::set_verify_callback(VerifyCallback callback) +{ + asio::error_code ec; + this->set_verify_callback(callback, ec); + asio::detail::throw_error(ec, "set_verify_callback"); +} + +template +ASIO_SYNC_OP_VOID context::set_verify_callback( + VerifyCallback callback, asio::error_code& ec) +{ + do_set_verify_callback( + new detail::verify_callback(callback), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); +} + +template +void context::set_password_callback(PasswordCallback callback) +{ + asio::error_code ec; + this->set_password_callback(callback, ec); + asio::detail::throw_error(ec, "set_password_callback"); +} + +template +ASIO_SYNC_OP_VOID context::set_password_callback( + PasswordCallback callback, asio::error_code& ec) +{ + do_set_password_callback( + new detail::password_callback(callback), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); +} + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_IMPL_CONTEXT_HPP diff --git a/tools/sdk/include/asio/asio/ssl/impl/src.hpp b/tools/sdk/include/asio/asio/ssl/impl/src.hpp new file mode 100644 index 00000000..9a1b038a --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/impl/src.hpp @@ -0,0 +1,28 @@ +// +// impl/ssl/src.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_IMPL_SRC_HPP +#define ASIO_SSL_IMPL_SRC_HPP + +#define ASIO_SOURCE + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HEADER_ONLY) +# error Do not compile Asio library source with ASIO_HEADER_ONLY defined +#endif + +#include "asio/ssl/impl/context.ipp" +#include "asio/ssl/impl/error.ipp" +#include "asio/ssl/detail/impl/engine.ipp" +#include "asio/ssl/detail/impl/openssl_init.ipp" +#include "asio/ssl/impl/rfc2818_verification.ipp" + +#endif // ASIO_SSL_IMPL_SRC_HPP diff --git a/tools/sdk/include/asio/asio/ssl/rfc2818_verification.hpp b/tools/sdk/include/asio/asio/ssl/rfc2818_verification.hpp new file mode 100644 index 00000000..3589f538 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/rfc2818_verification.hpp @@ -0,0 +1,94 @@ +// +// ssl/rfc2818_verification.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_RFC2818_VERIFICATION_HPP +#define ASIO_SSL_RFC2818_VERIFICATION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include +#include "asio/ssl/detail/openssl_types.hpp" +#include "asio/ssl/verify_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { + +/// Verifies a certificate against a hostname according to the rules described +/// in RFC 2818. +/** + * @par Example + * The following example shows how to synchronously open a secure connection to + * a given host name: + * @code + * using asio::ip::tcp; + * namespace ssl = asio::ssl; + * typedef ssl::stream ssl_socket; + * + * // Create a context that uses the default paths for finding CA certificates. + * ssl::context ctx(ssl::context::sslv23); + * ctx.set_default_verify_paths(); + * + * // Open a socket and connect it to the remote host. + * asio::io_context io_context; + * ssl_socket sock(io_context, ctx); + * tcp::resolver resolver(io_context); + * tcp::resolver::query query("host.name", "https"); + * asio::connect(sock.lowest_layer(), resolver.resolve(query)); + * sock.lowest_layer().set_option(tcp::no_delay(true)); + * + * // Perform SSL handshake and verify the remote host's certificate. + * sock.set_verify_mode(ssl::verify_peer); + * sock.set_verify_callback(ssl::rfc2818_verification("host.name")); + * sock.handshake(ssl_socket::client); + * + * // ... read and write as normal ... + * @endcode + */ +class rfc2818_verification +{ +public: + /// The type of the function object's result. + typedef bool result_type; + + /// Constructor. + explicit rfc2818_verification(const std::string& host) + : host_(host) + { + } + + /// Perform certificate verification. + ASIO_DECL bool operator()(bool preverified, verify_context& ctx) const; + +private: + // Helper function to check a host name against a pattern. + ASIO_DECL static bool match_pattern(const char* pattern, + std::size_t pattern_length, const char* host); + + // Helper function to check a host name against an IPv4 address + // The host name to be checked. + std::string host_; +}; + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/ssl/impl/rfc2818_verification.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_SSL_RFC2818_VERIFICATION_HPP diff --git a/tools/sdk/include/asio/asio/ssl/stream.hpp b/tools/sdk/include/asio/asio/ssl/stream.hpp new file mode 100644 index 00000000..2b221ed5 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/stream.hpp @@ -0,0 +1,761 @@ +// +// ssl/stream.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_STREAM_HPP +#define ASIO_SSL_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/async_result.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/ssl/context.hpp" +#include "asio/ssl/detail/buffered_handshake_op.hpp" +#include "asio/ssl/detail/handshake_op.hpp" +#include "asio/ssl/detail/io.hpp" +#include "asio/ssl/detail/read_op.hpp" +#include "asio/ssl/detail/shutdown_op.hpp" +#include "asio/ssl/detail/stream_core.hpp" +#include "asio/ssl/detail/write_op.hpp" +#include "asio/ssl/stream_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { + +/// Provides stream-oriented functionality using SSL. +/** + * The stream class template provides asynchronous and blocking stream-oriented + * functionality using SSL. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. The application must also ensure that all + * asynchronous operations are performed within the same implicit or explicit + * strand. + * + * @par Example + * To use the SSL stream template with an ip::tcp::socket, you would write: + * @code + * asio::io_context io_context; + * asio::ssl::context ctx(asio::ssl::context::sslv23); + * asio::ssl::stream sock(io_context, ctx); + * @endcode + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +template +class stream : + public stream_base, + private noncopyable +{ +public: + /// The native handle type of the SSL stream. + typedef SSL* native_handle_type; + + /// Structure for use with deprecated impl_type. + struct impl_struct + { + SSL* ssl; + }; + + /// The type of the next layer. + typedef typename remove_reference::type next_layer_type; + + /// The type of the lowest layer. + typedef typename next_layer_type::lowest_layer_type lowest_layer_type; + + /// The type of the executor associated with the object. + typedef typename lowest_layer_type::executor_type executor_type; + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Construct a stream. + /** + * This constructor creates a stream and initialises the underlying stream + * object. + * + * @param arg The argument to be passed to initialise the underlying stream. + * + * @param ctx The SSL context to be used for the stream. + */ + template + stream(Arg&& arg, context& ctx) + : next_layer_(ASIO_MOVE_CAST(Arg)(arg)), + core_(ctx.native_handle(), + next_layer_.lowest_layer().get_executor().context()) + { + } +#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + template + stream(Arg& arg, context& ctx) + : next_layer_(arg), + core_(ctx.native_handle(), + next_layer_.lowest_layer().get_executor().context()) + { + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destructor. + /** + * @note A @c stream object must not be destroyed while there are pending + * asynchronous operations associated with it. + */ + ~stream() + { + } + + /// Get the executor associated with the object. + /** + * This function may be used to obtain the executor object that the stream + * uses to dispatch handlers for asynchronous operations. + * + * @return A copy of the executor that stream will use to dispatch handlers. + */ + executor_type get_executor() ASIO_NOEXCEPT + { + return next_layer_.lowest_layer().get_executor(); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + asio::io_context& get_io_context() + { + return next_layer_.lowest_layer().get_io_context(); + } + + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + asio::io_context& get_io_service() + { + return next_layer_.lowest_layer().get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the underlying implementation in the native type. + /** + * This function may be used to obtain the underlying implementation of the + * context. This is intended to allow access to context functionality that is + * not otherwise provided. + * + * @par Example + * The native_handle() function returns a pointer of type @c SSL* that is + * suitable for passing to functions such as @c SSL_get_verify_result and + * @c SSL_get_peer_certificate: + * @code + * asio::ssl::stream sock(io_context, ctx); + * + * // ... establish connection and perform handshake ... + * + * if (X509* cert = SSL_get_peer_certificate(sock.native_handle())) + * { + * if (SSL_get_verify_result(sock.native_handle()) == X509_V_OK) + * { + * // ... + * } + * } + * @endcode + */ + native_handle_type native_handle() + { + return core_.engine_.native_handle(); + } + + /// Get a reference to the next layer. + /** + * This function returns a reference to the next layer in a stack of stream + * layers. + * + * @return A reference to the next layer in the stack of stream layers. + * Ownership is not transferred to the caller. + */ + const next_layer_type& next_layer() const + { + return next_layer_; + } + + /// Get a reference to the next layer. + /** + * This function returns a reference to the next layer in a stack of stream + * layers. + * + * @return A reference to the next layer in the stack of stream layers. + * Ownership is not transferred to the caller. + */ + next_layer_type& next_layer() + { + return next_layer_; + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * stream layers. + * + * @return A reference to the lowest layer in the stack of stream layers. + * Ownership is not transferred to the caller. + */ + lowest_layer_type& lowest_layer() + { + return next_layer_.lowest_layer(); + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * stream layers. + * + * @return A reference to the lowest layer in the stack of stream layers. + * Ownership is not transferred to the caller. + */ + const lowest_layer_type& lowest_layer() const + { + return next_layer_.lowest_layer(); + } + + /// Set the peer verification mode. + /** + * This function may be used to configure the peer verification mode used by + * the stream. The new mode will override the mode inherited from the context. + * + * @param v A bitmask of peer verification modes. See @ref verify_mode for + * available values. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_set_verify. + */ + void set_verify_mode(verify_mode v) + { + asio::error_code ec; + set_verify_mode(v, ec); + asio::detail::throw_error(ec, "set_verify_mode"); + } + + /// Set the peer verification mode. + /** + * This function may be used to configure the peer verification mode used by + * the stream. The new mode will override the mode inherited from the context. + * + * @param v A bitmask of peer verification modes. See @ref verify_mode for + * available values. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_set_verify. + */ + ASIO_SYNC_OP_VOID set_verify_mode( + verify_mode v, asio::error_code& ec) + { + core_.engine_.set_verify_mode(v, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Set the peer verification depth. + /** + * This function may be used to configure the maximum verification depth + * allowed by the stream. + * + * @param depth Maximum depth for the certificate chain verification that + * shall be allowed. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_set_verify_depth. + */ + void set_verify_depth(int depth) + { + asio::error_code ec; + set_verify_depth(depth, ec); + asio::detail::throw_error(ec, "set_verify_depth"); + } + + /// Set the peer verification depth. + /** + * This function may be used to configure the maximum verification depth + * allowed by the stream. + * + * @param depth Maximum depth for the certificate chain verification that + * shall be allowed. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_set_verify_depth. + */ + ASIO_SYNC_OP_VOID set_verify_depth( + int depth, asio::error_code& ec) + { + core_.engine_.set_verify_depth(depth, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Set the callback used to verify peer certificates. + /** + * This function is used to specify a callback function that will be called + * by the implementation when it needs to verify a peer certificate. + * + * @param callback The function object to be used for verifying a certificate. + * The function signature of the handler must be: + * @code bool verify_callback( + * bool preverified, // True if the certificate passed pre-verification. + * verify_context& ctx // The peer certificate and other context. + * ); @endcode + * The return value of the callback is true if the certificate has passed + * verification, false otherwise. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls @c SSL_set_verify. + */ + template + void set_verify_callback(VerifyCallback callback) + { + asio::error_code ec; + this->set_verify_callback(callback, ec); + asio::detail::throw_error(ec, "set_verify_callback"); + } + + /// Set the callback used to verify peer certificates. + /** + * This function is used to specify a callback function that will be called + * by the implementation when it needs to verify a peer certificate. + * + * @param callback The function object to be used for verifying a certificate. + * The function signature of the handler must be: + * @code bool verify_callback( + * bool preverified, // True if the certificate passed pre-verification. + * verify_context& ctx // The peer certificate and other context. + * ); @endcode + * The return value of the callback is true if the certificate has passed + * verification, false otherwise. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_set_verify. + */ + template + ASIO_SYNC_OP_VOID set_verify_callback(VerifyCallback callback, + asio::error_code& ec) + { + core_.engine_.set_verify_callback( + new detail::verify_callback(callback), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Perform SSL handshaking. + /** + * This function is used to perform SSL handshaking on the stream. The + * function call will block until handshaking is complete or an error occurs. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @throws asio::system_error Thrown on failure. + */ + void handshake(handshake_type type) + { + asio::error_code ec; + handshake(type, ec); + asio::detail::throw_error(ec, "handshake"); + } + + /// Perform SSL handshaking. + /** + * This function is used to perform SSL handshaking on the stream. The + * function call will block until handshaking is complete or an error occurs. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID handshake(handshake_type type, + asio::error_code& ec) + { + detail::io(next_layer_, core_, detail::handshake_op(type), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Perform SSL handshaking. + /** + * This function is used to perform SSL handshaking on the stream. The + * function call will block until handshaking is complete or an error occurs. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @param buffers The buffered data to be reused for the handshake. + * + * @throws asio::system_error Thrown on failure. + */ + template + void handshake(handshake_type type, const ConstBufferSequence& buffers) + { + asio::error_code ec; + handshake(type, buffers, ec); + asio::detail::throw_error(ec, "handshake"); + } + + /// Perform SSL handshaking. + /** + * This function is used to perform SSL handshaking on the stream. The + * function call will block until handshaking is complete or an error occurs. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @param buffers The buffered data to be reused for the handshake. + * + * @param ec Set to indicate what error occurred, if any. + */ + template + ASIO_SYNC_OP_VOID handshake(handshake_type type, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + detail::io(next_layer_, core_, + detail::buffered_handshake_op(type, buffers), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Start an asynchronous SSL handshake. + /** + * This function is used to asynchronously perform an SSL handshake on the + * stream. This function call always returns immediately. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @param handler The handler to be called when the handshake operation + * completes. Copies will be made of the handler as required. The equivalent + * function signature of the handler must be: + * @code void handler( + * const asio::error_code& error // Result of operation. + * ); @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(HandshakeHandler, + void (asio::error_code)) + async_handshake(handshake_type type, + ASIO_MOVE_ARG(HandshakeHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a HandshakeHandler. + ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check; + + asio::async_completion init(handler); + + detail::async_io(next_layer_, core_, + detail::handshake_op(type), init.completion_handler); + + return init.result.get(); + } + + /// Start an asynchronous SSL handshake. + /** + * This function is used to asynchronously perform an SSL handshake on the + * stream. This function call always returns immediately. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @param buffers The buffered data to be reused for the handshake. Although + * the buffers object may be copied as necessary, ownership of the underlying + * buffers 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 handshake operation + * completes. Copies will be made of the handler as required. The equivalent + * function signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Amount of buffers used in handshake. + * ); @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, + void (asio::error_code, std::size_t)) + async_handshake(handshake_type type, const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(BufferedHandshakeHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a BufferedHandshakeHandler. + ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( + BufferedHandshakeHandler, handler) type_check; + + asio::async_completion init(handler); + + detail::async_io(next_layer_, core_, + detail::buffered_handshake_op(type, buffers), + init.completion_handler); + + return init.result.get(); + } + + /// Shut down SSL on the stream. + /** + * This function is used to shut down SSL on the stream. The function call + * will block until SSL has been shut down or an error occurs. + * + * @throws asio::system_error Thrown on failure. + */ + void shutdown() + { + asio::error_code ec; + shutdown(ec); + asio::detail::throw_error(ec, "shutdown"); + } + + /// Shut down SSL on the stream. + /** + * This function is used to shut down SSL on the stream. The function call + * will block until SSL has been shut down or an error occurs. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID shutdown(asio::error_code& ec) + { + detail::io(next_layer_, core_, detail::shutdown_op(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Asynchronously shut down SSL on the stream. + /** + * This function is used to asynchronously shut down SSL on the stream. This + * function call always returns immediately. + * + * @param handler The handler to be called when the handshake operation + * completes. Copies will be made of the handler as required. The equivalent + * function signature of the handler must be: + * @code void handler( + * const asio::error_code& error // Result of operation. + * ); @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(ShutdownHandler, + void (asio::error_code)) + async_shutdown(ASIO_MOVE_ARG(ShutdownHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ShutdownHandler. + ASIO_SHUTDOWN_HANDLER_CHECK(ShutdownHandler, handler) type_check; + + asio::async_completion init(handler); + + detail::async_io(next_layer_, core_, detail::shutdown_op(), + init.completion_handler); + + return init.result.get(); + } + + /// Write some data to the stream. + /** + * This function is used to write data on the stream. The function call will + * block until one or more bytes of data has been written successfully, or + * until an error occurs. + * + * @param buffers The data to be written. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. + * + * @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) + { + asio::error_code ec; + std::size_t n = write_some(buffers, ec); + asio::detail::throw_error(ec, "write_some"); + return n; + } + + /// Write some data to the stream. + /** + * This function is used to write data on the stream. The function call will + * block until one or more bytes of data has been written successfully, or + * until an error occurs. + * + * @param buffers The data to be written to the stream. + * + * @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, + asio::error_code& ec) + { + return detail::io(next_layer_, core_, + detail::write_op(buffers), ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write one or more bytes of data to + * the stream. The function call always returns immediately. + * + * @param buffers The data to be written to the stream. Although the buffers + * object may be copied as necessary, ownership of the underlying buffers 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 equivalent function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes written. + * ); @endcode + * + * @note The async_write_some 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 blocking operation completes. + */ + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + asio::async_completion init(handler); + + detail::async_io(next_layer_, core_, + detail::write_op(buffers), + init.completion_handler); + + return init.result.get(); + } + + /// Read some data from the stream. + /** + * This function is used to read data from the stream. The function call will + * block until one or more bytes of data has been read successfully, or until + * an error occurs. + * + * @param buffers The buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. + * + * @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) + { + asio::error_code ec; + std::size_t n = read_some(buffers, ec); + asio::detail::throw_error(ec, "read_some"); + return n; + } + + /// Read some data from the stream. + /** + * This function is used to read data from the stream. The function call will + * block until one or more bytes of data has been read successfully, or until + * an error occurs. + * + * @param buffers The 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, + asio::error_code& ec) + { + return detail::io(next_layer_, core_, + detail::read_op(buffers), ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read one or more bytes of data from + * the stream. The function call always returns immediately. + * + * @param buffers The buffers into which the data will be read. Although the + * buffers object may be copied as necessary, ownership of the underlying + * buffers 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 equivalent function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes read. + * ); @endcode + * + * @note The async_read_some 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. + */ + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + asio::async_completion init(handler); + + detail::async_io(next_layer_, core_, + detail::read_op(buffers), + init.completion_handler); + + return init.result.get(); + } + +private: + Stream next_layer_; + detail::stream_core core_; +}; + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_STREAM_HPP diff --git a/tools/sdk/include/asio/asio/ssl/stream_base.hpp b/tools/sdk/include/asio/asio/ssl/stream_base.hpp new file mode 100644 index 00000000..56873e4a --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/stream_base.hpp @@ -0,0 +1,52 @@ +// +// ssl/stream_base.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_STREAM_BASE_HPP +#define ASIO_SSL_STREAM_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { + +/// The stream_base class is used as a base for the asio::ssl::stream +/// class template so that we have a common place to define various enums. +class stream_base +{ +public: + /// Different handshake types. + enum handshake_type + { + /// Perform handshaking as a client. + client, + + /// Perform handshaking as a server. + server + }; + +protected: + /// Protected destructor to prevent deletion through this type. + ~stream_base() + { + } +}; + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_STREAM_BASE_HPP diff --git a/tools/sdk/include/asio/asio/ssl/verify_context.hpp b/tools/sdk/include/asio/asio/ssl/verify_context.hpp new file mode 100644 index 00000000..e1726971 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/verify_context.hpp @@ -0,0 +1,67 @@ +// +// ssl/verify_context.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_VERIFY_CONTEXT_HPP +#define ASIO_SSL_VERIFY_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/detail/noncopyable.hpp" +#include "asio/ssl/detail/openssl_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { + +/// A simple wrapper around the X509_STORE_CTX type, used during verification of +/// a peer certificate. +/** + * @note The verify_context does not own the underlying X509_STORE_CTX object. + */ +class verify_context + : private noncopyable +{ +public: + /// The native handle type of the verification context. + typedef X509_STORE_CTX* native_handle_type; + + /// Constructor. + explicit verify_context(native_handle_type handle) + : handle_(handle) + { + } + + /// Get the underlying implementation in the native type. + /** + * This function may be used to obtain the underlying implementation of the + * context. This is intended to allow access to context functionality that is + * not otherwise provided. + */ + native_handle_type native_handle() + { + return handle_; + } + +private: + // The underlying native implementation. + native_handle_type handle_; +}; + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_VERIFY_CONTEXT_HPP diff --git a/tools/sdk/include/asio/asio/ssl/verify_mode.hpp b/tools/sdk/include/asio/asio/ssl/verify_mode.hpp new file mode 100644 index 00000000..8c4b3942 --- /dev/null +++ b/tools/sdk/include/asio/asio/ssl/verify_mode.hpp @@ -0,0 +1,63 @@ +// +// ssl/verify_mode.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SSL_VERIFY_MODE_HPP +#define ASIO_SSL_VERIFY_MODE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/ssl/detail/openssl_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ssl { + +/// Bitmask type for peer verification. +/** + * Possible values are: + * + * @li @ref verify_none + * @li @ref verify_peer + * @li @ref verify_fail_if_no_peer_cert + * @li @ref verify_client_once + */ +typedef int verify_mode; + +#if defined(GENERATING_DOCUMENTATION) +/// No verification. +const int verify_none = implementation_defined; + +/// Verify the peer. +const int verify_peer = implementation_defined; + +/// Fail verification if the peer has no certificate. Ignored unless +/// @ref verify_peer is set. +const int verify_fail_if_no_peer_cert = implementation_defined; + +/// Do not request client certificate on renegotiation. Ignored unless +/// @ref verify_peer is set. +const int verify_client_once = implementation_defined; +#else +const int verify_none = SSL_VERIFY_NONE; +const int verify_peer = SSL_VERIFY_PEER; +const int verify_fail_if_no_peer_cert = SSL_VERIFY_FAIL_IF_NO_PEER_CERT; +const int verify_client_once = SSL_VERIFY_CLIENT_ONCE; +#endif + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_VERIFY_MODE_HPP diff --git a/tools/sdk/include/asio/asio/steady_timer.hpp b/tools/sdk/include/asio/asio/steady_timer.hpp new file mode 100644 index 00000000..3ede2084 --- /dev/null +++ b/tools/sdk/include/asio/asio/steady_timer.hpp @@ -0,0 +1,42 @@ +// +// steady_timer.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_STEADY_TIMER_HPP +#define ASIO_STEADY_TIMER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) + +#include "asio/basic_waitable_timer.hpp" +#include "asio/detail/chrono.hpp" + +namespace asio { + +/// Typedef for a timer based on the steady clock. +/** + * This typedef uses the C++11 @c <chrono> standard library facility, if + * available. Otherwise, it may use the Boost.Chrono library. To explicitly + * utilise Boost.Chrono, use the basic_waitable_timer template directly: + * @code + * typedef basic_waitable_timer timer; + * @endcode + */ +typedef basic_waitable_timer steady_timer; + +} // namespace asio + +#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_STEADY_TIMER_HPP diff --git a/tools/sdk/include/asio/asio/strand.hpp b/tools/sdk/include/asio/asio/strand.hpp new file mode 100644 index 00000000..ea78ef02 --- /dev/null +++ b/tools/sdk/include/asio/asio/strand.hpp @@ -0,0 +1,286 @@ +// +// strand.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_STRAND_HPP +#define ASIO_STRAND_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/strand_executor_service.hpp" +#include "asio/detail/type_traits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Provides serialised function invocation for any executor type. +template +class strand +{ +public: + /// The type of the underlying executor. + typedef Executor inner_executor_type; + + /// Default constructor. + /** + * This constructor is only valid if the underlying executor type is default + * constructible. + */ + strand() + : executor_(), + impl_(use_service( + executor_.context()).create_implementation()) + { + } + + /// Construct a strand for the specified executor. + explicit strand(const Executor& e) + : executor_(e), + impl_(use_service( + executor_.context()).create_implementation()) + { + } + + /// Copy constructor. + strand(const strand& other) ASIO_NOEXCEPT + : executor_(other.executor_), + impl_(other.impl_) + { + } + + /// Converting constructor. + /** + * This constructor is only valid if the @c OtherExecutor type is convertible + * to @c Executor. + */ + template + strand( + const strand& other) ASIO_NOEXCEPT + : executor_(other.executor_), + impl_(other.impl_) + { + } + + /// Assignment operator. + strand& operator=(const strand& other) ASIO_NOEXCEPT + { + executor_ = other.executor_; + impl_ = other.impl_; + return *this; + } + + /// Converting assignment operator. + /** + * This assignment operator is only valid if the @c OtherExecutor type is + * convertible to @c Executor. + */ + template + strand& operator=( + const strand& other) ASIO_NOEXCEPT + { + executor_ = other.executor_; + impl_ = other.impl_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move constructor. + strand(strand&& other) ASIO_NOEXCEPT + : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)), + impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_)) + { + } + + /// Converting move constructor. + /** + * This constructor is only valid if the @c OtherExecutor type is convertible + * to @c Executor. + */ + template + strand(strand&& other) ASIO_NOEXCEPT + : executor_(ASIO_MOVE_CAST(OtherExecutor)(other)), + impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_)) + { + } + + /// Move assignment operator. + strand& operator=(strand&& other) ASIO_NOEXCEPT + { + executor_ = ASIO_MOVE_CAST(Executor)(other); + impl_ = ASIO_MOVE_CAST(implementation_type)(other.impl_); + return *this; + } + + /// Converting move assignment operator. + /** + * This assignment operator is only valid if the @c OtherExecutor type is + * convertible to @c Executor. + */ + template + strand& operator=( + const strand&& other) ASIO_NOEXCEPT + { + executor_ = ASIO_MOVE_CAST(OtherExecutor)(other); + impl_ = ASIO_MOVE_CAST(implementation_type)(other.impl_); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destructor. + ~strand() + { + } + + /// Obtain the underlying executor. + inner_executor_type get_inner_executor() const ASIO_NOEXCEPT + { + return executor_; + } + + /// Obtain the underlying execution context. + execution_context& context() const ASIO_NOEXCEPT + { + return executor_.context(); + } + + /// Inform the strand that it has some outstanding work to do. + /** + * The strand delegates this call to its underlying executor. + */ + void on_work_started() const ASIO_NOEXCEPT + { + executor_.on_work_started(); + } + + /// Inform the strand that some work is no longer outstanding. + /** + * The strand delegates this call to its underlying executor. + */ + void on_work_finished() const ASIO_NOEXCEPT + { + executor_.on_work_finished(); + } + + /// Request the strand to invoke the given function object. + /** + * This function is used to ask the strand to execute the given function + * object on its underlying executor. The function object will be executed + * inside this function if the strand is not otherwise busy and if the + * underlying executor's @c dispatch() function is also able to execute the + * function before returning. + * + * @param f The function object to be called. The executor will make + * a copy of the handler object as required. The function signature of the + * function object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const + { + detail::strand_executor_service::dispatch(impl_, + executor_, ASIO_MOVE_CAST(Function)(f), a); + } + + /// Request the strand to invoke the given function object. + /** + * This function is used to ask the executor to execute the given function + * object. The function object will never be executed inside this function. + * Instead, it will be scheduled by the underlying executor's defer function. + * + * @param f The function object to be called. The executor will make + * a copy of the handler object as required. The function signature of the + * function object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const + { + detail::strand_executor_service::post(impl_, + executor_, ASIO_MOVE_CAST(Function)(f), a); + } + + /// Request the strand to invoke the given function object. + /** + * This function is used to ask the executor to execute the given function + * object. The function object will never be executed inside this function. + * Instead, it will be scheduled by the underlying executor's defer function. + * + * @param f The function object to be called. The executor will make + * a copy of the handler object as required. The function signature of the + * function object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const + { + detail::strand_executor_service::defer(impl_, + executor_, ASIO_MOVE_CAST(Function)(f), a); + } + + /// Determine whether the strand is running in the current thread. + /** + * @return @c true if the current thread is executing a function that was + * submitted to the strand using post(), dispatch() or defer(). Otherwise + * returns @c false. + */ + bool running_in_this_thread() const ASIO_NOEXCEPT + { + return detail::strand_executor_service::running_in_this_thread(impl_); + } + + /// Compare two strands for equality. + /** + * Two strands are equal if they refer to the same ordered, non-concurrent + * state. + */ + friend bool operator==(const strand& a, const strand& b) ASIO_NOEXCEPT + { + return a.impl_ == b.impl_; + } + + /// Compare two strands for inequality. + /** + * Two strands are equal if they refer to the same ordered, non-concurrent + * state. + */ + friend bool operator!=(const strand& a, const strand& b) ASIO_NOEXCEPT + { + return a.impl_ != b.impl_; + } + +private: + Executor executor_; + typedef detail::strand_executor_service::implementation_type + implementation_type; + implementation_type impl_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +// If both io_context.hpp and strand.hpp have been included, automatically +// include the header file needed for the io_context::strand class. +#if !defined(ASIO_NO_EXTENSIONS) +# if defined(ASIO_IO_CONTEXT_HPP) +# include "asio/io_context_strand.hpp" +# endif // defined(ASIO_IO_CONTEXT_HPP) +#endif // !defined(ASIO_NO_EXTENSIONS) + +#endif // ASIO_STRAND_HPP diff --git a/tools/sdk/include/asio/asio/stream_socket_service.hpp b/tools/sdk/include/asio/asio/stream_socket_service.hpp new file mode 100644 index 00000000..91b0a711 --- /dev/null +++ b/tools/sdk/include/asio/asio/stream_socket_service.hpp @@ -0,0 +1,412 @@ +// +// stream_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_STREAM_SOCKET_SERVICE_HPP +#define ASIO_STREAM_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#include +#include "asio/async_result.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/winrt_ssocket_service.hpp" +#elif defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_socket_service.hpp" +#else +# include "asio/detail/reactive_socket_service.hpp" +#endif + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Default service implementation for a stream socket. +template +class stream_socket_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static 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(ASIO_WINDOWS_RUNTIME) + typedef detail::winrt_ssocket_service service_impl_type; +#elif defined(ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service service_impl_type; +#else + typedef detail::reactive_socket_service 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(asio::io_context& io_context) + : asio::detail::service_base< + stream_socket_service >(io_context), + service_impl_(io_context) + { + } + + /// Construct a new stream socket implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(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& 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; + + /// Move-construct a new stream socket implementation from another protocol + /// type. + template + void converting_move_construct(implementation_type& impl, + stream_socket_service& other_service, + typename stream_socket_service< + 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(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy a stream socket implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Open a stream socket. + ASIO_SYNC_OP_VOID open(implementation_type& impl, + const protocol_type& protocol, asio::error_code& ec) + { + if (protocol.type() == ASIO_OS_DEF(SOCK_STREAM)) + service_impl_.open(impl, protocol, ec); + else + ec = asio::error::invalid_argument; + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Assign an existing native socket to a stream socket. + ASIO_SYNC_OP_VOID assign(implementation_type& impl, + const protocol_type& protocol, const native_handle_type& native_socket, + asio::error_code& ec) + { + service_impl_.assign(impl, protocol, native_socket, ec); + 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. + ASIO_SYNC_OP_VOID close(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.close(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Release ownership of the underlying socket. + native_handle_type release(implementation_type& impl, + asio::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. + ASIO_SYNC_OP_VOID cancel(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.cancel(impl, ec); + 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, + asio::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, + asio::error_code& ec) const + { + return service_impl_.available(impl, ec); + } + + /// Bind the stream socket to the specified local endpoint. + ASIO_SYNC_OP_VOID bind(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + service_impl_.bind(impl, endpoint, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Connect the stream socket to the specified endpoint. + ASIO_SYNC_OP_VOID connect(implementation_type& impl, + const endpoint_type& peer_endpoint, asio::error_code& ec) + { + service_impl_.connect(impl, peer_endpoint, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Start an asynchronous connect. + template + ASIO_INITFN_RESULT_TYPE(ConnectHandler, + void (asio::error_code)) + async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, + 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 + ASIO_SYNC_OP_VOID set_option(implementation_type& impl, + const SettableSocketOption& option, asio::error_code& ec) + { + service_impl_.set_option(impl, option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get a socket option. + template + ASIO_SYNC_OP_VOID get_option(const implementation_type& impl, + GettableSocketOption& option, asio::error_code& ec) const + { + service_impl_.get_option(impl, option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Perform an IO control command on the socket. + template + ASIO_SYNC_OP_VOID io_control(implementation_type& impl, + IoControlCommand& command, asio::error_code& ec) + { + service_impl_.io_control(impl, command, ec); + 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. + ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl, + bool mode, asio::error_code& ec) + { + service_impl_.non_blocking(impl, mode, ec); + 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. + ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl, + bool mode, asio::error_code& ec) + { + service_impl_.native_non_blocking(impl, mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.remote_endpoint(impl, ec); + } + + /// Disable sends or receives on the socket. + ASIO_SYNC_OP_VOID shutdown(implementation_type& impl, + socket_base::shutdown_type what, asio::error_code& ec) + { + service_impl_.shutdown(impl, what, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Wait for the socket to become ready to read, ready to write, or to have + /// pending error conditions. + ASIO_SYNC_OP_VOID wait(implementation_type& impl, + socket_base::wait_type w, asio::error_code& ec) + { + service_impl_.wait(impl, w, ec); + 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 + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(implementation_type& impl, socket_base::wait_type w, + 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, asio::error_code& ec) + { + return service_impl_.send(impl, buffers, flags, ec); + } + + /// Start an asynchronous send. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_send(implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, + 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, asio::error_code& ec) + { + return service_impl_.receive(impl, buffers, flags, ec); + } + + /// Start an asynchronous receive. + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, + 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 + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_STREAM_SOCKET_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/streambuf.hpp b/tools/sdk/include/asio/asio/streambuf.hpp new file mode 100644 index 00000000..cb3f35f7 --- /dev/null +++ b/tools/sdk/include/asio/asio/streambuf.hpp @@ -0,0 +1,33 @@ +// +// streambuf.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_STREAMBUF_HPP +#define ASIO_STREAMBUF_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_NO_IOSTREAM) + +#include "asio/basic_streambuf.hpp" + +namespace asio { + +/// Typedef for the typical usage of basic_streambuf. +typedef basic_streambuf<> streambuf; + +} // namespace asio + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_STREAMBUF_HPP diff --git a/tools/sdk/include/asio/asio/system_context.hpp b/tools/sdk/include/asio/asio/system_context.hpp new file mode 100644 index 00000000..ccd11134 --- /dev/null +++ b/tools/sdk/include/asio/asio/system_context.hpp @@ -0,0 +1,78 @@ +// +// system_context.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SYSTEM_CONTEXT_HPP +#define ASIO_SYSTEM_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/scheduler.hpp" +#include "asio/detail/thread_group.hpp" +#include "asio/execution_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +class system_executor; + +/// The executor context for the system executor. +class system_context : public execution_context +{ +public: + /// The executor type associated with the context. + typedef system_executor executor_type; + + /// Destructor shuts down all threads in the system thread pool. + ASIO_DECL ~system_context(); + + /// Obtain an executor for the context. + executor_type get_executor() ASIO_NOEXCEPT; + + /// Signal all threads in the system thread pool to stop. + ASIO_DECL void stop(); + + /// Determine whether the system thread pool has been stopped. + ASIO_DECL bool stopped() const ASIO_NOEXCEPT; + + /// Join all threads in the system thread pool. + ASIO_DECL void join(); + +#if defined(GENERATING_DOCUMENTATION) +private: +#endif // defined(GENERATING_DOCUMENTATION) + // Constructor creates all threads in the system thread pool. + ASIO_DECL system_context(); + +private: + friend class system_executor; + + struct thread_function; + + // The underlying scheduler. + detail::scheduler& scheduler_; + + // The threads in the system thread pool. + detail::thread_group threads_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/system_context.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/impl/system_context.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_SYSTEM_CONTEXT_HPP diff --git a/tools/sdk/include/asio/asio/system_error.hpp b/tools/sdk/include/asio/asio/system_error.hpp new file mode 100644 index 00000000..63908941 --- /dev/null +++ b/tools/sdk/include/asio/asio/system_error.hpp @@ -0,0 +1,131 @@ +// +// system_error.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SYSTEM_ERROR_HPP +#define ASIO_SYSTEM_ERROR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_STD_SYSTEM_ERROR) +# include +#else // defined(ASIO_HAS_STD_SYSTEM_ERROR) +# include +# include +# include +# include "asio/error_code.hpp" +# include "asio/detail/scoped_ptr.hpp" +#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +#if defined(ASIO_HAS_STD_SYSTEM_ERROR) + +typedef std::system_error system_error; + +#else // defined(ASIO_HAS_STD_SYSTEM_ERROR) + +/// The system_error class is used to represent system conditions that +/// prevent the library from operating correctly. +class system_error + : public std::exception +{ +public: + /// Construct with an error code. + system_error(const error_code& ec) + : code_(ec), + context_() + { + } + + /// Construct with an error code and context. + system_error(const error_code& ec, const std::string& context) + : code_(ec), + context_(context) + { + } + + /// Copy constructor. + system_error(const system_error& other) + : std::exception(other), + code_(other.code_), + context_(other.context_), + what_() + { + } + + /// Destructor. + virtual ~system_error() throw () + { + } + + /// Assignment operator. + system_error& operator=(const system_error& e) + { + context_ = e.context_; + code_ = e.code_; + what_.reset(); + return *this; + } + + /// Get a string representation of the exception. + virtual const char* what() const throw () + { +#if !defined(ASIO_NO_EXCEPTIONS) + try +#endif // !defined(ASIO_NO_EXCEPTIONS) + { + if (!what_.get()) + { + std::string tmp(context_); + if (tmp.length()) + tmp += ": "; + tmp += code_.message(); + what_.reset(new std::string(tmp)); + } + return what_->c_str(); + } +#if !defined(ASIO_NO_EXCEPTIONS) + catch (std::exception&) + { + return "system_error"; + } +#endif // !defined(ASIO_NO_EXCEPTIONS) + } + + /// Get the error code associated with the exception. + error_code code() const + { + return code_; + } + +private: + // The code associated with the error. + error_code code_; + + // The context associated with the error. + std::string context_; + + // The string representation of the error. + mutable asio::detail::scoped_ptr what_; +}; + +#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SYSTEM_ERROR_HPP diff --git a/tools/sdk/include/asio/asio/system_executor.hpp b/tools/sdk/include/asio/asio/system_executor.hpp new file mode 100644 index 00000000..b588a21b --- /dev/null +++ b/tools/sdk/include/asio/asio/system_executor.hpp @@ -0,0 +1,129 @@ +// +// system_executor.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SYSTEM_EXECUTOR_HPP +#define ASIO_SYSTEM_EXECUTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +class system_context; + +/// An executor that uses arbitrary threads. +/** + * The system executor represents an execution context where functions are + * permitted to run on arbitrary threads. The post() and defer() functions + * schedule the function to run on an unspecified system thread pool, and + * dispatch() invokes the function immediately. + */ +class system_executor +{ +public: + /// Obtain the underlying execution context. + system_context& context() const ASIO_NOEXCEPT; + + /// Inform the executor that it has some outstanding work to do. + /** + * For the system executor, this is a no-op. + */ + void on_work_started() const ASIO_NOEXCEPT + { + } + + /// Inform the executor that some work is no longer outstanding. + /** + * For the system executor, this is a no-op. + */ + void on_work_finished() const ASIO_NOEXCEPT + { + } + + /// Request the system executor to invoke the given function object. + /** + * This function is used to ask the executor to execute the given function + * object. The function object will always be executed inside this function. + * + * @param f The function object to be called. The executor will make + * a copy of the handler object as required. The function signature of the + * function object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; + + /// Request the system executor to invoke the given function object. + /** + * This function is used to ask the executor to execute the given function + * object. The function object will never be executed inside this function. + * Instead, it will be scheduled to run on an unspecified system thread pool. + * + * @param f The function object to be called. The executor will make + * a copy of the handler object as required. The function signature of the + * function object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; + + /// Request the system executor to invoke the given function object. + /** + * This function is used to ask the executor to execute the given function + * object. The function object will never be executed inside this function. + * Instead, it will be scheduled to run on an unspecified system thread pool. + * + * @param f The function object to be called. The executor will make + * a copy of the handler object as required. The function signature of the + * function object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; + + /// Compare two executors for equality. + /** + * System executors always compare equal. + */ + friend bool operator==(const system_executor&, + const system_executor&) ASIO_NOEXCEPT + { + return true; + } + + /// Compare two executors for inequality. + /** + * System executors always compare equal. + */ + friend bool operator!=(const system_executor&, + const system_executor&) ASIO_NOEXCEPT + { + return false; + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/system_executor.hpp" + +#endif // ASIO_SYSTEM_EXECUTOR_HPP diff --git a/tools/sdk/include/asio/asio/system_timer.hpp b/tools/sdk/include/asio/asio/system_timer.hpp new file mode 100644 index 00000000..e75e7d4c --- /dev/null +++ b/tools/sdk/include/asio/asio/system_timer.hpp @@ -0,0 +1,42 @@ +// +// system_timer.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_SYSTEM_TIMER_HPP +#define ASIO_SYSTEM_TIMER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) + +#include "asio/basic_waitable_timer.hpp" +#include "asio/detail/chrono.hpp" + +namespace asio { + +/// Typedef for a timer based on the system clock. +/** + * This typedef uses the C++11 @c <chrono> standard library facility, if + * available. Otherwise, it may use the Boost.Chrono library. To explicitly + * utilise Boost.Chrono, use the basic_waitable_timer template directly: + * @code + * typedef basic_waitable_timer timer; + * @endcode + */ +typedef basic_waitable_timer system_timer; + +} // namespace asio + +#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_SYSTEM_TIMER_HPP diff --git a/tools/sdk/include/asio/asio/thread.hpp b/tools/sdk/include/asio/asio/thread.hpp new file mode 100644 index 00000000..eeeef7bb --- /dev/null +++ b/tools/sdk/include/asio/asio/thread.hpp @@ -0,0 +1,92 @@ +// +// thread.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_THREAD_HPP +#define ASIO_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/thread.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// A simple abstraction for starting threads. +/** + * The asio::thread class implements the smallest possible subset of the + * functionality of boost::thread. It is intended to be used only for starting + * a thread and waiting for it to exit. If more extensive threading + * capabilities are required, you are strongly advised to use something else. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Example + * A typical use of asio::thread would be to launch a thread to run an + * io_context's event processing loop: + * + * @par + * @code asio::io_context io_context; + * // ... + * asio::thread t(boost::bind(&asio::io_context::run, &io_context)); + * // ... + * t.join(); @endcode + */ +class thread + : private noncopyable +{ +public: + /// Start a new thread that executes the supplied function. + /** + * This constructor creates a new thread that will execute the given function + * or function object. + * + * @param f The function or function object to be run in the thread. The + * function signature must be: @code void f(); @endcode + */ + template + explicit thread(Function f) + : impl_(f) + { + } + + /// Destructor. + ~thread() + { + } + + /// Wait for the thread to exit. + /** + * This function will block until the thread has exited. + * + * If this function is not called before the thread object is destroyed, the + * thread itself will continue to run until completion. You will, however, + * no longer have the ability to wait for it to exit. + */ + void join() + { + impl_.join(); + } + +private: + detail::thread impl_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_THREAD_HPP diff --git a/tools/sdk/include/asio/asio/thread_pool.hpp b/tools/sdk/include/asio/asio/thread_pool.hpp new file mode 100644 index 00000000..f22f18d1 --- /dev/null +++ b/tools/sdk/include/asio/asio/thread_pool.hpp @@ -0,0 +1,232 @@ +// +// thread_pool.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_THREAD_POOL_HPP +#define ASIO_THREAD_POOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/scheduler.hpp" +#include "asio/detail/thread_group.hpp" +#include "asio/execution_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// A simple fixed-size thread pool. +/** + * The thread pool class is an execution context where functions are permitted + * to run on one of a fixed number of threads. + * + * @par Submitting tasks to the pool + * + * To submit functions to the io_context, use the @ref asio::dispatch, + * @ref asio::post or @ref asio::defer free functions. + * + * For example: + * + * @code void my_task() + * { + * ... + * } + * + * ... + * + * // Launch the pool with four threads. + * asio::thread_pool pool(4); + * + * // Submit a function to the pool. + * asio::post(pool, my_task); + * + * // Submit a lambda object to the pool. + * asio::post(pool, + * []() + * { + * ... + * }); + * + * // Wait for all tasks in the pool to complete. + * pool.join(); @endcode + */ +class thread_pool + : public execution_context +{ +public: + class executor_type; + + /// Constructs a pool with an automatically determined number of threads. + ASIO_DECL thread_pool(); + + /// Constructs a pool with a specified number of threads. + ASIO_DECL thread_pool(std::size_t num_threads); + + /// Destructor. + /** + * Automatically stops and joins the pool, if not explicitly done beforehand. + */ + ASIO_DECL ~thread_pool(); + + /// Obtains the executor associated with the pool. + executor_type get_executor() ASIO_NOEXCEPT; + + /// Stops the threads. + /** + * This function stops the threads as soon as possible. As a result of calling + * @c stop(), pending function objects may be never be invoked. + */ + ASIO_DECL void stop(); + + /// Joins the threads. + /** + * This function blocks until the threads in the pool have completed. If @c + * stop() is not called prior to @c join(), the @c join() call will wait + * until the pool has no more outstanding work. + */ + ASIO_DECL void join(); + +private: + friend class executor_type; + struct thread_function; + + // The underlying scheduler. + detail::scheduler& scheduler_; + + // The threads in the pool. + detail::thread_group threads_; +}; + +/// Executor used to submit functions to a thread pool. +class thread_pool::executor_type +{ +public: + /// Obtain the underlying execution context. + thread_pool& context() const ASIO_NOEXCEPT; + + /// Inform the thread pool that it has some outstanding work to do. + /** + * This function is used to inform the thread pool that some work has begun. + * This ensures that the thread pool's join() function will not return while + * the work is underway. + */ + void on_work_started() const ASIO_NOEXCEPT; + + /// Inform the thread pool that some work is no longer outstanding. + /** + * This function is used to inform the thread pool that some work has + * finished. Once the count of unfinished work reaches zero, the thread + * pool's join() function is permitted to exit. + */ + void on_work_finished() const ASIO_NOEXCEPT; + + /// Request the thread pool to invoke the given function object. + /** + * This function is used to ask the thread pool to execute the given function + * object. If the current thread belongs to the pool, @c dispatch() executes + * the function before returning. Otherwise, the function will be scheduled + * to run on the thread pool. + * + * @param f The function object to be called. The executor will make + * a copy of the handler object as required. The function signature of the + * function object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; + + /// Request the thread pool to invoke the given function object. + /** + * This function is used to ask the thread pool to execute the given function + * object. The function object will never be executed inside @c post(). + * Instead, it will be scheduled to run on the thread pool. + * + * @param f The function object to be called. The executor will make + * a copy of the handler object as required. The function signature of the + * function object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; + + /// Request the thread pool to invoke the given function object. + /** + * This function is used to ask the thread pool to execute the given function + * object. The function object will never be executed inside @c defer(). + * Instead, it will be scheduled to run on the thread pool. + * + * If the current thread belongs to the thread pool, @c defer() will delay + * scheduling the function object until the current thread returns control to + * the pool. + * + * @param f The function object to be called. The executor will make + * a copy of the handler object as required. The function signature of the + * function object must be: @code void function(); @endcode + * + * @param a An allocator that may be used by the executor to allocate the + * internal storage needed for function invocation. + */ + template + void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; + + /// Determine whether the thread pool is running in the current thread. + /** + * @return @c true if the current thread belongs to the pool. Otherwise + * returns @c false. + */ + bool running_in_this_thread() const ASIO_NOEXCEPT; + + /// Compare two executors for equality. + /** + * Two executors are equal if they refer to the same underlying thread pool. + */ + friend bool operator==(const executor_type& a, + const executor_type& b) ASIO_NOEXCEPT + { + return &a.pool_ == &b.pool_; + } + + /// Compare two executors for inequality. + /** + * Two executors are equal if they refer to the same underlying thread pool. + */ + friend bool operator!=(const executor_type& a, + const executor_type& b) ASIO_NOEXCEPT + { + return &a.pool_ != &b.pool_; + } + +private: + friend class thread_pool; + + // Constructor. + explicit executor_type(thread_pool& p) : pool_(p) {} + + // The underlying thread pool. + thread_pool& pool_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/thread_pool.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/impl/thread_pool.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_THREAD_POOL_HPP diff --git a/tools/sdk/include/asio/asio/time_traits.hpp b/tools/sdk/include/asio/asio/time_traits.hpp new file mode 100644 index 00000000..72f4aabe --- /dev/null +++ b/tools/sdk/include/asio/asio/time_traits.hpp @@ -0,0 +1,86 @@ +// +// time_traits.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_TIME_TRAITS_HPP +#define ASIO_TIME_TRAITS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/socket_types.hpp" // Must come before posix_time. + +#if defined(ASIO_HAS_BOOST_DATE_TIME) \ + || defined(GENERATING_DOCUMENTATION) + +#include + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Time traits suitable for use with the deadline timer. +template +struct time_traits; + +/// Time traits specialised for posix_time. +template <> +struct time_traits +{ + /// The time type. + typedef boost::posix_time::ptime time_type; + + /// The duration type. + typedef boost::posix_time::time_duration duration_type; + + /// Get the current time. + static time_type now() + { +#if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) + return boost::posix_time::microsec_clock::universal_time(); +#else // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) + return boost::posix_time::second_clock::universal_time(); +#endif // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) + } + + /// Add a duration to a time. + static time_type add(const time_type& t, const duration_type& d) + { + return t + d; + } + + /// Subtract one time from another. + static duration_type subtract(const time_type& t1, const time_type& t2) + { + return t1 - t2; + } + + /// Test whether one time is less than another. + static bool less_than(const time_type& t1, const time_type& t2) + { + return t1 < t2; + } + + /// Convert to POSIX duration type. + static boost::posix_time::time_duration to_posix_duration( + const duration_type& d) + { + return d; + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_TIME_TRAITS_HPP diff --git a/tools/sdk/include/asio/asio/ts/buffer.hpp b/tools/sdk/include/asio/asio/ts/buffer.hpp new file mode 100644 index 00000000..faf08a47 --- /dev/null +++ b/tools/sdk/include/asio/asio/ts/buffer.hpp @@ -0,0 +1,24 @@ +// +// ts/buffer.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_TS_BUFFER_HPP +#define ASIO_TS_BUFFER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/buffer.hpp" +#include "asio/completion_condition.hpp" +#include "asio/read.hpp" +#include "asio/write.hpp" +#include "asio/read_until.hpp" + +#endif // ASIO_TS_BUFFER_HPP diff --git a/tools/sdk/include/asio/asio/ts/executor.hpp b/tools/sdk/include/asio/asio/ts/executor.hpp new file mode 100644 index 00000000..8669cb6c --- /dev/null +++ b/tools/sdk/include/asio/asio/ts/executor.hpp @@ -0,0 +1,35 @@ +// +// ts/executor.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_TS_EXECUTOR_HPP +#define ASIO_TS_EXECUTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/handler_type.hpp" +#include "asio/async_result.hpp" +#include "asio/associated_allocator.hpp" +#include "asio/execution_context.hpp" +#include "asio/is_executor.hpp" +#include "asio/associated_executor.hpp" +#include "asio/bind_executor.hpp" +#include "asio/executor_work_guard.hpp" +#include "asio/system_executor.hpp" +#include "asio/executor.hpp" +#include "asio/dispatch.hpp" +#include "asio/post.hpp" +#include "asio/defer.hpp" +#include "asio/strand.hpp" +#include "asio/packaged_task.hpp" +#include "asio/use_future.hpp" + +#endif // ASIO_TS_EXECUTOR_HPP diff --git a/tools/sdk/include/asio/asio/ts/internet.hpp b/tools/sdk/include/asio/asio/ts/internet.hpp new file mode 100644 index 00000000..6282e905 --- /dev/null +++ b/tools/sdk/include/asio/asio/ts/internet.hpp @@ -0,0 +1,40 @@ +// +// ts/internet.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_TS_INTERNET_HPP +#define ASIO_TS_INTERNET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/ip/address.hpp" +#include "asio/ip/address_v4.hpp" +#include "asio/ip/address_v4_iterator.hpp" +#include "asio/ip/address_v4_range.hpp" +#include "asio/ip/address_v6.hpp" +#include "asio/ip/address_v6_iterator.hpp" +#include "asio/ip/address_v6_range.hpp" +#include "asio/ip/bad_address_cast.hpp" +#include "asio/ip/basic_endpoint.hpp" +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/ip/basic_resolver_entry.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver.hpp" +#include "asio/ip/host_name.hpp" +#include "asio/ip/network_v4.hpp" +#include "asio/ip/network_v6.hpp" +#include "asio/ip/tcp.hpp" +#include "asio/ip/udp.hpp" +#include "asio/ip/v6_only.hpp" +#include "asio/ip/unicast.hpp" +#include "asio/ip/multicast.hpp" + +#endif // ASIO_TS_INTERNET_HPP diff --git a/tools/sdk/include/asio/asio/ts/io_context.hpp b/tools/sdk/include/asio/asio/ts/io_context.hpp new file mode 100644 index 00000000..b967cd63 --- /dev/null +++ b/tools/sdk/include/asio/asio/ts/io_context.hpp @@ -0,0 +1,20 @@ +// +// ts/io_context.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_TS_IO_CONTEXT_HPP +#define ASIO_TS_IO_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/io_context.hpp" + +#endif // ASIO_TS_IO_CONTEXT_HPP diff --git a/tools/sdk/include/asio/asio/ts/net.hpp b/tools/sdk/include/asio/asio/ts/net.hpp new file mode 100644 index 00000000..f96075d9 --- /dev/null +++ b/tools/sdk/include/asio/asio/ts/net.hpp @@ -0,0 +1,26 @@ +// +// ts/net.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_TS_NET_HPP +#define ASIO_TS_NET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/ts/netfwd.hpp" +#include "asio/ts/executor.hpp" +#include "asio/ts/io_context.hpp" +#include "asio/ts/timer.hpp" +#include "asio/ts/buffer.hpp" +#include "asio/ts/socket.hpp" +#include "asio/ts/internet.hpp" + +#endif // ASIO_TS_NET_HPP diff --git a/tools/sdk/include/asio/asio/ts/netfwd.hpp b/tools/sdk/include/asio/asio/ts/netfwd.hpp new file mode 100644 index 00000000..657a21d3 --- /dev/null +++ b/tools/sdk/include/asio/asio/ts/netfwd.hpp @@ -0,0 +1,197 @@ +// +// ts/netfwd.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_TS_NETFWD_HPP +#define ASIO_TS_NETFWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_CHRONO) +# include "asio/detail/chrono.hpp" +#endif // defined(ASIO_HAS_CHRONO) + +#if defined(ASIO_HAS_BOOST_DATE_TIME) +# include "asio/detail/date_time_fwd.hpp" +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + +#if !defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +class execution_context; + +template +class executor_binder; + +template +class executor_work_guard; + +class system_executor; + +class executor; + +template +class strand; + +class io_context; + +template +struct wait_traits; + +#if defined(ASIO_HAS_BOOST_DATE_TIME) + +template +struct time_traits; + +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +template +class waitable_timer_service; + +#if defined(ASIO_HAS_BOOST_DATE_TIME) + +template +class deadline_timer_service; + +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#if !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) +#define ASIO_BASIC_WAITABLE_TIMER_FWD_DECL + +template + ASIO_SVC_TPARAM_DEF2(= waitable_timer_service)> +class basic_waitable_timer; + +#endif // !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) + +#if defined(ASIO_HAS_CHRONO) + +typedef basic_waitable_timer system_timer; + +typedef basic_waitable_timer steady_timer; + +typedef basic_waitable_timer + high_resolution_timer; + +#endif // defined(ASIO_HAS_CHRONO) + +template +class basic_socket; + +template +class basic_datagram_socket; + +template +class basic_stream_socket; + +template +class basic_socket_acceptor; + +#if !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL) +#define ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL + +// Forward declaration with defaulted arguments. +template ), +#if defined(ASIO_HAS_BOOST_DATE_TIME) \ + || defined(GENERATING_DOCUMENTATION) + typename Clock = boost::posix_time::ptime, + typename WaitTraits = time_traits + ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service)> +#else + typename Clock = chrono::steady_clock, + typename WaitTraits = wait_traits + ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)> +#endif +class basic_socket_streambuf; + +#endif // !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL) + +#if !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL) +#define ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL + +// Forward declaration with defaulted arguments. +template ), +#if defined(ASIO_HAS_BOOST_DATE_TIME) \ + || defined(GENERATING_DOCUMENTATION) + typename Clock = boost::posix_time::ptime, + typename WaitTraits = time_traits + ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service)> +#else + typename Clock = chrono::steady_clock, + typename WaitTraits = wait_traits + ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)> +#endif +class basic_socket_iostream; + +#endif // !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL) + +namespace ip { + +class address; + +class address_v4; + +class address_v6; + +template +class basic_address_iterator; + +typedef basic_address_iterator address_v4_iterator; + +typedef basic_address_iterator address_v6_iterator; + +template +class basic_address_range; + +typedef basic_address_range address_v4_range; + +typedef basic_address_range address_v6_range; + +class network_v4; + +class network_v6; + +template +class basic_endpoint; + +template +class basic_resolver_entry; + +template +class basic_resolver_results; + +template +class basic_resolver; + +class tcp; + +class udp; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_TS_NETFWD_HPP diff --git a/tools/sdk/include/asio/asio/ts/socket.hpp b/tools/sdk/include/asio/asio/ts/socket.hpp new file mode 100644 index 00000000..a5427348 --- /dev/null +++ b/tools/sdk/include/asio/asio/ts/socket.hpp @@ -0,0 +1,27 @@ +// +// ts/socket.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_TS_SOCKET_HPP +#define ASIO_TS_SOCKET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/socket_base.hpp" +#include "asio/basic_socket.hpp" +#include "asio/basic_datagram_socket.hpp" +#include "asio/basic_stream_socket.hpp" +#include "asio/basic_socket_acceptor.hpp" +#include "asio/basic_socket_streambuf.hpp" +#include "asio/basic_socket_iostream.hpp" +#include "asio/connect.hpp" + +#endif // ASIO_TS_SOCKET_HPP diff --git a/tools/sdk/include/asio/asio/ts/timer.hpp b/tools/sdk/include/asio/asio/ts/timer.hpp new file mode 100644 index 00000000..872be8bf --- /dev/null +++ b/tools/sdk/include/asio/asio/ts/timer.hpp @@ -0,0 +1,26 @@ +// +// ts/timer.hpp +// ~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_TS_TIMER_HPP +#define ASIO_TS_TIMER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/chrono.hpp" + +#include "asio/wait_traits.hpp" +#include "asio/basic_waitable_timer.hpp" +#include "asio/system_timer.hpp" +#include "asio/steady_timer.hpp" +#include "asio/high_resolution_timer.hpp" + +#endif // ASIO_TS_TIMER_HPP diff --git a/tools/sdk/include/asio/asio/unyield.hpp b/tools/sdk/include/asio/asio/unyield.hpp new file mode 100644 index 00000000..de3ed027 --- /dev/null +++ b/tools/sdk/include/asio/asio/unyield.hpp @@ -0,0 +1,21 @@ +// +// unyield.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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) +// + +#ifdef reenter +# undef reenter +#endif + +#ifdef yield +# undef yield +#endif + +#ifdef fork +# undef fork +#endif diff --git a/tools/sdk/include/asio/asio/use_future.hpp b/tools/sdk/include/asio/asio/use_future.hpp new file mode 100644 index 00000000..3f9c6968 --- /dev/null +++ b/tools/sdk/include/asio/asio/use_future.hpp @@ -0,0 +1,159 @@ +// +// use_future.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_USE_FUTURE_HPP +#define ASIO_USE_FUTURE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_STD_FUTURE) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/detail/type_traits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class packaged_token; + +template +class packaged_handler; + +} // namespace detail + +/// Class used to specify that an asynchronous operation should return a future. +/** + * The use_future_t class is used to indicate that an asynchronous operation + * should return a std::future object. A use_future_t object may be passed as a + * handler to an asynchronous operation, typically using the special value @c + * asio::use_future. For example: + * + * @code std::future my_future + * = my_socket.async_read_some(my_buffer, asio::use_future); @endcode + * + * The initiating function (async_read_some in the above example) returns a + * future that will receive the result of the operation. If the operation + * completes with an error_code indicating failure, it is converted into a + * system_error and passed back to the caller via the future. + */ +template > +class use_future_t +{ +public: + /// The allocator type. The allocator is used when constructing the + /// @c std::promise object for a given asynchronous operation. + typedef Allocator allocator_type; + + /// Construct using default-constructed allocator. + ASIO_CONSTEXPR use_future_t() + { + } + + /// Construct using specified allocator. + explicit use_future_t(const Allocator& allocator) + : allocator_(allocator) + { + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use rebind().) Specify an alternate allocator. + template + use_future_t operator[](const OtherAllocator& allocator) const + { + return use_future_t(allocator); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Specify an alternate allocator. + template + use_future_t rebind(const OtherAllocator& allocator) const + { + return use_future_t(allocator); + } + + /// Obtain allocator. + allocator_type get_allocator() const + { + return allocator_; + } + + /// Wrap a function object in a packaged task. + /** + * The @c package function is used to adapt a function object as a packaged + * task. When this adapter is passed as a completion token to an asynchronous + * operation, the result of the function object is retuned via a std::future. + * + * @par Example + * + * @code std::future fut = + * my_socket.async_read_some(buffer, + * use_future([](asio::error_code ec, std::size_t n) + * { + * return ec ? 0 : n; + * })); + * ... + * std::size_t n = fut.get(); @endcode + */ + template +#if defined(GENERATING_DOCUMENTATION) + unspecified +#else // defined(GENERATING_DOCUMENTATION) + detail::packaged_token::type, Allocator> +#endif // defined(GENERATING_DOCUMENTATION) + operator()(ASIO_MOVE_ARG(Function) f) const; + +private: + // Helper type to ensure that use_future can be constexpr default-constructed + // even when std::allocator can't be. + struct std_allocator_void + { + ASIO_CONSTEXPR std_allocator_void() + { + } + + operator std::allocator() const + { + return std::allocator(); + } + }; + + typename conditional< + is_same, Allocator>::value, + std_allocator_void, Allocator>::type allocator_; +}; + +/// A special value, similar to std::nothrow. +/** + * See the documentation for asio::use_future_t for a usage example. + */ +#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) +constexpr use_future_t<> use_future; +#elif defined(ASIO_MSVC) +__declspec(selectany) use_future_t<> use_future; +#endif + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/use_future.hpp" + +#endif // defined(ASIO_HAS_STD_FUTURE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_USE_FUTURE_HPP diff --git a/tools/sdk/include/asio/asio/uses_executor.hpp b/tools/sdk/include/asio/asio/uses_executor.hpp new file mode 100644 index 00000000..e985c282 --- /dev/null +++ b/tools/sdk/include/asio/asio/uses_executor.hpp @@ -0,0 +1,71 @@ +// +// uses_executor.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_USES_EXECUTOR_HPP +#define ASIO_USES_EXECUTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/type_traits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// A special type, similar to std::nothrow_t, used to disambiguate +/// constructors that accept executor arguments. +/** + * The executor_arg_t struct is an empty structure type used as a unique type + * to disambiguate constructor and function overloading. Specifically, some + * types have constructors with executor_arg_t as the first argument, + * immediately followed by an argument of a type that satisfies the Executor + * type requirements. + */ +struct executor_arg_t +{ + /// Constructor. + ASIO_CONSTEXPR executor_arg_t() ASIO_NOEXCEPT + { + } +}; + +/// A special value, similar to std::nothrow, used to disambiguate constructors +/// that accept executor arguments. +/** + * See asio::executor_arg_t and asio::uses_executor + * for more information. + */ +#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) +constexpr executor_arg_t executor_arg; +#elif defined(ASIO_MSVC) +__declspec(selectany) executor_arg_t executor_arg; +#endif + +/// The uses_executor trait detects whether a type T has an associated executor +/// that is convertible from type Executor. +/** + * Meets the BinaryTypeTrait requirements. The Asio library provides a + * definition that is derived from false_type. A program may specialize this + * template to derive from true_type for a user-defined type T that can be + * constructed with an executor, where the first argument of a constructor has + * type executor_arg_t and the second argument is convertible from type + * Executor. + */ +template +struct uses_executor : false_type {}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_USES_EXECUTOR_HPP diff --git a/tools/sdk/include/asio/asio/version.hpp b/tools/sdk/include/asio/asio/version.hpp new file mode 100644 index 00000000..ee0313f7 --- /dev/null +++ b/tools/sdk/include/asio/asio/version.hpp @@ -0,0 +1,23 @@ +// +// version.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_VERSION_HPP +#define ASIO_VERSION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +// ASIO_VERSION % 100 is the sub-minor version +// ASIO_VERSION / 100 % 1000 is the minor version +// ASIO_VERSION / 100000 is the major version +#define ASIO_VERSION 101200 // 1.12.0 + +#endif // ASIO_VERSION_HPP diff --git a/tools/sdk/include/asio/asio/wait_traits.hpp b/tools/sdk/include/asio/asio/wait_traits.hpp new file mode 100644 index 00000000..a6016f7c --- /dev/null +++ b/tools/sdk/include/asio/asio/wait_traits.hpp @@ -0,0 +1,56 @@ +// +// wait_traits.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_WAIT_TRAITS_HPP +#define ASIO_WAIT_TRAITS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Wait traits suitable for use with the basic_waitable_timer class template. +template +struct wait_traits +{ + /// Convert a clock duration into a duration used for waiting. + /** + * @returns @c d. + */ + static typename Clock::duration to_wait_duration( + const typename Clock::duration& d) + { + return d; + } + + /// Convert a clock duration into a duration used for waiting. + /** + * @returns @c d. + */ + static typename Clock::duration to_wait_duration( + const typename Clock::time_point& t) + { + typename Clock::time_point now = Clock::now(); + if (now + (Clock::duration::max)() < t) + return (Clock::duration::max)(); + if (now + (Clock::duration::min)() > t) + return (Clock::duration::min)(); + return t - now; + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_WAIT_TRAITS_HPP diff --git a/tools/sdk/include/asio/asio/waitable_timer_service.hpp b/tools/sdk/include/asio/asio/waitable_timer_service.hpp new file mode 100644 index 00000000..75e496f8 --- /dev/null +++ b/tools/sdk/include/asio/asio/waitable_timer_service.hpp @@ -0,0 +1,210 @@ +// +// waitable_timer_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_WAITABLE_TIMER_SERVICE_HPP +#define ASIO_WAITABLE_TIMER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#include +#include "asio/async_result.hpp" +#include "asio/detail/chrono_time_traits.hpp" +#include "asio/detail/deadline_timer_service.hpp" +#include "asio/io_context.hpp" +#include "asio/wait_traits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Default service implementation for a timer. +template > +class waitable_timer_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base< + waitable_timer_service > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_context::id id; +#endif + + /// The clock type. + typedef Clock clock_type; + + /// The duration type of the clock. + typedef typename clock_type::duration duration; + + /// The time point type of the clock. + typedef typename clock_type::time_point time_point; + + /// The wait traits type. + typedef WaitTraits traits_type; + +private: + // The type of the platform-specific implementation. + typedef detail::deadline_timer_service< + detail::chrono_time_traits > service_impl_type; + +public: + /// The implementation type of the waitable timer. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// Construct a new timer service for the specified io_context. + explicit waitable_timer_service(asio::io_context& io_context) + : asio::detail::service_base< + waitable_timer_service >(io_context), + service_impl_(io_context) + { + } + + /// Construct a new timer implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a timer implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new timer implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another timer implementation. + void move_assign(implementation_type& impl, + waitable_timer_service& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Cancel any asynchronous wait operations associated with the timer. + std::size_t cancel(implementation_type& impl, asio::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Cancels one asynchronous wait operation associated with the timer. + std::size_t cancel_one(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.cancel_one(impl, ec); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use expiry().) Get the expiry time for the timer as an + /// absolute time. + time_point expires_at(const implementation_type& impl) const + { + return service_impl_.expiry(impl); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the expiry time for the timer as an absolute time. + time_point expiry(const implementation_type& impl) const + { + return service_impl_.expiry(impl); + } + + /// Set the expiry time for the timer as an absolute time. + std::size_t expires_at(implementation_type& impl, + const time_point& expiry_time, asio::error_code& ec) + { + return service_impl_.expires_at(impl, expiry_time, ec); + } + + /// Set the expiry time for the timer relative to now. + std::size_t expires_after(implementation_type& impl, + const duration& expiry_time, asio::error_code& ec) + { + return service_impl_.expires_after(impl, expiry_time, ec); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use expiry().) Get the expiry time for the timer relative to + /// now. + duration expires_from_now(const implementation_type& impl) const + { + typedef detail::chrono_time_traits traits; + return traits::subtract(service_impl_.expiry(impl), traits::now()); + } + + /// (Deprecated: Use expires_after().) Set the expiry time for the timer + /// relative to now. + std::size_t expires_from_now(implementation_type& impl, + const duration& expiry_time, asio::error_code& ec) + { + return service_impl_.expires_after(impl, expiry_time, ec); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + // Perform a blocking wait on the timer. + void wait(implementation_type& impl, asio::error_code& ec) + { + service_impl_.wait(impl, ec); + } + + // Start an asynchronous wait on the timer. + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(implementation_type& impl, + ASIO_MOVE_ARG(WaitHandler) handler) + { + async_completion init(handler); + + service_impl_.async_wait(impl, 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 + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WAITABLE_TIMER_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/windows/basic_handle.hpp b/tools/sdk/include/asio/asio/windows/basic_handle.hpp new file mode 100644 index 00000000..f7c9d0d0 --- /dev/null +++ b/tools/sdk/include/asio/asio/windows/basic_handle.hpp @@ -0,0 +1,273 @@ +// +// windows/basic_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_WINDOWS_BASIC_HANDLE_HPP +#define ASIO_WINDOWS_BASIC_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/basic_io_object.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Provides Windows handle functionality. +/** + * The windows::basic_handle class template provides the ability to wrap a + * Windows handle. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_handle + : public basic_io_object +{ +public: + /// The native representation of a handle. + typedef typename HandleService::native_handle_type native_handle_type; + + /// A basic_handle is always the lowest layer. + typedef basic_handle lowest_layer_type; + + /// Construct a basic_handle without opening it. + /** + * This constructor creates a handle without opening it. + * + * @param io_context The io_context object that the handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + */ + explicit basic_handle(asio::io_context& io_context) + : basic_io_object(io_context) + { + } + + /// Construct a basic_handle on an existing native handle. + /** + * This constructor creates a handle object to hold an existing native handle. + * + * @param io_context The io_context object that the handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + * + * @param handle A native handle. + * + * @throws asio::system_error Thrown on failure. + */ + basic_handle(asio::io_context& io_context, + const native_handle_type& handle) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), handle, ec); + asio::detail::throw_error(ec, "assign"); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_handle from another. + /** + * This constructor moves a handle from one object to another. + * + * @param other The other basic_handle 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_handle(io_context&) constructor. + */ + basic_handle(basic_handle&& other) + : basic_io_object( + ASIO_MOVE_CAST(basic_handle)(other)) + { + } + + /// Move-assign a basic_handle from another. + /** + * This assignment operator moves a handle from one object to another. + * + * @param other The other basic_handle 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_handle(io_context&) constructor. + */ + basic_handle& operator=(basic_handle&& other) + { + basic_io_object::operator=( + ASIO_MOVE_CAST(basic_handle)(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since a basic_handle 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_handle 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; + } + + /// Assign an existing native handle to the handle. + /* + * This function opens the handle to hold an existing native handle. + * + * @param handle A native handle. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const native_handle_type& handle) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), handle, ec); + asio::detail::throw_error(ec, "assign"); + } + + /// Assign an existing native handle to the handle. + /* + * This function opens the handle to hold an existing native handle. + * + * @param handle A native handle. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID assign(const native_handle_type& handle, + asio::error_code& ec) + { + this->get_service().assign(this->get_implementation(), handle, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the handle is open. + bool is_open() const + { + return this->get_service().is_open(this->get_implementation()); + } + + /// Close the handle. + /** + * This function is used to close the handle. Any asynchronous read or write + * operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void close() + { + asio::error_code ec; + this->get_service().close(this->get_implementation(), ec); + asio::detail::throw_error(ec, "close"); + } + + /// Close the handle. + /** + * This function is used to close the handle. Any asynchronous read or write + * operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + this->get_service().close(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native handle representation. + /** + * This function may be used to obtain the underlying representation of the + * handle. This is intended to allow access to native handle 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 handle. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel"); + } + + /// Cancel all asynchronous operations associated with the handle. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) + { + this->get_service().cancel(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + +protected: + /// Protected destructor to prevent deletion through this type. + ~basic_handle() + { + } +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + // || defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) + // || defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_BASIC_HANDLE_HPP diff --git a/tools/sdk/include/asio/asio/windows/basic_object_handle.hpp b/tools/sdk/include/asio/asio/windows/basic_object_handle.hpp new file mode 100644 index 00000000..4b296846 --- /dev/null +++ b/tools/sdk/include/asio/asio/windows/basic_object_handle.hpp @@ -0,0 +1,182 @@ +// +// windows/basic_object_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2011 Boris Schaeling (boris@highscore.de) +// +// 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 ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP +#define ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/windows/basic_handle.hpp" +#include "asio/windows/object_handle_service.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Provides object-oriented handle functionality. +/** + * The windows::basic_object_handle class template provides asynchronous and + * blocking object-oriented handle functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_object_handle + : public basic_handle +{ +public: + /// The native representation of a handle. + typedef typename ObjectHandleService::native_handle_type native_handle_type; + + /// Construct a basic_object_handle without opening it. + /** + * This constructor creates an object handle without opening it. + * + * @param io_context The io_context object that the object handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + */ + explicit basic_object_handle(asio::io_context& io_context) + : basic_handle(io_context) + { + } + + /// Construct a basic_object_handle on an existing native handle. + /** + * This constructor creates an object handle object to hold an existing native + * handle. + * + * @param io_context The io_context object that the object handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + * + * @param native_handle The new underlying handle implementation. + * + * @throws asio::system_error Thrown on failure. + */ + basic_object_handle(asio::io_context& io_context, + const native_handle_type& native_handle) + : basic_handle(io_context, native_handle) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_object_handle from another. + /** + * This constructor moves an object handle from one object to another. + * + * @param other The other basic_object_handle 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_object_handle(io_context&) constructor. + */ + basic_object_handle(basic_object_handle&& other) + : basic_handle( + ASIO_MOVE_CAST(basic_object_handle)(other)) + { + } + + /// Move-assign a basic_object_handle from another. + /** + * This assignment operator moves an object handle from one object to another. + * + * @param other The other basic_object_handle 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_object_handle(io_context&) constructor. + */ + basic_object_handle& operator=(basic_object_handle&& other) + { + basic_handle::operator=( + ASIO_MOVE_CAST(basic_object_handle)(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Perform a blocking wait on the object handle. + /** + * This function is used to wait for the object handle to be set to the + * signalled state. This function blocks and does not return until the object + * handle has been set to the signalled state. + * + * @throws asio::system_error Thrown on failure. + */ + void wait() + { + asio::error_code ec; + this->get_service().wait(this->get_implementation(), ec); + asio::detail::throw_error(ec, "wait"); + } + + /// Perform a blocking wait on the object handle. + /** + * This function is used to wait for the object handle to be set to the + * signalled state. This function blocks and does not return until the object + * handle has been set to the signalled state. + * + * @param ec Set to indicate what error occurred, if any. + */ + void wait(asio::error_code& ec) + { + this->get_service().wait(this->get_implementation(), ec); + } + + /// Start an asynchronous wait on the object handle. + /** + * This function is be used to initiate an asynchronous wait against the + * object handle. It always returns immediately. + * + * @param handler The handler to be called when the object handle is set to + * the signalled state. Copies will be made of the handler as required. The + * function signature of the handler must be: + * @code void handler( + * const asio::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 + * asio::io_context::post(). + */ + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(ASIO_MOVE_ARG(WaitHandler) handler) + { + return this->get_service().async_wait(this->get_implementation(), + ASIO_MOVE_CAST(WaitHandler)(handler)); + } +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP diff --git a/tools/sdk/include/asio/asio/windows/basic_random_access_handle.hpp b/tools/sdk/include/asio/asio/windows/basic_random_access_handle.hpp new file mode 100644 index 00000000..42269773 --- /dev/null +++ b/tools/sdk/include/asio/asio/windows/basic_random_access_handle.hpp @@ -0,0 +1,376 @@ +// +// windows/basic_random_access_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP +#define ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/windows/basic_handle.hpp" +#include "asio/windows/random_access_handle_service.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Provides random-access handle functionality. +/** + * The windows::basic_random_access_handle class template provides asynchronous + * and blocking random-access handle functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_random_access_handle + : public basic_handle +{ +public: + /// The native representation of a handle. + typedef typename RandomAccessHandleService::native_handle_type + native_handle_type; + + /// Construct a basic_random_access_handle without opening it. + /** + * This constructor creates a random-access handle without opening it. The + * handle needs to be opened before data can be written to or read from it. + * + * @param io_context The io_context object that the random-access handle will + * use to dispatch handlers for any asynchronous operations performed on the + * handle. + */ + explicit basic_random_access_handle(asio::io_context& io_context) + : basic_handle(io_context) + { + } + + /// Construct a basic_random_access_handle on an existing native handle. + /** + * This constructor creates a random-access handle object to hold an existing + * native handle. + * + * @param io_context The io_context object that the random-access handle will + * use to dispatch handlers for any asynchronous operations performed on the + * handle. + * + * @param handle The new underlying handle implementation. + * + * @throws asio::system_error Thrown on failure. + */ + basic_random_access_handle(asio::io_context& io_context, + const native_handle_type& handle) + : basic_handle(io_context, handle) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_random_access_handle from another. + /** + * This constructor moves a random-access handle from one object to another. + * + * @param other The other basic_random_access_handle 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_random_access_handle(io_context&) + * constructor. + */ + basic_random_access_handle(basic_random_access_handle&& other) + : basic_handle( + ASIO_MOVE_CAST(basic_random_access_handle)(other)) + { + } + + /// Move-assign a basic_random_access_handle from another. + /** + * This assignment operator moves a random-access handle from one object to + * another. + * + * @param other The other basic_random_access_handle 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_random_access_handle(io_context&) + * constructor. + */ + basic_random_access_handle& operator=(basic_random_access_handle&& other) + { + basic_handle::operator=( + ASIO_MOVE_CAST(basic_random_access_handle)(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Write some data to the handle at the specified offset. + /** + * This function is used to write data to the random-access handle. The + * function call will block until one or more bytes of the data has been + * written successfully, or until an error occurs. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The write_some_at operation may not write all of the data. Consider + * using the @ref write_at 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 + * handle.write_some_at(42, 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_at(uint64_t offset, + const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->get_service().write_some_at( + this->get_implementation(), offset, buffers, ec); + asio::detail::throw_error(ec, "write_some_at"); + return s; + } + + /// Write some data to the handle at the specified offset. + /** + * This function is used to write data to the random-access handle. The + * function call will block until one or more bytes of the data has been + * written successfully, or until an error occurs. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @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_at function if you need to ensure that + * all data is written before the blocking operation completes. + */ + template + std::size_t write_some_at(uint64_t offset, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return this->get_service().write_some_at( + this->get_implementation(), offset, buffers, ec); + } + + /// Start an asynchronous write at the specified offset. + /** + * This function is used to asynchronously write data to the random-access + * handle. The function call always returns immediately. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * 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 asio::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 + * asio::io_context::post(). + * + * @note The write operation may not transmit all of the data to the peer. + * Consider using the @ref async_write_at 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 + * handle.async_write_some_at(42, 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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some_at(uint64_t offset, + const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + return this->get_service().async_write_some_at(this->get_implementation(), + offset, buffers, ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Read some data from the handle at the specified offset. + /** + * This function is used to read data from the random-access handle. The + * function call will block until one or more bytes of data has been read + * successfully, or until an error occurs. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. An error code of + * 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_at 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 + * handle.read_some_at(42, 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_at(uint64_t offset, + const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->get_service().read_some_at( + this->get_implementation(), offset, buffers, ec); + asio::detail::throw_error(ec, "read_some_at"); + return s; + } + + /// Read some data from the handle at the specified offset. + /** + * This function is used to read data from the random-access handle. The + * function call will block until one or more bytes of data has been read + * successfully, or until an error occurs. + * + * @param offset The offset at which the data will be read. + * + * @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_at 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_at(uint64_t offset, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return this->get_service().read_some_at( + this->get_implementation(), offset, buffers, ec); + } + + /// Start an asynchronous read at the specified offset. + /** + * This function is used to asynchronously read data from the random-access + * handle. The function call always returns immediately. + * + * @param offset The offset at which the data will be read. + * + * @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 asio::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 + * asio::io_context::post(). + * + * @note The read operation may not read all of the requested number of bytes. + * Consider using the @ref async_read_at 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 + * handle.async_read_some_at(42, 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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some_at(uint64_t offset, + const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + return this->get_service().async_read_some_at(this->get_implementation(), + offset, buffers, ASIO_MOVE_CAST(ReadHandler)(handler)); + } +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP diff --git a/tools/sdk/include/asio/asio/windows/basic_stream_handle.hpp b/tools/sdk/include/asio/asio/windows/basic_stream_handle.hpp new file mode 100644 index 00000000..3bfce688 --- /dev/null +++ b/tools/sdk/include/asio/asio/windows/basic_stream_handle.hpp @@ -0,0 +1,359 @@ +// +// windows/basic_stream_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP +#define ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/windows/basic_handle.hpp" +#include "asio/windows/stream_handle_service.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Provides stream-oriented handle functionality. +/** + * The windows::basic_stream_handle class template provides asynchronous and + * blocking stream-oriented handle 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_handle + : public basic_handle +{ +public: + /// The native representation of a handle. + typedef typename StreamHandleService::native_handle_type native_handle_type; + + /// Construct a basic_stream_handle without opening it. + /** + * This constructor creates a stream handle without opening it. The handle + * 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 handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + */ + explicit basic_stream_handle(asio::io_context& io_context) + : basic_handle(io_context) + { + } + + /// Construct a basic_stream_handle on an existing native handle. + /** + * This constructor creates a stream handle object to hold an existing native + * handle. + * + * @param io_context The io_context object that the stream handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + * + * @param handle The new underlying handle implementation. + * + * @throws asio::system_error Thrown on failure. + */ + basic_stream_handle(asio::io_context& io_context, + const native_handle_type& handle) + : basic_handle(io_context, handle) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_stream_handle from another. + /** + * This constructor moves a stream handle from one object to another. + * + * @param other The other basic_stream_handle 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_handle(io_context&) constructor. + */ + basic_stream_handle(basic_stream_handle&& other) + : basic_handle( + ASIO_MOVE_CAST(basic_stream_handle)(other)) + { + } + + /// Move-assign a basic_stream_handle from another. + /** + * This assignment operator moves a stream handle from one object to + * another. + * + * @param other The other basic_stream_handle 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_handle(io_context&) constructor. + */ + basic_stream_handle& operator=(basic_stream_handle&& other) + { + basic_handle::operator=( + ASIO_MOVE_CAST(basic_stream_handle)(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Write some data to the handle. + /** + * This function is used to write data to the stream handle. 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 handle. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * 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 + * handle.write_some(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) + { + asio::error_code ec; + std::size_t s = this->get_service().write_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "write_some"); + return s; + } + + /// Write some data to the handle. + /** + * This function is used to write data to the stream handle. 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 handle. + * + * @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, + asio::error_code& ec) + { + return this->get_service().write_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write data to the stream handle. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be written to the handle. + * 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 asio::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 + * 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 + * handle.async_write_some(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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + return this->get_service().async_write_some(this->get_implementation(), + buffers, ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Read some data from the handle. + /** + * This function is used to read data from the stream handle. 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 asio::system_error Thrown on failure. An error code of + * 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 + * handle.read_some(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) + { + asio::error_code ec; + std::size_t s = this->get_service().read_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "read_some"); + return s; + } + + /// Read some data from the handle. + /** + * This function is used to read data from the stream handle. 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, + asio::error_code& ec) + { + return this->get_service().read_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read data from the stream handle. + * 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 asio::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 + * 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 + * handle.async_read_some(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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + return this->get_service().async_read_some(this->get_implementation(), + buffers, ASIO_MOVE_CAST(ReadHandler)(handler)); + } +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP diff --git a/tools/sdk/include/asio/asio/windows/object_handle.hpp b/tools/sdk/include/asio/asio/windows/object_handle.hpp new file mode 100644 index 00000000..581b5680 --- /dev/null +++ b/tools/sdk/include/asio/asio/windows/object_handle.hpp @@ -0,0 +1,381 @@ +// +// windows/object_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2011 Boris Schaeling (boris@highscore.de) +// +// 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 ASIO_WINDOWS_OBJECT_HANDLE_HPP +#define ASIO_WINDOWS_OBJECT_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/async_result.hpp" +#include "asio/basic_io_object.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/win_object_handle_service.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#if defined(ASIO_HAS_MOVE) +# include +#endif // defined(ASIO_HAS_MOVE) + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/windows/basic_object_handle.hpp" +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#define ASIO_SVC_T asio::detail::win_object_handle_service + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +#if defined(ASIO_ENABLE_OLD_SERVICES) +// Typedef for the typical usage of an object handle. +typedef basic_object_handle<> object_handle; +#else // defined(ASIO_ENABLE_OLD_SERVICES) +/// Provides object-oriented handle functionality. +/** + * The windows::object_handle class provides asynchronous and blocking + * object-oriented handle functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class object_handle + : ASIO_SVC_ACCESS basic_io_object +{ +public: + /// The type of the executor associated with the object. + typedef io_context::executor_type executor_type; + + /// The native representation of a handle. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef ASIO_SVC_T::native_handle_type native_handle_type; +#endif + + /// An object_handle is always the lowest layer. + typedef object_handle lowest_layer_type; + + /// Construct an object_handle without opening it. + /** + * This constructor creates an object handle without opening it. + * + * @param io_context The io_context object that the object handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + */ + explicit object_handle(asio::io_context& io_context) + : basic_io_object(io_context) + { + } + + /// Construct an object_handle on an existing native handle. + /** + * This constructor creates an object handle object to hold an existing native + * handle. + * + * @param io_context The io_context object that the object handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + * + * @param native_handle The new underlying handle implementation. + * + * @throws asio::system_error Thrown on failure. + */ + object_handle(asio::io_context& io_context, + const native_handle_type& native_handle) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), native_handle, ec); + asio::detail::throw_error(ec, "assign"); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct an object_handle from another. + /** + * This constructor moves an object handle from one object to another. + * + * @param other The other object_handle 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 object_handle(io_context&) constructor. + */ + object_handle(object_handle&& other) + : basic_io_object(std::move(other)) + { + } + + /// Move-assign an object_handle from another. + /** + * This assignment operator moves an object handle from one object to another. + * + * @param other The other object_handle 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 object_handle(io_context&) constructor. + */ + object_handle& operator=(object_handle&& other) + { + basic_io_object::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + +#if !defined(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. + */ + 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. + */ + asio::io_context& get_io_service() + { + return basic_io_object::get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return basic_io_object::get_executor(); + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since an object_handle 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 an object_handle 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; + } + + /// Assign an existing native handle to the handle. + /* + * This function opens the handle to hold an existing native handle. + * + * @param handle A native handle. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const native_handle_type& handle) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), handle, ec); + asio::detail::throw_error(ec, "assign"); + } + + /// Assign an existing native handle to the handle. + /* + * This function opens the handle to hold an existing native handle. + * + * @param handle A native handle. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID assign(const native_handle_type& handle, + asio::error_code& ec) + { + this->get_service().assign(this->get_implementation(), handle, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the handle is open. + bool is_open() const + { + return this->get_service().is_open(this->get_implementation()); + } + + /// Close the handle. + /** + * This function is used to close the handle. Any asynchronous read or write + * operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void close() + { + asio::error_code ec; + this->get_service().close(this->get_implementation(), ec); + asio::detail::throw_error(ec, "close"); + } + + /// Close the handle. + /** + * This function is used to close the handle. Any asynchronous read or write + * operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + this->get_service().close(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native handle representation. + /** + * This function may be used to obtain the underlying representation of the + * handle. This is intended to allow access to native handle 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 handle. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel"); + } + + /// Cancel all asynchronous operations associated with the handle. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) + { + this->get_service().cancel(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Perform a blocking wait on the object handle. + /** + * This function is used to wait for the object handle to be set to the + * signalled state. This function blocks and does not return until the object + * handle has been set to the signalled state. + * + * @throws asio::system_error Thrown on failure. + */ + void wait() + { + asio::error_code ec; + this->get_service().wait(this->get_implementation(), ec); + asio::detail::throw_error(ec, "wait"); + } + + /// Perform a blocking wait on the object handle. + /** + * This function is used to wait for the object handle to be set to the + * signalled state. This function blocks and does not return until the object + * handle has been set to the signalled state. + * + * @param ec Set to indicate what error occurred, if any. + */ + void wait(asio::error_code& ec) + { + this->get_service().wait(this->get_implementation(), ec); + } + + /// Start an asynchronous wait on the object handle. + /** + * This function is be used to initiate an asynchronous wait against the + * object handle. It always returns immediately. + * + * @param handler The handler to be called when the object handle is set to + * the signalled state. Copies will be made of the handler as required. The + * function signature of the handler must be: + * @code void handler( + * const asio::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 + * asio::io_context::post(). + */ + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(ASIO_MOVE_ARG(WaitHandler) handler) + { + asio::async_completion init(handler); + + this->get_service().async_wait(this->get_implementation(), + init.completion_handler); + + return init.result.get(); + } +}; +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#undef ASIO_SVC_T + +#endif // defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_WINDOWS_OBJECT_HANDLE_HPP diff --git a/tools/sdk/include/asio/asio/windows/object_handle_service.hpp b/tools/sdk/include/asio/asio/windows/object_handle_service.hpp new file mode 100644 index 00000000..95436d79 --- /dev/null +++ b/tools/sdk/include/asio/asio/windows/object_handle_service.hpp @@ -0,0 +1,183 @@ +// +// windows/object_handle_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2011 Boris Schaeling (boris@highscore.de) +// +// 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 ASIO_WINDOWS_OBJECT_HANDLE_SERVICE_HPP +#define ASIO_WINDOWS_OBJECT_HANDLE_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/async_result.hpp" +#include "asio/detail/win_object_handle_service.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Default service implementation for an object handle. +class object_handle_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_context::id id; +#endif + +private: + // The type of the platform-specific implementation. + typedef detail::win_object_handle_service service_impl_type; + +public: + /// The type of an object handle implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef service_impl_type::implementation_type implementation_type; +#endif + + /// The native handle type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef service_impl_type::native_handle_type native_handle_type; +#endif + + /// Construct a new object handle service for the specified io_context. + explicit object_handle_service(asio::io_context& io_context) + : asio::detail::service_base(io_context), + service_impl_(io_context) + { + } + + /// Construct a new object handle implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new object handle implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another object handle implementation. + void move_assign(implementation_type& impl, + object_handle_service& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy an object handle implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Assign an existing native handle to an object handle. + ASIO_SYNC_OP_VOID assign(implementation_type& impl, + const native_handle_type& handle, asio::error_code& ec) + { + service_impl_.assign(impl, handle, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close an object handle implementation. + ASIO_SYNC_OP_VOID close(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.close(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native handle implementation. + native_handle_type native_handle(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Cancel all asynchronous operations associated with the handle. + ASIO_SYNC_OP_VOID cancel(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.cancel(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + // Wait for a signaled state. + void wait(implementation_type& impl, asio::error_code& ec) + { + service_impl_.wait(impl, ec); + } + + /// Start an asynchronous wait. + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(implementation_type& impl, + ASIO_MOVE_ARG(WaitHandler) handler) + { + asio::async_completion init(handler); + + service_impl_.async_wait(impl, 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 windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_OBJECT_HANDLE_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/windows/overlapped_handle.hpp b/tools/sdk/include/asio/asio/windows/overlapped_handle.hpp new file mode 100644 index 00000000..3d479ba6 --- /dev/null +++ b/tools/sdk/include/asio/asio/windows/overlapped_handle.hpp @@ -0,0 +1,331 @@ +// +// windows/overlapped_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_WINDOWS_OVERLAPPED_HANDLE_HPP +#define ASIO_WINDOWS_OVERLAPPED_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/async_result.hpp" +#include "asio/basic_io_object.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/win_iocp_handle_service.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#if defined(ASIO_HAS_MOVE) +# include +#endif // defined(ASIO_HAS_MOVE) + +#define ASIO_SVC_T asio::detail::win_iocp_handle_service + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Provides Windows handle functionality for objects that support +/// overlapped I/O. +/** + * The windows::overlapped_handle class provides the ability to wrap a Windows + * handle. The underlying object referred to by the handle must support + * overlapped I/O. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class overlapped_handle + : ASIO_SVC_ACCESS basic_io_object +{ +public: + /// The type of the executor associated with the object. + typedef io_context::executor_type executor_type; + + /// The native representation of a handle. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef ASIO_SVC_T::native_handle_type native_handle_type; +#endif + + /// An overlapped_handle is always the lowest layer. + typedef overlapped_handle lowest_layer_type; + + /// Construct an overlapped_handle without opening it. + /** + * This constructor creates a handle without opening it. + * + * @param io_context The io_context object that the handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + */ + explicit overlapped_handle(asio::io_context& io_context) + : basic_io_object(io_context) + { + } + + /// Construct an overlapped_handle on an existing native handle. + /** + * This constructor creates a handle object to hold an existing native handle. + * + * @param io_context The io_context object that the handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + * + * @param handle A native handle. + * + * @throws asio::system_error Thrown on failure. + */ + overlapped_handle(asio::io_context& io_context, + const native_handle_type& handle) + : basic_io_object(io_context) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), handle, ec); + asio::detail::throw_error(ec, "assign"); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct an overlapped_handle from another. + /** + * This constructor moves a handle from one object to another. + * + * @param other The other overlapped_handle 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 overlapped_handle(io_context&) constructor. + */ + overlapped_handle(overlapped_handle&& other) + : basic_io_object(std::move(other)) + { + } + + /// Move-assign an overlapped_handle from another. + /** + * This assignment operator moves a handle from one object to another. + * + * @param other The other overlapped_handle 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 overlapped_handle(io_context&) constructor. + */ + overlapped_handle& operator=(overlapped_handle&& other) + { + basic_io_object::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + +#if !defined(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. + */ + 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. + */ + asio::io_context& get_io_service() + { + return basic_io_object::get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return basic_io_object::get_executor(); + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since an overlapped_handle 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 an overlapped_handle 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; + } + + /// Assign an existing native handle to the handle. + /* + * This function opens the handle to hold an existing native handle. + * + * @param handle A native handle. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const native_handle_type& handle) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), handle, ec); + asio::detail::throw_error(ec, "assign"); + } + + /// Assign an existing native handle to the handle. + /* + * This function opens the handle to hold an existing native handle. + * + * @param handle A native handle. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID assign(const native_handle_type& handle, + asio::error_code& ec) + { + this->get_service().assign(this->get_implementation(), handle, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the handle is open. + bool is_open() const + { + return this->get_service().is_open(this->get_implementation()); + } + + /// Close the handle. + /** + * This function is used to close the handle. Any asynchronous read or write + * operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void close() + { + asio::error_code ec; + this->get_service().close(this->get_implementation(), ec); + asio::detail::throw_error(ec, "close"); + } + + /// Close the handle. + /** + * This function is used to close the handle. Any asynchronous read or write + * operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + this->get_service().close(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native handle representation. + /** + * This function may be used to obtain the underlying representation of the + * handle. This is intended to allow access to native handle 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 handle. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel"); + } + + /// Cancel all asynchronous operations associated with the handle. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) + { + this->get_service().cancel(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + +protected: + /// Protected destructor to prevent deletion through this type. + /** + * This function destroys the handle, cancelling any outstanding asynchronous + * wait operations associated with the handle as if by calling @c cancel. + */ + ~overlapped_handle() + { + } +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#undef ASIO_SVC_T + +#endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + // || defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // !defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_OVERLAPPED_HANDLE_HPP diff --git a/tools/sdk/include/asio/asio/windows/overlapped_ptr.hpp b/tools/sdk/include/asio/asio/windows/overlapped_ptr.hpp new file mode 100644 index 00000000..ce0b2a42 --- /dev/null +++ b/tools/sdk/include/asio/asio/windows/overlapped_ptr.hpp @@ -0,0 +1,116 @@ +// +// windows/overlapped_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_WINDOWS_OVERLAPPED_PTR_HPP +#define ASIO_WINDOWS_OVERLAPPED_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/win_iocp_overlapped_ptr.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Wraps a handler to create an OVERLAPPED object for use with overlapped I/O. +/** + * A special-purpose smart pointer used to wrap an application handler so that + * it can be passed as the LPOVERLAPPED argument to overlapped I/O functions. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class overlapped_ptr + : private noncopyable +{ +public: + /// Construct an empty overlapped_ptr. + overlapped_ptr() + : impl_() + { + } + + /// Construct an overlapped_ptr to contain the specified handler. + template + explicit overlapped_ptr(asio::io_context& io_context, + ASIO_MOVE_ARG(Handler) handler) + : impl_(io_context, ASIO_MOVE_CAST(Handler)(handler)) + { + } + + /// Destructor automatically frees the OVERLAPPED object unless released. + ~overlapped_ptr() + { + } + + /// Reset to empty. + void reset() + { + impl_.reset(); + } + + /// Reset to contain the specified handler, freeing any current OVERLAPPED + /// object. + template + void reset(asio::io_context& io_context, + ASIO_MOVE_ARG(Handler) handler) + { + impl_.reset(io_context, ASIO_MOVE_CAST(Handler)(handler)); + } + + /// Get the contained OVERLAPPED object. + OVERLAPPED* get() + { + return impl_.get(); + } + + /// Get the contained OVERLAPPED object. + const OVERLAPPED* get() const + { + return impl_.get(); + } + + /// Release ownership of the OVERLAPPED object. + OVERLAPPED* release() + { + return impl_.release(); + } + + /// Post completion notification for overlapped operation. Releases ownership. + void complete(const asio::error_code& ec, + std::size_t bytes_transferred) + { + impl_.complete(ec, bytes_transferred); + } + +private: + detail::win_iocp_overlapped_ptr impl_; +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_WINDOWS_OVERLAPPED_PTR_HPP diff --git a/tools/sdk/include/asio/asio/windows/random_access_handle.hpp b/tools/sdk/include/asio/asio/windows/random_access_handle.hpp new file mode 100644 index 00000000..301d5f8d --- /dev/null +++ b/tools/sdk/include/asio/asio/windows/random_access_handle.hpp @@ -0,0 +1,378 @@ +// +// windows/random_access_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP +#define ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/windows/overlapped_handle.hpp" + +#if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/windows/basic_random_access_handle.hpp" +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +#if defined(ASIO_ENABLE_OLD_SERVICES) +// Typedef for the typical usage of a random-access handle. +typedef basic_random_access_handle<> random_access_handle; +#else // defined(ASIO_ENABLE_OLD_SERVICES) +/// Provides random-access handle functionality. +/** + * The windows::random_access_handle class provides asynchronous and + * blocking random-access handle functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class random_access_handle + : public overlapped_handle +{ +public: + /// Construct a random_access_handle without opening it. + /** + * This constructor creates a random-access handle without opening it. The + * handle needs to be opened before data can be written to or read from it. + * + * @param io_context The io_context object that the random-access handle will + * use to dispatch handlers for any asynchronous operations performed on the + * handle. + */ + explicit random_access_handle(asio::io_context& io_context) + : overlapped_handle(io_context) + { + } + + /// Construct a random_access_handle on an existing native handle. + /** + * This constructor creates a random-access handle object to hold an existing + * native handle. + * + * @param io_context The io_context object that the random-access handle will + * use to dispatch handlers for any asynchronous operations performed on the + * handle. + * + * @param handle The new underlying handle implementation. + * + * @throws asio::system_error Thrown on failure. + */ + random_access_handle(asio::io_context& io_context, + const native_handle_type& handle) + : overlapped_handle(io_context, handle) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a random_access_handle from another. + /** + * This constructor moves a random-access handle from one object to another. + * + * @param other The other random_access_handle 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 random_access_handle(io_context&) + * constructor. + */ + random_access_handle(random_access_handle&& other) + : overlapped_handle(std::move(other)) + { + } + + /// Move-assign a random_access_handle from another. + /** + * This assignment operator moves a random-access handle from one object to + * another. + * + * @param other The other random_access_handle 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 random_access_handle(io_context&) + * constructor. + */ + random_access_handle& operator=(random_access_handle&& other) + { + overlapped_handle::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Write some data to the handle at the specified offset. + /** + * This function is used to write data to the random-access handle. The + * function call will block until one or more bytes of the data has been + * written successfully, or until an error occurs. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The write_some_at operation may not write all of the data. Consider + * using the @ref write_at 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 + * handle.write_some_at(42, 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_at(uint64_t offset, + const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->get_service().write_some_at( + this->get_implementation(), offset, buffers, ec); + asio::detail::throw_error(ec, "write_some_at"); + return s; + } + + /// Write some data to the handle at the specified offset. + /** + * This function is used to write data to the random-access handle. The + * function call will block until one or more bytes of the data has been + * written successfully, or until an error occurs. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @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_at function if you need to ensure that + * all data is written before the blocking operation completes. + */ + template + std::size_t write_some_at(uint64_t offset, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return this->get_service().write_some_at( + this->get_implementation(), offset, buffers, ec); + } + + /// Start an asynchronous write at the specified offset. + /** + * This function is used to asynchronously write data to the random-access + * handle. The function call always returns immediately. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * 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 asio::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 + * asio::io_context::post(). + * + * @note The write operation may not transmit all of the data to the peer. + * Consider using the @ref async_write_at 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 + * handle.async_write_some_at(42, 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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some_at(uint64_t offset, + const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + asio::async_completion init(handler); + + this->get_service().async_write_some_at(this->get_implementation(), + offset, buffers, init.completion_handler); + + return init.result.get(); + } + + /// Read some data from the handle at the specified offset. + /** + * This function is used to read data from the random-access handle. The + * function call will block until one or more bytes of data has been read + * successfully, or until an error occurs. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. An error code of + * 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_at 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 + * handle.read_some_at(42, 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_at(uint64_t offset, + const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->get_service().read_some_at( + this->get_implementation(), offset, buffers, ec); + asio::detail::throw_error(ec, "read_some_at"); + return s; + } + + /// Read some data from the handle at the specified offset. + /** + * This function is used to read data from the random-access handle. The + * function call will block until one or more bytes of data has been read + * successfully, or until an error occurs. + * + * @param offset The offset at which the data will be read. + * + * @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_at 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_at(uint64_t offset, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return this->get_service().read_some_at( + this->get_implementation(), offset, buffers, ec); + } + + /// Start an asynchronous read at the specified offset. + /** + * This function is used to asynchronously read data from the random-access + * handle. The function call always returns immediately. + * + * @param offset The offset at which the data will be read. + * + * @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 asio::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 + * asio::io_context::post(). + * + * @note The read operation may not read all of the requested number of bytes. + * Consider using the @ref async_read_at 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 + * handle.async_read_some_at(42, 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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some_at(uint64_t offset, + const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + asio::async_completion init(handler); + + this->get_service().async_read_some_at(this->get_implementation(), + offset, buffers, init.completion_handler); + + return init.result.get(); + } +}; +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP diff --git a/tools/sdk/include/asio/asio/windows/random_access_handle_service.hpp b/tools/sdk/include/asio/asio/windows/random_access_handle_service.hpp new file mode 100644 index 00000000..ebccf3e3 --- /dev/null +++ b/tools/sdk/include/asio/asio/windows/random_access_handle_service.hpp @@ -0,0 +1,214 @@ +// +// windows/random_access_handle_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP +#define ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/async_result.hpp" +#include "asio/detail/cstdint.hpp" +#include "asio/detail/win_iocp_handle_service.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Default service implementation for a random-access handle. +class random_access_handle_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_context::id id; +#endif + +private: + // The type of the platform-specific implementation. + typedef detail::win_iocp_handle_service service_impl_type; + +public: + /// The type of a random-access handle implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef service_impl_type::implementation_type implementation_type; +#endif + + /// The native handle type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef service_impl_type::native_handle_type native_handle_type; +#endif + + /// Construct a new random-access handle service for the specified io_context. + explicit random_access_handle_service(asio::io_context& io_context) + : asio::detail::service_base< + random_access_handle_service>(io_context), + service_impl_(io_context) + { + } + + /// Construct a new random-access handle implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new random-access handle implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another random-access handle implementation. + void move_assign(implementation_type& impl, + random_access_handle_service& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy a random-access handle implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Assign an existing native handle to a random-access handle. + ASIO_SYNC_OP_VOID assign(implementation_type& impl, + const native_handle_type& handle, asio::error_code& ec) + { + service_impl_.assign(impl, handle, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a random-access handle implementation. + ASIO_SYNC_OP_VOID close(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.close(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native handle implementation. + native_handle_type native_handle(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Cancel all asynchronous operations associated with the handle. + ASIO_SYNC_OP_VOID cancel(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.cancel(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Write the given data at the specified offset. + template + std::size_t write_some_at(implementation_type& impl, uint64_t offset, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.write_some_at(impl, offset, buffers, ec); + } + + /// Start an asynchronous write at the specified offset. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some_at(implementation_type& impl, + uint64_t offset, const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) + { + asio::async_completion init(handler); + + service_impl_.async_write_some_at(impl, + offset, buffers, init.completion_handler); + + return init.result.get(); + } + + /// Read some data from the specified offset. + template + std::size_t read_some_at(implementation_type& impl, uint64_t offset, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.read_some_at(impl, offset, buffers, ec); + } + + /// Start an asynchronous read at the specified offset. + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some_at(implementation_type& impl, + uint64_t offset, const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) + { + asio::async_completion init(handler); + + service_impl_.async_read_some_at(impl, + offset, buffers, 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 windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/windows/stream_handle.hpp b/tools/sdk/include/asio/asio/windows/stream_handle.hpp new file mode 100644 index 00000000..8f0a21b1 --- /dev/null +++ b/tools/sdk/include/asio/asio/windows/stream_handle.hpp @@ -0,0 +1,362 @@ +// +// windows/stream_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_WINDOWS_STREAM_HANDLE_HPP +#define ASIO_WINDOWS_STREAM_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/windows/overlapped_handle.hpp" + +#if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/windows/basic_stream_handle.hpp" +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +#if defined(ASIO_ENABLE_OLD_SERVICES) +// Typedef for the typical usage of a stream-oriented handle. +typedef basic_stream_handle<> stream_handle; +#else // defined(ASIO_ENABLE_OLD_SERVICES) +/// Provides stream-oriented handle functionality. +/** + * The windows::stream_handle class provides asynchronous and blocking + * stream-oriented handle functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +class stream_handle + : public overlapped_handle +{ +public: + /// Construct a stream_handle without opening it. + /** + * This constructor creates a stream handle without opening it. The handle + * 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 handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + */ + explicit stream_handle(asio::io_context& io_context) + : overlapped_handle(io_context) + { + } + + /// Construct a stream_handle on an existing native handle. + /** + * This constructor creates a stream handle object to hold an existing native + * handle. + * + * @param io_context The io_context object that the stream handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + * + * @param handle The new underlying handle implementation. + * + * @throws asio::system_error Thrown on failure. + */ + stream_handle(asio::io_context& io_context, + const native_handle_type& handle) + : overlapped_handle(io_context, handle) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a stream_handle from another. + /** + * This constructor moves a stream handle from one object to another. + * + * @param other The other stream_handle 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 stream_handle(io_context&) constructor. + */ + stream_handle(stream_handle&& other) + : overlapped_handle(std::move(other)) + { + } + + /// Move-assign a stream_handle from another. + /** + * This assignment operator moves a stream handle from one object to + * another. + * + * @param other The other stream_handle 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 stream_handle(io_context&) constructor. + */ + stream_handle& operator=(stream_handle&& other) + { + overlapped_handle::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Write some data to the handle. + /** + * This function is used to write data to the stream handle. 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 handle. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * 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 + * handle.write_some(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) + { + asio::error_code ec; + std::size_t s = this->get_service().write_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "write_some"); + return s; + } + + /// Write some data to the handle. + /** + * This function is used to write data to the stream handle. 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 handle. + * + * @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, + asio::error_code& ec) + { + return this->get_service().write_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write data to the stream handle. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be written to the handle. + * 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 asio::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 + * 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 + * handle.async_write_some(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 + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + 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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + asio::async_completion init(handler); + + this->get_service().async_write_some( + this->get_implementation(), buffers, init.completion_handler); + + return init.result.get(); + } + + /// Read some data from the handle. + /** + * This function is used to read data from the stream handle. 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 asio::system_error Thrown on failure. An error code of + * 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 + * handle.read_some(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) + { + asio::error_code ec; + std::size_t s = this->get_service().read_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "read_some"); + return s; + } + + /// Read some data from the handle. + /** + * This function is used to read data from the stream handle. 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, + asio::error_code& ec) + { + return this->get_service().read_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read data from the stream handle. + * 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 asio::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 + * 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 + * handle.async_read_some(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 + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + 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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + asio::async_completion init(handler); + + this->get_service().async_read_some( + this->get_implementation(), buffers, init.completion_handler); + + return init.result.get(); + } +}; +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_WINDOWS_STREAM_HANDLE_HPP diff --git a/tools/sdk/include/asio/asio/windows/stream_handle_service.hpp b/tools/sdk/include/asio/asio/windows/stream_handle_service.hpp new file mode 100644 index 00000000..1c665d5e --- /dev/null +++ b/tools/sdk/include/asio/asio/windows/stream_handle_service.hpp @@ -0,0 +1,210 @@ +// +// windows/stream_handle_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_WINDOWS_STREAM_HANDLE_SERVICE_HPP +#define ASIO_WINDOWS_STREAM_HANDLE_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/async_result.hpp" +#include "asio/detail/win_iocp_handle_service.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Default service implementation for a stream handle. +class stream_handle_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_context::id id; +#endif + +private: + // The type of the platform-specific implementation. + typedef detail::win_iocp_handle_service service_impl_type; + +public: + /// The type of a stream handle implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef service_impl_type::implementation_type implementation_type; +#endif + + /// The native handle type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef service_impl_type::native_handle_type native_handle_type; +#endif + + /// Construct a new stream handle service for the specified io_context. + explicit stream_handle_service(asio::io_context& io_context) + : asio::detail::service_base(io_context), + service_impl_(io_context) + { + } + + /// Construct a new stream handle implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new stream handle implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another stream handle implementation. + void move_assign(implementation_type& impl, + stream_handle_service& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy a stream handle implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Assign an existing native handle to a stream handle. + ASIO_SYNC_OP_VOID assign(implementation_type& impl, + const native_handle_type& handle, asio::error_code& ec) + { + service_impl_.assign(impl, handle, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a stream handle implementation. + ASIO_SYNC_OP_VOID close(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.close(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native handle implementation. + native_handle_type native_handle(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Cancel all asynchronous operations associated with the handle. + ASIO_SYNC_OP_VOID cancel(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.cancel(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Write the given data to the stream. + template + std::size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.write_some(impl, buffers, ec); + } + + /// Start an asynchronous write. + template + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) + { + asio::async_completion init(handler); + + service_impl_.async_write_some(impl, buffers, init.completion_handler); + + return init.result.get(); + } + + /// Read some data from the stream. + template + std::size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.read_some(impl, buffers, ec); + } + + /// Start an asynchronous read. + template + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) + { + asio::async_completion init(handler); + + service_impl_.async_read_some(impl, buffers, 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 windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_STREAM_HANDLE_SERVICE_HPP diff --git a/tools/sdk/include/asio/asio/write.hpp b/tools/sdk/include/asio/asio/write.hpp new file mode 100644 index 00000000..517a8420 --- /dev/null +++ b/tools/sdk/include/asio/asio/write.hpp @@ -0,0 +1,927 @@ +// +// write.hpp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_WRITE_HPP +#define ASIO_WRITE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/async_result.hpp" +#include "asio/buffer.hpp" +#include "asio/error.hpp" + +#if !defined(ASIO_NO_EXTENSIONS) +# include "asio/basic_streambuf_fwd.hpp" +#endif // !defined(ASIO_NO_EXTENSIONS) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/** + * @defgroup write asio::write + * + * @brief Write a certain amount of data to a stream before returning. + */ +/*@{*/ + +/// Write all of the supplied data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * stream. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code asio::write(s, 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. + * + * @note This overload is equivalent to calling: + * @code asio::write( + * s, buffers, + * asio::transfer_all()); @endcode + */ +template +std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + typename enable_if< + is_const_buffer_sequence::value + >::type* = 0); + +/// Write all of the supplied data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * stream. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes transferred. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code asio::write(s, asio::buffer(data, size), ec); @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. + * + * @note This overload is equivalent to calling: + * @code asio::write( + * s, buffers, + * asio::transfer_all(), ec); @endcode + */ +template +std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + asio::error_code& ec, + typename enable_if< + is_const_buffer_sequence::value + >::type* = 0); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * stream. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's write_some function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code asio::write(s, asio::buffer(data, size), + * asio::transfer_at_least(32)); @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(SyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, + typename enable_if< + is_const_buffer_sequence::value + >::type* = 0); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * stream. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's write_some function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec, + typename enable_if< + is_const_buffer_sequence::value + >::type* = 0); + +/// Write all of the supplied data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied dynamic buffer sequence has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param buffers The dynamic buffer sequence from which data will be written. + * Successfully written data is automatically consumed from the buffers. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @note This overload is equivalent to calling: + * @code asio::write( + * s, buffers, + * asio::transfer_all()); @endcode + */ +template +std::size_t write(SyncWriteStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + typename enable_if< + is_dynamic_buffer::type>::value + >::type* = 0); + +/// Write all of the supplied data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied dynamic buffer sequence has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param buffers The dynamic buffer sequence from which data will be written. + * Successfully written data is automatically consumed from the buffers. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes transferred. + * + * @note This overload is equivalent to calling: + * @code asio::write( + * s, buffers, + * asio::transfer_all(), ec); @endcode + */ +template +std::size_t write(SyncWriteStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + asio::error_code& ec, + typename enable_if< + is_dynamic_buffer::type>::value + >::type* = 0); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied dynamic buffer sequence has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param buffers The dynamic buffer sequence from which data will be written. + * Successfully written data is automatically consumed from the buffers. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's write_some function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + */ +template +std::size_t write(SyncWriteStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + CompletionCondition completion_condition, + typename enable_if< + is_dynamic_buffer::type>::value + >::type* = 0); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied dynamic buffer sequence has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param buffers The dynamic buffer sequence from which data will be written. + * Successfully written data is automatically consumed from the buffers. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's write_some function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t write(SyncWriteStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + CompletionCondition completion_condition, asio::error_code& ec, + typename enable_if< + is_dynamic_buffer::type>::value + >::type* = 0); + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +/// Write all of the supplied data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param b The basic_streambuf object from which data will be written. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @note This overload is equivalent to calling: + * @code asio::write( + * s, b, + * asio::transfer_all()); @endcode + */ +template +std::size_t write(SyncWriteStream& s, basic_streambuf& b); + +/// Write all of the supplied data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param b The basic_streambuf object from which data will be written. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes transferred. + * + * @note This overload is equivalent to calling: + * @code asio::write( + * s, b, + * asio::transfer_all(), ec); @endcode + */ +template +std::size_t write(SyncWriteStream& s, basic_streambuf& b, + asio::error_code& ec); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param b The basic_streambuf object from which data will be written. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's write_some function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + */ +template +std::size_t write(SyncWriteStream& s, basic_streambuf& b, + CompletionCondition completion_condition); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param b The basic_streambuf object from which data will be written. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's write_some function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t write(SyncWriteStream& s, basic_streambuf& b, + CompletionCondition completion_condition, asio::error_code& ec); + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +/*@}*/ +/** + * @defgroup async_write asio::async_write + * + * @brief Start an asynchronous operation to write a certain amount of data to a + * stream. + */ +/*@{*/ + +/// Start an asynchronous operation to write all of the supplied data to a +/// stream. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_write_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other write operations (such + * as async_write, the stream's async_write_some function, or any other composed + * operations that perform writes) until this operation completes. + * + * @param s The stream to which the data is to be written. The type must support + * the AsyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. + * 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 asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. + * ); @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 + * asio::io_context::post(). + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * asio::async_write(s, 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 +ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler, + typename enable_if< + is_const_buffer_sequence::value + >::type* = 0); + +/// Start an asynchronous operation to write a certain amount of data to a +/// stream. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_write_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other write operations (such + * as async_write, the stream's async_write_some function, or any other composed + * operations that perform writes) until this operation completes. + * + * @param s The stream to which the data is to be written. The type must support + * the AsyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. + * 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 completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's async_write_some function. + * + * @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 asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. + * ); @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 + * asio::io_context::post(). + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code asio::async_write(s, + * asio::buffer(data, size), + * asio::transfer_at_least(32), + * 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 +ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(WriteHandler) handler, + typename enable_if< + is_const_buffer_sequence::value + >::type* = 0); + +/// Start an asynchronous operation to write all of the supplied data to a +/// stream. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li All of the data in the supplied dynamic buffer sequence has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_write_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other write operations (such + * as async_write, the stream's async_write_some function, or any other composed + * operations that perform writes) until this operation completes. + * + * @param s The stream to which the data is to be written. The type must support + * the AsyncWriteStream concept. + * + * @param buffers The dynamic buffer sequence from which data will be written. + * 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. Successfully written + * data is automatically consumed from the buffers. + * + * @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 asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. + * ); @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 + * asio::io_context::post(). + */ +template +ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write(AsyncWriteStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + ASIO_MOVE_ARG(WriteHandler) handler, + typename enable_if< + is_dynamic_buffer::type>::value + >::type* = 0); + +/// Start an asynchronous operation to write a certain amount of data to a +/// stream. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li All of the data in the supplied dynamic buffer sequence has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_write_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other write operations (such + * as async_write, the stream's async_write_some function, or any other composed + * operations that perform writes) until this operation completes. + * + * @param s The stream to which the data is to be written. The type must support + * the AsyncWriteStream concept. + * + * @param buffers The dynamic buffer sequence from which data will be written. + * 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. Successfully written + * data is automatically consumed from the buffers. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's async_write_some function. + * + * @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 asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. + * ); @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 + * asio::io_context::post(). + */ +template +ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write(AsyncWriteStream& s, + ASIO_MOVE_ARG(DynamicBuffer) buffers, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(WriteHandler) handler, + typename enable_if< + is_dynamic_buffer::type>::value + >::type* = 0); + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +/// Start an asynchronous operation to write all of the supplied data to a +/// stream. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_write_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other write operations (such + * as async_write, the stream's async_write_some function, or any other composed + * operations that perform writes) until this operation completes. + * + * @param s The stream to which the data is to be written. The type must support + * the AsyncWriteStream concept. + * + * @param b A basic_streambuf object from which data will be written. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains 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 asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. + * ); @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 + * asio::io_context::post(). + */ +template +ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write(AsyncWriteStream& s, basic_streambuf& b, + ASIO_MOVE_ARG(WriteHandler) handler); + +/// Start an asynchronous operation to write a certain amount of data to a +/// stream. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_write_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other write operations (such + * as async_write, the stream's async_write_some function, or any other composed + * operations that perform writes) until this operation completes. + * + * @param s The stream to which the data is to be written. The type must support + * the AsyncWriteStream concept. + * + * @param b A basic_streambuf object from which data will be written. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's async_write_some function. + * + * @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 asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. + * ); @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 + * asio::io_context::post(). + */ +template +ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write(AsyncWriteStream& s, basic_streambuf& b, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(WriteHandler) handler); + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +/*@}*/ + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/write.hpp" + +#endif // ASIO_WRITE_HPP diff --git a/tools/sdk/include/asio/asio/write_at.hpp b/tools/sdk/include/asio/asio/write_at.hpp new file mode 100644 index 00000000..5018d210 --- /dev/null +++ b/tools/sdk/include/asio/asio/write_at.hpp @@ -0,0 +1,677 @@ +// +// write_at.hpp +// ~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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 ASIO_WRITE_AT_HPP +#define ASIO_WRITE_AT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/async_result.hpp" +#include "asio/detail/cstdint.hpp" +#include "asio/error.hpp" + +#if !defined(ASIO_NO_EXTENSIONS) +# include "asio/basic_streambuf_fwd.hpp" +#endif // !defined(ASIO_NO_EXTENSIONS) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/** + * @defgroup write_at asio::write_at + * + * @brief Write a certain amount of data at a specified offset before returning. + */ +/*@{*/ + +/// Write all of the supplied data at the specified offset before returning. +/** + * This function is used to write a certain number of bytes of data to a random + * access device at a specified offset. The call will block until one of the + * following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the SyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * device. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code asio::write_at(d, 42, 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. + * + * @note This overload is equivalent to calling: + * @code asio::write_at( + * d, offset, buffers, + * asio::transfer_all()); @endcode + */ +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, + uint64_t offset, const ConstBufferSequence& buffers); + +/// Write all of the supplied data at the specified offset before returning. +/** + * This function is used to write a certain number of bytes of data to a random + * access device at a specified offset. The call will block until one of the + * following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the SyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * device. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes transferred. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code asio::write_at(d, 42, + * asio::buffer(data, size), ec); @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. + * + * @note This overload is equivalent to calling: + * @code asio::write_at( + * d, offset, buffers, + * asio::transfer_all(), ec); @endcode + */ +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, + uint64_t offset, const ConstBufferSequence& buffers, + asio::error_code& ec); + +/// Write a certain amount of data at a specified offset before returning. +/** + * This function is used to write a certain number of bytes of data to a random + * access device at a specified offset. The call will block until one of the + * following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the SyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * device. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the device's write_some_at function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code asio::write_at(d, 42, asio::buffer(data, size), + * asio::transfer_at_least(32)); @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_at(SyncRandomAccessWriteDevice& d, + uint64_t offset, const ConstBufferSequence& buffers, + CompletionCondition completion_condition); + +/// Write a certain amount of data at a specified offset before returning. +/** + * This function is used to write a certain number of bytes of data to a random + * access device at a specified offset. The call will block until one of the + * following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the SyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * device. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the device's write_some_at function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, + uint64_t offset, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec); + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +/// Write all of the supplied data at the specified offset before returning. +/** + * This function is used to write a certain number of bytes of data to a random + * access device at a specified offset. The call will block until one of the + * following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the SyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param b The basic_streambuf object from which data will be written. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @note This overload is equivalent to calling: + * @code asio::write_at( + * d, 42, b, + * asio::transfer_all()); @endcode + */ +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, + uint64_t offset, basic_streambuf& b); + +/// Write all of the supplied data at the specified offset before returning. +/** + * This function is used to write a certain number of bytes of data to a random + * access device at a specified offset. The call will block until one of the + * following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the SyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param b The basic_streambuf object from which data will be written. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes transferred. + * + * @note This overload is equivalent to calling: + * @code asio::write_at( + * d, 42, b, + * asio::transfer_all(), ec); @endcode + */ +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, + uint64_t offset, basic_streambuf& b, + asio::error_code& ec); + +/// Write a certain amount of data at a specified offset before returning. +/** + * This function is used to write a certain number of bytes of data to a random + * access device at a specified offset. The call will block until one of the + * following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the SyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param b The basic_streambuf object from which data will be written. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the device's write_some_at function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + */ +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, + basic_streambuf& b, CompletionCondition completion_condition); + +/// Write a certain amount of data at a specified offset before returning. +/** + * This function is used to write a certain number of bytes of data to a random + * access device at a specified offset. The call will block until one of the + * following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the SyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param b The basic_streambuf object from which data will be written. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the device's write_some_at function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, + basic_streambuf& b, CompletionCondition completion_condition, + asio::error_code& ec); + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +/*@}*/ +/** + * @defgroup async_write_at asio::async_write_at + * + * @brief Start an asynchronous operation to write a certain amount of data at + * the specified offset. + */ +/*@{*/ + +/// Start an asynchronous operation to write all of the supplied data at the +/// specified offset. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a random access device at a specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * async_write_some_at function, and is known as a composed operation. + * The program must ensure that the device performs no overlapping + * write operations (such as async_write_at, the device's async_write_some_at + * function, or any other composed operations that perform writes) until this + * operation completes. Operations are overlapping if the regions defined by + * their offsets, and the numbers of bytes to write, intersect. + * + * @param d The device to which the data is to be written. The type must support + * the AsyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more buffers containing the data to be written. + * 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( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes written from the buffers. If an error + * // occurred, this will be less than the sum of the buffer sizes. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * asio::async_write_at(d, 42, 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 +ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, + const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler); + +/// Start an asynchronous operation to write a certain amount of data at the +/// specified offset. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a random access device at a specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * async_write_some_at function, and is known as a composed operation. + * The program must ensure that the device performs no overlapping + * write operations (such as async_write_at, the device's async_write_some_at + * function, or any other composed operations that perform writes) until this + * operation completes. Operations are overlapping if the regions defined by + * their offsets, and the numbers of bytes to write, intersect. + * + * @param d The device to which the data is to be written. The type must support + * the AsyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more buffers containing the data to be written. + * 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 completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_write_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the device's async_write_some_at function. + * + * @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( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes written from the buffers. If an error + * // occurred, this will be less than the sum of the buffer sizes. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code asio::async_write_at(d, 42, + * asio::buffer(data, size), + * asio::transfer_at_least(32), + * 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 +ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write_at(AsyncRandomAccessWriteDevice& d, + uint64_t offset, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, + ASIO_MOVE_ARG(WriteHandler) handler); + +#if !defined(ASIO_NO_EXTENSIONS) +#if !defined(ASIO_NO_IOSTREAM) + +/// Start an asynchronous operation to write all of the supplied data at the +/// specified offset. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a random access device at a specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * async_write_some_at function, and is known as a composed operation. + * The program must ensure that the device performs no overlapping + * write operations (such as async_write_at, the device's async_write_some_at + * function, or any other composed operations that perform writes) until this + * operation completes. Operations are overlapping if the regions defined by + * their offsets, and the numbers of bytes to write, intersect. + * + * @param d The device to which the data is to be written. The type must support + * the AsyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param b A basic_streambuf object from which data will be written. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains 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( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes written from the buffers. If an error + * // occurred, this will be less than the sum of the buffer sizes. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + */ +template +ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, + basic_streambuf& b, ASIO_MOVE_ARG(WriteHandler) handler); + +/// Start an asynchronous operation to write a certain amount of data at the +/// specified offset. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a random access device at a specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * async_write_some_at function, and is known as a composed operation. + * The program must ensure that the device performs no overlapping + * write operations (such as async_write_at, the device's async_write_some_at + * function, or any other composed operations that perform writes) until this + * operation completes. Operations are overlapping if the regions defined by + * their offsets, and the numbers of bytes to write, intersect. + * + * @param d The device to which the data is to be written. The type must support + * the AsyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param b A basic_streambuf object from which data will be written. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_write_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the device's async_write_some_at function. + * + * @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( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes written from the buffers. If an error + * // occurred, this will be less than the sum of the buffer sizes. + * std::size_t bytes_transferred + * ); @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 + * asio::io_context::post(). + */ +template +ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, + basic_streambuf& b, CompletionCondition completion_condition, + ASIO_MOVE_ARG(WriteHandler) handler); + +#endif // !defined(ASIO_NO_IOSTREAM) +#endif // !defined(ASIO_NO_EXTENSIONS) + +/*@}*/ + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/write_at.hpp" + +#endif // ASIO_WRITE_AT_HPP diff --git a/tools/sdk/include/asio/asio/yield.hpp b/tools/sdk/include/asio/asio/yield.hpp new file mode 100644 index 00000000..b527ac9b --- /dev/null +++ b/tools/sdk/include/asio/asio/yield.hpp @@ -0,0 +1,23 @@ +// +// yield.hpp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// 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) +// + +#include "coroutine.hpp" + +#ifndef reenter +# define reenter(c) ASIO_CORO_REENTER(c) +#endif + +#ifndef yield +# define yield ASIO_CORO_YIELD +#endif + +#ifndef fork +# define fork ASIO_CORO_FORK +#endif diff --git a/tools/sdk/include/asio/esp_asio_config.h b/tools/sdk/include/asio/esp_asio_config.h new file mode 100644 index 00000000..accccad0 --- /dev/null +++ b/tools/sdk/include/asio/esp_asio_config.h @@ -0,0 +1,45 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef _ESP_ASIO_CONFIG_H_ +#define _ESP_ASIO_CONFIG_H_ + +// +// Enabling exceptions only when they are enabled in menuconfig +// +# include +# ifndef CONFIG_CXX_EXCEPTIONS +# define ASIO_NO_EXCEPTIONS +# endif // CONFIG_CXX_EXCEPTIONS + +// +// LWIP compatifility inet and address macros/functions +// +# define LWIP_COMPAT_SOCKET_INET 1 +# define LWIP_COMPAT_SOCKET_ADDR 1 + +// +// Specific ASIO feature flags +// +# define ASIO_DISABLE_SERIAL_PORT +# define ASIO_SEPARATE_COMPILATION +# define ASIO_STANDALONE +# define ASIO_NO_TYPEID +# define ASIO_DISABLE_SIGNAL +# define ASIO_HAS_PTHREADS +# define ASIO_DISABLE_EPOLL +# define ASIO_DISABLE_EVENTFD +# define ASIO_DISABLE_SIGNAL +# define ASIO_DISABLE_SIGACTION + +#endif // _ESP_ASIO_CONFIG_H_ diff --git a/tools/sdk/include/asio/esp_exception.h b/tools/sdk/include/asio/esp_exception.h new file mode 100644 index 00000000..3c5c0437 --- /dev/null +++ b/tools/sdk/include/asio/esp_exception.h @@ -0,0 +1,39 @@ + +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef _ESP_EXCEPTION_H_ +#define _ESP_EXCEPTION_H_ + +// +// This exception stub is enabled only if exceptions are disabled in menuconfig +// +#if !defined(CONFIG_CXX_EXCEPTIONS) && defined (ASIO_NO_EXCEPTIONS) + +#include "esp_log.h" + +// +// asio exception stub +// +namespace asio { +namespace detail { +template +void throw_exception(const Exception& e) +{ + ESP_LOGE("esp32_asio_exception", "Caught exception: %s!", e.what()); + abort(); +} +}} +#endif // CONFIG_CXX_EXCEPTIONS==1 && defined (ASIO_NO_EXCEPTIONS) + +#endif // _ESP_EXCEPTION_H_ diff --git a/tools/sdk/include/bluedroid/a2d_int.h b/tools/sdk/include/bluedroid/a2d_int.h deleted file mode 100644 index ddd3e964..00000000 --- a/tools/sdk/include/bluedroid/a2d_int.h +++ /dev/null @@ -1,81 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2002-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * 2DP internal header file - * - ******************************************************************************/ -#ifndef A2D_INT_H -#define A2D_INT_H - -#include "stack/a2d_api.h" -#if (A2D_INCLUDED == TRUE) -/***************************************************************************** -** Constants -*****************************************************************************/ -#define A2D_VERSION 0x0102 - -/* Number of attributes in A2D SDP record. */ -#define A2D_NUM_ATTR 6 - -/* Number of protocol elements in protocol element list. */ -#define A2D_NUM_PROTO_ELEMS 2 - -/***************************************************************************** -** Type definitions -*****************************************************************************/ - -/* Control block used by A2D_FindService(). */ -typedef struct { - tA2D_FIND_CBACK *p_cback; /* pointer to application callback */ - tSDP_DISCOVERY_DB *p_db; /* pointer to discovery database */ - UINT16 service_uuid; /* service UUID of search */ -} tA2D_FIND_CB; - -typedef struct { - tA2D_FIND_CB find; /* find service control block */ - UINT8 trace_level; - BOOLEAN use_desc; - UINT16 avdt_sdp_ver; /* AVDTP version */ -} tA2D_CB; - - -#ifdef __cplusplus -extern "C" -{ -#endif - -/****************************************************************************** -** Main Control Block -*******************************************************************************/ -#if A2D_DYNAMIC_MEMORY == FALSE -extern tA2D_CB a2d_cb; -#else -extern tA2D_CB *a2d_cb_ptr; -#define a2d_cb (*a2d_cb_ptr) -#endif - -/* Used only for conformance testing */ -extern void a2d_set_avdt_sdp_ver (UINT16 avdt_sdp_ver); - -#ifdef __cplusplus -} -#endif -#endif ///A2D_INCLUDED == TRUE -#endif /* A2D_INT_H */ diff --git a/tools/sdk/include/bluedroid/aes.h b/tools/sdk/include/bluedroid/aes.h deleted file mode 100644 index 48495bb1..00000000 --- a/tools/sdk/include/bluedroid/aes.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - --------------------------------------------------------------------------- - Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. - - LICENSE TERMS - - The redistribution and use of this software (with or without changes) - is allowed without the payment of fees or royalties provided that: - - 1. source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - 2. binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation; - - 3. the name of the copyright holder is not used to endorse products - built using this software without specific written permission. - - DISCLAIMER - - This software is provided 'as is' with no explicit or implied warranties - in respect of its properties, including, but not limited to, correctness - and/or fitness for purpose. - --------------------------------------------------------------------------- - Issue 09/09/2006 - - This is an AES implementation that uses only 8-bit byte operations on the - cipher state. - */ - -#ifndef AES_H -#define AES_H - -#if 1 -# define AES_ENC_PREKEYED /* AES encryption with a precomputed key schedule */ -#endif -#if 1 -# define AES_DEC_PREKEYED /* AES decryption with a precomputed key schedule */ -#endif -#if 1 -# define AES_ENC_128_OTFK /* AES encryption with 'on the fly' 128 bit keying */ -#endif -#if 1 -# define AES_DEC_128_OTFK /* AES decryption with 'on the fly' 128 bit keying */ -#endif -#if 1 -# define AES_ENC_256_OTFK /* AES encryption with 'on the fly' 256 bit keying */ -#endif -#if 1 -# define AES_DEC_256_OTFK /* AES decryption with 'on the fly' 256 bit keying */ -#endif - -#define N_ROW 4 -#define N_COL 4 -#define N_BLOCK (N_ROW * N_COL) -#define N_MAX_ROUNDS 14 - -typedef unsigned char uint_8t; - -typedef uint_8t return_type; - -/* Warning: The key length for 256 bit keys overflows a byte - (see comment below) -*/ - -typedef uint_8t length_type; - -typedef struct { - uint_8t ksch[(N_MAX_ROUNDS + 1) * N_BLOCK]; - uint_8t rnd; -} aes_context; - -/* The following calls are for a precomputed key schedule - - NOTE: If the length_type used for the key length is an - unsigned 8-bit character, a key length of 256 bits must - be entered as a length in bytes (valid inputs are hence - 128, 192, 16, 24 and 32). -*/ - -#if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED ) - -return_type aes_set_key( const unsigned char key[], - length_type keylen, - aes_context ctx[1] ); -#endif - -#if defined( AES_ENC_PREKEYED ) - -return_type bluedroid_aes_encrypt( const unsigned char in[N_BLOCK], - unsigned char out[N_BLOCK], - const aes_context ctx[1] ); - -return_type aes_cbc_encrypt( const unsigned char *in, - unsigned char *out, - int n_block, - unsigned char iv[N_BLOCK], - const aes_context ctx[1] ); -#endif - -#if defined( AES_DEC_PREKEYED ) - -return_type bluedroid_aes_decrypt( const unsigned char in[N_BLOCK], - unsigned char out[N_BLOCK], - const aes_context ctx[1] ); - -return_type aes_cbc_decrypt( const unsigned char *in, - unsigned char *out, - int n_block, - unsigned char iv[N_BLOCK], - const aes_context ctx[1] ); -#endif - -/* The following calls are for 'on the fly' keying. In this case the - encryption and decryption keys are different. - - The encryption subroutines take a key in an array of bytes in - key[L] where L is 16, 24 or 32 bytes for key lengths of 128, - 192, and 256 bits respectively. They then encrypts the input - data, in[] with this key and put the reult in the output array - out[]. In addition, the second key array, o_key[L], is used - to output the key that is needed by the decryption subroutine - to reverse the encryption operation. The two key arrays can - be the same array but in this case the original key will be - overwritten. - - In the same way, the decryption subroutines output keys that - can be used to reverse their effect when used for encryption. - - Only 128 and 256 bit keys are supported in these 'on the fly' - modes. -*/ - -#if defined( AES_ENC_128_OTFK ) -void bluedroid_aes_encrypt_128( const unsigned char in[N_BLOCK], - unsigned char out[N_BLOCK], - const unsigned char key[N_BLOCK], - uint_8t o_key[N_BLOCK] ); -#endif - -#if defined( AES_DEC_128_OTFK ) -void bluedroid_aes_decrypt_128( const unsigned char in[N_BLOCK], - unsigned char out[N_BLOCK], - const unsigned char key[N_BLOCK], - unsigned char o_key[N_BLOCK] ); -#endif - -#if defined( AES_ENC_256_OTFK ) -void bluedroid_aes_encrypt_256( const unsigned char in[N_BLOCK], - unsigned char out[N_BLOCK], - const unsigned char key[2 * N_BLOCK], - unsigned char o_key[2 * N_BLOCK] ); -#endif - -#if defined( AES_DEC_256_OTFK ) -void bluedroid_aes_decrypt_256( const unsigned char in[N_BLOCK], - unsigned char out[N_BLOCK], - const unsigned char key[2 * N_BLOCK], - unsigned char o_key[2 * N_BLOCK] ); -#endif - -#endif diff --git a/tools/sdk/include/bluedroid/avct_defs.h b/tools/sdk/include/bluedroid/avct_defs.h deleted file mode 100644 index 30b8859f..00000000 --- a/tools/sdk/include/bluedroid/avct_defs.h +++ /dev/null @@ -1,62 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2003-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This contains constants definitions and other information from the AVCTP - * specification. This file is intended for use internal to AVCT only. - * - ******************************************************************************/ -#ifndef AVCT_DEFS_H -#define AVCT_DEFS_H - -/***************************************************************************** -** constants -*****************************************************************************/ - -/* packet type */ -#define AVCT_PKT_TYPE_SINGLE 0 /* single packet */ -#define AVCT_PKT_TYPE_START 1 /* start packet */ -#define AVCT_PKT_TYPE_CONT 2 /* continue packet */ -#define AVCT_PKT_TYPE_END 3 /* end packet */ - -/* header lengths for different packet types */ -#define AVCT_HDR_LEN_SINGLE 3 -#define AVCT_HDR_LEN_START 4 -#define AVCT_HDR_LEN_CONT 1 -#define AVCT_HDR_LEN_END 1 - -/* invalid cr+ipid value */ -#define AVCT_CR_IPID_INVALID 1 - -/***************************************************************************** -** message parsing and building macros -*****************************************************************************/ - -#define AVCT_BLD_HDR(p, label, type, cr_ipid) \ - *(p)++ = ((label) << 4) | ((type) << 2) | (cr_ipid); - -#define AVCT_PRS_HDR(p, label, type, cr_ipid) \ - label = *(p) >> 4; \ - type = (*(p) >> 2) & 3; \ - cr_ipid = *(p)++ & 3; - -#define AVCT_PRS_PKT_TYPE(p, type) \ - type = (*(p) >> 2) & 3; - -#endif /* AVCT_DEFS_H */ diff --git a/tools/sdk/include/bluedroid/avct_int.h b/tools/sdk/include/bluedroid/avct_int.h deleted file mode 100644 index 0a91a96f..00000000 --- a/tools/sdk/include/bluedroid/avct_int.h +++ /dev/null @@ -1,237 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2003-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains interfaces which are internal to AVCTP. - * - ******************************************************************************/ -#ifndef AVCT_INT_H -#define AVCT_INT_H - -#include "stack/avct_api.h" -#include "avct_defs.h" -#include "stack/l2c_api.h" -#include "osi/fixed_queue.h" - -/***************************************************************************** -** constants -*****************************************************************************/ - -/* lcb state machine events */ -enum { - AVCT_LCB_UL_BIND_EVT, - AVCT_LCB_UL_UNBIND_EVT, - AVCT_LCB_UL_MSG_EVT, - AVCT_LCB_INT_CLOSE_EVT, - AVCT_LCB_LL_OPEN_EVT, - AVCT_LCB_LL_CLOSE_EVT, - AVCT_LCB_LL_MSG_EVT, - AVCT_LCB_LL_CONG_EVT -}; - - -/* "states" used for L2CAP channel */ -#define AVCT_CH_IDLE 0 /* No connection */ -#define AVCT_CH_CONN 1 /* Waiting for connection confirm */ -#define AVCT_CH_CFG 2 /* Waiting for configuration complete */ -#define AVCT_CH_OPEN 3 /* Channel opened */ - -/* "no event" indicator used by ccb dealloc */ -#define AVCT_NO_EVT 0xFF - -/***************************************************************************** -** data types -*****************************************************************************/ -/* sub control block type - common data members for tAVCT_LCB and tAVCT_BCB */ -typedef struct { - UINT16 peer_mtu; /* peer l2c mtu */ - UINT16 ch_result; /* L2CAP connection result value */ - UINT16 ch_lcid; /* L2CAP channel LCID */ - UINT8 allocated; /* 0, not allocated. index+1, otherwise. */ - UINT8 state; /* The state machine state */ - UINT8 ch_state; /* L2CAP channel state */ - UINT8 ch_flags; /* L2CAP configuration flags */ -} tAVCT_SCB; - -/* link control block type */ -typedef struct { - UINT16 peer_mtu; /* peer l2c mtu */ - UINT16 ch_result; /* L2CAP connection result value */ - UINT16 ch_lcid; /* L2CAP channel LCID */ - UINT8 allocated; /* 0, not allocated. index+1, otherwise. */ - UINT8 state; /* The state machine state */ - UINT8 ch_state; /* L2CAP channel state */ - UINT8 ch_flags; /* L2CAP configuration flags */ - BT_HDR *p_rx_msg; /* Message being reassembled */ - UINT16 conflict_lcid; /* L2CAP channel LCID */ - BD_ADDR peer_addr; /* BD address of peer */ - fixed_queue_t *tx_q; /* Transmit data buffer queue */ - BOOLEAN cong; /* TRUE, if congested */ -} tAVCT_LCB; - -/* browse control block type */ -typedef struct { - UINT16 peer_mtu; /* peer l2c mtu */ - UINT16 ch_result; /* L2CAP connection result value */ - UINT16 ch_lcid; /* L2CAP channel LCID */ - UINT8 allocated; /* 0, not allocated. index+1, otherwise. */ - UINT8 state; /* The state machine state */ - UINT8 ch_state; /* L2CAP channel state */ - UINT8 ch_flags; /* L2CAP configuration flags */ - BT_HDR *p_tx_msg; /* Message to be sent - in case the browsing channel is not open when MsgReg is called */ - UINT8 ch_close; /* CCB index+1, if CCB initiated channel close */ -} tAVCT_BCB; - -#define AVCT_ALOC_LCB 0x01 -#define AVCT_ALOC_BCB 0x02 -/* connection control block */ -typedef struct { - tAVCT_CC cc; /* parameters from connection creation */ - tAVCT_LCB *p_lcb; /* Associated LCB */ - tAVCT_BCB *p_bcb; /* associated BCB */ - BOOLEAN ch_close; /* Whether CCB initiated channel close */ - UINT8 allocated; /* Whether LCB/BCB is allocated */ -} tAVCT_CCB; - -/* data type associated with UL_MSG_EVT */ -typedef struct { - BT_HDR *p_buf; - tAVCT_CCB *p_ccb; - UINT8 label; - UINT8 cr; -} tAVCT_UL_MSG; - -/* union associated with lcb state machine events */ -typedef union { - tAVCT_UL_MSG ul_msg; - BT_HDR *p_buf; - tAVCT_CCB *p_ccb; - UINT16 result; - BOOLEAN cong; - UINT8 err_code; -} tAVCT_LCB_EVT; - -/* Control block for AVCT */ -typedef struct { - tAVCT_LCB lcb[AVCT_NUM_LINKS]; /* link control blocks */ - tAVCT_BCB bcb[AVCT_NUM_LINKS]; /* browse control blocks */ - tAVCT_CCB ccb[AVCT_NUM_CONN]; /* connection control blocks */ - UINT16 mtu; /* our L2CAP MTU */ - UINT16 mtu_br; /* our L2CAP MTU for the Browsing channel */ - UINT8 trace_level; /* trace level */ -} tAVCT_CB; - -/***************************************************************************** -** function declarations -*****************************************************************************/ - -/* LCB function declarations */ -extern void avct_lcb_event(tAVCT_LCB *p_lcb, UINT8 event, tAVCT_LCB_EVT *p_data); -#if (AVCT_BROWSE_INCLUDED == TRUE) -extern void avct_bcb_event(tAVCT_BCB *p_bcb, UINT8 event, tAVCT_LCB_EVT *p_data); -extern void avct_close_bcb(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern tAVCT_LCB *avct_lcb_by_bcb(tAVCT_BCB *p_bcb); -extern tAVCT_BCB *avct_bcb_by_lcb(tAVCT_LCB *p_lcb); -extern BOOLEAN avct_bcb_last_ccb(tAVCT_BCB *p_bcb, tAVCT_CCB *p_ccb_last); -extern tAVCT_BCB *avct_bcb_by_lcid(UINT16 lcid); -#endif -extern tAVCT_LCB *avct_lcb_by_bd(BD_ADDR bd_addr); -extern tAVCT_LCB *avct_lcb_alloc(BD_ADDR bd_addr); -extern void avct_lcb_dealloc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern tAVCT_LCB *avct_lcb_by_lcid(UINT16 lcid); -extern tAVCT_CCB *avct_lcb_has_pid(tAVCT_LCB *p_lcb, UINT16 pid); -extern BOOLEAN avct_lcb_last_ccb(tAVCT_LCB *p_lcb, tAVCT_CCB *p_ccb_last); - -/* LCB action functions */ -extern void avct_lcb_chnl_open(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern void avct_lcb_unbind_disc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern void avct_lcb_open_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern void avct_lcb_open_fail(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern void avct_lcb_close_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern void avct_lcb_close_cfm(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern void avct_lcb_bind_conn(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern void avct_lcb_chk_disc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern void avct_lcb_chnl_disc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern void avct_lcb_bind_fail(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern void avct_lcb_cong_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern void avct_lcb_discard_msg(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern void avct_lcb_send_msg(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern void avct_lcb_msg_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); -extern void avct_lcb_free_msg_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data); - -/* BCB action functions */ -#if (AVCT_BROWSE_INCLUDED == TRUE) -typedef void (*tAVCT_BCB_ACTION)(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_chnl_open(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_unbind_disc(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_open_ind(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_open_fail(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_close_ind(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_close_cfm(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_bind_conn(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_chk_disc(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_chnl_disc(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_bind_fail(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_cong_ind(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_discard_msg(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_send_msg(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_msg_ind(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); -extern void avct_bcb_free_msg_ind(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); - -extern void avct_bcb_dealloc(tAVCT_BCB *p_bcb, tAVCT_LCB_EVT *p_data); - -extern const tAVCT_BCB_ACTION avct_bcb_action[]; -extern const UINT8 avct_lcb_pkt_type_len[]; -extern const tL2CAP_FCR_OPTS avct_l2c_br_fcr_opts_def; -#endif - -/* CCB function declarations */ -extern tAVCT_CCB *avct_ccb_alloc(tAVCT_CC *p_cc); -extern void avct_ccb_dealloc(tAVCT_CCB *p_ccb, UINT8 event, UINT16 result, BD_ADDR bd_addr); -extern UINT8 avct_ccb_to_idx(tAVCT_CCB *p_ccb); -extern tAVCT_CCB *avct_ccb_by_idx(UINT8 idx); - - -/***************************************************************************** -** global data -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Main control block */ -#if AVCT_DYNAMIC_MEMORY == FALSE -extern tAVCT_CB avct_cb; -#else -extern tAVCT_CB *avct_cb_ptr; -#define avct_cb (*avct_cb_ptr) -#endif - -/* L2CAP callback registration structure */ -extern const tL2CAP_APPL_INFO avct_l2c_appl; -#if (AVCT_BROWSE_INCLUDED == TRUE) -extern const tL2CAP_APPL_INFO avct_l2c_br_appl; -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* AVCT_INT_H */ diff --git a/tools/sdk/include/bluedroid/avdt_defs.h b/tools/sdk/include/bluedroid/avdt_defs.h deleted file mode 100644 index 8b65c52d..00000000 --- a/tools/sdk/include/bluedroid/avdt_defs.h +++ /dev/null @@ -1,208 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2002-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This contains constants definitions and other information from the AVDTP - * specification. This file is intended for use internal to AVDT only. - * - ******************************************************************************/ -#ifndef AVDT_DEFS_H -#define AVDT_DEFS_H -#include "common/bt_target.h" - -#if (AVDT_INCLUDED == TRUE) - -/***************************************************************************** -** constants -*****************************************************************************/ - -/* signalling packet type */ -#define AVDT_PKT_TYPE_SINGLE 0 /* single packet */ -#define AVDT_PKT_TYPE_START 1 /* start packet */ -#define AVDT_PKT_TYPE_CONT 2 /* continue packet */ -#define AVDT_PKT_TYPE_END 3 /* end packet */ - -/* signalling message type */ -#define AVDT_MSG_TYPE_CMD 0 /* command */ -#define AVDT_MSG_TYPE_GRJ 1 /* general reject */ -#define AVDT_MSG_TYPE_RSP 2 /* response accept */ -#define AVDT_MSG_TYPE_REJ 3 /* response reject */ - -/* signalling messages */ -#define AVDT_SIG_DISCOVER 1 /* discover */ -#define AVDT_SIG_GETCAP 2 /* get capabilities */ -#define AVDT_SIG_SETCONFIG 3 /* set configuration */ -#define AVDT_SIG_GETCONFIG 4 /* get configuration */ -#define AVDT_SIG_RECONFIG 5 /* reconfigure */ -#define AVDT_SIG_OPEN 6 /* open */ -#define AVDT_SIG_START 7 /* start */ -#define AVDT_SIG_CLOSE 8 /* close */ -#define AVDT_SIG_SUSPEND 9 /* suspend */ -#define AVDT_SIG_ABORT 10 /* abort */ -#define AVDT_SIG_SECURITY 11 /* security control */ -#define AVDT_SIG_GET_ALLCAP 12 /* get all capabilities */ -#define AVDT_SIG_DELAY_RPT 13 /* delay report */ - -/* maximum signal value */ -#define AVDT_SIG_MAX AVDT_SIG_DELAY_RPT - -/* used for general reject */ -#define AVDT_SIG_NONE 0 - -/* some maximum and minimum sizes of signalling messages */ -#define AVDT_DISCOVER_REQ_MIN 1 -#define AVDT_DISCOVER_REQ_MAX 124 - -/* service category information element field values */ -#define AVDT_CAT_TRANS 1 /* Media Transport */ -#define AVDT_CAT_REPORT 2 /* Reporting */ -#define AVDT_CAT_RECOV 3 /* Recovery */ -#define AVDT_CAT_PROTECT 4 /* Content Protection */ -#define AVDT_CAT_HDRCMP 5 /* Header Compression */ -#define AVDT_CAT_MUX 6 /* Multiplexing */ -#define AVDT_CAT_CODEC 7 /* Media Codec */ -#define AVDT_CAT_DELAY_RPT 8 /* Delay Reporting */ -#define AVDT_CAT_MAX_CUR AVDT_CAT_DELAY_RPT - -/* min/max lengths of service category information elements */ -#define AVDT_LEN_TRANS_MIN 0 -#define AVDT_LEN_REPORT_MIN 0 -#define AVDT_LEN_RECOV_MIN 3 -#define AVDT_LEN_PROTECT_MIN 2 -#define AVDT_LEN_HDRCMP_MIN 1 -#define AVDT_LEN_MUX_MIN 3 -#define AVDT_LEN_CODEC_MIN 2 -#define AVDT_LEN_DELAY_RPT_MIN 0 - -#define AVDT_LEN_TRANS_MAX 0 -#define AVDT_LEN_REPORT_MAX 0 -#define AVDT_LEN_RECOV_MAX 3 -#define AVDT_LEN_PROTECT_MAX 255 -#define AVDT_LEN_HDRCMP_MAX 1 -#define AVDT_LEN_MUX_MAX 7 -#define AVDT_LEN_CODEC_MAX 255 -#define AVDT_LEN_DELAY_RPT_MAX 0 - -/* minimum possible size of configuration or capabilities data */ -#define AVDT_LEN_CFG_MIN 2 - -/* minimum and maximum lengths for different message types */ -#define AVDT_LEN_SINGLE 1 -#define AVDT_LEN_SETCONFIG_MIN 2 -#define AVDT_LEN_RECONFIG_MIN 1 -#define AVDT_LEN_MULTI_MIN 1 -#define AVDT_LEN_SECURITY_MIN 1 -#define AVDT_LEN_DELAY_RPT 3 - -/* header lengths for different packet types */ -#define AVDT_LEN_TYPE_SINGLE 2 /* single packet */ -#define AVDT_LEN_TYPE_START 3 /* start packet */ -#define AVDT_LEN_TYPE_CONT 1 /* continue packet */ -#define AVDT_LEN_TYPE_END 1 /* end packet */ - -/* length of general reject message */ -#define AVDT_LEN_GEN_REJ 2 - -/* recovery service capabilities information elements */ -#define AVDT_RECOV_MRWS_MIN 0x01 /* min value for maximum recovery window */ -#define AVDT_RECOV_MRWS_MAX 0x18 /* max value for maximum recovery window */ -#define AVDT_RECOV_MNMP_MIN 0x01 /* min value for maximum number of media packets */ -#define AVDT_RECOV_MNMP_MAX 0x18 /* max value for maximum number of media packets */ - -/* SEID value range */ -#define AVDT_SEID_MIN 0x01 -#define AVDT_SEID_MAX 0x3E - -/* first byte of media packet header */ -#define AVDT_MEDIA_OCTET1 0x80 - -/* for adaptation layer header */ -#define AVDT_ALH_LCODE_MASK 0x03 /* coding of length field */ -#define AVDT_ALH_LCODE_NONE 0x00 /* No length field present. Take length from l2cap */ -#define AVDT_ALH_LCODE_16BIT 0x01 /* 16bit length field */ -#define AVDT_ALH_LCODE_9BITM0 0x02 /* 9 bit length field, MSB = 0, 8 LSBs in 1 octet following */ -#define AVDT_ALH_LCODE_9BITM1 0x03 /* 9 bit length field, MSB = 1, 8 LSBs in 1 octet following */ - -#define AVDT_ALH_FRAG_MASK 0x04 /* set this for continuation packet */ - -/***************************************************************************** -** message parsing and building macros -*****************************************************************************/ - -#define AVDT_MSG_PRS_HDR(p, lbl, pkt, msg) \ - lbl = *(p) >> 4; \ - pkt = (*(p) >> 2) & 0x03; \ - msg = *(p)++ & 0x03; - -#define AVDT_MSG_PRS_DISC(p, seid, in_use, type, tsep) \ - seid = *(p) >> 2; \ - in_use = (*(p)++ >> 1) & 0x01; \ - type = *(p) >> 4; \ - tsep = (*(p)++ >> 3) & 0x01; - -#define AVDT_MSG_PRS_SIG(p, sig) \ - sig = *(p)++ & 0x3F; - -#define AVDT_MSG_PRS_SEID(p, seid) \ - seid = *(p)++ >> 2; - -#define AVDT_MSG_PRS_PKT_TYPE(p, pkt) \ - pkt = (*(p) >> 2) & 0x03; - -#define AVDT_MSG_PRS_OCTET1(p, o_v, o_p, o_x, o_cc) \ - o_v = *(p) >> 6; \ - o_p = (*(p) >> 5) & 0x01; \ - o_x = (*(p) >> 4) & 0x01; \ - o_cc = *(p)++ & 0x0F; - -#define AVDT_MSG_PRS_RPT_OCTET1(p, o_v, o_p, o_cc) \ - o_v = *(p) >> 6; \ - o_p = (*(p) >> 5) & 0x01; \ - o_cc = *(p)++ & 0x1F; - -#define AVDT_MSG_PRS_M_PT(p, m_pt, marker) \ - marker = *(p) >> 7; \ - m_pt = *(p)++ & 0x7F; - -#define AVDT_MSG_BLD_HDR(p, lbl, pkt, msg) \ - *(p)++ = (UINT8) ((lbl) << 4) | ((pkt) << 2) | (msg); - -#define AVDT_MSG_BLD_DISC(p, seid, in_use, type, tsep) \ - *(p)++ = (UINT8) (((seid) << 2) | ((in_use) << 1)); \ - *(p)++ = (UINT8) (((type) << 4) | ((tsep) << 3)); - -#define AVDT_MSG_BLD_SIG(p, sig) \ - *(p)++ = (UINT8) (sig); - -#define AVDT_MSG_BLD_SEID(p, seid) \ - *(p)++ = (UINT8) ((seid) << 2); - -#define AVDT_MSG_BLD_ERR(p, err) \ - *(p)++ = (UINT8) (err); - -#define AVDT_MSG_BLD_PARAM(p, param) \ - *(p)++ = (UINT8) (param); - -#define AVDT_MSG_BLD_NOSP(p, nosp) \ - *(p)++ = (UINT8) (nosp); - -#endif ///AVRC_INCLUDED == TRUE - -#endif /* AVDT_DEFS_H */ - diff --git a/tools/sdk/include/bluedroid/avdt_int.h b/tools/sdk/include/bluedroid/avdt_int.h deleted file mode 100644 index 06bedc35..00000000 --- a/tools/sdk/include/bluedroid/avdt_int.h +++ /dev/null @@ -1,748 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2002-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains interfaces which are internal to AVDTP. - * - ******************************************************************************/ -#ifndef AVDT_INT_H -#define AVDT_INT_H - -#include "stack/avdt_api.h" -#include "stack/avdtc_api.h" -#include "avdt_defs.h" -#include "stack/l2c_api.h" -#include "stack/btm_api.h" -#include "osi/fixed_queue.h" - -#if (AVRC_INCLUDED == TRUE) - -#ifndef AVDT_DEBUG -#define AVDT_DEBUG FALSE -#endif - -/***************************************************************************** -** constants -*****************************************************************************/ - -/* channel types */ -enum { - AVDT_CHAN_SIG, /* signaling channel */ - AVDT_CHAN_MEDIA, /* media channel */ -#if AVDT_REPORTING == TRUE - AVDT_CHAN_REPORT, /* reporting channel */ -#endif - AVDT_CHAN_NUM_TYPES -}; - -/* protocol service capabilities of this AVDTP implementation */ -/* for now multiplexing will be used only for fragmentation */ -#if ((AVDT_MULTIPLEXING == TRUE) && (AVDT_REPORTING == TRUE)) -#define AVDT_PSC (AVDT_PSC_TRANS | AVDT_PSC_MUX | AVDT_PSC_REPORT | AVDT_PSC_DELAY_RPT) -#define AVDT_LEG_PSC (AVDT_PSC_TRANS | AVDT_PSC_MUX | AVDT_PSC_REPORT) -#else /* AVDT_MULTIPLEXING && AVDT_REPORTING */ - -#if (AVDT_MULTIPLEXING == TRUE) -#define AVDT_PSC (AVDT_PSC_TRANS | AVDT_PSC_MUX | AVDT_PSC_DELAY_RPT) -#define AVDT_LEG_PSC (AVDT_PSC_TRANS | AVDT_PSC_MUX) -#else /* AVDT_MULTIPLEXING */ - -#if (AVDT_REPORTING == TRUE) -#define AVDT_PSC (AVDT_PSC_TRANS | AVDT_PSC_REPORT | AVDT_PSC_DELAY_RPT) -#define AVDT_LEG_PSC (AVDT_PSC_TRANS | AVDT_PSC_REPORT) -#else /* AVDT_REPORTING */ -#define AVDT_PSC (AVDT_PSC_TRANS | AVDT_PSC_DELAY_RPT) -#define AVDT_LEG_PSC (AVDT_PSC_TRANS) -#endif /* AVDT_REPORTING */ - -#endif /* AVDT_MULTIPLEXING */ - -#endif /* AVDT_MULTIPLEXING && AVDT_REPORTING */ - -/* initiator/acceptor signaling roles */ -#define AVDT_CLOSE_ACP 0 -#define AVDT_CLOSE_INT 1 -#define AVDT_OPEN_ACP 2 -#define AVDT_OPEN_INT 3 - -/* states for avdt_scb_verify */ -#define AVDT_VERIFY_OPEN 0 -#define AVDT_VERIFY_STREAMING 1 -#define AVDT_VERIFY_SUSPEND 2 -#define AVDT_VERIFY_START 3 - -/* to distinguish CCB events from SCB events */ -#define AVDT_CCB_MKR 0x80 - -/* offset where AVDTP signaling message header starts in message */ -#define AVDT_HDR_OFFSET (L2CAP_MIN_OFFSET + AVDT_NUM_SEPS) - -/* offset where AVDTP signaling message content starts; -** use the size of a start header since it's the largest possible -** layout of signaling message in a buffer is: -** -** | BT_HDR | SCB handles | L2CAP + HCI header | AVDTP header | data ... | -** -** Note that we "hide" the scb handles at the top of the message buffer. -*/ -#define AVDT_MSG_OFFSET (L2CAP_MIN_OFFSET + AVDT_NUM_SEPS + AVDT_LEN_TYPE_START) - -/* scb transport channel connect timeout value */ -#define AVDT_SCB_TC_CONN_TOUT 10 - -/* scb transport channel disconnect timeout value */ -#define AVDT_SCB_TC_DISC_TOUT 10 - -/* maximum number of command retransmissions */ -#ifndef AVDT_RET_MAX -#define AVDT_RET_MAX 1 -#endif - - -/* ccb state machine states */ -enum { - AVDT_CCB_IDLE_ST, - AVDT_CCB_OPENING_ST, - AVDT_CCB_OPEN_ST, - AVDT_CCB_CLOSING_ST -}; - -/* state machine action enumeration list */ -enum { - AVDT_CCB_CHAN_OPEN, - AVDT_CCB_CHAN_CLOSE, - AVDT_CCB_CHK_CLOSE, - AVDT_CCB_HDL_DISCOVER_CMD, - AVDT_CCB_HDL_DISCOVER_RSP, - AVDT_CCB_HDL_GETCAP_CMD, - AVDT_CCB_HDL_GETCAP_RSP, - AVDT_CCB_HDL_START_CMD, - AVDT_CCB_HDL_START_RSP, - AVDT_CCB_HDL_SUSPEND_CMD, - AVDT_CCB_HDL_SUSPEND_RSP, - AVDT_CCB_SND_DISCOVER_CMD, - AVDT_CCB_SND_DISCOVER_RSP, - AVDT_CCB_SND_GETCAP_CMD, - AVDT_CCB_SND_GETCAP_RSP, - AVDT_CCB_SND_START_CMD, - AVDT_CCB_SND_START_RSP, - AVDT_CCB_SND_SUSPEND_CMD, - AVDT_CCB_SND_SUSPEND_RSP, - AVDT_CCB_CLEAR_CMDS, - AVDT_CCB_CMD_FAIL, - AVDT_CCB_FREE_CMD, - AVDT_CCB_CONG_STATE, - AVDT_CCB_RET_CMD, - AVDT_CCB_SND_CMD, - AVDT_CCB_SND_MSG, - AVDT_CCB_SET_RECONN, - AVDT_CCB_CLR_RECONN, - AVDT_CCB_CHK_RECONN, - AVDT_CCB_CHK_TIMER, - AVDT_CCB_SET_CONN, - AVDT_CCB_SET_DISCONN, - AVDT_CCB_DO_DISCONN, - AVDT_CCB_LL_CLOSED, - AVDT_CCB_LL_OPENED, - AVDT_CCB_DEALLOC, - AVDT_CCB_NUM_ACTIONS -}; - -#define AVDT_CCB_IGNORE AVDT_CCB_NUM_ACTIONS - -/* ccb state machine events */ -enum { - AVDT_CCB_API_DISCOVER_REQ_EVT, - AVDT_CCB_API_GETCAP_REQ_EVT, - AVDT_CCB_API_START_REQ_EVT, - AVDT_CCB_API_SUSPEND_REQ_EVT, - AVDT_CCB_API_DISCOVER_RSP_EVT, - AVDT_CCB_API_GETCAP_RSP_EVT, - AVDT_CCB_API_START_RSP_EVT, - AVDT_CCB_API_SUSPEND_RSP_EVT, - AVDT_CCB_API_CONNECT_REQ_EVT, - AVDT_CCB_API_DISCONNECT_REQ_EVT, - AVDT_CCB_MSG_DISCOVER_CMD_EVT, - AVDT_CCB_MSG_GETCAP_CMD_EVT, - AVDT_CCB_MSG_START_CMD_EVT, - AVDT_CCB_MSG_SUSPEND_CMD_EVT, - AVDT_CCB_MSG_DISCOVER_RSP_EVT, - AVDT_CCB_MSG_GETCAP_RSP_EVT, - AVDT_CCB_MSG_START_RSP_EVT, - AVDT_CCB_MSG_SUSPEND_RSP_EVT, - AVDT_CCB_RCVRSP_EVT, - AVDT_CCB_SENDMSG_EVT, - AVDT_CCB_RET_TOUT_EVT, - AVDT_CCB_RSP_TOUT_EVT, - AVDT_CCB_IDLE_TOUT_EVT, - AVDT_CCB_UL_OPEN_EVT, - AVDT_CCB_UL_CLOSE_EVT, - AVDT_CCB_LL_OPEN_EVT, - AVDT_CCB_LL_CLOSE_EVT, - AVDT_CCB_LL_CONG_EVT -}; - - -/* scb state machine states; these state values are private to this module so -** the scb state cannot be read or set by actions functions -*/ -enum { - AVDT_SCB_IDLE_ST, - AVDT_SCB_CONF_ST, - AVDT_SCB_OPENING_ST, - AVDT_SCB_OPEN_ST, - AVDT_SCB_STREAM_ST, - AVDT_SCB_CLOSING_ST -}; - -/* state machine action enumeration list */ -enum { - AVDT_SCB_HDL_ABORT_CMD, - AVDT_SCB_HDL_ABORT_RSP, - AVDT_SCB_HDL_CLOSE_CMD, - AVDT_SCB_HDL_CLOSE_RSP, - AVDT_SCB_HDL_GETCONFIG_CMD, - AVDT_SCB_HDL_GETCONFIG_RSP, - AVDT_SCB_HDL_OPEN_CMD, - AVDT_SCB_HDL_OPEN_REJ, - AVDT_SCB_HDL_OPEN_RSP, - AVDT_SCB_HDL_PKT, - AVDT_SCB_DROP_PKT, - AVDT_SCB_HDL_RECONFIG_CMD, - AVDT_SCB_HDL_RECONFIG_RSP, - AVDT_SCB_HDL_SECURITY_CMD, - AVDT_SCB_HDL_SECURITY_RSP, - AVDT_SCB_HDL_SETCONFIG_CMD, - AVDT_SCB_HDL_SETCONFIG_REJ, - AVDT_SCB_HDL_SETCONFIG_RSP, - AVDT_SCB_HDL_START_CMD, - AVDT_SCB_HDL_START_RSP, - AVDT_SCB_HDL_SUSPEND_CMD, - AVDT_SCB_HDL_SUSPEND_RSP, - AVDT_SCB_HDL_TC_CLOSE, -#if AVDT_REPORTING == TRUE - AVDT_SCB_HDL_TC_CLOSE_STO, -#endif - AVDT_SCB_HDL_TC_OPEN, -#if AVDT_REPORTING == TRUE - AVDT_SCB_HDL_TC_OPEN_STO, -#endif - AVDT_SCB_SND_DELAY_RPT_REQ, - AVDT_SCB_HDL_DELAY_RPT_CMD, - AVDT_SCB_HDL_DELAY_RPT_RSP, - AVDT_SCB_HDL_WRITE_REQ, - AVDT_SCB_SND_ABORT_REQ, - AVDT_SCB_SND_ABORT_RSP, - AVDT_SCB_SND_CLOSE_REQ, - AVDT_SCB_SND_STREAM_CLOSE, - AVDT_SCB_SND_CLOSE_RSP, - AVDT_SCB_SND_GETCONFIG_REQ, - AVDT_SCB_SND_GETCONFIG_RSP, - AVDT_SCB_SND_OPEN_REQ, - AVDT_SCB_SND_OPEN_RSP, - AVDT_SCB_SND_RECONFIG_REQ, - AVDT_SCB_SND_RECONFIG_RSP, - AVDT_SCB_SND_SECURITY_REQ, - AVDT_SCB_SND_SECURITY_RSP, - AVDT_SCB_SND_SETCONFIG_REQ, - AVDT_SCB_SND_SETCONFIG_REJ, - AVDT_SCB_SND_SETCONFIG_RSP, - AVDT_SCB_SND_TC_CLOSE, - AVDT_SCB_CB_ERR, - AVDT_SCB_CONG_STATE, - AVDT_SCB_REJ_STATE, - AVDT_SCB_REJ_IN_USE, - AVDT_SCB_REJ_NOT_IN_USE, - AVDT_SCB_SET_REMOVE, - AVDT_SCB_FREE_PKT, - AVDT_SCB_CLR_PKT, - AVDT_SCB_CHK_SND_PKT, - AVDT_SCB_TC_TIMER, - AVDT_SCB_CLR_VARS, - AVDT_SCB_DEALLOC, - AVDT_SCB_NUM_ACTIONS -}; - -#define AVDT_SCB_IGNORE AVDT_SCB_NUM_ACTIONS - -/* scb state machine events */ -enum { - AVDT_SCB_API_REMOVE_EVT, - AVDT_SCB_API_WRITE_REQ_EVT, - AVDT_SCB_API_GETCONFIG_REQ_EVT, - AVDT_SCB_API_DELAY_RPT_REQ_EVT, - AVDT_SCB_API_SETCONFIG_REQ_EVT, - AVDT_SCB_API_OPEN_REQ_EVT, - AVDT_SCB_API_CLOSE_REQ_EVT, - AVDT_SCB_API_RECONFIG_REQ_EVT, - AVDT_SCB_API_SECURITY_REQ_EVT, - AVDT_SCB_API_ABORT_REQ_EVT, - AVDT_SCB_API_GETCONFIG_RSP_EVT, - AVDT_SCB_API_SETCONFIG_RSP_EVT, - AVDT_SCB_API_SETCONFIG_REJ_EVT, - AVDT_SCB_API_OPEN_RSP_EVT, - AVDT_SCB_API_CLOSE_RSP_EVT, - AVDT_SCB_API_RECONFIG_RSP_EVT, - AVDT_SCB_API_SECURITY_RSP_EVT, - AVDT_SCB_API_ABORT_RSP_EVT, - AVDT_SCB_MSG_SETCONFIG_CMD_EVT, - AVDT_SCB_MSG_GETCONFIG_CMD_EVT, - AVDT_SCB_MSG_OPEN_CMD_EVT, - AVDT_SCB_MSG_START_CMD_EVT, - AVDT_SCB_MSG_SUSPEND_CMD_EVT, - AVDT_SCB_MSG_CLOSE_CMD_EVT, - AVDT_SCB_MSG_ABORT_CMD_EVT, - AVDT_SCB_MSG_RECONFIG_CMD_EVT, - AVDT_SCB_MSG_SECURITY_CMD_EVT, - AVDT_SCB_MSG_DELAY_RPT_CMD_EVT, - AVDT_SCB_MSG_DELAY_RPT_RSP_EVT, - AVDT_SCB_MSG_SETCONFIG_RSP_EVT, - AVDT_SCB_MSG_GETCONFIG_RSP_EVT, - AVDT_SCB_MSG_OPEN_RSP_EVT, - AVDT_SCB_MSG_START_RSP_EVT, - AVDT_SCB_MSG_SUSPEND_RSP_EVT, - AVDT_SCB_MSG_CLOSE_RSP_EVT, - AVDT_SCB_MSG_ABORT_RSP_EVT, - AVDT_SCB_MSG_RECONFIG_RSP_EVT, - AVDT_SCB_MSG_SECURITY_RSP_EVT, - AVDT_SCB_MSG_SETCONFIG_REJ_EVT, - AVDT_SCB_MSG_OPEN_REJ_EVT, - AVDT_SCB_MSG_START_REJ_EVT, - AVDT_SCB_MSG_SUSPEND_REJ_EVT, - AVDT_SCB_TC_TOUT_EVT, - AVDT_SCB_TC_OPEN_EVT, - AVDT_SCB_TC_CLOSE_EVT, - AVDT_SCB_TC_CONG_EVT, - AVDT_SCB_TC_DATA_EVT, - AVDT_SCB_CC_CLOSE_EVT -}; - -/* adaption layer number of stream routing table entries */ -#if AVDT_REPORTING == TRUE -/* 2 channels(1 media, 1 report) for each SEP and one for signalling */ -#define AVDT_NUM_RT_TBL ((AVDT_NUM_SEPS<<1) + 1) -#else -#define AVDT_NUM_RT_TBL (AVDT_NUM_SEPS + 1) -#endif - -/* adaption layer number of transport channel table entries - moved to target.h -#define AVDT_NUM_TC_TBL (AVDT_NUM_SEPS + AVDT_NUM_LINKS) */ - -/* "states" used in transport channel table */ -#define AVDT_AD_ST_UNUSED 0 /* Unused - unallocated */ -#define AVDT_AD_ST_IDLE 1 /* No connection */ -#define AVDT_AD_ST_ACP 2 /* Waiting to accept a connection */ -#define AVDT_AD_ST_INT 3 /* Initiating a connection */ -#define AVDT_AD_ST_CONN 4 /* Waiting for connection confirm */ -#define AVDT_AD_ST_CFG 5 /* Waiting for configuration complete */ -#define AVDT_AD_ST_OPEN 6 /* Channel opened */ -#define AVDT_AD_ST_SEC_INT 7 /* Security process as INT */ -#define AVDT_AD_ST_SEC_ACP 8 /* Security process as ACP */ - -/* Configuration flags. tAVDT_TC_TBL.cfg_flags */ -#define AVDT_L2C_CFG_IND_DONE (1<<0) -#define AVDT_L2C_CFG_CFM_DONE (1<<1) -#define AVDT_L2C_CFG_CONN_INT (1<<2) -#define AVDT_L2C_CFG_CONN_ACP (1<<3) - - -/* result code for avdt_ad_write_req() (L2CA_DataWrite()) */ -#define AVDT_AD_FAILED L2CAP_DW_FAILED /* FALSE */ -#define AVDT_AD_SUCCESS L2CAP_DW_SUCCESS /* TRUE */ -#define AVDT_AD_CONGESTED L2CAP_DW_CONGESTED /* 2 */ - -/***************************************************************************** -** data types -*****************************************************************************/ - -/* msg union of all message parameter types */ -typedef union { - tAVDT_EVT_HDR hdr; - tAVDT_EVT_HDR single; - tAVDT_SETCONFIG config_cmd; - tAVDT_CONFIG reconfig_cmd; - tAVDT_MULTI multi; - tAVDT_SECURITY security_cmd; - tAVDT_DISCOVER discover_rsp; - tAVDT_CONFIG svccap; - tAVDT_SECURITY security_rsp; - tAVDT_DELAY_RPT delay_rpt_cmd; -} tAVDT_MSG; - -/* data type for AVDT_CCB_API_DISCOVER_REQ_EVT */ -typedef struct { - tAVDT_CTRL_CBACK *p_cback; - tAVDT_SEP_INFO *p_sep_info; - UINT8 num_seps; -} tAVDT_CCB_API_DISCOVER; - -/* data type for AVDT_CCB_API_GETCAP_REQ_EVT */ -typedef struct { - tAVDT_EVT_HDR single; - tAVDT_CTRL_CBACK *p_cback; - tAVDT_CFG *p_cfg; -} tAVDT_CCB_API_GETCAP; - -/* data type for AVDT_CCB_API_CONNECT_REQ_EVT */ -typedef struct { - tAVDT_CTRL_CBACK *p_cback; - UINT8 sec_mask; -} tAVDT_CCB_API_CONNECT; - -/* data type for AVDT_CCB_API_DISCONNECT_REQ_EVT */ -typedef struct { - tAVDT_CTRL_CBACK *p_cback; -} tAVDT_CCB_API_DISCONNECT; - -/* union associated with ccb state machine events */ -typedef union { - tAVDT_CCB_API_DISCOVER discover; - tAVDT_CCB_API_GETCAP getcap; - tAVDT_CCB_API_CONNECT connect; - tAVDT_CCB_API_DISCONNECT disconnect; - tAVDT_MSG msg; - BOOLEAN llcong; - UINT8 err_code; -} tAVDT_CCB_EVT; - -/* channel control block type */ -typedef struct { - BD_ADDR peer_addr; /* BD address of peer */ - TIMER_LIST_ENT timer_entry; /* CCB timer list entry */ - fixed_queue_t *cmd_q; /* Queue for outgoing command messages */ - fixed_queue_t *rsp_q; /* Queue for outgoing response and reject messages */ - tAVDT_CTRL_CBACK *proc_cback; /* Procedure callback function */ - tAVDT_CTRL_CBACK *p_conn_cback; /* Connection/disconnection callback function */ - void *p_proc_data; /* Pointer to data storage for procedure */ - BT_HDR *p_curr_cmd; /* Current command being sent awaiting response */ - BT_HDR *p_curr_msg; /* Current message being sent */ - BT_HDR *p_rx_msg; /* Current message being received */ - BOOLEAN allocated; /* Whether ccb is allocated */ - UINT8 state; /* The CCB state machine state */ - BOOLEAN ll_opened; /* TRUE if LL is opened */ - BOOLEAN proc_busy; /* TRUE when a discover or get capabilities procedure in progress */ - UINT8 proc_param; /* Procedure parameter; either SEID for get capabilities or number of SEPS for discover */ - BOOLEAN cong; /* Whether signaling channel is congested */ - UINT8 label; /* Message header "label" (sequence number) */ - BOOLEAN reconn; /* If TRUE, reinitiate connection after transitioning from CLOSING to IDLE state */ - UINT8 ret_count; /* Command retransmission count */ - UINT8 disc_rsn; /* disconnection reason */ -} tAVDT_CCB; - -/* type for action functions */ -typedef void (*tAVDT_CCB_ACTION)(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); - -/* type for AVDT_SCB_API_WRITE_REQ_EVT */ -typedef struct { - BT_HDR *p_buf; - UINT32 time_stamp; -#if AVDT_MULTIPLEXING == TRUE - fixed_queue_t *frag_q; /* Queue for outgoing media fragments. p_buf should be 0 */ - UINT8 *p_data; - UINT32 data_len; -#endif - UINT8 m_pt; - tAVDT_DATA_OPT_MASK opt; -} tAVDT_SCB_APIWRITE; - -/* type for AVDT_SCB_TC_CLOSE_EVT */ -typedef struct { - UINT8 old_tc_state; /* channel state before closed */ - UINT8 tcid; /* TCID */ - UINT8 type; /* channel type */ - UINT8 disc_rsn; /* disconnection reason */ -} tAVDT_SCB_TC_CLOSE; - -/* type for scb event data */ -typedef union { - tAVDT_MSG msg; - tAVDT_SCB_APIWRITE apiwrite; - tAVDT_DELAY_RPT apidelay; - tAVDT_OPEN open; - tAVDT_SCB_TC_CLOSE close; - BOOLEAN llcong; - BT_HDR *p_pkt; -} tAVDT_SCB_EVT; - -/* stream control block type */ -typedef struct { - tAVDT_CS cs; /* stream creation struct */ - tAVDT_CFG curr_cfg; /* current configuration */ - tAVDT_CFG req_cfg; /* requested configuration */ - TIMER_LIST_ENT timer_entry; /* timer entry */ - BT_HDR *p_pkt; /* packet waiting to be sent */ - tAVDT_CCB *p_ccb; /* ccb associated with this scb */ - UINT16 media_seq; /* media packet sequence number */ - BOOLEAN allocated; /* whether scb is allocated or unused */ - BOOLEAN in_use; /* whether stream being used by peer */ - BOOLEAN sink_activated; /* A2DP Sink activated/de-activated from Application */ - UINT8 role; /* initiator/acceptor role in current procedure */ - BOOLEAN remove; /* whether CB is marked for removal */ - UINT8 state; /* state machine state */ - UINT8 peer_seid; /* SEID of peer stream */ - UINT8 curr_evt; /* current event; set only by state machine */ - BOOLEAN cong; /* Whether media transport channel is congested */ - UINT8 close_code; /* Error code received in close response */ -#if AVDT_MULTIPLEXING == TRUE - fixed_queue_t *frag_q; /* Queue for outgoing media fragments */ - UINT32 frag_off; /* length of already received media fragments */ - UINT32 frag_org_len; /* original length before fragmentation of receiving media packet */ - UINT8 *p_next_frag; /* next fragment to send */ - UINT8 *p_media_buf; /* buffer for media packet assigned by AVDT_SetMediaBuf */ - UINT32 media_buf_len; /* length of buffer for media packet assigned by AVDT_SetMediaBuf */ -#endif -} tAVDT_SCB; - -/* type for action functions */ -typedef void (*tAVDT_SCB_ACTION)(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); - -/* adaption layer type for transport channel table */ -typedef struct { - UINT16 peer_mtu; /* L2CAP mtu of the peer device */ - UINT16 my_mtu; /* Our MTU for this channel */ - UINT16 my_flush_to; /* Our flush timeout for this channel */ - UINT16 lcid; - UINT8 tcid; /* transport channel id */ - UINT8 ccb_idx; /* channel control block associated with this tc */ - UINT8 state; /* transport channel state */ - UINT8 cfg_flags; /* L2CAP configuration flags */ - UINT8 id; -} tAVDT_TC_TBL; - -/* adaption layer type for stream routing table */ -typedef struct { - UINT16 lcid; /* L2CAP LCID of the associated transport channel */ - UINT8 scb_hdl; /* stream control block associated with this tc */ -} tAVDT_RT_TBL; - - -/* adaption layer control block */ -typedef struct { - tAVDT_RT_TBL rt_tbl[AVDT_NUM_LINKS][AVDT_NUM_RT_TBL]; - tAVDT_TC_TBL tc_tbl[AVDT_NUM_TC_TBL]; - UINT8 lcid_tbl[MAX_L2CAP_CHANNELS]; /* map LCID to tc_tbl index */ -} tAVDT_AD; - -/* Control block for AVDT */ -typedef struct { - tAVDT_REG rcb; /* registration control block */ - tAVDT_CCB ccb[AVDT_NUM_LINKS]; /* channel control blocks */ - tAVDT_SCB scb[AVDT_NUM_SEPS]; /* stream control blocks */ - tAVDT_AD ad; /* adaption layer control block */ - tAVDTC_CTRL_CBACK *p_conf_cback; /* conformance callback function */ - tAVDT_CCB_ACTION *p_ccb_act; /* pointer to CCB action functions */ - tAVDT_SCB_ACTION *p_scb_act; /* pointer to SCB action functions */ - tAVDT_CTRL_CBACK *p_conn_cback; /* connection callback function */ - UINT8 trace_level; /* trace level */ -} tAVDT_CB; - - -/***************************************************************************** -** function declarations -*****************************************************************************/ - -/* CCB function declarations */ -extern void avdt_ccb_init(void); -extern void avdt_ccb_event(tAVDT_CCB *p_ccb, UINT8 event, tAVDT_CCB_EVT *p_data); -extern tAVDT_CCB *avdt_ccb_by_bd(BD_ADDR bd_addr); -extern tAVDT_CCB *avdt_ccb_alloc(BD_ADDR bd_addr); -extern void avdt_ccb_dealloc(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern UINT8 avdt_ccb_to_idx(tAVDT_CCB *p_ccb); -extern tAVDT_CCB *avdt_ccb_by_idx(UINT8 idx); - -/* CCB action functions */ -extern void avdt_ccb_chan_open(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_chan_close(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_chk_close(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_hdl_discover_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_hdl_discover_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_hdl_getcap_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_hdl_getcap_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_hdl_start_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_hdl_start_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_hdl_suspend_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_hdl_suspend_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_snd_discover_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_snd_discover_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_snd_getcap_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_snd_getcap_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_snd_start_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_snd_start_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_snd_suspend_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_snd_suspend_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_clear_cmds(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_cmd_fail(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_free_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_cong_state(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_ret_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_snd_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_snd_msg(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_set_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_clr_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_chk_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_chk_timer(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_set_conn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_set_disconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_do_disconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_ll_closed(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); -extern void avdt_ccb_ll_opened(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data); - -/* SCB function prototypes */ -extern void avdt_scb_event(tAVDT_SCB *p_scb, UINT8 event, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_init(void); -extern tAVDT_SCB *avdt_scb_alloc(tAVDT_CS *p_cs); -extern void avdt_scb_dealloc(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern UINT8 avdt_scb_to_hdl(tAVDT_SCB *p_scb); -extern tAVDT_SCB *avdt_scb_by_hdl(UINT8 hdl); -extern UINT8 avdt_scb_verify(tAVDT_CCB *p_ccb, UINT8 state, UINT8 *p_seid, UINT16 num_seid, UINT8 *p_err_code); -extern void avdt_scb_peer_seid_list(tAVDT_MULTI *p_multi); -extern UINT32 avdt_scb_gen_ssrc(tAVDT_SCB *p_scb); - -/* SCB action functions */ -extern void avdt_scb_hdl_abort_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_abort_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_close_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_close_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_getconfig_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_getconfig_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_open_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_open_rej(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_open_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_pkt(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_drop_pkt(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_reconfig_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_reconfig_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_security_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_security_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_setconfig_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_setconfig_rej(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_setconfig_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_start_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_start_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_suspend_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_suspend_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_delay_rpt_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_delay_rpt_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_delay_rpt_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_tc_close(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_tc_open(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_tc_close_sto(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_tc_open_sto(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_hdl_write_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_abort_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_abort_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_close_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_stream_close(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_close_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_getconfig_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_getconfig_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_open_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_open_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_reconfig_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_reconfig_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_security_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_security_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_setconfig_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_setconfig_rej(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_setconfig_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_snd_tc_close(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_cb_err(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_cong_state(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_rej_state(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_rej_in_use(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_rej_not_in_use(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_set_remove(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_free_pkt(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_chk_snd_pkt(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_clr_pkt(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_tc_timer(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_clr_vars(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); -extern void avdt_scb_queue_frags(tAVDT_SCB *p_scb, UINT8 **pp_data, UINT32 *p_data_len, fixed_queue_t *pq); - -/* msg function declarations */ -extern BOOLEAN avdt_msg_send(tAVDT_CCB *p_ccb, BT_HDR *p_msg); -extern void avdt_msg_send_cmd(tAVDT_CCB *p_ccb, void *p_scb, UINT8 sig_id, tAVDT_MSG *p_params); -extern void avdt_msg_send_rsp(tAVDT_CCB *p_ccb, UINT8 sig_id, tAVDT_MSG *p_params); -extern void avdt_msg_send_rej(tAVDT_CCB *p_ccb, UINT8 sig_id, tAVDT_MSG *p_params); -extern void avdt_msg_send_grej(tAVDT_CCB *p_ccb, UINT8 sig_id, tAVDT_MSG *p_params); -extern void avdt_msg_ind(tAVDT_CCB *p_ccb, BT_HDR *p_buf); - -/* adaption layer function declarations */ -extern void avdt_ad_init(void); -extern UINT8 avdt_ad_type_to_tcid(UINT8 type, tAVDT_SCB *p_scb); -extern tAVDT_TC_TBL *avdt_ad_tc_tbl_by_st(UINT8 type, tAVDT_CCB *p_ccb, UINT8 state); -extern tAVDT_TC_TBL *avdt_ad_tc_tbl_by_lcid(UINT16 lcid); -extern tAVDT_TC_TBL *avdt_ad_tc_tbl_alloc(tAVDT_CCB *p_ccb); -extern UINT8 avdt_ad_tc_tbl_to_idx(tAVDT_TC_TBL *p_tbl); -extern void avdt_ad_tc_close_ind(tAVDT_TC_TBL *p_tbl, UINT16 reason); -extern void avdt_ad_tc_open_ind(tAVDT_TC_TBL *p_tbl); -extern void avdt_ad_tc_cong_ind(tAVDT_TC_TBL *p_tbl, BOOLEAN is_congested); -extern void avdt_ad_tc_data_ind(tAVDT_TC_TBL *p_tbl, BT_HDR *p_buf); -extern tAVDT_TC_TBL *avdt_ad_tc_tbl_by_type(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb); -extern UINT8 avdt_ad_write_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb, BT_HDR *p_buf); -extern void avdt_ad_open_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb, UINT8 role); -extern void avdt_ad_close_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb); - -extern void avdt_process_timeout(TIMER_LIST_ENT *p_tle); - -/***************************************************************************** -** macros -*****************************************************************************/ - -/* we store the scb and the label in the layer_specific field of the -** current cmd -*/ -#define AVDT_BLD_LAYERSPEC(ls, msg, label) \ - ls = (((label) << 4) | (msg)) - -#define AVDT_LAYERSPEC_LABEL(ls) ((UINT8)((ls) >> 4)) - -#define AVDT_LAYERSPEC_MSG(ls) ((UINT8)((ls) & 0x000F)) - -/***************************************************************************** -** global data -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/****************************************************************************** -** Main Control Block -*******************************************************************************/ -#if AVDT_DYNAMIC_MEMORY == FALSE -extern tAVDT_CB avdt_cb; -#else -extern tAVDT_CB *avdt_cb_ptr; -#define avdt_cb (*avdt_cb_ptr) -#endif - - -/* L2CAP callback registration structure */ -extern const tL2CAP_APPL_INFO avdt_l2c_appl; - -/* reject message event lookup table */ -extern const UINT8 avdt_msg_rej_2_evt[]; -#ifdef __cplusplus -} -#endif - -#endif ///AVRC_INCLUDED == TRUE - -#endif /* AVDT_INT_H */ diff --git a/tools/sdk/include/bluedroid/avrc_int.h b/tools/sdk/include/bluedroid/avrc_int.h deleted file mode 100644 index f13e0ccb..00000000 --- a/tools/sdk/include/bluedroid/avrc_int.h +++ /dev/null @@ -1,158 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2003-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * VRCP internal header file. - * - ******************************************************************************/ - - -#ifndef AVRC_INT_H -#define AVRC_INT_H - -#include "avct_defs.h" -#include "stack/avrc_api.h" - -#if (AVRC_INCLUDED == TRUE) -/* DEBUG FLAGS - * - * #define META_DEBUG_ENABLED - */ -/***************************************************************************** -** Constants -*****************************************************************************/ - -/* Number of attributes in AVRC SDP record. */ -#define AVRC_NUM_ATTR 6 - -/* Number of protocol elements in protocol element list. */ -#define AVRC_NUM_PROTO_ELEMS 2 - -#ifndef AVRC_MIN_CMD_LEN -#define AVRC_MIN_CMD_LEN 20 -#endif - -#define AVRC_UNIT_OPRND_BYTES 5 -#define AVRC_SUB_OPRND_BYTES 4 -#define AVRC_SUBRSP_OPRND_BYTES 3 -#define AVRC_SUB_PAGE_MASK 7 -#define AVRC_SUB_PAGE_SHIFT 4 -#define AVRC_SUB_EXT_CODE 7 -#define AVRC_PASS_OP_ID_MASK 0x7F -#define AVRC_PASS_STATE_MASK 0x80 -#define AVRC_CMD_OPRND_PAD 0xFF - -#define AVRC_CTYPE_MASK 0x0F -#define AVRC_SUBTYPE_MASK 0xF8 -#define AVRC_SUBTYPE_SHIFT 3 -#define AVRC_SUBID_MASK 0x07 -#define AVRC_SUBID_IGNORE 0x07 - -#define AVRC_SINGLE_PARAM_SIZE 1 -#define AVRC_METADATA_PKT_TYPE_MASK 0x03 -#define AVRC_PASS_THOUGH_MSG_MASK 0x80 /* MSB of msg_type indicates the PAS THROUGH msg */ -#define AVRC_VENDOR_UNIQUE_MASK 0x70 /* vendor unique id */ - - -/* Company ID is 24-bit integer We can not use the macros in stack/bt_types.h */ -#define AVRC_CO_ID_TO_BE_STREAM(p, u32) {*(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)(u32); } -#define AVRC_BE_STREAM_TO_CO_ID(u32, p) {u32 = (((UINT32)(*((p) + 2))) + (((UINT32)(*((p) + 1))) << 8) + (((UINT32)(*(p))) << 16)); (p) += 3;} - -#define AVRC_AVC_HDR_SIZE 3 /* ctype, subunit*, opcode */ - -#define AVRC_MIN_META_HDR_SIZE 4 /* pdu id(1), packet type(1), param len(2) */ -#define AVRC_MIN_BROWSE_HDR_SIZE 3 /* pdu id(1), param len(2) */ - -#define AVRC_VENDOR_HDR_SIZE 6 /* ctype, subunit*, opcode, CO_ID */ -#define AVRC_MSG_VENDOR_OFFSET 23 -#define AVRC_MIN_VENDOR_SIZE (AVRC_MSG_VENDOR_OFFSET + BT_HDR_SIZE + AVRC_MIN_META_HDR_SIZE) - -#define AVRC_PASS_THRU_SIZE 8 -#define AVRC_MSG_PASS_THRU_OFFSET 25 -#define AVRC_MIN_PASS_THRU_SIZE (AVRC_MSG_PASS_THRU_OFFSET + BT_HDR_SIZE + 4) - -#define AVRC_MIN_BROWSE_SIZE (AVCT_BROWSE_OFFSET + BT_HDR_SIZE + AVRC_MIN_BROWSE_HDR_SIZE) - -#define AVRC_CTRL_PKT_LEN(pf, pk) {pf = (UINT8 *)((pk) + 1) + (pk)->offset + 2;} - -#define AVRC_MAX_CTRL_DATA_LEN (AVRC_PACKET_LEN) - -/***************************************************************************** -** Type definitions -*****************************************************************************/ - -#if (AVRC_METADATA_INCLUDED == TRUE) -/* type for Metadata fragmentation control block */ -typedef struct { - BT_HDR *p_fmsg; /* the fragmented message */ - UINT8 frag_pdu; /* the PDU ID for fragmentation */ - BOOLEAN frag_enabled; /* fragmentation flag */ -} tAVRC_FRAG_CB; - -/* type for Metadata re-assembly control block */ -typedef struct { - BT_HDR *p_rmsg; /* the received message */ - UINT16 rasm_offset; /* re-assembly flag, the offset of the start fragment */ - UINT8 rasm_pdu; /* the PDU ID for re-assembly */ -} tAVRC_RASM_CB; -#endif - -typedef struct { - tAVRC_CONN_CB ccb[AVCT_NUM_CONN]; -#if (AVRC_METADATA_INCLUDED == TRUE) - tAVRC_FRAG_CB fcb[AVCT_NUM_CONN]; - tAVRC_RASM_CB rcb[AVCT_NUM_CONN]; -#endif - tAVRC_FIND_CBACK *p_cback; /* pointer to application callback */ - tSDP_DISCOVERY_DB *p_db; /* pointer to discovery database */ - UINT16 service_uuid; /* service UUID to search */ - UINT8 trace_level; -} tAVRC_CB; - - - -#ifdef __cplusplus -extern "C" -{ -#endif - -/****************************************************************************** -** Main Control Block -*******************************************************************************/ -#if AVRC_DYNAMIC_MEMORY == FALSE -extern tAVRC_CB avrc_cb; -#else -extern tAVRC_CB *avrc_cb_ptr; -#define avrc_cb (*avrc_cb_ptr) -#endif - -extern BOOLEAN avrc_is_valid_pdu_id(UINT8 pdu_id); -extern BOOLEAN avrc_is_valid_player_attrib_value(UINT8 attrib, UINT8 value); -extern BT_HDR *avrc_alloc_ctrl_pkt (UINT8 pdu); -extern tAVRC_STS avrc_pars_pass_thru(tAVRC_MSG_PASS *p_msg, UINT16 *p_vendor_unique_id); -extern UINT8 avrc_opcode_from_pdu(UINT8 pdu); -extern BOOLEAN avrc_is_valid_opcode(UINT8 opcode); - -#ifdef __cplusplus -} -#endif - -#endif ///AVRC_INCLUDED == TRUE - -#endif /* AVRC_INT_H */ diff --git a/tools/sdk/include/bluedroid/blufi_int.h b/tools/sdk/include/bluedroid/blufi_int.h deleted file mode 100644 index eab51ad8..00000000 --- a/tools/sdk/include/bluedroid/blufi_int.h +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BLUFI_INT_H__ -#define __BLUFI_INT_H__ - -#define BTC_BLUFI_GREAT_VER 0x01 //Version + Subversion -#define BTC_BLUFI_SUB_VER 0x02 //Version + Subversion -#define BTC_BLUFI_VERSION ((BTC_BLUFI_GREAT_VER<<8)|BTC_BLUFI_SUB_VER) //Version + Subversion - -/* service engine control block */ -typedef struct { - /* Protocol reference */ - tGATT_IF gatt_if; - UINT8 srvc_inst; - UINT16 handle_srvc; - UINT16 handle_char_p2e; - UINT16 handle_char_e2p; - UINT16 handle_descr_e2p; - UINT16 conn_id; - BOOLEAN is_connected; - BD_ADDR remote_bda; - UINT32 trans_id; - UINT8 congest; - UINT16 frag_size; -#define BLUFI_PREPAIR_BUF_MAX_SIZE 1024 - uint8_t *prepare_buf; - int prepare_len; - /* Control reference */ - esp_blufi_callbacks_t *cbs; - BOOLEAN enabled; - uint8_t send_seq; - uint8_t recv_seq; - uint8_t sec_mode; - uint8_t *aggr_buf; - uint16_t total_len; - uint16_t offset; -} tBLUFI_ENV; - -/* BLUFI protocol */ -struct blufi_hdr{ - uint8_t type; - uint8_t fc; - uint8_t seq; - uint8_t data_len; - uint8_t data[0]; -}; -typedef struct blufi_hdr blufi_hd_t; - -struct blufi_frag_hdr { - uint8_t type; - uint8_t fc; - uint8_t seq; - uint8_t data_len; - uint16_t total_len; - uint8_t content[0]; -}; -typedef struct blufi_frag_hdr blufi_frag_hdr_t; - -#define BLUFI_DATA_SEC_MODE_CHECK_MASK 0x01 -#define BLUFI_DATA_SEC_MODE_ENC_MASK 0x02 -#define BLUFI_CTRL_SEC_MODE_CHECK_MASK 0x10 -#define BLUFI_CTRL_SEC_MODE_ENC_MASK 0x20 - -// packet type -#define BLUFI_TYPE_MASK 0x03 -#define BLUFI_TYPE_SHIFT 0 -#define BLUFI_SUBTYPE_MASK 0xFC -#define BLUFI_SUBTYPE_SHIFT 2 - -#define BLUFI_GET_TYPE(type) ((type) & BLUFI_TYPE_MASK) -#define BLUFI_GET_SUBTYPE(type) (((type) & BLUFI_SUBTYPE_MASK) >>BLUFI_SUBTYPE_SHIFT) -#define BLUFI_BUILD_TYPE(type, subtype) (((type) & BLUFI_TYPE_MASK) | ((subtype)< -// #include "bluetooth.h" -#include "common/bt_defs.h" - -#define SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH 15 - -/** - * These events are handled by the state machine - */ -typedef enum { - SDP_TYPE_RAW, // Used to carry raw SDP search data for unknown UUIDs - SDP_TYPE_MAP_MAS, // Message Access Profile - Server - SDP_TYPE_MAP_MNS, // Message Access Profile - Client (Notification Server) - SDP_TYPE_PBAP_PSE, // Phone Book Profile - Server - SDP_TYPE_PBAP_PCE, // Phone Book Profile - Client - SDP_TYPE_OPP_SERVER, // Object Push Profile - SDP_TYPE_SAP_SERVER // SIM Access Profile -} bluetooth_sdp_types; - -typedef struct _bluetooth_sdp_hdr { - bluetooth_sdp_types type; - bt_uuid_t uuid; - uint32_t service_name_length; - char *service_name; - int32_t rfcomm_channel_number; - int32_t l2cap_psm; - int32_t profile_version; -} bluetooth_sdp_hdr; - -/** - * Some signals need additional pointers, hence we introduce a - * generic way to handle these pointers. - */ -typedef struct _bluetooth_sdp_hdr_overlay { - bluetooth_sdp_types type; - bt_uuid_t uuid; - uint32_t service_name_length; - char *service_name; - int32_t rfcomm_channel_number; - int32_t l2cap_psm; - int32_t profile_version; - - // User pointers, only used for some signals - see bluetooth_sdp_ops_record - int user1_ptr_len; - uint8_t *user1_ptr; - int user2_ptr_len; - uint8_t *user2_ptr; -} bluetooth_sdp_hdr_overlay; - -typedef struct _bluetooth_sdp_mas_record { - bluetooth_sdp_hdr_overlay hdr; - uint32_t mas_instance_id; - uint32_t supported_features; - uint32_t supported_message_types; -} bluetooth_sdp_mas_record; - -typedef struct _bluetooth_sdp_mns_record { - bluetooth_sdp_hdr_overlay hdr; - uint32_t supported_features; -} bluetooth_sdp_mns_record; - -typedef struct _bluetooth_sdp_pse_record { - bluetooth_sdp_hdr_overlay hdr; - uint32_t supported_features; - uint32_t supported_repositories; -} bluetooth_sdp_pse_record; - -typedef struct _bluetooth_sdp_pce_record { - bluetooth_sdp_hdr_overlay hdr; -} bluetooth_sdp_pce_record; - -typedef struct _bluetooth_sdp_ops_record { - bluetooth_sdp_hdr_overlay hdr; - int supported_formats_list_len; - uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH]; -} bluetooth_sdp_ops_record; - -typedef struct _bluetooth_sdp_sap_record { - bluetooth_sdp_hdr_overlay hdr; -} bluetooth_sdp_sap_record; - -typedef union { - bluetooth_sdp_hdr_overlay hdr; - bluetooth_sdp_mas_record mas; - bluetooth_sdp_mns_record mns; - bluetooth_sdp_pse_record pse; - bluetooth_sdp_pce_record pce; - bluetooth_sdp_ops_record ops; - bluetooth_sdp_sap_record sap; -} bluetooth_sdp_record; - -#endif /* __BT_SDP_H__ */ diff --git a/tools/sdk/include/bluedroid/bta/bta_api.h b/tools/sdk/include/bluedroid/bta/bta_api.h deleted file mode 100644 index 15c22ba6..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_api.h +++ /dev/null @@ -1,2543 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2003-2014 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the public interface file for BTA, Broadcom's Bluetooth - * application layer for mobile phones. - * - ******************************************************************************/ -#ifndef BTA_API_H -#define BTA_API_H - -#include "common/bt_target.h" -#include "stack/bt_types.h" -#include "stack/btm_api.h" -// #include "uipc_msg.h" -#include "stack/sdp_api.h" - -#if BLE_INCLUDED == TRUE -#include "stack/btm_ble_api.h" -#endif - -/***************************************************************************** -** Constants and data types -*****************************************************************************/ - -/* Status Return Value */ -#define BTA_SUCCESS 0 /* Successful operation. */ -#define BTA_FAILURE 1 /* Generic failure. */ -#define BTA_PENDING 2 /* API cannot be completed right now */ -#define BTA_BUSY 3 -#define BTA_NO_RESOURCES 4 -#define BTA_WRONG_MODE 5 - -typedef UINT8 tBTA_STATUS; - -/* - * Service ID - * - * NOTES: When you add a new Service ID for BTA AND require to change the value of BTA_MAX_SERVICE_ID, - * make sure that the correct security ID of the new service from Security service definitions (stack/btm_api.h) - * should be added to bta_service_id_to_btm_srv_id_lkup_tbl table in bta_dm_act.c. - */ - -#define BTA_RES_SERVICE_ID 0 /* Reserved */ -#define BTA_SPP_SERVICE_ID 1 /* Serial port profile. */ -#define BTA_DUN_SERVICE_ID 2 /* Dial-up networking profile. */ -#define BTA_A2DP_SOURCE_SERVICE_ID 3 /* A2DP Source profile. */ -#define BTA_LAP_SERVICE_ID 4 /* LAN access profile. */ -#define BTA_HSP_SERVICE_ID 5 /* Headset profile. */ -#define BTA_HFP_SERVICE_ID 6 /* Hands-free profile. */ -#define BTA_OPP_SERVICE_ID 7 /* Object push */ -#define BTA_FTP_SERVICE_ID 8 /* File transfer */ -#define BTA_CTP_SERVICE_ID 9 /* Cordless Terminal */ -#define BTA_ICP_SERVICE_ID 10 /* Intercom Terminal */ -#define BTA_SYNC_SERVICE_ID 11 /* Synchronization */ -#define BTA_BPP_SERVICE_ID 12 /* Basic printing profile */ -#define BTA_BIP_SERVICE_ID 13 /* Basic Imaging profile */ -#define BTA_PANU_SERVICE_ID 14 /* PAN User */ -#define BTA_NAP_SERVICE_ID 15 /* PAN Network access point */ -#define BTA_GN_SERVICE_ID 16 /* PAN Group Ad-hoc networks */ -#define BTA_SAP_SERVICE_ID 17 /* SIM Access profile */ -#define BTA_A2DP_SINK_SERVICE_ID 18 /* A2DP Sink */ -#define BTA_AVRCP_SERVICE_ID 19 /* A/V remote control */ -#define BTA_HID_SERVICE_ID 20 /* HID */ -#define BTA_VDP_SERVICE_ID 21 /* Video distribution */ -#define BTA_PBAP_SERVICE_ID 22 /* PhoneBook Access Server*/ -#define BTA_HSP_HS_SERVICE_ID 23 /* HFP HS role */ -#define BTA_HFP_HS_SERVICE_ID 24 /* HSP HS role */ -#define BTA_MAP_SERVICE_ID 25 /* Message Access Profile */ -#define BTA_MN_SERVICE_ID 26 /* Message Notification Service */ -#define BTA_HDP_SERVICE_ID 27 /* Health Device Profile */ -#define BTA_PCE_SERVICE_ID 28 /* PhoneBook Access Client*/ -#define BTA_SDP_SERVICE_ID 29 /* SDP Search*/ -#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE -/* BLE profile service ID */ -#define BTA_BLE_SERVICE_ID 30 /* GATT profile */ - -// btla-specific ++ -#define BTA_USER_SERVICE_ID 31 /* User requested UUID */ - -#define BTA_MAX_SERVICE_ID 32 -// btla-specific -- -#else -#define BTA_USER_SERVICE_ID 30 /* User requested UUID */ -#define BTA_MAX_SERVICE_ID 31 -#endif -/* service IDs (BTM_SEC_SERVICE_FIRST_EMPTY + 1) to (BTM_SEC_MAX_SERVICES - 1) - * are used by BTA JV */ -#define BTA_FIRST_JV_SERVICE_ID (BTM_SEC_SERVICE_FIRST_EMPTY + 1) -#define BTA_LAST_JV_SERVICE_ID (BTM_SEC_MAX_SERVICES - 1) - -typedef UINT8 tBTA_SERVICE_ID; - -/* Service ID Mask */ -#define BTA_RES_SERVICE_MASK 0x00000001 /* Reserved */ -#define BTA_SPP_SERVICE_MASK 0x00000002 /* Serial port profile. */ -#define BTA_DUN_SERVICE_MASK 0x00000004 /* Dial-up networking profile. */ -#define BTA_FAX_SERVICE_MASK 0x00000008 /* Fax profile. */ -#define BTA_LAP_SERVICE_MASK 0x00000010 /* LAN access profile. */ -#define BTA_HSP_SERVICE_MASK 0x00000020 /* HSP AG role. */ -#define BTA_HFP_SERVICE_MASK 0x00000040 /* HFP AG role */ -#define BTA_OPP_SERVICE_MASK 0x00000080 /* Object push */ -#define BTA_FTP_SERVICE_MASK 0x00000100 /* File transfer */ -#define BTA_CTP_SERVICE_MASK 0x00000200 /* Cordless Terminal */ -#define BTA_ICP_SERVICE_MASK 0x00000400 /* Intercom Terminal */ -#define BTA_SYNC_SERVICE_MASK 0x00000800 /* Synchronization */ -#define BTA_BPP_SERVICE_MASK 0x00001000 /* Print server */ -#define BTA_BIP_SERVICE_MASK 0x00002000 /* Basic Imaging */ -#define BTA_PANU_SERVICE_MASK 0x00004000 /* PAN User */ -#define BTA_NAP_SERVICE_MASK 0x00008000 /* PAN Network access point */ -#define BTA_GN_SERVICE_MASK 0x00010000 /* PAN Group Ad-hoc networks */ -#define BTA_SAP_SERVICE_MASK 0x00020000 /* PAN Group Ad-hoc networks */ -#define BTA_A2DP_SERVICE_MASK 0x00040000 /* Advanced audio distribution */ -#define BTA_AVRCP_SERVICE_MASK 0x00080000 /* A/V remote control */ -#define BTA_HID_SERVICE_MASK 0x00100000 /* HID */ -#define BTA_VDP_SERVICE_MASK 0x00200000 /* Video distribution */ -#define BTA_PBAP_SERVICE_MASK 0x00400000 /* Phone Book Server */ -#define BTA_HSP_HS_SERVICE_MASK 0x00800000 /* HFP HS role */ -#define BTA_HFP_HS_SERVICE_MASK 0x01000000 /* HSP HS role */ -#define BTA_MAS_SERVICE_MASK 0x02000000 /* Message Access Profile */ -#define BTA_MN_SERVICE_MASK 0x04000000 /* Message Notification Profile */ -#define BTA_HL_SERVICE_MASK 0x08000000 /* Health Device Profile */ -#define BTA_PCE_SERVICE_MASK 0x10000000 /* Phone Book Client */ - -#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE -#define BTA_BLE_SERVICE_MASK 0x20000000 /* GATT based service */ -// btla-specific ++ -#define BTA_USER_SERVICE_MASK 0x40000000 /* Message Notification Profile */ -// btla-specific -- -#else -// btla-specific ++ -#define BTA_USER_SERVICE_MASK 0x20000000 /* Message Notification Profile */ -// btla-specific -- -#endif - -#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE -#define BTA_ALL_SERVICE_MASK 0x3FFFFFFF /* All services supported by BTA. */ -#else -#define BTA_ALL_SERVICE_MASK 0x1FFFFFFF /* All services supported by BTA. */ -#endif - -typedef UINT32 tBTA_SERVICE_MASK; - -/* extended service mask, including mask with one or more GATT UUID */ -typedef struct { - tBTA_SERVICE_MASK srvc_mask; - UINT8 num_uuid; - tBT_UUID *p_uuid; -} tBTA_SERVICE_MASK_EXT; - -/* Security Setting Mask */ -#define BTA_SEC_NONE BTM_SEC_NONE /* No security. */ -#define BTA_SEC_AUTHORIZE (BTM_SEC_IN_AUTHORIZE ) /* Authorization required (only needed for out going connection )*/ -#define BTA_SEC_AUTHENTICATE (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_OUT_AUTHENTICATE) /* Authentication required. */ -#define BTA_SEC_ENCRYPT (BTM_SEC_IN_ENCRYPT | BTM_SEC_OUT_ENCRYPT) /* Encryption required. */ -#define BTA_SEC_MODE4_LEVEL4 (BTM_SEC_MODE4_LEVEL4) /* Mode 4 level 4 service, i.e. incoming/outgoing MITM and P-256 encryption */ -#define BTA_SEC_MITM (BTM_SEC_IN_MITM | BTM_SEC_OUT_MITM) /* Man-In-The_Middle protection */ -#define BTA_SEC_IN_16_DIGITS (BTM_SEC_IN_MIN_16_DIGIT_PIN) /* Min 16 digit for pin code */ - -typedef UINT16 tBTA_SEC; - -/* Ignore for Discoverable, Connectable, Pairable and Connectable Paired only device modes */ -#define BTA_DM_IGNORE 0x00FF - -/* Ignore for Discoverable, Connectable only for LE modes */ -#define BTA_DM_LE_IGNORE 0xFF00 - -#define BTA_APP_ID_PAN_MULTI 0xFE /* app id for pan multiple connection */ -#define BTA_ALL_APP_ID 0xFF - -/* Discoverable Modes */ -#define BTA_DM_NON_DISC BTM_NON_DISCOVERABLE /* Device is not discoverable. */ -#define BTA_DM_GENERAL_DISC BTM_GENERAL_DISCOVERABLE /* General discoverable. */ -#define BTA_DM_LIMITED_DISC BTM_LIMITED_DISCOVERABLE /* Limited discoverable. */ -#if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) -#define BTA_DM_BLE_NON_DISCOVERABLE BTM_BLE_NON_DISCOVERABLE /* Device is not LE discoverable */ -#define BTA_DM_BLE_GENERAL_DISCOVERABLE BTM_BLE_GENERAL_DISCOVERABLE /* Device is LE General discoverable */ -#define BTA_DM_BLE_LIMITED_DISCOVERABLE BTM_BLE_LIMITED_DISCOVERABLE /* Device is LE Limited discoverable */ -#endif -typedef UINT16 tBTA_DM_DISC; /* this discoverability mode is a bit mask among BR mode and LE mode */ - -/* Connectable Modes */ -#define BTA_DM_NON_CONN BTM_NON_CONNECTABLE /* Device is not connectable. */ -#define BTA_DM_CONN BTM_CONNECTABLE /* Device is connectable. */ -#if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) -#define BTA_DM_BLE_NON_CONNECTABLE BTM_BLE_NON_CONNECTABLE /* Device is LE non-connectable. */ -#define BTA_DM_BLE_CONNECTABLE BTM_BLE_CONNECTABLE /* Device is LE connectable. */ -#endif - -// btla-specific ++ -typedef UINT16 tBTA_DM_CONN; - -#define BTA_TRANSPORT_UNKNOWN 0 -#define BTA_TRANSPORT_BR_EDR BT_TRANSPORT_BR_EDR -#define BTA_TRANSPORT_LE BT_TRANSPORT_LE -typedef tBT_TRANSPORT tBTA_TRANSPORT; - -/* Pairable Modes */ -#define BTA_DM_PAIRABLE 1 -#define BTA_DM_NON_PAIRABLE 0 - -/* Connectable Paired Only Mode */ -#define BTA_DM_CONN_ALL 0 -#define BTA_DM_CONN_PAIRED 1 - -/* Inquiry Modes */ -#define BTA_DM_INQUIRY_NONE BTM_INQUIRY_NONE /*No BR inquiry. */ -#define BTA_DM_GENERAL_INQUIRY BTM_GENERAL_INQUIRY /* Perform general inquiry. */ -#define BTA_DM_LIMITED_INQUIRY BTM_LIMITED_INQUIRY /* Perform limited inquiry. */ - -#if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) -#define BTA_BLE_INQUIRY_NONE BTM_BLE_INQUIRY_NONE -#define BTA_BLE_GENERAL_INQUIRY BTM_BLE_GENERAL_INQUIRY /* Perform LE general inquiry. */ -#define BTA_BLE_LIMITED_INQUIRY BTM_BLE_LIMITED_INQUIRY /* Perform LE limited inquiry. */ -#endif -typedef UINT8 tBTA_DM_INQ_MODE; - -/* Inquiry Filter Type */ -#define BTA_DM_INQ_CLR BTM_CLR_INQUIRY_FILTER /* Clear inquiry filter. */ -#define BTA_DM_INQ_DEV_CLASS BTM_FILTER_COND_DEVICE_CLASS /* Filter on device class. */ -#define BTA_DM_INQ_BD_ADDR BTM_FILTER_COND_BD_ADDR /* Filter on a specific BD address. */ - -typedef UINT8 tBTA_DM_INQ_FILT; - -/* Authorize Response */ -#define BTA_DM_AUTH_PERM 0 /* Authorized for future connections to the service */ -#define BTA_DM_AUTH_TEMP 1 /* Authorized for current connection only */ -#define BTA_DM_NOT_AUTH 2 /* Not authorized for the service */ - -typedef UINT8 tBTA_AUTH_RESP; - -/* M/S preferred roles */ -#define BTA_ANY_ROLE 0x00 -#define BTA_MASTER_ROLE_PREF 0x01 -#define BTA_MASTER_ROLE_ONLY 0x02 -#define BTA_SLAVE_ROLE_ONLY 0x03 /* Used for PANU only, skip role switch to master */ - -typedef UINT8 tBTA_PREF_ROLES; - -enum { - - BTA_DM_NO_SCATTERNET, /* Device doesn't support scatternet, it might - support "role switch during connection" for - an incoming connection, when it already has - another connection in master role */ - BTA_DM_PARTIAL_SCATTERNET, /* Device supports partial scatternet. It can have - simulateous connection in Master and Slave roles - for short period of time */ - BTA_DM_FULL_SCATTERNET /* Device can have simultaneous connection in master - and slave roles */ - -}; - - -/* Inquiry filter device class condition */ -typedef struct { - DEV_CLASS dev_class; /* device class of interest */ - DEV_CLASS dev_class_mask; /* mask to determine the bits of device class of interest */ -} tBTA_DM_COD_COND; - - -/* Inquiry Filter Condition */ -typedef union { - BD_ADDR bd_addr; /* BD address of device to filter. */ - tBTA_DM_COD_COND dev_class_cond; /* Device class filter condition */ -} tBTA_DM_INQ_COND; - -/* Inquiry Parameters */ -typedef struct { - tBTA_DM_INQ_MODE mode; /* Inquiry mode, limited or general. */ - UINT8 duration; /* Inquiry duration in 1.28 sec units. */ - UINT8 max_resps; /* Maximum inquiry responses. Set to zero for unlimited responses. */ - BOOLEAN report_dup; /* report duplicated inquiry response with higher RSSI value */ - tBTA_DM_INQ_FILT filter_type; /* Filter condition type. */ - tBTA_DM_INQ_COND filter_cond; /* Filter condition data. */ -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - UINT8 intl_duration[4];/*duration array storing the interleave scan's time portions*/ -#endif -} tBTA_DM_INQ; - -typedef struct { - UINT8 bta_dm_eir_min_name_len; /* minimum length of local name when it is shortened */ -#if (BTA_EIR_CANNED_UUID_LIST == TRUE) - UINT8 bta_dm_eir_uuid16_len; /* length of 16-bit UUIDs */ - UINT8 *bta_dm_eir_uuid16; /* 16-bit UUIDs */ -#else - UINT32 uuid_mask[BTM_EIR_SERVICE_ARRAY_SIZE]; /* mask of UUID list in EIR */ -#endif - INT8 *bta_dm_eir_inq_tx_power; /* Inquiry TX power */ - UINT8 bta_dm_eir_flag_len; /* length of flags in bytes */ - UINT8 *bta_dm_eir_flags; /* flags for EIR */ - UINT8 bta_dm_eir_manufac_spec_len; /* length of manufacturer specific in bytes */ - UINT8 *bta_dm_eir_manufac_spec; /* manufacturer specific */ - UINT8 bta_dm_eir_additional_len; /* length of additional data in bytes */ - UINT8 *bta_dm_eir_additional; /* additional data */ -} tBTA_DM_EIR_CONF; - -#if BLE_INCLUDED == TRUE -/* ADV data flag bit definition used for BTM_BLE_AD_TYPE_FLAG */ -#define BTA_BLE_LIMIT_DISC_FLAG BTM_BLE_LIMIT_DISC_FLAG -#define BTA_BLE_GEN_DISC_FLAG BTM_BLE_GEN_DISC_FLAG -#define BTA_BLE_BREDR_NOT_SPT BTM_BLE_BREDR_NOT_SPT -#define BTA_BLE_DMT_CONTROLLER_SPT BTM_BLE_DMT_CONTROLLER_SPT -#define BTA_BLE_DMT_HOST_SPT BTM_BLE_DMT_HOST_SPT -#define BTA_BLE_NON_LIMIT_DISC_FLAG BTM_BLE_NON_LIMIT_DISC_FLAG -#define BTA_BLE_ADV_FLAG_MASK BTM_BLE_ADV_FLAG_MASK -#define BTA_BLE_LIMIT_DISC_MASK BTM_BLE_LIMIT_DISC_MASK - -/* ADV data bit mask */ -#define BTA_BLE_AD_BIT_DEV_NAME BTM_BLE_AD_BIT_DEV_NAME -#define BTA_BLE_AD_BIT_FLAGS BTM_BLE_AD_BIT_FLAGS -#define BTA_BLE_AD_BIT_MANU BTM_BLE_AD_BIT_MANU -#define BTA_BLE_AD_BIT_TX_PWR BTM_BLE_AD_BIT_TX_PWR -#define BTA_BLE_AD_BIT_INT_RANGE BTM_BLE_AD_BIT_INT_RANGE -#define BTA_BLE_AD_BIT_SERVICE BTM_BLE_AD_BIT_SERVICE -#define BTA_BLE_AD_BIT_APPEARANCE BTM_BLE_AD_BIT_APPEARANCE -#define BTA_BLE_AD_BIT_PROPRIETARY BTM_BLE_AD_BIT_PROPRIETARY -#define BTA_DM_BLE_AD_BIT_SERVICE_SOL BTM_BLE_AD_BIT_SERVICE_SOL -#define BTA_DM_BLE_AD_BIT_SERVICE_DATA BTM_BLE_AD_BIT_SERVICE_DATA -#define BTA_DM_BLE_AD_BIT_SIGN_DATA BTM_BLE_AD_BIT_SIGN_DATA -#define BTA_DM_BLE_AD_BIT_SERVICE_128SOL BTM_BLE_AD_BIT_SERVICE_128SOL -#define BTA_DM_BLE_AD_BIT_PUBLIC_ADDR BTM_BLE_AD_BIT_PUBLIC_ADDR -#define BTA_DM_BLE_AD_BIT_RANDOM_ADDR BTM_BLE_AD_BIT_RANDOM_ADDR -#define BTA_DM_BLE_AD_BIT_SERVICE_128 BTM_BLE_AD_BIT_SERVICE_128 /*128-bit Service UUIDs*/ - -typedef tBTM_BLE_AD_MASK tBTA_BLE_AD_MASK; - -/* slave preferred connection interval range */ -typedef struct { - UINT16 low; - UINT16 hi; - -} tBTA_BLE_INT_RANGE; - -/* Service tag supported in the device */ -typedef struct { - UINT8 num_service; - BOOLEAN list_cmpl; - UINT16 *p_uuid; -} tBTA_BLE_SERVICE; - - -typedef struct { - UINT8 len; - UINT8 *p_val; -} tBTA_BLE_MANU; - -typedef struct { - UINT8 adv_type; - UINT8 len; - UINT8 *p_val; /* number of len byte */ -} tBTA_BLE_PROP_ELEM; - -/* vendor proprietary adv type */ -typedef struct { - UINT8 num_elem; - tBTA_BLE_PROP_ELEM *p_elem; -} tBTA_BLE_PROPRIETARY; - -typedef struct { - tBT_UUID service_uuid; - UINT8 len; - UINT8 *p_val; -} tBTA_BLE_SERVICE_DATA; - -typedef tBTM_BLE_128SERVICE tBTA_BLE_128SERVICE; -typedef tBTM_BLE_32SERVICE tBTA_BLE_32SERVICE; - -typedef struct { - tBTA_BLE_INT_RANGE int_range; /* slave prefered conn interval range */ - tBTA_BLE_MANU *p_manu; /* manufacturer data */ - tBTA_BLE_SERVICE *p_services; /* 16 bits services */ - tBTA_BLE_128SERVICE *p_services_128b; /* 128 bits service */ - tBTA_BLE_32SERVICE *p_service_32b; /* 32 bits Service UUID */ - tBTA_BLE_SERVICE *p_sol_services; /* 16 bits services Solicitation UUIDs */ - tBTA_BLE_32SERVICE *p_sol_service_32b; /* List of 32 bit Service Solicitation UUIDs */ - tBTA_BLE_128SERVICE *p_sol_service_128b;/* List of 128 bit Service Solicitation UUIDs */ - tBTA_BLE_PROPRIETARY *p_proprietary; /* proprietary data */ - tBTA_BLE_SERVICE_DATA *p_service_data; /* service data */ - UINT16 appearance; /* appearance data */ - UINT8 flag; - UINT8 tx_power; -} tBTA_BLE_ADV_DATA; - -typedef void (tBTA_SET_ADV_DATA_CMPL_CBACK) (tBTA_STATUS status); - -typedef tBTM_START_ADV_CMPL_CBACK tBTA_START_ADV_CMPL_CBACK; - -typedef tBTM_START_STOP_ADV_CMPL_CBACK tBTA_START_STOP_ADV_CMPL_CBACK; - - -typedef tBTM_ADD_WHITELIST_CBACK tBTA_ADD_WHITELIST_CBACK; - -typedef tBTM_SET_PKT_DATA_LENGTH_CBACK tBTA_SET_PKT_DATA_LENGTH_CBACK; - -typedef tBTM_SET_RAND_ADDR_CBACK tBTA_SET_RAND_ADDR_CBACK; - -typedef tBTM_SET_LOCAL_PRIVACY_CBACK tBTA_SET_LOCAL_PRIVACY_CBACK; - -typedef tBTM_CMPL_CB tBTA_CMPL_CB; - -typedef tBTM_TX_POWER_RESULTS tBTA_TX_POWER_RESULTS; - -typedef tBTM_RSSI_RESULTS tBTA_RSSI_RESULTS; - -/* advertising channel map */ -#define BTA_BLE_ADV_CHNL_37 BTM_BLE_ADV_CHNL_37 -#define BTA_BLE_ADV_CHNL_38 BTM_BLE_ADV_CHNL_38 -#define BTA_BLE_ADV_CHNL_39 BTM_BLE_ADV_CHNL_39 -typedef tBTM_BLE_ADV_CHNL_MAP tBTA_BLE_ADV_CHNL_MAP; /* use as a bit mask */ - -/* advertising filter policy */ -typedef tBTM_BLE_AFP tBTA_BLE_AFP; - -/* adv event type */ -#define BTA_BLE_CONNECT_EVT BTM_BLE_CONNECT_EVT /* Connectable undirected advertising */ -#define BTA_BLE_CONNECT_DIR_EVT BTM_BLE_CONNECT_DIR_EVT /* Connectable directed advertising */ -#define BTA_BLE_DISCOVER_EVT BTM_BLE_DISCOVER_EVT /* Scannable undirected advertising */ -#define BTA_BLE_NON_CONNECT_EVT BTM_BLE_NON_CONNECT_EVT /* Non connectable undirected advertising */ -typedef UINT8 tBTA_BLE_ADV_EVT; - -/* adv tx power level */ -#define BTA_BLE_ADV_TX_POWER_MIN 0 /* minimum tx power */ -#define BTA_BLE_ADV_TX_POWER_LOW 1 /* low tx power */ -#define BTA_BLE_ADV_TX_POWER_MID 2 /* middle tx power */ -#define BTA_BLE_ADV_TX_POWER_UPPER 3 /* upper tx power */ -#define BTA_BLE_ADV_TX_POWER_MAX 4 /* maximum tx power */ -typedef UINT8 tBTA_BLE_ADV_TX_POWER; - -/* advertising instance parameters */ -typedef struct { - UINT16 adv_int_min; /* minimum adv interval */ - UINT16 adv_int_max; /* maximum adv interval */ - tBTA_BLE_ADV_EVT adv_type; /* adv event type */ - tBTA_BLE_ADV_CHNL_MAP channel_map; /* adv channel map */ - tBTA_BLE_AFP adv_filter_policy; /* advertising filter policy */ - tBTA_BLE_ADV_TX_POWER tx_power; /* adv tx power */ -} tBTA_BLE_ADV_PARAMS; - -/* These are the fields returned in each device adv packet. It -** is returned in the results callback if registered. -*/ -typedef struct { - UINT8 conn_mode; - tBTA_BLE_AD_MASK ad_mask; /* mask of the valid adv data field */ - UINT8 flag; - UINT8 tx_power_level; - UINT8 remote_name_len; - UINT8 *p_remote_name; - tBTA_BLE_SERVICE service; -} tBTA_BLE_INQ_DATA; - -enum { - BTA_BLE_BATCH_SCAN_MODE_PASS = 1, - BTA_BLE_BATCH_SCAN_MODE_ACTI = 2, - BTA_BLE_BATCH_SCAN_MODE_PASS_ACTI = 3 -}; -typedef UINT8 tBTA_BLE_BATCH_SCAN_MODE; - -enum { - BTA_BLE_DISCARD_OLD_ITEMS = 0, - BTA_BLE_DISCARD_LOWER_RSSI_ITEMS = 1 -}; -typedef UINT8 tBTA_BLE_DISCARD_RULE; - -enum { - BTA_BLE_ADV_SEEN_FIRST_TIME = 0, - BTA_BLE_ADV_TRACKING_TIMEOUT = 1 -}; -typedef UINT8 tBTA_BLE_ADV_CHANGE_REASON; - -enum { - BTA_BLE_BATCH_SCAN_ENB_EVT = 1, - BTA_BLE_BATCH_SCAN_CFG_STRG_EVT = 2, - BTA_BLE_BATCH_SCAN_DATA_EVT = 3, - BTA_BLE_BATCH_SCAN_THRES_EVT = 4, - BTA_BLE_BATCH_SCAN_PARAM_EVT = 5, - BTA_BLE_BATCH_SCAN_DIS_EVT = 6 -}; -typedef tBTM_BLE_BATCH_SCAN_EVT tBTA_BLE_BATCH_SCAN_EVT; - -typedef tBTM_BLE_TRACK_ADV_ACTION tBTA_BLE_TRACK_ADV_ACTION; -#endif - -/* BLE customer specific feature function type definitions */ -/* data type used on customer specific feature for RSSI monitoring */ -#define BTA_BLE_RSSI_ALERT_HI 0 -#define BTA_BLE_RSSI_ALERT_RANGE 1 -#define BTA_BLE_RSSI_ALERT_LO 2 -typedef UINT8 tBTA_DM_BLE_RSSI_ALERT_TYPE; - -#define BTA_BLE_RSSI_ALERT_NONE BTM_BLE_RSSI_ALERT_NONE /* (0) */ -#define BTA_BLE_RSSI_ALERT_HI_BIT BTM_BLE_RSSI_ALERT_HI_BIT /* (1) */ -#define BTA_BLE_RSSI_ALERT_RANGE_BIT BTM_BLE_RSSI_ALERT_RANGE_BIT /* (1 << 1) */ -#define BTA_BLE_RSSI_ALERT_LO_BIT BTM_BLE_RSSI_ALERT_LO_BIT /* (1 << 2) */ -typedef UINT8 tBTA_DM_BLE_RSSI_ALERT_MASK; - - -typedef void (tBTA_DM_BLE_RSSI_CBACK) (BD_ADDR bd_addr, tBTA_DM_BLE_RSSI_ALERT_TYPE alert_type, INT8 rssi); - -/* max number of filter spot for different filter type */ -#define BTA_DM_BLE_MAX_UUID_FILTER BTM_BLE_MAX_UUID_FILTER /* 8 */ -#define BTA_DM_BLE_MAX_ADDR_FILTER BTM_BLE_MAX_ADDR_FILTER /* 8 */ -#define BTA_DM_BLE_PF_STR_COND_MAX BTM_BLE_PF_STR_COND_MAX /* 4 apply to manu data , or local name */ -#define BTA_DM_BLE_PF_STR_LEN_MAX BTM_BLE_PF_STR_LEN_MAX /* match for first 20 bytes */ - -#define BTA_DM_BLE_PF_LOGIC_OR 0 -#define BTA_DM_BLE_PF_LOGIC_AND 1 -typedef UINT8 tBTA_DM_BLE_PF_LOGIC_TYPE; - -enum { - BTA_DM_BLE_SCAN_COND_ADD, - BTA_DM_BLE_SCAN_COND_DELETE, - BTA_DM_BLE_SCAN_COND_CLEAR = 2 -}; -typedef UINT8 tBTA_DM_BLE_SCAN_COND_OP; - -/* ADV payload filtering vendor specific call event */ -enum { - BTA_BLE_SCAN_PF_ENABLE_EVT = 7, - BTA_BLE_SCAN_PF_COND_EVT -}; - -/* filter selection bit index */ -#define BTA_DM_BLE_PF_ADDR_FILTER BTM_BLE_PF_ADDR_FILTER -#define BTA_DM_BLE_PF_SRVC_DATA BTM_BLE_PF_SRVC_DATA -#define BTA_DM_BLE_PF_SRVC_UUID BTM_BLE_PF_SRVC_UUID -#define BTA_DM_BLE_PF_SRVC_SOL_UUID BTM_BLE_PF_SRVC_SOL_UUID -#define BTA_DM_BLE_PF_LOCAL_NAME BTM_BLE_PF_LOCAL_NAME -#define BTA_DM_BLE_PF_MANU_DATA BTM_BLE_PF_MANU_DATA -#define BTA_DM_BLE_PF_SRVC_DATA_PATTERN BTM_BLE_PF_SRVC_DATA_PATTERN -#define BTA_DM_BLE_PF_TYPE_ALL BTM_BLE_PF_TYPE_ALL -#define BTA_DM_BLE_PF_TYPE_MAX BTM_BLE_PF_TYPE_MAX -typedef UINT8 tBTA_DM_BLE_PF_COND_TYPE; - -typedef union { - UINT16 uuid16_mask; - UINT32 uuid32_mask; - UINT8 uuid128_mask[LEN_UUID_128]; -} tBTA_DM_BLE_PF_COND_MASK; - -typedef struct { - tBLE_BD_ADDR *p_target_addr; /* target address, if NULL, generic UUID filter */ - tBT_UUID uuid; /* UUID condition */ - tBTA_DM_BLE_PF_LOGIC_TYPE cond_logic; /* AND/OR */ - tBTA_DM_BLE_PF_COND_MASK *p_uuid_mask; /* UUID condition mask, if NULL, match exact as UUID condition */ -} tBTA_DM_BLE_PF_UUID_COND; - -typedef struct { - UINT8 data_len; /* <= 20 bytes */ - UINT8 *p_data; -} tBTA_DM_BLE_PF_LOCAL_NAME_COND; - -typedef struct { - UINT16 company_id; /* company ID */ - UINT8 data_len; /* <= 20 bytes */ - UINT8 *p_pattern; - UINT16 company_id_mask; /* UUID value mask */ - UINT8 *p_pattern_mask; /* Manufacturer data matching mask, same length - as data pattern, set to all 0xff, match exact data */ -} tBTA_DM_BLE_PF_MANU_COND; - -typedef struct { - UINT16 uuid; /* service ID */ - UINT8 data_len; /* <= 20 bytes */ - UINT8 *p_pattern; - UINT8 *p_pattern_mask; /* Service data matching mask, same length - as data pattern, set to all 0xff, match exact data */ -} tBTA_DM_BLE_PF_SRVC_PATTERN_COND; - -typedef union { - tBLE_BD_ADDR target_addr; - tBTA_DM_BLE_PF_LOCAL_NAME_COND local_name; /* lcoal name filtering */ - tBTA_DM_BLE_PF_MANU_COND manu_data; /* manufactuer data filtering */ - tBTA_DM_BLE_PF_UUID_COND srvc_uuid; /* service UUID filtering */ - tBTA_DM_BLE_PF_UUID_COND solicitate_uuid; /* solicitated service UUID filtering */ - tBTA_DM_BLE_PF_SRVC_PATTERN_COND srvc_data; /* service data pattern */ -} tBTA_DM_BLE_PF_COND_PARAM; - -typedef UINT8 tBTA_DM_BLE_PF_FILT_INDEX; -typedef UINT8 tBTA_DM_BLE_PF_AVBL_SPACE; - -typedef INT8 tBTA_DM_RSSI_VALUE; -typedef UINT8 tBTA_DM_LINK_QUALITY_VALUE; - - -typedef UINT8 tBTA_SIG_STRENGTH_MASK; - - -/* Security Callback Events */ -#define BTA_DM_ENABLE_EVT 0 /* Enable Event */ -#define BTA_DM_DISABLE_EVT 1 /* Disable Event */ -#define BTA_DM_PIN_REQ_EVT 2 /* PIN request. */ -#define BTA_DM_AUTH_CMPL_EVT 3 /* Authentication complete indication. */ -#define BTA_DM_AUTHORIZE_EVT 4 /* Authorization request. */ -#define BTA_DM_LINK_UP_EVT 5 /* Connection UP event */ -#define BTA_DM_LINK_DOWN_EVT 6 /* Connection DOWN event */ -#define BTA_DM_SIG_STRENGTH_EVT 7 /* Signal strength for bluetooth connection */ -#define BTA_DM_BUSY_LEVEL_EVT 8 /* System busy level */ -#define BTA_DM_BOND_CANCEL_CMPL_EVT 9 /* Bond cancel complete indication */ -#define BTA_DM_SP_CFM_REQ_EVT 10 /* Simple Pairing User Confirmation request. */ -#define BTA_DM_SP_KEY_NOTIF_EVT 11 /* Simple Pairing Passkey Notification */ -#define BTA_DM_SP_RMT_OOB_EVT 12 /* Simple Pairing Remote OOB Data request. */ -#define BTA_DM_SP_KEYPRESS_EVT 13 /* Key press notification event. */ -#define BTA_DM_ROLE_CHG_EVT 14 /* Role Change event. */ -#define BTA_DM_BLE_KEY_EVT 15 /* BLE SMP key event for peer device keys */ -#define BTA_DM_BLE_SEC_REQ_EVT 16 /* BLE SMP security request */ -#define BTA_DM_BLE_PASSKEY_NOTIF_EVT 17 /* SMP passkey notification event */ -#define BTA_DM_BLE_PASSKEY_REQ_EVT 18 /* SMP passkey request event */ -#define BTA_DM_BLE_OOB_REQ_EVT 19 /* SMP OOB request event */ -#define BTA_DM_BLE_LOCAL_IR_EVT 20 /* BLE local IR event */ -#define BTA_DM_BLE_LOCAL_ER_EVT 21 /* BLE local ER event */ -#define BTA_DM_BLE_NC_REQ_EVT 22 /* SMP Numeric Comparison request event */ -// btla-specific ++ -#define BTA_DM_SP_RMT_OOB_EXT_EVT 23 /* Simple Pairing Remote OOB Extended Data request. */ -#define BTA_DM_BLE_AUTH_CMPL_EVT 24 /* BLE Auth complete */ -// btla-specific -- -#define BTA_DM_DEV_UNPAIRED_EVT 25 /* BT unpair event */ -#define BTA_DM_HW_ERROR_EVT 26 /* BT Chip H/W error */ -#define BTA_DM_LE_FEATURES_READ 27 /* Cotroller specific LE features are read */ -#define BTA_DM_ENER_INFO_READ 28 /* Energy info read */ -#define BTA_DM_BLE_DEV_UNPAIRED_EVT 29 /* BLE unpair event */ -#define BTA_DM_SP_KEY_REQ_EVT 30 /* Simple Pairing Passkey request */ - -typedef UINT8 tBTA_DM_SEC_EVT; - -/* Structure associated with BTA_DM_ENABLE_EVT */ -typedef struct { - tBTA_STATUS status; -} tBTA_DM_ENABLE; - -/* Structure associated with BTA_DM_PIN_REQ_EVT */ -typedef struct { - /* Note: First 3 data members must be, bd_addr, dev_class, and bd_name in order */ - BD_ADDR bd_addr; /* BD address peer device. */ - DEV_CLASS dev_class; /* Class of Device */ - BD_NAME bd_name; /* Name of peer device. */ - BOOLEAN min_16_digit; /* TRUE if the pin returned must be at least 16 digits */ -} tBTA_DM_PIN_REQ; - -/* BLE related definition */ -#if (SMP_INCLUDED == TRUE) -#define BTA_DM_AUTH_FAIL_BASE (HCI_ERR_MAX_ERR + 10) -#define BTA_DM_AUTH_CONVERT_SMP_CODE(x) (BTA_DM_AUTH_FAIL_BASE + (x)) -#define BTA_DM_AUTH_SMP_PASSKEY_FAIL BTA_DM_AUTH_CONVERT_SMP_CODE (SMP_PASSKEY_ENTRY_FAIL) -#define BTA_DM_AUTH_SMP_OOB_FAIL (BTA_DM_AUTH_FAIL_BASE + SMP_OOB_FAIL) -#define BTA_DM_AUTH_SMP_PAIR_AUTH_FAIL (BTA_DM_AUTH_FAIL_BASE + SMP_PAIR_AUTH_FAIL) -#define BTA_DM_AUTH_SMP_CONFIRM_VALUE_FAIL (BTA_DM_AUTH_FAIL_BASE + SMP_CONFIRM_VALUE_ERR) -#define BTA_DM_AUTH_SMP_PAIR_NOT_SUPPORT (BTA_DM_AUTH_FAIL_BASE + SMP_PAIR_NOT_SUPPORT) -#define BTA_DM_AUTH_SMP_ENC_KEY_SIZE (BTA_DM_AUTH_FAIL_BASE + SMP_ENC_KEY_SIZE) -#define BTA_DM_AUTH_SMP_INVALID_CMD (BTA_DM_AUTH_FAIL_BASE + SMP_INVALID_CMD) -#define BTA_DM_AUTH_SMP_UNKNOWN_ERR (BTA_DM_AUTH_FAIL_BASE + SMP_PAIR_FAIL_UNKNOWN) -#define BTA_DM_AUTH_SMP_REPEATED_ATTEMPT (BTA_DM_AUTH_FAIL_BASE + SMP_REPEATED_ATTEMPTS) -#define BTA_DM_AUTH_SMP_INVALID_PARAMETERS (BTA_DM_AUTH_FAIL_BASE + SMP_INVALID_PARAMETERS) -#define BTA_DM_AUTH_SMP_INTERNAL_ERR (BTA_DM_AUTH_FAIL_BASE + SMP_PAIR_INTERNAL_ERR) -#define BTA_DM_AUTH_SMP_UNKNOWN_IO (BTA_DM_AUTH_FAIL_BASE + SMP_UNKNOWN_IO_CAP) -#define BTA_DM_AUTH_SMP_INIT_FAIL (BTA_DM_AUTH_FAIL_BASE + SMP_INIT_FAIL) -#define BTA_DM_AUTH_SMP_CONFIRM_FAIL (BTA_DM_AUTH_FAIL_BASE + SMP_CONFIRM_FAIL) -#define BTA_DM_AUTH_SMP_BUSY (BTA_DM_AUTH_FAIL_BASE + SMP_BUSY) -#define BTA_DM_AUTH_SMP_ENC_FAIL (BTA_DM_AUTH_FAIL_BASE + SMP_ENC_FAIL) -#define BTA_DM_AUTH_SMP_RSP_TIMEOUT (BTA_DM_AUTH_FAIL_BASE + SMP_RSP_TIMEOUT) -#endif ///SMP_INCLUDED == TRUE -/* connection parameter boundary value and dummy value */ -#define BTA_DM_BLE_SCAN_INT_MIN BTM_BLE_SCAN_INT_MIN -#define BTA_DM_BLE_SCAN_INT_MAX BTM_BLE_SCAN_INT_MAX -#define BTA_DM_BLE_SCAN_WIN_MIN BTM_BLE_SCAN_WIN_MIN -#define BTA_DM_BLE_SCAN_WIN_MAX BTM_BLE_SCAN_WIN_MAX -#define BTA_DM_BLE_CONN_INT_MIN BTM_BLE_CONN_INT_MIN -#define BTA_DM_BLE_CONN_INT_MAX BTM_BLE_CONN_INT_MAX -#define BTA_DM_BLE_CONN_LATENCY_MAX BTM_BLE_CONN_LATENCY_MAX -#define BTA_DM_BLE_CONN_SUP_TOUT_MIN BTM_BLE_CONN_SUP_TOUT_MIN -#define BTA_DM_BLE_CONN_SUP_TOUT_MAX BTM_BLE_CONN_SUP_TOUT_MAX -#define BTA_DM_BLE_CONN_PARAM_UNDEF BTM_BLE_CONN_PARAM_UNDEF /* use this value when a specific value not to be overwritten */ - -#if (SMP_INCLUDED == TRUE) -#define BTA_LE_KEY_PENC BTM_LE_KEY_PENC /* encryption information of peer device */ -#define BTA_LE_KEY_PID BTM_LE_KEY_PID /* identity key of the peer device */ -#define BTA_LE_KEY_PCSRK BTM_LE_KEY_PCSRK /* peer SRK */ -#define BTA_LE_KEY_LENC BTM_LE_KEY_LENC /* master role security information:div */ -#define BTA_LE_KEY_LID BTM_LE_KEY_LID /* master device ID key */ -#define BTA_LE_KEY_LCSRK BTM_LE_KEY_LCSRK /* local CSRK has been deliver to peer */ -#endif ///SMP_INCLUDED == TRUE -typedef UINT8 tBTA_LE_KEY_TYPE; /* can be used as a bit mask */ - - -typedef tBTM_LE_PENC_KEYS tBTA_LE_PENC_KEYS ; -typedef tBTM_LE_PCSRK_KEYS tBTA_LE_PCSRK_KEYS; -typedef tBTM_LE_LENC_KEYS tBTA_LE_LENC_KEYS ; -typedef tBTM_LE_LCSRK_KEYS tBTA_LE_LCSRK_KEYS ; -typedef tBTM_LE_PID_KEYS tBTA_LE_PID_KEYS ; - -typedef union { - tBTA_LE_PENC_KEYS penc_key; /* received peer encryption key */ - tBTA_LE_PCSRK_KEYS psrk_key; /* received peer device SRK */ - tBTA_LE_PID_KEYS pid_key; /* peer device ID key */ - tBTA_LE_LENC_KEYS lenc_key; /* local encryption reproduction keys LTK = = d1(ER,DIV,0)*/ - tBTA_LE_LCSRK_KEYS lcsrk_key; /* local device CSRK = d1(ER,DIV,1)*/ - tBTA_LE_PID_KEYS lid_key; /* local device ID key for the particular remote */ -} tBTA_LE_KEY_VALUE; - -#define BTA_BLE_LOCAL_KEY_TYPE_ID 1 -#define BTA_BLE_LOCAL_KEY_TYPE_ER 2 -typedef UINT8 tBTA_DM_BLE_LOCAL_KEY_MASK; - -typedef struct { - BT_OCTET16 ir; - BT_OCTET16 irk; - BT_OCTET16 dhk; -} tBTA_BLE_LOCAL_ID_KEYS; -#if (SMP_INCLUDED == TRUE) -#define BTA_DM_SEC_GRANTED BTA_SUCCESS -#define BTA_DM_SEC_PAIR_NOT_SPT BTA_DM_AUTH_SMP_PAIR_NOT_SUPPORT -#define BTA_DM_SEC_REP_ATTEMPTS BTA_DM_AUTH_SMP_REPEATED_ATTEMPT -#endif ///SMP_INCLUDED == TRUE -typedef UINT8 tBTA_DM_BLE_SEC_GRANT; - - -#define BTA_DM_BLE_ONN_NONE BTM_BLE_CONN_NONE -#define BTA_DM_BLE_CONN_AUTO BTM_BLE_CONN_AUTO -#define BTA_DM_BLE_CONN_SELECTIVE BTM_BLE_CONN_SELECTIVE -typedef UINT8 tBTA_DM_BLE_CONN_TYPE; - -typedef BOOLEAN (tBTA_DM_BLE_SEL_CBACK)(BD_ADDR random_bda, UINT8 *p_remote_name); - -typedef tBTM_LE_UPDATE_CONN_PRAMS tBTA_LE_UPDATE_CONN_PRAMS; -typedef tBTM_UPDATE_CONN_PARAM_CBACK tBTA_UPDATE_CONN_PARAM_CBACK; - - -/* Structure associated with BTA_DM_BLE_SEC_REQ_EVT */ -typedef struct { - BD_ADDR bd_addr; /* peer address */ - BD_NAME bd_name; /* peer device name */ -} tBTA_DM_BLE_SEC_REQ; - -typedef struct { - BD_ADDR bd_addr; /* peer address */ - tBTM_LE_KEY_TYPE key_type; - tBTM_LE_KEY_VALUE *p_key_value; -} tBTA_DM_BLE_KEY; - -/* Structure associated with BTA_DM_AUTH_CMPL_EVT */ -typedef struct { - BD_ADDR bd_addr; /* BD address peer device. */ - BD_NAME bd_name; /* Name of peer device. */ - BOOLEAN key_present; /* Valid link key value in key element */ - LINK_KEY key; /* Link key associated with peer device. */ - UINT8 key_type; /* The type of Link Key */ - BOOLEAN success; /* TRUE of authentication succeeded, FALSE if failed. */ - UINT8 fail_reason; /* The HCI reason/error code for when success=FALSE */ - tBLE_ADDR_TYPE addr_type; /* Peer device address type */ - tBT_DEVICE_TYPE dev_type; -} tBTA_DM_AUTH_CMPL; - - -/* Structure associated with BTA_DM_AUTHORIZE_EVT */ -typedef struct { - BD_ADDR bd_addr; /* BD address peer device. */ - BD_NAME bd_name; /* Name of peer device. */ - tBTA_SERVICE_ID service; /* Service ID to authorize. */ -// btla-specific ++ - DEV_CLASS dev_class; -// btla-specific -- -} tBTA_DM_AUTHORIZE; - -/* Structure associated with BTA_DM_LINK_UP_EVT */ -typedef struct { - BD_ADDR bd_addr; /* BD address peer device. */ -#if BLE_INCLUDED == TRUE - tBTA_TRANSPORT link_type; -#endif -} tBTA_DM_LINK_UP; - -/* Structure associated with BTA_DM_LINK_DOWN_EVT */ -typedef struct { - BD_ADDR bd_addr; /* BD address peer device. */ - UINT8 status; /* connection open/closed */ - UINT8 reason; /* link down reason */ - BOOLEAN is_removed; /* TRUE if device is removed when link is down */ -#if BLE_INCLUDED == TRUE - tBTA_TRANSPORT link_type; -#endif -} tBTA_DM_LINK_DOWN; - -/* Structure associated with BTA_DM_ROLE_CHG_EVT */ -typedef struct { - BD_ADDR bd_addr; /* BD address peer device. */ - UINT8 new_role; /* the new connection role */ -} tBTA_DM_ROLE_CHG; - -/* Structure associated with BTA_DM_BUSY_LEVEL_EVT */ -typedef struct { - UINT8 level; /* when paging or inquiring, level is 10. - Otherwise, the number of ACL links */ - UINT8 level_flags; /* indicates individual flags */ -} tBTA_DM_BUSY_LEVEL; - -#define BTA_IO_CAP_OUT BTM_IO_CAP_OUT /* 0 DisplayOnly */ -#define BTA_IO_CAP_IO BTM_IO_CAP_IO /* 1 DisplayYesNo */ -#define BTA_IO_CAP_IN BTM_IO_CAP_IN /* 2 KeyboardOnly */ -#define BTA_IO_CAP_NONE BTM_IO_CAP_NONE /* 3 NoInputNoOutput */ -#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE -#define BTA_IO_CAP_KBDISP BTM_IO_CAP_KBDISP /* 4 Keyboard display */ -#endif -typedef tBTM_IO_CAP tBTA_IO_CAP; - -#define BTA_AUTH_SP_NO BTM_AUTH_SP_NO /* 0 MITM Protection Not Required - Single Profile/non-bonding - Numeric comparison with automatic accept allowed */ -#define BTA_AUTH_SP_YES BTM_AUTH_SP_YES /* 1 MITM Protection Required - Single Profile/non-bonding - Use IO Capabilities to determine authentication procedure */ -#define BTA_AUTH_AP_NO BTM_AUTH_AP_NO /* 2 MITM Protection Not Required - All Profiles/dedicated bonding - Numeric comparison with automatic accept allowed */ -#define BTA_AUTH_AP_YES BTM_AUTH_AP_YES /* 3 MITM Protection Required - All Profiles/dedicated bonding - Use IO Capabilities to determine authentication procedure */ -#define BTA_AUTH_SPGB_NO BTM_AUTH_SPGB_NO /* 4 MITM Protection Not Required - Single Profiles/general bonding - Numeric comparison with automatic accept allowed */ -#define BTA_AUTH_SPGB_YES BTM_AUTH_SPGB_YES /* 5 MITM Protection Required - Single Profiles/general bonding - Use IO Capabilities to determine authentication procedure */ -typedef tBTM_AUTH_REQ tBTA_AUTH_REQ; - -#define BTA_AUTH_DD_BOND BTM_AUTH_DD_BOND /* 2 this bit is set for dedicated bonding */ -#define BTA_AUTH_GEN_BOND BTM_AUTH_SPGB_NO /* 4 this bit is set for general bonding */ -#define BTA_AUTH_BONDS BTM_AUTH_BONDS /* 6 the general/dedicated bonding bits */ - -#if (SMP_INCLUDED == TRUE) -#define BTA_LE_AUTH_NO_BOND BTM_LE_AUTH_REQ_NO_BOND /* 0*/ -#define BTA_LE_AUTH_BOND BTM_LE_AUTH_REQ_BOND /* 1 << 0 */ -#define BTA_LE_AUTH_REQ_MITM BTM_LE_AUTH_REQ_MITM /* 1 << 2 */ - -#define BTA_LE_AUTH_REQ_SC_ONLY BTM_LE_AUTH_REQ_SC_ONLY /* 1 << 3 */ -#define BTA_LE_AUTH_REQ_SC_BOND BTM_LE_AUTH_REQ_SC_BOND /* 1001 */ -#define BTA_LE_AUTH_REQ_SC_MITM BTM_LE_AUTH_REQ_SC_MITM /* 1100 */ -#define BTA_LE_AUTH_REQ_SC_MITM_BOND BTM_LE_AUTH_REQ_SC_MITM_BOND /* 1101 */ -#endif ///SMP_INCLUDED == TRUE -typedef tBTM_LE_AUTH_REQ tBTA_LE_AUTH_REQ; /* combination of the above bit pattern */ - -#define BTA_OOB_NONE BTM_OOB_NONE -#define BTA_OOB_PRESENT BTM_OOB_PRESENT -#if BTM_OOB_INCLUDED == TRUE -#define BTA_OOB_UNKNOWN BTM_OOB_UNKNOWN -#endif -typedef tBTM_OOB_DATA tBTA_OOB_DATA; - -/* Structure associated with BTA_DM_SP_CFM_REQ_EVT */ -typedef struct { - /* Note: First 3 data members must be, bd_addr, dev_class, and bd_name in order */ - BD_ADDR bd_addr; /* peer address */ - DEV_CLASS dev_class; /* peer CoD */ - BD_NAME bd_name; /* peer device name */ - UINT32 num_val; /* the numeric value for comparison. If just_works, do not show this number to UI */ - BOOLEAN just_works; /* TRUE, if "Just Works" association model */ - tBTA_AUTH_REQ loc_auth_req; /* Authentication required for local device */ - tBTA_AUTH_REQ rmt_auth_req; /* Authentication required for peer device */ - tBTA_IO_CAP loc_io_caps; /* IO Capabilities of local device */ - tBTA_AUTH_REQ rmt_io_caps; /* IO Capabilities of remote device */ -} tBTA_DM_SP_CFM_REQ; - -/* Structure associated with tBTA_DM_SP_KEY_REQ */ -typedef struct { - BD_ADDR bd_addr; /* peer address */ - DEV_CLASS dev_class; /* peer CoD */ - BD_NAME bd_name; /* peer device name */ -} tBTA_DM_SP_KEY_REQ; - -enum { - BTA_SP_KEY_STARTED, /* passkey entry started */ - BTA_SP_KEY_ENTERED, /* passkey digit entered */ - BTA_SP_KEY_ERASED, /* passkey digit erased */ - BTA_SP_KEY_CLEARED, /* passkey cleared */ - BTA_SP_KEY_COMPLT /* passkey entry completed */ -}; -typedef UINT8 tBTA_SP_KEY_TYPE; - -/* Structure associated with BTA_DM_SP_KEYPRESS_EVT */ -typedef struct { - BD_ADDR bd_addr; /* peer address */ - tBTA_SP_KEY_TYPE notif_type; -} tBTA_DM_SP_KEY_PRESS; - -/* Structure associated with BTA_DM_SP_KEY_NOTIF_EVT */ -typedef struct { - /* Note: First 3 data members must be, bd_addr, dev_class, and bd_name in order */ - BD_ADDR bd_addr; /* peer address */ - DEV_CLASS dev_class; /* peer CoD */ - BD_NAME bd_name; /* peer device name */ - UINT32 passkey; /* the numeric value for comparison. If just_works, do not show this number to UI */ -} tBTA_DM_SP_KEY_NOTIF; - -/* Structure associated with BTA_DM_SP_RMT_OOB_EVT */ -typedef struct { - /* Note: First 3 data members must be, bd_addr, dev_class, and bd_name in order */ - BD_ADDR bd_addr; /* peer address */ - DEV_CLASS dev_class; /* peer CoD */ - BD_NAME bd_name; /* peer device name */ -} tBTA_DM_SP_RMT_OOB; - -/* Structure associated with BTA_DM_BOND_CANCEL_CMPL_EVT */ -typedef struct { - tBTA_STATUS result; /* TRUE of bond cancel succeeded, FALSE if failed. */ -} tBTA_DM_BOND_CANCEL_CMPL; - -/* Union of all security callback structures */ -typedef union { - tBTA_DM_ENABLE enable; /* BTA enabled */ - tBTA_DM_PIN_REQ pin_req; /* PIN request. */ - tBTA_DM_AUTH_CMPL auth_cmpl; /* Authentication complete indication. */ - tBTA_DM_AUTHORIZE authorize; /* Authorization request. */ - tBTA_DM_LINK_UP link_up; /* ACL connection down event */ - tBTA_DM_LINK_DOWN link_down; /* ACL connection down event */ - tBTA_DM_BUSY_LEVEL busy_level; /* System busy level */ - tBTA_DM_SP_CFM_REQ cfm_req; /* user confirm request */ - tBTA_DM_SP_KEY_REQ key_req; /* user passkey request */ - tBTA_DM_SP_KEY_NOTIF key_notif; /* passkey notification */ - tBTA_DM_SP_RMT_OOB rmt_oob; /* remote oob */ - tBTA_DM_BOND_CANCEL_CMPL bond_cancel_cmpl; /* Bond Cancel Complete indication */ - tBTA_DM_SP_KEY_PRESS key_press; /* key press notification event */ - tBTA_DM_ROLE_CHG role_chg; /* role change event */ - tBTA_DM_BLE_SEC_REQ ble_req; /* BLE SMP related request */ - tBTA_DM_BLE_KEY ble_key; /* BLE SMP keys used when pairing */ - tBTA_BLE_LOCAL_ID_KEYS ble_id_keys; /* IR event */ - BT_OCTET16 ble_er; /* ER event data */ -} tBTA_DM_SEC; - -/* Security callback */ -typedef void (tBTA_DM_SEC_CBACK)(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data); - -#define BTA_BLE_MULTI_ADV_ILLEGAL 0 - -/* multi adv callback event */ -#define BTA_BLE_MULTI_ADV_ENB_EVT 1 -#define BTA_BLE_MULTI_ADV_DISABLE_EVT 2 -#define BTA_BLE_MULTI_ADV_PARAM_EVT 3 -#define BTA_BLE_MULTI_ADV_DATA_EVT 4 - -typedef UINT8 tBTA_BLE_MULTI_ADV_EVT; - -/* multi adv callback */ -typedef void (tBTA_BLE_MULTI_ADV_CBACK)(tBTA_BLE_MULTI_ADV_EVT event, - UINT8 inst_id, void *p_ref, tBTA_STATUS status); -typedef UINT32 tBTA_DM_BLE_REF_VALUE; - -#define BTA_DM_BLE_PF_ENABLE_EVT BTM_BLE_PF_ENABLE -#define BTA_DM_BLE_PF_CONFIG_EVT BTM_BLE_PF_CONFIG -typedef UINT8 tBTA_DM_BLE_PF_EVT; - -#define BTA_DM_BLE_PF_ENABLE 1 -#define BTA_DM_BLE_PF_CONFIG 2 -typedef UINT8 tBTA_DM_BLE_PF_ACTION; - -/* Config callback */ -typedef void (tBTA_DM_BLE_PF_CFG_CBACK) (tBTA_DM_BLE_PF_ACTION action, - tBTA_DM_BLE_PF_COND_TYPE cfg_cond, - tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, tBTA_STATUS status, - tBTA_DM_BLE_REF_VALUE ref_value); -/* Param callback */ -typedef void (tBTA_DM_BLE_PF_PARAM_CBACK) (UINT8 action_type, tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, - tBTA_DM_BLE_REF_VALUE ref_value, tBTA_STATUS status); - -/* Status callback */ -typedef void (tBTA_DM_BLE_PF_STATUS_CBACK) (UINT8 action, tBTA_STATUS status, - tBTA_DM_BLE_REF_VALUE ref_value); - - -#define BTA_DM_BLE_PF_BRDCAST_ADDR_FILT 1 -#define BTA_DM_BLE_PF_SERV_DATA_CHG_FILT 2 -#define BTA_DM_BLE_PF_SERV_UUID 4 -#define BTA_DM_BLE_PF_SERV_SOLC_UUID 8 -#define BTA_DM_BLE_PF_LOC_NAME_CHECK 16 -#define BTA_DM_BLE_PF_MANUF_NAME_CHECK 32 -#define BTA_DM_BLE_PF_SERV_DATA_CHECK 64 -typedef UINT16 tBTA_DM_BLE_PF_FEAT_SEL; - -#define BTA_DM_BLE_PF_LIST_LOGIC_OR 1 -#define BTA_DM_BLE_PF_LIST_LOGIC_AND 2 -typedef UINT16 tBTA_DM_BLE_PF_LIST_LOGIC_TYPE; - -#define BTA_DM_BLE_PF_FILT_LOGIC_OR 0 -#define BTA_DM_BLE_PF_FILT_LOGIC_AND 1 -typedef UINT16 tBTA_DM_BLE_PF_FILT_LOGIC_TYPE; - -typedef UINT8 tBTA_DM_BLE_PF_RSSI_THRESHOLD; -typedef UINT8 tBTA_DM_BLE_PF_DELIVERY_MODE; -typedef UINT16 tBTA_DM_BLE_PF_TIMEOUT; -typedef UINT8 tBTA_DM_BLE_PF_TIMEOUT_CNT; -typedef UINT16 tBTA_DM_BLE_PF_ADV_TRACK_ENTRIES; - -typedef struct { - tBTA_DM_BLE_PF_FEAT_SEL feat_seln; - tBTA_DM_BLE_PF_LIST_LOGIC_TYPE list_logic_type; - tBTA_DM_BLE_PF_FILT_LOGIC_TYPE filt_logic_type; - tBTA_DM_BLE_PF_RSSI_THRESHOLD rssi_high_thres; - tBTA_DM_BLE_PF_RSSI_THRESHOLD rssi_low_thres; - tBTA_DM_BLE_PF_DELIVERY_MODE dely_mode; - tBTA_DM_BLE_PF_TIMEOUT found_timeout; - tBTA_DM_BLE_PF_TIMEOUT lost_timeout; - tBTA_DM_BLE_PF_TIMEOUT_CNT found_timeout_cnt; - tBTA_DM_BLE_PF_ADV_TRACK_ENTRIES num_of_tracking_entries; -} tBTA_DM_BLE_PF_FILT_PARAMS; - -/* Search callback events */ -#define BTA_DM_INQ_RES_EVT 0 /* Inquiry result for a peer device. */ -#define BTA_DM_INQ_CMPL_EVT 1 /* Inquiry complete. */ -#define BTA_DM_DISC_RES_EVT 2 /* Discovery result for a peer device. */ -#define BTA_DM_DISC_BLE_RES_EVT 3 /* Discovery result for BLE GATT based servoce on a peer device. */ -#define BTA_DM_DISC_CMPL_EVT 4 /* Discovery complete. */ -#define BTA_DM_DI_DISC_CMPL_EVT 5 /* Discovery complete. */ -#define BTA_DM_SEARCH_CANCEL_CMPL_EVT 6 /* Search cancelled */ - -typedef UINT8 tBTA_DM_SEARCH_EVT; - -#define BTA_DM_INQ_RES_IGNORE_RSSI BTM_INQ_RES_IGNORE_RSSI /* 0x7f RSSI value not supplied (ignore it) */ - -/* Structure associated with BTA_DM_INQ_RES_EVT */ -typedef struct { - BD_ADDR bd_addr; /* BD address peer device. */ - DEV_CLASS dev_class; /* Device class of peer device. */ - BOOLEAN remt_name_not_required; /* Application sets this flag if it already knows the name of the device */ - /* If the device name is known to application BTA skips the remote name request */ - BOOLEAN is_limited; /* TRUE, if the limited inquiry bit is set in the CoD */ - INT8 rssi; /* The rssi value */ - UINT8 *p_eir; /* Received EIR */ -#if (BLE_INCLUDED == TRUE) - UINT8 inq_result_type; - UINT8 ble_addr_type; - tBTM_BLE_EVT_TYPE ble_evt_type; - tBT_DEVICE_TYPE device_type; - UINT8 flag; - UINT8 adv_data_len; - UINT8 scan_rsp_len; -#endif - -} tBTA_DM_INQ_RES; - -/* Structure associated with BTA_DM_INQ_CMPL_EVT */ -typedef struct { - UINT8 num_resps; /* Number of inquiry responses. */ -} tBTA_DM_INQ_CMPL; - -/* Structure associated with BTA_DM_DI_DISC_CMPL_EVT */ -typedef struct { - BD_ADDR bd_addr; /* BD address peer device. */ - UINT8 num_record; /* Number of DI record */ - tBTA_STATUS result; -} tBTA_DM_DI_DISC_CMPL; - -/* Structure associated with BTA_DM_DISC_RES_EVT */ -typedef struct { - BD_ADDR bd_addr; /* BD address peer device. */ - BD_NAME bd_name; /* Name of peer device. */ - tBTA_SERVICE_MASK services; /* Services found on peer device. */ -// btla-specific ++ - UINT8 *p_raw_data; /* Raw data for discovery DB */ - UINT32 raw_data_size; /* Size of raw data */ - tBT_DEVICE_TYPE device_type; /* device type in case it is BLE device */ - UINT32 num_uuids; - UINT8 *p_uuid_list; -// btla-specific -- - tBTA_STATUS result; -} tBTA_DM_DISC_RES; - -/* Structure associated with tBTA_DM_DISC_BLE_RES */ -typedef struct { - BD_ADDR bd_addr; /* BD address peer device. */ - BD_NAME bd_name; /* Name of peer device. */ - tBT_UUID service; /* GATT based Services UUID found on peer device. */ -} tBTA_DM_DISC_BLE_RES; - - -/* Union of all search callback structures */ -typedef union { - tBTA_DM_INQ_RES inq_res; /* Inquiry result for a peer device. */ - tBTA_DM_INQ_CMPL inq_cmpl; /* Inquiry complete. */ - tBTA_DM_DISC_RES disc_res; /* Discovery result for a peer device. */ - tBTA_DM_DISC_BLE_RES disc_ble_res; /* Discovery result for GATT based service */ - tBTA_DM_DI_DISC_CMPL di_disc; /* DI discovery result for a peer device */ -} tBTA_DM_SEARCH; - -/* Structure of search callback event and structures */ -typedef struct { - tBTA_DM_SEARCH_EVT event; /* Search callback events */ - UINT16 len; /* Length of p_data */ - tBTA_DM_SEARCH *p_data; /* Union of all search callback structures */ -} tBTA_DM_SEARCH_PARAM; - -/* Search callback */ -typedef void (tBTA_DM_SEARCH_CBACK)(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data); - -/* Execute call back */ -typedef void (tBTA_DM_EXEC_CBACK) (void *p_param); - -/* Encryption callback*/ -typedef void (tBTA_DM_ENCRYPT_CBACK) (BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_STATUS result); - -/* Relate to ESP_BLE_SEC_xxx in esp_gatt_defs.h */ -#if BLE_INCLUDED == TRUE -#define BTA_DM_BLE_SEC_NONE BTM_BLE_SEC_NONE -#define BTA_DM_BLE_SEC_ENCRYPT BTM_BLE_SEC_ENCRYPT -#define BTA_DM_BLE_SEC_NO_MITM BTM_BLE_SEC_ENCRYPT_NO_MITM -#define BTA_DM_BLE_SEC_MITM BTM_BLE_SEC_ENCRYPT_MITM -typedef tBTM_BLE_SEC_ACT tBTA_DM_BLE_SEC_ACT; - -typedef tBTM_BLE_TX_TIME_MS tBTA_DM_BLE_TX_TIME_MS; -typedef tBTM_BLE_RX_TIME_MS tBTA_DM_BLE_RX_TIME_MS; -typedef tBTM_BLE_IDLE_TIME_MS tBTA_DM_BLE_IDLE_TIME_MS; -typedef tBTM_BLE_ENERGY_USED tBTA_DM_BLE_ENERGY_USED; - -#define BTA_DM_CONTRL_UNKNOWN 0 /* Unknown state */ -#define BTA_DM_CONTRL_ACTIVE 1 /* ACL link on, SCO link ongoing, sniff mode */ -#define BTA_DM_CONTRL_SCAN 2 /* Scan state - paging/inquiry/trying to connect*/ -#define BTA_DM_CONTRL_IDLE 3 /* Idle state - page scan, LE advt, inquiry scan */ - -typedef UINT8 tBTA_DM_CONTRL_STATE; - -typedef UINT8 tBTA_DM_BLE_ADV_STATE; -typedef UINT8 tBTA_DM_BLE_ADV_INFO_PRESENT; -typedef UINT8 tBTA_DM_BLE_RSSI_VALUE; -typedef UINT16 tBTA_DM_BLE_ADV_INFO_TIMESTAMP; - -typedef tBTM_BLE_TRACK_ADV_DATA tBTA_DM_BLE_TRACK_ADV_DATA; - -typedef void (tBTA_BLE_SCAN_THRESHOLD_CBACK)(tBTA_DM_BLE_REF_VALUE ref_value); - -typedef void (tBTA_BLE_SCAN_REP_CBACK) (tBTA_DM_BLE_REF_VALUE ref_value, UINT8 report_format, - UINT8 num_records, UINT16 data_len, - UINT8 *p_rep_data, tBTA_STATUS status); - -typedef void (tBTA_BLE_SCAN_SETUP_CBACK) (tBTA_BLE_BATCH_SCAN_EVT evt, - tBTA_DM_BLE_REF_VALUE ref_value, - tBTA_STATUS status); - -typedef void (tBTA_START_STOP_SCAN_CMPL_CBACK) (tBTA_STATUS status); - -typedef void (tBTA_START_STOP_ADV_CMPL_CBACK) (tBTA_STATUS status); - -typedef void (tBTA_BLE_TRACK_ADV_CMPL_CBACK)(int action, tBTA_STATUS status, - tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, - tBTA_DM_BLE_REF_VALUE ref_value); - -typedef void (tBTA_BLE_TRACK_ADV_CBACK)(tBTA_DM_BLE_TRACK_ADV_DATA *p_adv_data); - -typedef void (tBTA_BLE_ENERGY_INFO_CBACK)(tBTA_DM_BLE_TX_TIME_MS tx_time, - tBTA_DM_BLE_RX_TIME_MS rx_time, - tBTA_DM_BLE_IDLE_TIME_MS idle_time, - tBTA_DM_BLE_ENERGY_USED energy_used, - tBTA_DM_CONTRL_STATE ctrl_state, - tBTA_STATUS status); - -#else -typedef UINT8 tBTA_DM_BLE_SEC_ACT; -#endif - -/* Maximum service name length */ -#define BTA_SERVICE_NAME_LEN 35 -#define BTA_SERVICE_DESP_LEN BTA_SERVICE_NAME_LEN -#define BTA_PROVIDER_NAME_LEN BTA_SERVICE_NAME_LEN - - -/* link policy masks */ -#define BTA_DM_LP_SWITCH HCI_ENABLE_MASTER_SLAVE_SWITCH -#define BTA_DM_LP_HOLD HCI_ENABLE_HOLD_MODE -#define BTA_DM_LP_SNIFF HCI_ENABLE_SNIFF_MODE -#define BTA_DM_LP_PARK HCI_ENABLE_PARK_MODE -typedef UINT16 tBTA_DM_LP_MASK; - -/* power mode actions */ -#define BTA_DM_PM_NO_ACTION 0x00 /* no change to the current pm setting */ -#define BTA_DM_PM_PARK 0x10 /* prefers park mode */ -#define BTA_DM_PM_SNIFF 0x20 /* prefers sniff mode */ -#define BTA_DM_PM_SNIFF1 0x21 /* prefers sniff1 mode */ -#define BTA_DM_PM_SNIFF2 0x22 /* prefers sniff2 mode */ -#define BTA_DM_PM_SNIFF3 0x23 /* prefers sniff3 mode */ -#define BTA_DM_PM_SNIFF4 0x24 /* prefers sniff4 mode */ -#define BTA_DM_PM_SNIFF5 0x25 /* prefers sniff5 mode */ -#define BTA_DM_PM_SNIFF6 0x26 /* prefers sniff6 mode */ -#define BTA_DM_PM_SNIFF7 0x27 /* prefers sniff7 mode */ -#define BTA_DM_PM_SNIFF_USER0 0x28 /* prefers user-defined sniff0 mode (testtool only) */ -#define BTA_DM_PM_SNIFF_USER1 0x29 /* prefers user-defined sniff1 mode (testtool only) */ -#define BTA_DM_PM_ACTIVE 0x40 /* prefers active mode */ -#define BTA_DM_PM_RETRY 0x80 /* retry power mode based on current settings */ -#define BTA_DM_PM_SUSPEND 0x04 /* prefers suspend mode */ -#define BTA_DM_PM_NO_PREF 0x01 /* service has no prefernce on power mode setting. eg. connection to service got closed */ - -typedef UINT8 tBTA_DM_PM_ACTION; - -/* index to bta_dm_ssr_spec */ -#define BTA_DM_PM_SSR0 0 -#define BTA_DM_PM_SSR1 1 /* BTA_DM_PM_SSR1 will be dedicated for - HH SSR setting entry, no other profile can use it */ -#define BTA_DM_PM_SSR2 2 -#define BTA_DM_PM_SSR3 3 -#define BTA_DM_PM_SSR4 4 -#define BTA_DM_PM_SSR5 5 -#define BTA_DM_PM_SSR6 6 - -#define BTA_DM_PM_NUM_EVTS 9 - -#ifndef BTA_DM_PM_PARK_IDX -#define BTA_DM_PM_PARK_IDX 5 /* the actual index to bta_dm_pm_md[] for PARK mode */ -#endif - -#ifndef BTA_DM_PM_SNIFF_A2DP_IDX -#define BTA_DM_PM_SNIFF_A2DP_IDX BTA_DM_PM_SNIFF -#endif - -#ifndef BTA_DM_PM_SNIFF_HD_IDLE_IDX -#define BTA_DM_PM_SNIFF_HD_IDLE_IDX BTA_DM_PM_SNIFF2 -#endif - -#ifndef BTA_DM_PM_SNIFF_SCO_OPEN_IDX -#define BTA_DM_PM_SNIFF_SCO_OPEN_IDX BTA_DM_PM_SNIFF3 -#endif - -#ifndef BTA_DM_PM_SNIFF_HD_ACTIVE_IDX -#define BTA_DM_PM_SNIFF_HD_ACTIVE_IDX BTA_DM_PM_SNIFF4 -#endif - -#ifndef BTA_DM_PM_SNIFF_HH_OPEN_IDX -#define BTA_DM_PM_SNIFF_HH_OPEN_IDX BTA_DM_PM_SNIFF2 -#endif - -#ifndef BTA_DM_PM_SNIFF_HH_ACTIVE_IDX -#define BTA_DM_PM_SNIFF_HH_ACTIVE_IDX BTA_DM_PM_SNIFF2 -#endif - -#ifndef BTA_DM_PM_SNIFF_HH_IDLE_IDX -#define BTA_DM_PM_SNIFF_HH_IDLE_IDX BTA_DM_PM_SNIFF2 -#endif - - -#ifndef BTA_DM_PM_HH_OPEN_DELAY -#define BTA_DM_PM_HH_OPEN_DELAY 30000 -#endif - -#ifndef BTA_DM_PM_HH_ACTIVE_DELAY -#define BTA_DM_PM_HH_ACTIVE_DELAY 30000 -#endif - -#ifndef BTA_DM_PM_HH_IDLE_DELAY -#define BTA_DM_PM_HH_IDLE_DELAY 30000 -#endif - -/* The Sniff Parameters defined below must be ordered from highest - * latency (biggest interval) to lowest latency. If there is a conflict - * among the connected services the setting with the lowest latency will - * be selected. If a device should override a sniff parameter then it - * must insure that order is maintained. - */ -#ifndef BTA_DM_PM_SNIFF_MAX -#define BTA_DM_PM_SNIFF_MAX 800 -#define BTA_DM_PM_SNIFF_MIN 400 -#define BTA_DM_PM_SNIFF_ATTEMPT 4 -#define BTA_DM_PM_SNIFF_TIMEOUT 1 -#endif - -#ifndef BTA_DM_PM_SNIFF1_MAX -#define BTA_DM_PM_SNIFF1_MAX 400 -#define BTA_DM_PM_SNIFF1_MIN 200 -#define BTA_DM_PM_SNIFF1_ATTEMPT 4 -#define BTA_DM_PM_SNIFF1_TIMEOUT 1 -#endif - -#ifndef BTA_DM_PM_SNIFF2_MAX -#define BTA_DM_PM_SNIFF2_MAX 180 -#define BTA_DM_PM_SNIFF2_MIN 150 -#define BTA_DM_PM_SNIFF2_ATTEMPT 4 -#define BTA_DM_PM_SNIFF2_TIMEOUT 1 -#endif - -#ifndef BTA_DM_PM_SNIFF3_MAX -#define BTA_DM_PM_SNIFF3_MAX 150 -#define BTA_DM_PM_SNIFF3_MIN 50 -#define BTA_DM_PM_SNIFF3_ATTEMPT 4 -#define BTA_DM_PM_SNIFF3_TIMEOUT 1 -#endif - -#ifndef BTA_DM_PM_SNIFF4_MAX -#define BTA_DM_PM_SNIFF4_MAX 54 -#define BTA_DM_PM_SNIFF4_MIN 30 -#define BTA_DM_PM_SNIFF4_ATTEMPT 4 -#define BTA_DM_PM_SNIFF4_TIMEOUT 1 -#endif - -#ifndef BTA_DM_PM_SNIFF5_MAX -#define BTA_DM_PM_SNIFF5_MAX 36 -#define BTA_DM_PM_SNIFF5_MIN 30 -#define BTA_DM_PM_SNIFF5_ATTEMPT 2 -#define BTA_DM_PM_SNIFF5_TIMEOUT 0 -#endif - -#ifndef BTA_DM_PM_PARK_MAX -#define BTA_DM_PM_PARK_MAX 800 -#define BTA_DM_PM_PARK_MIN 400 -#define BTA_DM_PM_PARK_ATTEMPT 0 -#define BTA_DM_PM_PARK_TIMEOUT 0 -#endif - - -/* Switch callback events */ -#define BTA_DM_SWITCH_CMPL_EVT 0 /* Completion of the Switch API */ - -typedef UINT8 tBTA_DM_SWITCH_EVT; -typedef void (tBTA_DM_SWITCH_CBACK)(tBTA_DM_SWITCH_EVT event, tBTA_STATUS status); - -/* Audio routing out configuration */ -#define BTA_DM_ROUTE_NONE 0x00 /* No Audio output */ -#define BTA_DM_ROUTE_DAC 0x01 /* routing over analog output */ -#define BTA_DM_ROUTE_I2S 0x02 /* routing over digital (I2S) output */ -#define BTA_DM_ROUTE_BT_MONO 0x04 /* routing over SCO */ -#define BTA_DM_ROUTE_BT_STEREO 0x08 /* routing over BT Stereo */ -#define BTA_DM_ROUTE_HOST 0x10 /* routing over Host */ -#define BTA_DM_ROUTE_FMTX 0x20 /* routing over FMTX */ -#define BTA_DM_ROUTE_FMRX 0x40 /* routing over FMRX */ -#define BTA_DM_ROUTE_BTSNK 0x80 /* routing over BT SNK */ - -typedef UINT8 tBTA_DM_ROUTE_PATH; - -#if (SDP_INCLUDED == TRUE) -/* Device Identification (DI) data structure -*/ -/* Used to set the DI record */ -typedef tSDP_DI_RECORD tBTA_DI_RECORD; -/* Used to get the DI record */ -typedef tSDP_DI_GET_RECORD tBTA_DI_GET_RECORD; -/* SDP discovery database */ -typedef tSDP_DISCOVERY_DB tBTA_DISCOVERY_DB; -#endif ///SDP_INCLUDED == TRUE - -#ifndef BTA_DI_NUM_MAX -#define BTA_DI_NUM_MAX 3 -#endif - -/* Device features mask definitions */ -#define BTA_FEATURE_BYTES_PER_PAGE BTM_FEATURE_BYTES_PER_PAGE -#define BTA_EXT_FEATURES_PAGE_MAX BTM_EXT_FEATURES_PAGE_MAX -/* ACL type -*/ -#define BTA_DM_LINK_TYPE_BR_EDR 0x01 -#define BTA_DM_LINK_TYPE_LE 0x02 -#define BTA_DM_LINK_TYPE_ALL 0xFF -typedef UINT8 tBTA_DM_LINK_TYPE; - -#define IMMEDIATE_DELY_MODE 0x00 -#define ONFOUND_DELY_MODE 0x01 -#define BATCH_DELY_MODE 0x02 -#define ALLOW_ALL_FILTER 0x00 -#define LOWEST_RSSI_VALUE 129 - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/******************************************************************************* -** -** Function BTA_EnableBluetooth -** -** Description This function initializes BTA and prepares BTA and the -** Bluetooth protocol stack for use. This function is -** typically called at startup or when Bluetooth services -** are required by the phone. This function must be called -** before calling any other API function. -** -** -** Returns BTA_SUCCESS if successful. -** BTA_FAIL if internal failure. -** -*******************************************************************************/ -extern tBTA_STATUS BTA_EnableBluetooth(tBTA_DM_SEC_CBACK *p_cback); - -/******************************************************************************* -** -** Function BTA_DisableBluetooth -** -** Description This function disables BTA and the Bluetooth protocol -** stack. It is called when BTA is no longer being used -** by any application in the system. -** -** -** Returns void -** -*******************************************************************************/ -extern tBTA_STATUS BTA_DisableBluetooth(void); - -/******************************************************************************* -** -** Function BTA_EnableTestMode -** -** Description Enables bluetooth device under test mode -** -** -** Returns tBTA_STATUS -** -*******************************************************************************/ -extern tBTA_STATUS BTA_EnableTestMode(void); - -/******************************************************************************* -** -** Function BTA_DisableTestMode -** -** Description Disable bluetooth device under test mode -** -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DisableTestMode(void); - -/******************************************************************************* -** -** Function BTA_DmSetDeviceName -** -** Description This function sets the Bluetooth name of the local device. -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmSetDeviceName(const char *p_name); - -extern void BTA_DmUpdateWhiteList(BOOLEAN add_remove, BD_ADDR remote_addr, tBTA_ADD_WHITELIST_CBACK *add_wl_cb); - -extern void BTA_DmBleReadAdvTxPower(tBTA_CMPL_CB *cmpl_cb); - -extern void BTA_DmBleReadRSSI(BD_ADDR remote_addr, tBTA_TRANSPORT transport, tBTA_CMPL_CB *cmpl_cb); - -/******************************************************************************* -** -** Function BTA_DmSetVisibility -** -** Description This function sets the Bluetooth connectable,discoverable, -** pairable and conn paired only modesmodes of the local device. -** This controls whether other Bluetooth devices can find and connect to -** the local device. -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmSetVisibility(tBTA_DM_DISC disc_mode, tBTA_DM_CONN conn_mode, UINT8 pairable_mode, UINT8 conn_filter); - -/******************************************************************************* -** -** Function BTA_DmSearch -** -** Description This function searches for peer Bluetooth devices. It -** first performs an inquiry; for each device found from the -** inquiry it gets the remote name of the device. If -** parameter services is nonzero, service discovery will be -** performed on each device for the services specified. -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmSearch(tBTA_DM_INQ *p_dm_inq, tBTA_SERVICE_MASK services, - tBTA_DM_SEARCH_CBACK *p_cback); - -/******************************************************************************* -** -** Function BTA_DmSearchCancel -** -** Description This function cancels a search that has been initiated -** by calling BTA_DmSearch(). -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmSearchCancel(void); - -/******************************************************************************* -** -** Function BTA_DmDiscover -** -** Description This function performs service discovery for the services -** of a particular peer device. -** -** -** Returns void -** -*******************************************************************************/ -#if (SDP_INCLUDED == TRUE) -extern void BTA_DmDiscover(BD_ADDR bd_addr, tBTA_SERVICE_MASK services, - tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search); -// btla-specific ++ -/******************************************************************************* -** -** Function BTA_DmDiscoverUUID -** -** Description This function performs service discovery for the services -** of a particular peer device. -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmDiscoverUUID(BD_ADDR bd_addr, tSDP_UUID *uuid, - tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search); -#endif ///SDP_INCLUDED == TRUE -/******************************************************************************* -** -** Function BTA_DmGetCachedRemoteName -** -** Description Retieve cached remote name if available -** -** Returns BTA_SUCCESS if cached name was retrieved -** BTA_FAILURE if cached name is not available -** -*******************************************************************************/ -tBTA_STATUS BTA_DmGetCachedRemoteName(BD_ADDR remote_device, UINT8 **pp_cached_name); -// btla-specific -- - -/******************************************************************************* -** -** Function BTA_DmBond -** -** Description This function initiates a bonding procedure with a peer -** device. The bonding procedure enables authentication -** and optionally encryption on the Bluetooth link. -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBond(BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function BTA_DmBondByTransport -** -** Description This function initiates a bonding procedure with a peer -** device by designated transport. The bonding procedure enables -** authentication and optionally encryption on the Bluetooth link. -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBondByTransport(BD_ADDR bd_addr, tBTA_TRANSPORT transport); - - -/******************************************************************************* -** -** Function BTA_DmBondCancel -** -** Description This function cancels a bonding procedure with a peer -** device. -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBondCancel(BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function BTA_DMSetPinType -** -** Description This function sets pin type as BTM_PIN_TYPE_FIXED or BTM_PIN_TYPE_VARIABLE -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DMSetPinType (UINT8 pin_type, UINT8 *pin_code, UINT8 pin_code_len); - -/******************************************************************************* -** -** Function BTA_DmPinReply -** -** Description This function provides a PIN when one is requested by DM -** during a bonding procedure. The application should call -** this function after the security callback is called with -** a BTA_DM_PIN_REQ_EVT. -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmPinReply(BD_ADDR bd_addr, BOOLEAN accept, UINT8 pin_len, - UINT8 *p_pin); - -#if (BTM_OOB_INCLUDED == TRUE) -/******************************************************************************* -** -** Function BTA_DmLocalOob -** -** Description This function retrieves the OOB data from local controller. -** The result is reported by bta_dm_co_loc_oob(). -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmLocalOob(void); -#endif /* BTM_OOB_INCLUDED */ - -/******************************************************************************* -** -** Function BTA_DmConfirm -** -** Description This function accepts or rejects the numerical value of the -** Simple Pairing process on BTA_DM_SP_CFM_REQ_EVT -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmConfirm(BD_ADDR bd_addr, BOOLEAN accept); - -/******************************************************************************* -** -** Function BTA_DmPasskeyReqReply -** -** Description This function is called to provide the passkey for -** Simple Pairing in response to BTA_DM_SP_KEY_REQ_EVT -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmPasskeyReqReply(BOOLEAN accept, BD_ADDR bd_addr, UINT32 passkey); - -/******************************************************************************* -** -** Function BTA_DmAddDevice -** -** Description This function adds a device to the security database list -** of peer devices. This function would typically be called -** at system startup to initialize the security database with -** known peer devices. This is a direct execution function -** that may lock task scheduling on some platforms. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmAddDevice(BD_ADDR bd_addr, DEV_CLASS dev_class, - LINK_KEY link_key, tBTA_SERVICE_MASK trusted_mask, - BOOLEAN is_trusted, UINT8 key_type, - tBTA_IO_CAP io_cap, UINT8 pin_length); - -/******************************************************************************* -** -** Function BTA_DmRemoveDevice -** -** Description This function removes a device from the security database. -** This is a direct execution function that may lock task -** scheduling on some platforms. -** -** -** Returns BTA_SUCCESS if successful. -** BTA_FAIL if operation failed. -** -*******************************************************************************/ -extern tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr, tBT_TRANSPORT transport); - -/******************************************************************************* -** -** Function BTA_GetEirService -** -** Description This function is called to get BTA service mask from EIR. -** -** Parameters p_eir - pointer of EIR significant part -** p_services - return the BTA service mask -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GetEirService( UINT8 *p_eir, tBTA_SERVICE_MASK *p_services ); - -/******************************************************************************* -** -** Function BTA_DmGetConnectionState -** -** Description Returns whether the remote device is currently connected. -** -** Returns 0 if the device is NOT connected. -** -*******************************************************************************/ -extern UINT16 BTA_DmGetConnectionState( BD_ADDR bd_addr ); - -#if (SDP_INCLUDED == TRUE) -/******************************************************************************* -** -** Function BTA_DmSetLocalDiRecord -** -** Description This function adds a DI record to the local SDP database. -** -** Returns BTA_SUCCESS if record set sucessfully, otherwise error code. -** -*******************************************************************************/ -extern tBTA_STATUS BTA_DmSetLocalDiRecord( tBTA_DI_RECORD *p_device_info, - UINT32 *p_handle ); -#endif ///SDP_INCLUDED == TRUE -/******************************************************************************* -** -** -** Function BTA_DmCloseACL -** -** Description This function force to close an ACL connection and remove the -** device from the security database list of known devices. -** -** Parameters: bd_addr - Address of the peer device -** remove_dev - remove device or not after link down -** transport - which transport to close - -** -** Returns void. -** -*******************************************************************************/ -extern void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev, tBTA_TRANSPORT transport); - -/******************************************************************************* -** -** Function bta_dmexecutecallback -** -** Description This function will request BTA to execute a call back in the context of BTU task -** This API was named in lower case because it is only intended -** for the internal customers(like BTIF). -** -** Returns void -** -*******************************************************************************/ -extern void bta_dmexecutecallback (tBTA_DM_EXEC_CBACK *p_callback, void *p_param); - -#if (BTM_SCO_HCI_INCLUDED == TRUE) -/******************************************************************************* -** -** Function BTA_DmPcmInitSamples -** -** Description initialize the down sample converter. -** -** src_sps: original samples per second (source audio data) -** (ex. 44100, 48000) -** bits: number of bits per pcm sample (16) -** n_channels: number of channels (i.e. mono(1), stereo(2)...) -** -** Returns none -** -*******************************************************************************/ -extern void BTA_DmPcmInitSamples (UINT32 src_sps, UINT32 bits, UINT32 n_channels); - -/************************************************************************************** -** Function BTA_DmPcmResample -** -** Description Down sampling utility to convert higher sampling rate into 8K/16bits -** PCM samples. -** -** Parameters p_src: pointer to the buffer where the original sampling PCM -** are stored. -** in_bytes: Length of the input PCM sample buffer in byte. -** p_dst: pointer to the buffer which is to be used to store -** the converted PCM samples. -** -** -** Returns INT32: number of samples converted. -** -**************************************************************************************/ -extern INT32 BTA_DmPcmResample (void *p_src, UINT32 in_bytes, void *p_dst); -#endif - -#if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) -/* BLE related API functions */ -/******************************************************************************* -** -** Function BTA_DmBleSecurityGrant -** -** Description Grant security request access. -** -** Parameters: bd_addr - BD address of the peer -** res - security grant status. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleSecurityGrant(BD_ADDR bd_addr, tBTA_DM_BLE_SEC_GRANT res); - - - -/******************************************************************************* -** -** Function BTA_DmBleSetBgConnType -** -** Description This function is called to set BLE connectable mode for a -** peripheral device. -** -** Parameters bg_conn_type: it can be auto connection, or selective connection. -** p_select_cback: callback function when selective connection procedure -** is being used. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleSetBgConnType(tBTA_DM_BLE_CONN_TYPE bg_conn_type, tBTA_DM_BLE_SEL_CBACK *p_select_cback); - -/******************************************************************************* -** -** Function BTA_DmBlePasskeyReply -** -** Description Send BLE SMP passkey reply. -** -** Parameters: bd_addr - BD address of the peer -** accept - passkey entry sucessful or declined. -** passkey - passkey value, must be a 6 digit number, -** can be lead by 0. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBlePasskeyReply(BD_ADDR bd_addr, BOOLEAN accept, UINT32 passkey); - -/******************************************************************************* -** -** Function BTA_DmBleSetStaticPasskey -** -** Description Set BLE SMP static passkey. -** -** Parameters: add - add static passkey when add is true -** clear static passkey when add is false -** passkey - static passkey value -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleSetStaticPasskey(bool add, uint32_t passkey); - -/******************************************************************************* -** -** Function BTA_DmBleConfirmReply -** -** Description Send BLE SMP SC user confirmation reply. -** -** Parameters: bd_addr - BD address of the peer -** accept - numbers to compare are the same or different. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleConfirmReply(BD_ADDR bd_addr, BOOLEAN accept); - -/******************************************************************************* -** -** Function BTA_DmAddBleDevice -** -** Description Add a BLE device. This function will be normally called -** during host startup to restore all required information -** for a LE device stored in the NVRAM. -** -** Parameters: bd_addr - BD address of the peer -** dev_type - Remote device's device type. -** addr_type - LE device address type. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmAddBleDevice(BD_ADDR bd_addr, tBLE_ADDR_TYPE addr_type, - tBT_DEVICE_TYPE dev_type); - - -/******************************************************************************* -** -** Function BTA_DmAddBleKey -** -** Description Add/modify LE device information. This function will be -** normally called during host startup to restore all required -** information stored in the NVRAM. -** -** Parameters: bd_addr - BD address of the peer -** p_le_key - LE key values. -** key_type - LE SMP key type. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmAddBleKey (BD_ADDR bd_addr, - tBTA_LE_KEY_VALUE *p_le_key, - tBTA_LE_KEY_TYPE key_type); - -/******************************************************************************* -** -** Function BTA_DmSetBlePrefConnParams -** -** Description This function is called to set the preferred connection -** parameters when default connection parameter is not desired. -** -** Parameters: bd_addr - BD address of the peripheral -** min_conn_int - minimum preferred connection interval -** max_conn_int - maximum preferred connection interval -** slave_latency - preferred slave latency -** supervision_tout - preferred supervision timeout -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmSetBlePrefConnParams(BD_ADDR bd_addr, - UINT16 min_conn_int, UINT16 max_conn_int, - UINT16 slave_latency, UINT16 supervision_tout ); - -/******************************************************************************* -** -** Function BTA_DmSetBleConnScanParams -** -** Description This function is called to set scan parameters used in -** BLE connection request -** -** Parameters: scan_interval - scan interval -** scan_window - scan window -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmSetBleConnScanParams(UINT32 scan_interval, - UINT32 scan_window); - -/******************************************************************************* -** -** Function BTA_DmSetBleScanParams -** -** Description This function is called to set scan parameters -** -** Parameters: client_if - Client IF -** scan_interval - scan interval -** scan_window - scan window -** scan_mode - scan mode -** scan_param_setup_status_cback - Set scan param status callback -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmSetBleScanParams(tGATT_IF client_if, UINT32 scan_interval, - UINT32 scan_window, tBLE_SCAN_MODE scan_mode, - tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_status_cback); - - -/******************************************************************************* -** -** Function BTA_DmSetBleScanFilterParams -** -** Description This function is called to set scan parameters -** -** Parameters: client_if - Client IF -** scan_interval - scan interval -** scan_window - scan window -** scan_mode - scan mode -** scan_duplicate_filter - scan duplicate filter -** scan_param_setup_status_cback - Set scan param status callback -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmSetBleScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, - UINT32 scan_window, tBLE_SCAN_MODE scan_mode, UINT8 scan_fil_poilcy, - UINT8 addr_type_own, UINT8 scan_duplicate_filter, tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_cback); - - -/******************************************************************************* -** -** Function BTA_DmSetBleAdvParams -** -** Description This function sets the advertising parameters BLE functionality. -** It is to be called when device act in peripheral or broadcaster -** role. -** -** Parameters: adv_int_min - adv interval minimum -** adv_int_max - adv interval max -** p_dir_bda - directed adv initator address -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmSetBleAdvParams (UINT16 adv_int_min, UINT16 adv_int_max, - tBLE_BD_ADDR *p_dir_bda); - -extern void BTA_DmSetBleAdvParamsAll (UINT16 adv_int_min, UINT16 adv_int_max, - UINT8 adv_type, tBLE_ADDR_TYPE addr_type_own, - tBTM_BLE_ADV_CHNL_MAP chnl_map, tBTM_BLE_AFP adv_fil_pol, - tBLE_BD_ADDR *p_dir_bda, tBTA_START_ADV_CMPL_CBACK p_start_adv_cb); - - -/******************************************************************************* -** -** Function BTA_DmSearchExt -** -** Description This function searches for peer Bluetooth devices. It performs -** an inquiry and gets the remote name for devices. Service -** discovery is done if services is non zero -** -** Parameters p_dm_inq: inquiry conditions -** services: if service is not empty, service discovery will be done. -** for all GATT based service condition, put num_uuid, and -** p_uuid is the pointer to the list of UUID values. -** p_cback: callback functino when search is completed. -** -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmSearchExt(tBTA_DM_INQ *p_dm_inq, tBTA_SERVICE_MASK_EXT *p_services, - tBTA_DM_SEARCH_CBACK *p_cback); - -/******************************************************************************* -** -** Function BTA_DmDiscoverExt -** -** Description This function does service discovery for services of a -** peer device. When services.num_uuid is 0, it indicates all -** GATT based services are to be searched; other wise a list of -** UUID of interested services should be provided through -** services.p_uuid. -** -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services, - tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search); - -/******************************************************************************* -** -** Function BTA_DmDiscoverByTransport -** -** Description This function does service discovery on particular transport -** for services of a -** peer device. When services.num_uuid is 0, it indicates all -** GATT based services are to be searched; other wise a list of -** UUID of interested services should be provided through -** p_services->p_uuid. -** -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmDiscoverByTransport(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services, - tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search, - tBTA_TRANSPORT transport); - -/******************************************************************************* -** -** Function BTA_DmSetEncryption -** -** Description This function is called to ensure that connection is -** encrypted. Should be called only on an open connection. -** Typically only needed for connections that first want to -** bring up unencrypted links, then later encrypt them. -** -** Parameters: bd_addr - Address of the peer device -** transport - transport of the link to be encruypted -** p_callback - Pointer to callback function to indicat the -** link encryption status -** sec_act - This is the security action to indicate -** what knid of BLE security level is required for -** the BLE link if the BLE is supported -** Note: This parameter is ignored for the BR/EDR link -** or the BLE is not supported -** -** Returns void -** -** -*******************************************************************************/ -extern void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_TRANSPORT transport, - tBTA_DM_ENCRYPT_CBACK *p_callback, - tBTA_DM_BLE_SEC_ACT sec_act); - - -/******************************************************************************* -** -** Function BTA_DmBleObserve -** -** Description This procedure keep the device listening for advertising -** events from a broadcast device. -** -** Parameters start: start or stop observe. -** duration : Duration of the scan. Continuous scan if 0 is passed -** p_results_cb: Callback to be called with scan results -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleObserve(BOOLEAN start, UINT32 duration, - tBTA_DM_SEARCH_CBACK *p_results_cb, - tBTA_START_STOP_SCAN_CMPL_CBACK *p_start_stop_scan_cb); - -/******************************************************************************* -** -** Function BTA_DmBleScan -** -** Description This procedure keep the device listening for advertising -** events from a broadcast device. -** -** Parameters start: start or stop observe. -** duration : Duration of the scan. Continuous scan if 0 is passed -** p_results_cb: Callback to be called with scan results -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleScan(BOOLEAN start, UINT32 duration, - tBTA_DM_SEARCH_CBACK *p_results_cb, - tBTA_START_STOP_SCAN_CMPL_CBACK *p_start_stop_scan_cb); - -extern void BTA_DmBleStopAdvertising(void); - -extern void BTA_DmSetRandAddress(BD_ADDR rand_addr, tBTA_SET_RAND_ADDR_CBACK *p_set_rand_addr_cback); - -#endif - -#if BLE_INCLUDED == TRUE -// btla-specific -- -/******************************************************************************* -** -** Function BTA_DmBleConfigLocalPrivacy -** -** Description Enable/disable privacy on the local device -** -** Parameters: privacy_enable - enable/disabe privacy on remote device. -** set_local_privacy_cback -callback to be called with result -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable, tBTA_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cback); - -/******************************************************************************* -** -** Function BTA_DmBleConfigLocalIcon -** -** Description set gap local icon -** -** Parameters: icon - appearance value. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleConfigLocalIcon(uint16_t icon); - -/******************************************************************************* -** -** Function BTA_DmBleEnableRemotePrivacy -** -** Description Enable/disable privacy on a remote device -** -** Parameters: bd_addr - BD address of the peer -** privacy_enable - enable/disabe privacy on remote device. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleEnableRemotePrivacy(BD_ADDR bd_addr, BOOLEAN privacy_enable); - - -/******************************************************************************* -** -** Function BTA_DmBleSetAdvConfig -** -** Description This function is called to override the BTA default ADV parameters. -** -** Parameters Pointer to User defined ADV data structure -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask, - tBTA_BLE_ADV_DATA *p_adv_cfg, - tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback); - -/******************************************************************************* -** -** Function BTA_DmBleSetAdvConfigRaw -** -** Description This function is called to set raw Advertising data -** -** Parameters p_raw_adv : raw advertising data. -** raw_adv_len : raw advertising data length. -** p_adv_data_cback : set adv data complete callback. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleSetAdvConfigRaw (UINT8 *p_raw_adv, UINT32 raw_adv_len, - tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback); - -/******************************************************************************* -** -** Function BTA_DmBleSetScanRsp -** -** Description This function is called to override the BTA scan response. -** -** Parameters Pointer to User defined ADV data structure -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask, - tBTA_BLE_ADV_DATA *p_adv_cfg, - tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback); - -/******************************************************************************* -** -** Function BTA_DmBleSetScanRspRaw -** -** Description This function is called to set raw scan response data -** -** Parameters p_raw_scan_rsp : raw scan_rspertising data. -** raw_scan_rsp_len : raw scan_rspertising data length. -** p_scan_rsp_data_cback : set scan_rsp data complete callback. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleSetScanRspRaw (UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_len, - tBTA_SET_ADV_DATA_CMPL_CBACK *p_scan_rsp_data_cback); - -/******************************************************************************* -** -** Function BTA_DmBleBroadcast -** -** Description This function starts or stops LE broadcasting. -** -** Parameters start: start or stop broadcast. -** p_start_stop_adv_cb: stop broadcast completed event -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleBroadcast (BOOLEAN start, tBTA_START_STOP_ADV_CMPL_CBACK *p_start_stop_adv_cb); - - -/******************************************************************************* -** -** Function BTA_BleEnableAdvInstance -** -** Description This function enables the Multi ADV instance feature -** -** Parameters p_params Pointer to ADV param user defined structure -** p_cback Pointer to Multi ADV callback structure -** p_ref - Reference pointer -** -** Returns None -** -*******************************************************************************/ -extern void BTA_BleEnableAdvInstance (tBTA_BLE_ADV_PARAMS *p_params, - tBTA_BLE_MULTI_ADV_CBACK *p_cback, void *p_ref); - -/******************************************************************************* -** -** Function BTA_BleUpdateAdvInstParam -** -** Description This function updates the Multi ADV instance params -** -** Parameters inst_id Instance ID -** p_params Pointer to ADV param user defined structure -** -** Returns None -** -*******************************************************************************/ -extern void BTA_BleUpdateAdvInstParam (UINT8 inst_id, - tBTA_BLE_ADV_PARAMS *p_params); - -/******************************************************************************* -** -** Function BTA_BleCfgAdvInstData -** -** Description This function is called to configure the ADV instance data -** -** Parameters inst_id - Instance ID -** is_scan_rsp - Boolean value Scan response -** Pointer to User defined ADV data structure -** Returns None -** -*******************************************************************************/ -extern void BTA_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp, - tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_data); - -/******************************************************************************* -** -** Function BTA_BleDisableAdvInstance -** -** Description This function is called to disable the ADV instance -** -** Parameters inst_id - Instance ID to be disabled -** -** Returns None -** -*******************************************************************************/ -extern void BTA_BleDisableAdvInstance(UINT8 inst_id); - -/******************************************************************************* -** -** Function BTA_DmBleUpdateConnectionParams -** -** Description Update connection parameters, can only be used when connection is up. -** -** Parameters: bd_addr - BD address of the peer -** min_int - minimum connection interval, [0x0004~ 0x4000] -** max_int - maximum connection interval, [0x0004~ 0x4000] -** latency - slave latency [0 ~ 500] -** timeout - supervision timeout [0x000a ~ 0xc80] -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, - UINT16 max_int, UINT16 latency, UINT16 timeout); - -/******************************************************************************* -** -** Function BTA_DmBleDisconnect -** -** Description This function is to disconnect the ble connection -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleDisconnect(BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function BTA_DmBleSetDataLength -** -** Description This function is to set maximum LE data packet size -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleSetDataLength(BD_ADDR remote_device, UINT16 tx_data_length, tBTA_SET_PKT_DATA_LENGTH_CBACK *p_set_pkt_data_cback); - -/******************************************************************************* -** -** Function BTA_DmBleSetStorageParams -** -** Description This function is called to set the storage parameters -** -** Parameters batch_scan_full_max -Max storage space (in %) allocated to full scanning -** batch_scan_trunc_max -Max storage space (in %) allocated to truncated scanning -** batch_scan_notify_threshold - Setup notification level based on total space -** consumed by both pools. Setting it to 0 will disable threshold notification -** p_setup_cback - Setup callback -** p_thres_cback - Threshold callback -** p_rep_cback - Reports callback -** ref_value - Reference value -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleSetStorageParams(UINT8 batch_scan_full_max, - UINT8 batch_scan_trunc_max, - UINT8 batch_scan_notify_threshold, - tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback, - tBTA_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback, - tBTA_BLE_SCAN_REP_CBACK *p_rep_cback, - tBTA_DM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTA_DmBleEnableBatchScan -** -** Description This function is called to enable the batch scan -** -** Parameters scan_mode -Batch scan mode -** scan_interval - Scan interval -** scan_window - Scan window -** discard_rule -Discard rules -** addr_type - Address type -** ref_value - Reference value -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleEnableBatchScan(tBTA_BLE_BATCH_SCAN_MODE scan_mode, - UINT32 scan_interval, UINT32 scan_window, - tBTA_BLE_DISCARD_RULE discard_rule, - tBLE_ADDR_TYPE addr_type, - tBTA_DM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTA_DmBleReadScanReports -** -** Description This function is called to read the batch scan reports -** -** Parameters scan_mode -Batch scan mode -** ref_value - Reference value -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleReadScanReports(tBTA_BLE_BATCH_SCAN_MODE scan_type, - tBTA_DM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTA_DmBleDisableBatchScan -** -** Description This function is called to disable the batch scanning -** -** Parameters ref_value - Reference value -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleDisableBatchScan(tBTA_DM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTA_DmEnableScanFilter -** -** Description This function is called to enable the adv data payload filter -** -** Parameters action - enable or disable the APCF feature -** p_cmpl_cback - Command completed callback -** ref_value - Reference value -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmEnableScanFilter(UINT8 action, - tBTA_DM_BLE_PF_STATUS_CBACK *p_cmpl_cback, - tBTA_DM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTA_DmBleScanFilterSetup -** -** Description This function is called to setup the filter params -** -** Parameters p_target: enable the filter condition on a target device; if NULL -** filt_index - Filter index -** p_filt_params -Filter parameters -** ref_value - Reference value -** action - Add, delete or clear -** p_cmpl_back - Command completed callback -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleScanFilterSetup(UINT8 action, - tBTA_DM_BLE_PF_FILT_INDEX filt_index, - tBTA_DM_BLE_PF_FILT_PARAMS *p_filt_params, - tBLE_BD_ADDR *p_target, - tBTA_DM_BLE_PF_PARAM_CBACK *p_cmpl_cback, - tBTA_DM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTA_DmBleCfgFilterCondition -** -** Description This function is called to configure the adv data payload filter -** condition. -** -** Parameters action: to read/write/clear -** cond_type: filter condition type -** filt_index - Filter index -** p_cond: filter condition parameter -** p_cmpl_back - Command completed callback -** ref_value - Reference value -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleCfgFilterCondition(tBTA_DM_BLE_SCAN_COND_OP action, - tBTA_DM_BLE_PF_COND_TYPE cond_type, - tBTA_DM_BLE_PF_FILT_INDEX filt_index, - tBTA_DM_BLE_PF_COND_PARAM *p_cond, - tBTA_DM_BLE_PF_CFG_CBACK *p_cmpl_cback, - tBTA_DM_BLE_REF_VALUE ref_value); - - -/******************************************************************************* -** -** Function BTA_DmBleTrackAdvertiser -** -** Description This function is called to track the advertiser -** -** Parameters ref_value - Reference value -** p_track_adv_cback - ADV callback -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleTrackAdvertiser(tBTA_DM_BLE_REF_VALUE ref_value, - tBTA_BLE_TRACK_ADV_CBACK *p_track_adv_cback); - -/******************************************************************************* -** -** Function BTA_DmBleGetEnergyInfo -** -** Description This function is called to obtain the energy info -** -** Parameters p_cmpl_cback - Command complete callback -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleGetEnergyInfo(tBTA_BLE_ENERGY_INFO_CBACK *p_cmpl_cback); - -/******************************************************************************* -** -** Function BTA_BrcmInit -** -** Description This function initializes Broadcom specific VS handler in BTA -** -** Returns void -** -*******************************************************************************/ -extern void BTA_VendorInit (void); - -/******************************************************************************* -** -** Function BTA_BrcmCleanup -** -** Description This function frees up Broadcom specific VS specific dynamic memory -** -** Returns void -** -*******************************************************************************/ -extern void BTA_VendorCleanup (void); - -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* BTA_API_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_ar_api.h b/tools/sdk/include/bluedroid/bta/bta_ar_api.h deleted file mode 100644 index 99cc511e..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_ar_api.h +++ /dev/null @@ -1,144 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2004-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the public interface file for the simulatenous advanced - * audio/video streaming (AV) source and sink of BTA, Broadcom's Bluetooth - * application layer for mobile phones. - * - ******************************************************************************/ -#ifndef BTA_AR_API_H -#define BTA_AR_API_H - -#include "stack/avdt_api.h" -#include "stack/avct_api.h" -#include "stack/avrc_api.h" -#include "stack/sdp_api.h" -#include "bta/bta_av_api.h" -#include "bta/bta_sys.h" - -#if (BTA_AR_INCLUDED == TRUE) - -/***************************************************************************** -** Constants and data types -*****************************************************************************/ -/* This event signal to AR user that other profile is connected */ -#define BTA_AR_AVDT_CONN_EVT (AVDT_MAX_EVT + 1) - -/******************************************************************************* -** -** Function bta_ar_init -** -** Description This function is called from bta_sys_init(). -** to initialize the control block -** -** Returns void -** -*******************************************************************************/ -extern void bta_ar_init(void); - -/******************************************************************************* -** -** Function bta_ar_reg_avdt -** -** Description This function is called to register to AVDTP. -** -** Returns void -** -*******************************************************************************/ -extern void bta_ar_reg_avdt(tAVDT_REG *p_reg, tAVDT_CTRL_CBACK *p_cback, tBTA_SYS_ID sys_id); - -/******************************************************************************* -** -** Function bta_ar_dereg_avdt -** -** Description This function is called to de-register from AVDTP. -** -** Returns void -** -*******************************************************************************/ -extern void bta_ar_dereg_avdt(tBTA_SYS_ID sys_id); - -/******************************************************************************* -** -** Function bta_ar_avdt_conn -** -** Description This function is called to let ar know that some AVDTP profile -** is connected for this sys_id. -** If the other sys modules started a timer for PENDING_EVT, -** the timer can be stopped now. -** -** Returns void -** -*******************************************************************************/ -extern void bta_ar_avdt_conn(tBTA_SYS_ID sys_id, BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function bta_ar_reg_avct -** -** Description This function is called to register to AVCTP. -** -** Returns void -** -*******************************************************************************/ -extern void bta_ar_reg_avct(UINT16 mtu, UINT16 mtu_br, UINT8 sec_mask, tBTA_SYS_ID sys_id); - -/******************************************************************************* -** -** Function bta_ar_dereg_avct -** -** Description This function is called to deregister from AVCTP. -** -** Returns void -** -*******************************************************************************/ -extern void bta_ar_dereg_avct(tBTA_SYS_ID sys_id); - -/****************************************************************************** -** -** Function bta_ar_reg_avrc -** -** Description This function is called to register an SDP record for AVRCP. -** -** Returns void -** -******************************************************************************/ -extern void bta_ar_reg_avrc(UINT16 service_uuid, char *p_service_name, - char *p_provider_name, UINT16 categories, tBTA_SYS_ID sys_id); - -/****************************************************************************** -** -** Function bta_ar_dereg_avrc -** -** Description This function is called to de-register/delete an SDP record for AVRCP. -** -** Returns void -** -******************************************************************************/ -extern void bta_ar_dereg_avrc(UINT16 service_uuid, tBTA_SYS_ID sys_id); - - -#ifdef __cplusplus -} -#endif - -#endif ///BTA_AR_INCLUDED == TRUE - -#endif /* BTA_AR_API_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_av_api.h b/tools/sdk/include/bluedroid/bta/bta_av_api.h deleted file mode 100644 index 87c2d374..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_av_api.h +++ /dev/null @@ -1,813 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2004-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the public interface file for the advanced audio/video streaming - * (AV) subsystem of BTA, Broadcom's Bluetooth application layer for mobile - * phones. - * - ******************************************************************************/ -#ifndef BTA_AV_API_H -#define BTA_AV_API_H - -#include "stack/avrc_api.h" -#include "stack/avdt_api.h" -#include "stack/a2d_api.h" -#include "bta/bta_api.h" - -#if (BTA_AV_INCLUDED == TRUE) - -/***************************************************************************** -** Constants and data types -*****************************************************************************/ -/* Set to TRUE if seperate authorization prompt desired for AVCTP besides A2DP authorization */ -/* Typically FALSE when AVRCP is used in conjunction with A2DP */ -#ifndef BTA_AV_WITH_AVCTP_AUTHORIZATION -#define BTA_AV_WITH_AVCTP_AUTHORIZATION FALSE -#endif - -/* AV status values */ -#define BTA_AV_SUCCESS 0 /* successful operation */ -#define BTA_AV_FAIL 1 /* generic failure */ -#define BTA_AV_FAIL_SDP 2 /* service not found */ -#define BTA_AV_FAIL_STREAM 3 /* stream connection failed */ -#define BTA_AV_FAIL_RESOURCES 4 /* no resources */ -#define BTA_AV_FAIL_ROLE 5 /* failed due to role management related issues */ -#define BTA_AV_FAIL_GET_CAP 6 /* get capability failed due to no SEP availale on the peer */ - -typedef UINT8 tBTA_AV_STATUS; - -/* AV features masks */ -#define BTA_AV_FEAT_RCTG 0x0001 /* remote control target */ -#define BTA_AV_FEAT_RCCT 0x0002 /* remote control controller */ -#define BTA_AV_FEAT_PROTECT 0x0004 /* streaming media contect protection */ -#define BTA_AV_FEAT_VENDOR 0x0008 /* remote control vendor dependent commands */ -#define BTA_AV_FEAT_REPORT 0x0020 /* use reporting service for VDP */ -#define BTA_AV_FEAT_METADATA 0x0040 /* remote control Metadata Transfer command/response */ -#define BTA_AV_FEAT_MULTI_AV 0x0080 /* use multi-av, if controller supports it */ -#define BTA_AV_FEAT_BROWSE 0x0010 /* use browsing channel */ -#define BTA_AV_FEAT_MASTER 0x0100 /* stream only as master role */ -#define BTA_AV_FEAT_ADV_CTRL 0x0200 /* remote control Advanced Control command/response */ -#define BTA_AV_FEAT_DELAY_RPT 0x0400 /* allow delay reporting */ -#define BTA_AV_FEAT_ACP_START 0x0800 /* start stream when 2nd SNK was accepted */ - -/* Internal features */ -#define BTA_AV_FEAT_NO_SCO_SSPD 0x8000 /* Do not suspend av streaming as to AG events(SCO or Call) */ - -typedef UINT16 tBTA_AV_FEAT; - -/* AV channel values */ -#define BTA_AV_CHNL_MSK 0xC0 -#define BTA_AV_CHNL_AUDIO 0x40 /* audio channel */ -#define BTA_AV_CHNL_VIDEO 0x80 /* video channel */ -typedef UINT8 tBTA_AV_CHNL; - - -#define BTA_AV_HNDL_MSK 0x3F -typedef UINT8 tBTA_AV_HNDL; -/* handle index to mask */ -#define BTA_AV_HNDL_TO_MSK(h) ((UINT8)(1 << (h))) - -/* tBTA_AV_HNDL to mask */ -#define BTA_AV_HNDL_TYPE_TO_MSK(h) ((UINT8)(1 << (h&BTA_AV_HNDL_MSK))) - -/* offset of codec type in codec info byte array */ -#define BTA_AV_CODEC_TYPE_IDX AVDT_CODEC_TYPE_INDEX /* 2 */ - - - -/* maximum number of streams created: 1 for audio, 1 for video */ -#ifndef BTA_AV_NUM_STRS -#define BTA_AV_NUM_STRS 2 -#endif - -#ifndef BTA_AV_MAX_SEPS -#define BTA_AV_MAX_SEPS 1 -#endif - -#ifndef BTA_AV_MAX_A2DP_MTU -/*#define BTA_AV_MAX_A2DP_MTU 668 //224 (DM5) * 3 - 4(L2CAP header) */ -#define BTA_AV_MAX_A2DP_MTU 1008 -#endif - -#ifndef BTA_AV_MAX_VDP_MTU -#define BTA_AV_MAX_VDP_MTU 1008 -#endif - - -/* codec type */ -#define BTA_AV_CODEC_SBC A2D_MEDIA_CT_SBC /* SBC media codec type */ -#define BTA_AV_CODEC_M12 A2D_MEDIA_CT_M12 /* MPEG-1, 2 Audio media codec type */ -#define BTA_AV_CODEC_M24 A2D_MEDIA_CT_M24 /* MPEG-2, 4 AAC media codec type */ -#define BTA_AV_CODEC_ATRAC A2D_MEDIA_CT_ATRAC /* ATRAC family media codec type */ -#define BTA_AV_CODEC_H263_P0 VDP_MEDIA_CT_H263_P0 /* H.263 baseline (profile 0) */ -#define BTA_AV_CODEC_MPEG4 VDP_MEDIA_CT_MPEG4 /* MPEG-4 Visual Simple Profile */ -#define BTA_AV_CODEC_H263_P3 VDP_MEDIA_CT_H263_P3 /* H.263 profile 3 */ -#define BTA_AV_CODEC_H263_P8 VDP_MEDIA_CT_H263_P8 /* H.263 profile 8 */ -#define BTA_AV_CODEC_VEND VDP_MEDIA_CT_VEND /* Non-VDP */ - -typedef UINT8 tBTA_AV_CODEC; - -/* Company ID in BT assigned numbers */ -#define BTA_AV_BT_VENDOR_ID VDP_BT_VENDOR_ID /* Broadcom Corporation */ - -/* vendor specific codec ID */ -#define BTA_AV_CODEC_ID_H264 VDP_CODEC_ID_H264 /* Non-VDP codec ID - H.264 */ -#define BTA_AV_CODEC_ID_IMG VDP_CODEC_ID_IMG /* Non-VDP codec ID - images/slideshow */ - -/* operation id list for BTA_AvRemoteCmd */ -#define BTA_AV_RC_SELECT AVRC_ID_SELECT /* select */ -#define BTA_AV_RC_UP AVRC_ID_UP /* up */ -#define BTA_AV_RC_DOWN AVRC_ID_DOWN /* down */ -#define BTA_AV_RC_LEFT AVRC_ID_LEFT /* left */ -#define BTA_AV_RC_RIGHT AVRC_ID_RIGHT /* right */ -#define BTA_AV_RC_RIGHT_UP AVRC_ID_RIGHT_UP /* right-up */ -#define BTA_AV_RC_RIGHT_DOWN AVRC_ID_RIGHT_DOWN /* right-down */ -#define BTA_AV_RC_LEFT_UP AVRC_ID_LEFT_UP /* left-up */ -#define BTA_AV_RC_LEFT_DOWN AVRC_ID_LEFT_DOWN /* left-down */ -#define BTA_AV_RC_ROOT_MENU AVRC_ID_ROOT_MENU /* root menu */ -#define BTA_AV_RC_SETUP_MENU AVRC_ID_SETUP_MENU /* setup menu */ -#define BTA_AV_RC_CONT_MENU AVRC_ID_CONT_MENU /* contents menu */ -#define BTA_AV_RC_FAV_MENU AVRC_ID_FAV_MENU /* favorite menu */ -#define BTA_AV_RC_EXIT AVRC_ID_EXIT /* exit */ -#define BTA_AV_RC_0 AVRC_ID_0 /* 0 */ -#define BTA_AV_RC_1 AVRC_ID_1 /* 1 */ -#define BTA_AV_RC_2 AVRC_ID_2 /* 2 */ -#define BTA_AV_RC_3 AVRC_ID_3 /* 3 */ -#define BTA_AV_RC_4 AVRC_ID_4 /* 4 */ -#define BTA_AV_RC_5 AVRC_ID_5 /* 5 */ -#define BTA_AV_RC_6 AVRC_ID_6 /* 6 */ -#define BTA_AV_RC_7 AVRC_ID_7 /* 7 */ -#define BTA_AV_RC_8 AVRC_ID_8 /* 8 */ -#define BTA_AV_RC_9 AVRC_ID_9 /* 9 */ -#define BTA_AV_RC_DOT AVRC_ID_DOT /* dot */ -#define BTA_AV_RC_ENTER AVRC_ID_ENTER /* enter */ -#define BTA_AV_RC_CLEAR AVRC_ID_CLEAR /* clear */ -#define BTA_AV_RC_CHAN_UP AVRC_ID_CHAN_UP /* channel up */ -#define BTA_AV_RC_CHAN_DOWN AVRC_ID_CHAN_DOWN /* channel down */ -#define BTA_AV_RC_PREV_CHAN AVRC_ID_PREV_CHAN /* previous channel */ -#define BTA_AV_RC_SOUND_SEL AVRC_ID_SOUND_SEL /* sound select */ -#define BTA_AV_RC_INPUT_SEL AVRC_ID_INPUT_SEL /* input select */ -#define BTA_AV_RC_DISP_INFO AVRC_ID_DISP_INFO /* display information */ -#define BTA_AV_RC_HELP AVRC_ID_HELP /* help */ -#define BTA_AV_RC_PAGE_UP AVRC_ID_PAGE_UP /* page up */ -#define BTA_AV_RC_PAGE_DOWN AVRC_ID_PAGE_DOWN /* page down */ -#define BTA_AV_RC_POWER AVRC_ID_POWER /* power */ -#define BTA_AV_RC_VOL_UP AVRC_ID_VOL_UP /* volume up */ -#define BTA_AV_RC_VOL_DOWN AVRC_ID_VOL_DOWN /* volume down */ -#define BTA_AV_RC_MUTE AVRC_ID_MUTE /* mute */ -#define BTA_AV_RC_PLAY AVRC_ID_PLAY /* play */ -#define BTA_AV_RC_STOP AVRC_ID_STOP /* stop */ -#define BTA_AV_RC_PAUSE AVRC_ID_PAUSE /* pause */ -#define BTA_AV_RC_RECORD AVRC_ID_RECORD /* record */ -#define BTA_AV_RC_REWIND AVRC_ID_REWIND /* rewind */ -#define BTA_AV_RC_FAST_FOR AVRC_ID_FAST_FOR /* fast forward */ -#define BTA_AV_RC_EJECT AVRC_ID_EJECT /* eject */ -#define BTA_AV_RC_FORWARD AVRC_ID_FORWARD /* forward */ -#define BTA_AV_RC_BACKWARD AVRC_ID_BACKWARD /* backward */ -#define BTA_AV_RC_ANGLE AVRC_ID_ANGLE /* angle */ -#define BTA_AV_RC_SUBPICT AVRC_ID_SUBPICT /* subpicture */ -#define BTA_AV_RC_F1 AVRC_ID_F1 /* F1 */ -#define BTA_AV_RC_F2 AVRC_ID_F2 /* F2 */ -#define BTA_AV_RC_F3 AVRC_ID_F3 /* F3 */ -#define BTA_AV_RC_F4 AVRC_ID_F4 /* F4 */ -#define BTA_AV_RC_F5 AVRC_ID_F5 /* F5 */ -#define BTA_AV_VENDOR AVRC_ID_VENDOR /* vendor unique */ - -typedef UINT8 tBTA_AV_RC; - -/* state flag for pass through command */ -#define BTA_AV_STATE_PRESS AVRC_STATE_PRESS /* key pressed */ -#define BTA_AV_STATE_RELEASE AVRC_STATE_RELEASE /* key released */ - -typedef UINT8 tBTA_AV_STATE; - -/* command codes for BTA_AvVendorCmd */ -#define BTA_AV_CMD_CTRL AVRC_CMD_CTRL -#define BTA_AV_CMD_STATUS AVRC_CMD_STATUS -#define BTA_AV_CMD_SPEC_INQ AVRC_CMD_SPEC_INQ -#define BTA_AV_CMD_NOTIF AVRC_CMD_NOTIF -#define BTA_AV_CMD_GEN_INQ AVRC_CMD_GEN_INQ - -typedef UINT8 tBTA_AV_CMD; - -/* response codes for BTA_AvVendorRsp */ -#define BTA_AV_RSP_NOT_IMPL AVRC_RSP_NOT_IMPL -#define BTA_AV_RSP_ACCEPT AVRC_RSP_ACCEPT -#define BTA_AV_RSP_REJ AVRC_RSP_REJ -#define BTA_AV_RSP_IN_TRANS AVRC_RSP_IN_TRANS -#define BTA_AV_RSP_IMPL_STBL AVRC_RSP_IMPL_STBL -#define BTA_AV_RSP_CHANGED AVRC_RSP_CHANGED -#define BTA_AV_RSP_INTERIM AVRC_RSP_INTERIM - -typedef UINT8 tBTA_AV_CODE; - -/* error codes for BTA_AvProtectRsp */ -#define BTA_AV_ERR_NONE A2D_SUCCESS /* Success, no error */ -#define BTA_AV_ERR_BAD_STATE AVDT_ERR_BAD_STATE /* Message cannot be processed in this state */ -#define BTA_AV_ERR_RESOURCE AVDT_ERR_RESOURCE /* Insufficient resources */ -#define BTA_AV_ERR_BAD_CP_TYPE A2D_BAD_CP_TYPE /* The requested Content Protection Type is not supported */ -#define BTA_AV_ERR_BAD_CP_FORMAT A2D_BAD_CP_FORMAT /* The format of Content Protection Data is not correct */ - -typedef UINT8 tBTA_AV_ERR; - - -/* AV callback events */ -#define BTA_AV_ENABLE_EVT 0 /* AV enabled */ -#define BTA_AV_REGISTER_EVT 1 /* registered to AVDT */ -#define BTA_AV_OPEN_EVT 2 /* connection opened */ -#define BTA_AV_CLOSE_EVT 3 /* connection closed */ -#define BTA_AV_START_EVT 4 /* stream data transfer started */ -#define BTA_AV_STOP_EVT 5 /* stream data transfer stopped */ -#define BTA_AV_PROTECT_REQ_EVT 6 /* content protection request */ -#define BTA_AV_PROTECT_RSP_EVT 7 /* content protection response */ -#define BTA_AV_RC_OPEN_EVT 8 /* remote control channel open */ -#define BTA_AV_RC_CLOSE_EVT 9 /* remote control channel closed */ -#define BTA_AV_REMOTE_CMD_EVT 10 /* remote control command */ -#define BTA_AV_REMOTE_RSP_EVT 11 /* remote control response */ -#define BTA_AV_VENDOR_CMD_EVT 12 /* vendor dependent remote control command */ -#define BTA_AV_VENDOR_RSP_EVT 13 /* vendor dependent remote control response */ -#define BTA_AV_RECONFIG_EVT 14 /* reconfigure response */ -#define BTA_AV_SUSPEND_EVT 15 /* suspend response */ -#define BTA_AV_PENDING_EVT 16 /* incoming connection pending: - * signal channel is open and stream is not open - * after BTA_AV_SIG_TIME_VAL ms */ -#define BTA_AV_META_MSG_EVT 17 /* metadata messages */ -#define BTA_AV_REJECT_EVT 18 /* incoming connection rejected */ -#define BTA_AV_RC_FEAT_EVT 19 /* remote control channel peer supported features update */ -#define BTA_AV_MEDIA_SINK_CFG_EVT 20 /* command to configure codec */ -#define BTA_AV_MEDIA_DATA_EVT 21 /* sending data to Media Task */ -/* Max BTA event */ -#define BTA_AV_MAX_EVT 22 - - -/* function types for call-out functions */ -typedef BOOLEAN (*tBTA_AV_CO_INIT) (UINT8 *p_codec_type, UINT8 *p_codec_info, - UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 tsep); -typedef void (*tBTA_AV_CO_DISC_RES) (tBTA_AV_HNDL hndl, UINT8 num_seps, - UINT8 num_snk, UINT8 num_src, BD_ADDR addr, UINT16 uuid_local); -typedef UINT8 (*tBTA_AV_CO_GETCFG) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, - UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid, - UINT8 *p_num_protect, UINT8 *p_protect_info); -typedef void (*tBTA_AV_CO_SETCFG) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, - UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr, - UINT8 num_protect, UINT8 *p_protect_info, - UINT8 t_local_sep, UINT8 avdt_handle); -typedef void (*tBTA_AV_CO_OPEN) (tBTA_AV_HNDL hndl, - tBTA_AV_CODEC codec_type, UINT8 *p_codec_info, - UINT16 mtu); -typedef void (*tBTA_AV_CO_CLOSE) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT16 mtu); -typedef void (*tBTA_AV_CO_START) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT8 *p_codec_info, BOOLEAN *p_no_rtp_hdr); -typedef void (*tBTA_AV_CO_STOP) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type); -typedef void *(*tBTA_AV_CO_DATAPATH) (tBTA_AV_CODEC codec_type, - UINT32 *p_len, UINT32 *p_timestamp); -typedef void (*tBTA_AV_CO_DELAY) (tBTA_AV_HNDL hndl, UINT16 delay); - -/* the call-out functions for one stream */ -typedef struct { - tBTA_AV_CO_INIT init; - tBTA_AV_CO_DISC_RES disc_res; - tBTA_AV_CO_GETCFG getcfg; - tBTA_AV_CO_SETCFG setcfg; - tBTA_AV_CO_OPEN open; - tBTA_AV_CO_CLOSE close; - tBTA_AV_CO_START start; - tBTA_AV_CO_STOP stop; - tBTA_AV_CO_DATAPATH data; - tBTA_AV_CO_DELAY delay; -} tBTA_AV_CO_FUNCTS; - -typedef UINT8 tBTA_AV_EVT; - -/* Event associated with BTA_AV_ENABLE_EVT */ -typedef struct { - tBTA_AV_FEAT features; -} tBTA_AV_ENABLE; - -/* Event associated with BTA_AV_REGISTER_EVT */ -typedef struct { - tBTA_AV_CHNL chnl; /* audio/video */ - tBTA_AV_HNDL hndl; /* Handle associated with the stream. */ - UINT8 app_id; /* ID associated with call to BTA_AvRegister() */ - tBTA_AV_STATUS status; - tBTA_AV_CO_FUNCTS *p_bta_av_cos; -} tBTA_AV_REGISTER; - -/* data associated with BTA_AV_OPEN_EVT */ -#define BTA_AV_EDR_2MBPS 0x01 -#define BTA_AV_EDR_3MBPS 0x02 -typedef UINT8 tBTA_AV_EDR; - -typedef struct { - tBTA_AV_CHNL chnl; - tBTA_AV_HNDL hndl; - BD_ADDR bd_addr; - tBTA_AV_STATUS status; - BOOLEAN starting; - tBTA_AV_EDR edr; /* 0, if peer device does not support EDR */ - UINT8 sep; /* sep type of peer device */ -} tBTA_AV_OPEN; - -/* data associated with BTA_AV_CLOSE_EVT */ -typedef struct { - tBTA_AV_CHNL chnl; - tBTA_AV_HNDL hndl; - UINT8 disc_rsn; /* disconnection reason */ -} tBTA_AV_CLOSE; - -/* data associated with BTA_AV_START_EVT */ -typedef struct { - tBTA_AV_CHNL chnl; - tBTA_AV_HNDL hndl; - tBTA_AV_STATUS status; - BOOLEAN initiator; /* TRUE, if local device initiates the START */ - BOOLEAN suspending; -} tBTA_AV_START; - -/* data associated with BTA_AV_SUSPEND_EVT */ -typedef struct { - tBTA_AV_CHNL chnl; - tBTA_AV_HNDL hndl; - BOOLEAN initiator; /* TRUE, if local device initiates the SUSPEND */ - tBTA_AV_STATUS status; -} tBTA_AV_SUSPEND; - -/* data associated with BTA_AV_RECONFIG_EVT */ -typedef struct { - tBTA_AV_CHNL chnl; - tBTA_AV_HNDL hndl; - tBTA_AV_STATUS status; -} tBTA_AV_RECONFIG; - -/* data associated with BTA_AV_PROTECT_REQ_EVT */ -typedef struct { - tBTA_AV_CHNL chnl; - tBTA_AV_HNDL hndl; - UINT8 *p_data; - UINT16 len; -} tBTA_AV_PROTECT_REQ; - -/* data associated with BTA_AV_PROTECT_RSP_EVT */ -typedef struct { - tBTA_AV_CHNL chnl; - tBTA_AV_HNDL hndl; - UINT8 *p_data; - UINT16 len; - tBTA_AV_ERR err_code; -} tBTA_AV_PROTECT_RSP; - -/* data associated with BTA_AV_RC_OPEN_EVT */ -typedef struct { - UINT8 rc_handle; - BOOLEAN sdp_disc_done; - tBTA_AV_FEAT peer_features; - BD_ADDR peer_addr; - tBTA_AV_STATUS status; -} tBTA_AV_RC_OPEN; - -/* data associated with BTA_AV_RC_CLOSE_EVT */ -typedef struct { - UINT8 rc_handle; - BD_ADDR peer_addr; -} tBTA_AV_RC_CLOSE; - -/* data associated with BTA_AV_RC_FEAT_EVT */ -typedef struct { - UINT8 rc_handle; - tBTA_AV_FEAT peer_features; -} tBTA_AV_RC_FEAT; - -/* data associated with BTA_AV_REMOTE_CMD_EVT */ -typedef struct { - UINT8 rc_handle; - tBTA_AV_RC rc_id; - tBTA_AV_STATE key_state; - UINT8 len; - UINT8 *p_data; - tAVRC_HDR hdr; /* Message header. */ - UINT8 label; -} tBTA_AV_REMOTE_CMD; - -/* data associated with BTA_AV_REMOTE_RSP_EVT */ -typedef struct { - UINT8 rc_handle; - tBTA_AV_RC rc_id; - tBTA_AV_STATE key_state; - UINT8 len; - UINT8 *p_data; - tBTA_AV_CODE rsp_code; - UINT8 label; -} tBTA_AV_REMOTE_RSP; - -/* data associated with BTA_AV_VENDOR_CMD_EVT, BTA_AV_VENDOR_RSP_EVT */ -typedef struct { - UINT8 rc_handle; - UINT16 len; /* Max vendor dependent message is 512 */ - UINT8 label; - tBTA_AV_CODE code; - UINT32 company_id; - UINT8 *p_data; -} tBTA_AV_VENDOR; - -/* data associated with BTA_AV_META_MSG_EVT */ -typedef struct { - UINT8 rc_handle; - UINT16 len; - UINT8 label; - tBTA_AV_CODE code; - UINT32 company_id; - UINT8 *p_data; - tAVRC_MSG *p_msg; -} tBTA_AV_META_MSG; - -/* data associated with BTA_AV_PENDING_EVT */ -typedef struct { - BD_ADDR bd_addr; -} tBTA_AV_PEND; - -/* data associated with BTA_AV_REJECT_EVT */ -typedef struct { - BD_ADDR bd_addr; - tBTA_AV_HNDL hndl; /* Handle associated with the stream that rejected the connection. */ -} tBTA_AV_REJECT; - - -/* union of data associated with AV callback */ -typedef union { - tBTA_AV_CHNL chnl; - tBTA_AV_ENABLE enable; - tBTA_AV_REGISTER registr; - tBTA_AV_OPEN open; - tBTA_AV_CLOSE close; - tBTA_AV_START start; - tBTA_AV_PROTECT_REQ protect_req; - tBTA_AV_PROTECT_RSP protect_rsp; - tBTA_AV_RC_OPEN rc_open; - tBTA_AV_RC_CLOSE rc_close; - tBTA_AV_REMOTE_CMD remote_cmd; - tBTA_AV_REMOTE_RSP remote_rsp; - tBTA_AV_VENDOR vendor_cmd; - tBTA_AV_VENDOR vendor_rsp; - tBTA_AV_RECONFIG reconfig; - tBTA_AV_SUSPEND suspend; - tBTA_AV_PEND pend; - tBTA_AV_META_MSG meta_msg; - tBTA_AV_REJECT reject; - tBTA_AV_RC_FEAT rc_feat; -} tBTA_AV; - -/* union of data associated with AV Media callback */ -typedef union { - BT_HDR *p_data; - UINT8 *codec_info; -} tBTA_AV_MEDIA; - - -#define BTA_AVC_PACKET_LEN AVRC_PACKET_LEN -#define BTA_VENDOR_DATA_OFFSET 6 -#define BTA_VENDOR_HEADER_LEN 4 -#define BTA_MAX_VENDOR_DEPENDENT_DATA_LEN (BTA_AVC_PACKET_LEN-BTA_VENDOR_DATA_OFFSET-BTA_VENDOR_HEADER_LEN) -#define BTA_GROUP_NAVI_MSG_OP_DATA_LEN 5 - -#define BTA_ERROR_INVALID_CMD AVRC_STS_BAD_CMD -#define BTA_ERROR_INVALID_PARAM AVRC_STS_BAD_PARAM -#define BTA_ERROR_BAD_CONTENTS AVRC_STS_NOT_FOUND -#define BTA_ERROR_INTERNAL AVRC_STS_INTERNAL_ERR - -#define BTA_AV_META_SINGLE_PACKET AVRC_PKT_SINGLE - -#define BTA_AV_CO_METADATA AVRC_CO_METADATA - -/* AV callback */ -typedef void (tBTA_AV_CBACK)(tBTA_AV_EVT event, tBTA_AV *p_data); -typedef void (tBTA_AV_DATA_CBACK)(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data); - -/* type for stream state machine action functions */ -typedef void (*tBTA_AV_ACT)(void *p_cb, void *p_data); - -/* type for registering VDP */ -typedef void (tBTA_AV_REG) (tAVDT_CS *p_cs, char *p_service_name, void *p_data); - -/* AV configuration structure */ -typedef struct { - UINT32 company_id; /* AVRCP Company ID */ - UINT16 avrc_mtu; /* AVRCP MTU at L2CAP for control channel */ - UINT16 avrc_br_mtu; /* AVRCP MTU at L2CAP for browsing channel */ - UINT16 avrc_ct_cat; /* AVRCP controller categories */ - UINT16 avrc_tg_cat; /* AVRCP target categories */ - UINT16 sig_mtu; /* AVDTP signaling channel MTU at L2CAP */ - UINT16 audio_mtu; /* AVDTP audio transport channel MTU at L2CAP */ - const UINT16 *p_audio_flush_to;/* AVDTP audio transport channel flush timeout */ - UINT16 audio_mqs; /* AVDTP audio channel max data queue size */ - UINT16 video_mtu; /* AVDTP video transport channel MTU at L2CAP */ - UINT16 video_flush_to; /* AVDTP video transport channel flush timeout */ - BOOLEAN avrc_group; /* TRUE, to accept AVRC 1.3 group nevigation command */ - UINT8 num_co_ids; /* company id count in p_meta_co_ids */ - UINT8 num_evt_ids; /* event id count in p_meta_evt_ids */ - tBTA_AV_CODE rc_pass_rsp; /* the default response code for pass through commands */ - const UINT32 *p_meta_co_ids;/* the metadata Get Capabilities response for company id */ - const UINT8 *p_meta_evt_ids;/* the the metadata Get Capabilities response for event id */ - const tBTA_AV_ACT *p_act_tbl;/* the action function table for VDP stream */ - tBTA_AV_REG *p_reg; /* action function to register VDP */ - char avrc_controller_name[BTA_SERVICE_NAME_LEN]; /* Default AVRCP controller name */ - char avrc_target_name[BTA_SERVICE_NAME_LEN]; /* Default AVRCP target name*/ -} tBTA_AV_CFG; - -#ifdef __cplusplus -extern "C" -{ -#endif - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ - -/******************************************************************************* -** -** Function BTA_AvEnable -** -** Description Enable the advanced audio/video service. When the enable -** operation is complete the callback function will be -** called with a BTA_AV_ENABLE_EVT. This function must -** be called before other function in the AV API are -** called. -** -** Returns void -** -*******************************************************************************/ -void BTA_AvEnable(tBTA_SEC sec_mask, tBTA_AV_FEAT features, - tBTA_AV_CBACK *p_cback); - -/******************************************************************************* -** -** Function BTA_AvDisable -** -** Description Disable the advanced audio/video service. -** -** -** Returns void -** -*******************************************************************************/ -void BTA_AvDisable(void); - -/******************************************************************************* -** -** Function BTA_AvRegister -** -** Description Register the audio or video service to stack. When the -** operation is complete the callback function will be -** called with a BTA_AV_REGISTER_EVT. This function must -** be called before AVDT stream is open. -** -** -** Returns void -** -*******************************************************************************/ -void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, - UINT8 app_id, tBTA_AV_DATA_CBACK *p_data_cback, tBTA_AV_CO_FUNCTS *bta_av_cos, UINT8 tsep); - -/******************************************************************************* -** -** Function BTA_AvDeregister -** -** Description Deregister the audio or video service -** -** Returns void -** -*******************************************************************************/ -void BTA_AvDeregister(tBTA_AV_HNDL hndl); - -/******************************************************************************* -** -** Function BTA_AvOpen -** -** Description Opens an advanced audio/video connection to a peer device. -** When connection is open callback function is called -** with a BTA_AV_OPEN_EVT. -** -** Returns void -** -*******************************************************************************/ -void BTA_AvOpen(BD_ADDR bd_addr, tBTA_AV_HNDL handle, - BOOLEAN use_rc, tBTA_SEC sec_mask, UINT16 uuid); - -/******************************************************************************* -** -** Function BTA_AvClose -** -** Description Close the current streams. -** -** Returns void -** -*******************************************************************************/ -void BTA_AvClose(tBTA_AV_HNDL handle); - -/******************************************************************************* -** -** Function BTA_AvDisconnect -** -** Description Close the connection to the address. -** -** Returns void -** -*******************************************************************************/ -void BTA_AvDisconnect(BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function BTA_AvEnable_Sink -** -** Description Enable/Disable A2DP Sink. -** -** Returns void -** -*******************************************************************************/ -void BTA_AvEnable_Sink(int enable); - -/******************************************************************************* -** -** Function BTA_AvStart -** -** Description Start audio/video stream data transfer. -** -** Returns void -** -*******************************************************************************/ -void BTA_AvStart(void); - -/******************************************************************************* -** -** Function BTA_AvStop -** -** Description Stop audio/video stream data transfer. -** If suspend is TRUE, this function sends AVDT suspend signal -** to the connected peer(s). -** -** Returns void -** -*******************************************************************************/ -void BTA_AvStop(BOOLEAN suspend); - -/******************************************************************************* -** -** Function BTA_AvReconfig -** -** Description Reconfigure the audio/video stream. -** If suspend is TRUE, this function tries the suspend/reconfigure -** procedure first. -** If suspend is FALSE or when suspend/reconfigure fails, -** this function closes and re-opens the AVDT connection. -** -** Returns void -** -*******************************************************************************/ -void BTA_AvReconfig(tBTA_AV_HNDL hndl, BOOLEAN suspend, UINT8 sep_info_idx, - UINT8 *p_codec_info, UINT8 num_protect, UINT8 *p_protect_info); - -/******************************************************************************* -** -** Function BTA_AvProtectReq -** -** Description Send a content protection request. This function can only -** be used if AV is enabled with feature BTA_AV_FEAT_PROTECT. -** -** Returns void -** -*******************************************************************************/ -void BTA_AvProtectReq(tBTA_AV_HNDL hndl, UINT8 *p_data, UINT16 len); - -/******************************************************************************* -** -** Function BTA_AvProtectRsp -** -** Description Send a content protection response. This function must -** be called if a BTA_AV_PROTECT_REQ_EVT is received. -** This function can only be used if AV is enabled with -** feature BTA_AV_FEAT_PROTECT. -** -** Returns void -** -*******************************************************************************/ -void BTA_AvProtectRsp(tBTA_AV_HNDL hndl, UINT8 error_code, UINT8 *p_data, - UINT16 len); - -/******************************************************************************* -** -** Function BTA_AvRemoteCmd -** -** Description Send a remote control command. This function can only -** be used if AV is enabled with feature BTA_AV_FEAT_RCCT. -** -** Returns void -** -*******************************************************************************/ -void BTA_AvRemoteCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_RC rc_id, - tBTA_AV_STATE key_state); - -/******************************************************************************* -** -** Function BTA_AvVendorCmd -** -** Description Send a vendor dependent remote control command. This -** function can only be used if AV is enabled with feature -** BTA_AV_FEAT_VENDOR. -** -** Returns void -** -*******************************************************************************/ -void BTA_AvVendorCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE cmd_code, - UINT8 *p_data, UINT16 len); - -/******************************************************************************* -** -** Function BTA_AvVendorRsp -** -** Description Send a vendor dependent remote control response. -** This function must be called if a BTA_AV_VENDOR_CMD_EVT -** is received. This function can only be used if AV is -** enabled with feature BTA_AV_FEAT_VENDOR. -** -** Returns void -** -*******************************************************************************/ -void BTA_AvVendorRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code, - UINT8 *p_data, UINT16 len, UINT32 company_id); - - -/******************************************************************************* -** -** Function BTA_AvOpenRc -** -** Description Open an AVRCP connection toward the device with the -** specified handle -** -** Returns void -** -*******************************************************************************/ -void BTA_AvOpenRc(tBTA_AV_HNDL handle); - -/******************************************************************************* -** -** Function BTA_AvCloseRc -** -** Description Close an AVRCP connection -** -** Returns void -** -*******************************************************************************/ -void BTA_AvCloseRc(UINT8 rc_handle); - -/******************************************************************************* -** -** Function BTA_AvMetaRsp -** -** Description Send a Metadata command/response. The message contained -** in p_pkt can be composed with AVRC utility functions. -** This function can only be used if AV is enabled with feature -** BTA_AV_FEAT_METADATA. -** -** Returns void -** -*******************************************************************************/ -void BTA_AvMetaRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code, - BT_HDR *p_pkt); - -/******************************************************************************* -** -** Function BTA_AvMetaCmd -** -** Description Send a Metadata/Advanced Control command. The message contained -** in p_pkt can be composed with AVRC utility functions. -** This function can only be used if AV is enabled with feature -** BTA_AV_FEAT_METADATA. -** This message is sent only when the peer supports the TG role. -*8 The only command makes sense right now is the absolute volume command. -** -** Returns void -** -*******************************************************************************/ -void BTA_AvMetaCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CMD cmd_code, BT_HDR *p_pkt); - -#ifdef __cplusplus -} -#endif - -#endif ///BTA_AV_INCLUDED == TRUE - -#endif /* BTA_AV_API_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_av_ci.h b/tools/sdk/include/bluedroid/bta/bta_av_ci.h deleted file mode 100644 index b39acace..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_av_ci.h +++ /dev/null @@ -1,77 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2005-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the interface file for advanced audio/video call-in functions. - * - ******************************************************************************/ -#ifndef BTA_AV_CI_H -#define BTA_AV_CI_H - -#include "bta/bta_av_api.h" - -#if (BTA_AV_INCLUDED == TRUE) - -/***************************************************************************** -** Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/******************************************************************************* -** -** Function bta_av_ci_src_data_ready -** -** Description This function sends an event to the AV indicating that -** the phone has audio stream data ready to send and AV -** should call bta_av_co_audio_src_data_path() or -** bta_av_co_video_src_data_path(). -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_ci_src_data_ready(tBTA_AV_CHNL chnl); - -/******************************************************************************* -** -** Function bta_av_ci_setconfig -** -** Description This function must be called in response to function -** bta_av_co_audio_setconfig() or bta_av_co_video_setconfig. -** Parameter err_code is set to an AVDTP status value; -** AVDT_SUCCESS if the codec configuration is ok, -** otherwise error. -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_ci_setconfig(tBTA_AV_HNDL hndl, UINT8 err_code, - UINT8 category, UINT8 num_seid, UINT8 *p_seid, - BOOLEAN recfg_needed, UINT8 avdt_handle); - - -#ifdef __cplusplus -} -#endif - -#endif ///BTA_AV_INCLUDED == TRUE - -#endif /* BTA_AV_CI_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_av_co.h b/tools/sdk/include/bluedroid/bta/bta_av_co.h deleted file mode 100644 index 03c07c33..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_av_co.h +++ /dev/null @@ -1,393 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2003-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the interface file for advanced audio/video call-out functions. - * - ******************************************************************************/ -#ifndef BTA_AV_CO_H -#define BTA_AV_CO_H - -#include "stack/l2c_api.h" -#include "bta/bta_av_api.h" - -#if (BTA_AV_INCLUDED == TRUE) - -/***************************************************************************** -** Constants and data types -*****************************************************************************/ - -/* TRUE to use SCMS-T content protection */ -#ifndef BTA_AV_CO_CP_SCMS_T -#define BTA_AV_CO_CP_SCMS_T FALSE -#endif - -/* the content protection IDs assigned by BT SIG */ -#define BTA_AV_CP_SCMS_T_ID 0x0002 -#define BTA_AV_CP_DTCP_ID 0x0001 - -#define BTA_AV_CP_LOSC 2 -#define BTA_AV_CP_INFO_LEN 3 - -#define BTA_AV_CP_SCMS_COPY_MASK 3 -#define BTA_AV_CP_SCMS_COPY_FREE 2 -#define BTA_AV_CP_SCMS_COPY_ONCE 1 -#define BTA_AV_CP_SCMS_COPY_NEVER 0 - -#define BTA_AV_CO_DEFAULT_AUDIO_OFFSET AVDT_MEDIA_OFFSET - -enum { - BTA_AV_CO_ST_INIT, - BTA_AV_CO_ST_IN, - BTA_AV_CO_ST_OUT, - BTA_AV_CO_ST_OPEN, - BTA_AV_CO_ST_STREAM -}; - - -/* data type for the Audio Codec Information*/ -typedef struct { - UINT16 bit_rate; /* SBC encoder bit rate in kbps */ - UINT16 bit_rate_busy; /* SBC encoder bit rate in kbps */ - UINT16 bit_rate_swampd;/* SBC encoder bit rate in kbps */ - UINT8 busy_level; /* Busy level indicating the bit-rate to be used */ - UINT8 codec_info[AVDT_CODEC_SIZE]; - UINT8 codec_type; /* Codec type */ -} tBTA_AV_AUDIO_CODEC_INFO; - -/******************************************************************************* -** -** Function bta_av_co_audio_init -** -** Description This callout function is executed by AV when it is -** started by calling BTA_AvEnable(). This function can be -** used by the phone to initialize audio paths or for other -** initialization purposes. -** -** -** Returns Stream codec and content protection capabilities info. -** -*******************************************************************************/ -extern BOOLEAN bta_av_co_audio_init(UINT8 *p_codec_type, UINT8 *p_codec_info, - UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 tsep); - -/******************************************************************************* -** -** Function bta_av_co_audio_disc_res -** -** Description This callout function is executed by AV to report the -** number of stream end points (SEP) were found during the -** AVDT stream discovery process. -** -** -** Returns void. -** -*******************************************************************************/ -extern void bta_av_co_audio_disc_res(tBTA_AV_HNDL hndl, UINT8 num_seps, - UINT8 num_snk, UINT8 num_src, BD_ADDR addr, UINT16 uuid_local); - -/******************************************************************************* -** -** Function bta_av_co_video_disc_res -** -** Description This callout function is executed by AV to report the -** number of stream end points (SEP) were found during the -** AVDT stream discovery process. -** -** -** Returns void. -** -*******************************************************************************/ -extern void bta_av_co_video_disc_res(tBTA_AV_HNDL hndl, UINT8 num_seps, - UINT8 num_snk, BD_ADDR addr); - -/******************************************************************************* -** -** Function bta_av_co_audio_getconfig -** -** Description This callout function is executed by AV to retrieve the -** desired codec and content protection configuration for the -** audio stream. -** -** -** Returns Stream codec and content protection configuration info. -** -*******************************************************************************/ -extern UINT8 bta_av_co_audio_getconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, - UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid, - UINT8 *p_num_protect, UINT8 *p_protect_info); - -/******************************************************************************* -** -** Function bta_av_co_video_getconfig -** -** Description This callout function is executed by AV to retrieve the -** desired codec and content protection configuration for the -** video stream. -** -** -** Returns Stream codec and content protection configuration info. -** -*******************************************************************************/ -extern UINT8 bta_av_co_video_getconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, - UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid, - UINT8 *p_num_protect, UINT8 *p_protect_info); - -/******************************************************************************* -** -** Function bta_av_co_audio_setconfig -** -** Description This callout function is executed by AV to set the -** codec and content protection configuration of the audio stream. -** -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_audio_setconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, - UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr, - UINT8 num_protect, UINT8 *p_protect_info, UINT8 t_local_sep, UINT8 avdt_handle); - -/******************************************************************************* -** -** Function bta_av_co_video_setconfig -** -** Description This callout function is executed by AV to set the -** codec and content protection configuration of the video stream. -** -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_video_setconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, - UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr, - UINT8 num_protect, UINT8 *p_protect_info); - -/******************************************************************************* -** -** Function bta_av_co_audio_open -** -** Description This function is called by AV when the audio stream connection -** is opened. -** BTA-AV maintains the MTU of A2DP streams. -** If this is the 2nd audio stream, mtu is the smaller of the 2 -** streams. -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_audio_open(tBTA_AV_HNDL hndl, - tBTA_AV_CODEC codec_type, UINT8 *p_codec_info, - UINT16 mtu); - -/******************************************************************************* -** -** Function bta_av_co_video_open -** -** Description This function is called by AV when the video stream connection -** is opened. -** -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_video_open(tBTA_AV_HNDL hndl, - tBTA_AV_CODEC codec_type, UINT8 *p_codec_info, - UINT16 mtu); - -/******************************************************************************* -** -** Function bta_av_co_audio_close -** -** Description This function is called by AV when the audio stream connection -** is closed. -** BTA-AV maintains the MTU of A2DP streams. -** When one stream is closed and no other audio stream is open, -** mtu is reported as 0. -** Otherwise, the MTU remains open is reported. -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_audio_close(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, - UINT16 mtu); - -/******************************************************************************* -** -** Function bta_av_co_video_close -** -** Description This function is called by AV when the video stream connection -** is closed. -** -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_video_close(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, - UINT16 mtu); - -/******************************************************************************* -** -** Function bta_av_co_audio_start -** -** Description This function is called by AV when the audio streaming data -** transfer is started. -** -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_audio_start(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, - UINT8 *p_codec_info, BOOLEAN *p_no_rtp_hdr); - -/******************************************************************************* -** -** Function bta_av_co_video_start -** -** Description This function is called by AV when the video streaming data -** transfer is started. -** -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_video_start(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, - UINT8 *p_codec_info, BOOLEAN *p_no_rtp_hdr); - -/******************************************************************************* -** -** Function bta_av_co_audio_stop -** -** Description This function is called by AV when the audio streaming data -** transfer is stopped. -** -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_audio_stop(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type); - -/******************************************************************************* -** -** Function bta_av_co_video_stop -** -** Description This function is called by AV when the video streaming data -** transfer is stopped. -** -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_video_stop(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type); - -/******************************************************************************* -** -** Function bta_av_co_audio_src_data_path -** -** Description This function is called to get the next data buffer from -** the audio codec -** -** Returns NULL if data is not ready. -** Otherwise, a buffer (BT_HDR*) containing the audio data. -** -*******************************************************************************/ -extern void *bta_av_co_audio_src_data_path(tBTA_AV_CODEC codec_type, - UINT32 *p_len, UINT32 *p_timestamp); - -/******************************************************************************* -** -** Function bta_av_co_video_src_data_path -** -** Description This function is called to get the next data buffer from -** the video codec. -** -** Returns NULL if data is not ready. -** Otherwise, a video data buffer (UINT8*). -** -*******************************************************************************/ -extern void *bta_av_co_video_src_data_path(tBTA_AV_CODEC codec_type, - UINT32 *p_len, UINT32 *p_timestamp); - -/******************************************************************************* -** -** Function bta_av_co_audio_drop -** -** Description An Audio packet is dropped. . -** It's very likely that the connected headset with this handle -** is moved far away. The implementation may want to reduce -** the encoder bit rate setting to reduce the packet size. -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_audio_drop(tBTA_AV_HNDL hndl); - -/******************************************************************************* -** -** Function bta_av_co_video_report_conn -** -** Description This function is called by AV when the reporting channel is -** opened (open=TRUE) or closed (open=FALSE). -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_video_report_conn (BOOLEAN open, UINT8 avdt_handle); - -/******************************************************************************* -** -** Function bta_av_co_video_report_rr -** -** Description This function is called by AV when a Receiver Report is -** received -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_video_report_rr (UINT32 packet_lost); - -/******************************************************************************* -** -** Function bta_av_co_audio_delay -** -** Description This function is called by AV when the audio stream connection -** needs to send the initial delay report to the connected SRC. -** -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_audio_delay(tBTA_AV_HNDL hndl, UINT16 delay); - -/******************************************************************************* -** -** Function bta_av_co_video_delay -** -** Description This function is called by AV when the video stream connection -** needs to send the initial delay report to the connected SRC. -** -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_co_video_delay(tBTA_AV_HNDL hndl, UINT16 delay); - -#endif ///BTA_AV_INCLUDED == TRUE - -#endif /* BTA_AV_CO_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_av_sbc.h b/tools/sdk/include/bluedroid/bta/bta_av_sbc.h deleted file mode 100644 index 966ee61b..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_av_sbc.h +++ /dev/null @@ -1,223 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2004-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the interface to utility functions for dealing with SBC data - * frames and codec capabilities. - * - ******************************************************************************/ -#ifndef BTA_AV_SBC_H -#define BTA_AV_SBC_H - -#if (BTA_AV_INCLUDED == TRUE) - -/***************************************************************************** -** constants -*****************************************************************************/ - -/* SBC packet header size */ -#define BTA_AV_SBC_HDR_SIZE A2D_SBC_MPL_HDR_LEN - -/******************************************************************************* -** -** Function bta_av_sbc_init_up_sample -** -** Description initialize the up sample -** -** src_sps: samples per second (source audio data) -** dst_sps: samples per second (converted audio data) -** bits: number of bits per pcm sample -** n_channels: number of channels (i.e. mono(1), stereo(2)...) -** -** Returns none -** -*******************************************************************************/ -extern void bta_av_sbc_init_up_sample (UINT32 src_sps, UINT32 dst_sps, - UINT16 bits, UINT16 n_channels); - -/******************************************************************************* -** -** Function bta_av_sbc_up_sample -** -** Description Given the source (p_src) audio data and -** source speed (src_sps, samples per second), -** This function converts it to audio data in the desired format -** -** p_src: the data buffer that holds the source audio data -** p_dst: the data buffer to hold the converted audio data -** src_samples: The number of source samples (number of bytes) -** dst_samples: The size of p_dst (number of bytes) -** -** Note: An AE reported an issue with this function. -** When called with bta_av_sbc_up_sample(src, uint8_array_dst..) -** the byte before uint8_array_dst may get overwritten. -** Using uint16_array_dst avoids the problem. -** This issue is related to endian-ness and is hard to resolve -** in a generic manner. -** **************** Please use uint16 array as dst. -** -** Returns The number of bytes used in p_dst -** The number of bytes used in p_src (in *p_ret) -** -*******************************************************************************/ -extern int bta_av_sbc_up_sample (void *p_src, void *p_dst, - UINT32 src_samples, UINT32 dst_samples, - UINT32 *p_ret); - -/******************************************************************************* -** -** Function bta_av_sbc_up_sample_16s (16bits-stereo) -** -** Description Given the source (p_src) audio data and -** source speed (src_sps, samples per second), -** This function converts it to audio data in the desired format -** -** p_src: the data buffer that holds the source audio data -** p_dst: the data buffer to hold the converted audio data -** src_samples: The number of source samples (in uint of 4 bytes) -** dst_samples: The size of p_dst (in uint of 4 bytes) -** -** Returns The number of bytes used in p_dst -** The number of bytes used in p_src (in *p_ret) -** -*******************************************************************************/ -extern int bta_av_sbc_up_sample_16s (void *p_src, void *p_dst, - UINT32 src_samples, UINT32 dst_samples, - UINT32 *p_ret); - -/******************************************************************************* -** -** Function bta_av_sbc_up_sample_16m (16bits-mono) -** -** Description Given the source (p_src) audio data and -** source speed (src_sps, samples per second), -** This function converts it to audio data in the desired format -** -** p_src: the data buffer that holds the source audio data -** p_dst: the data buffer to hold the converted audio data -** src_samples: The number of source samples (in uint of 2 bytes) -** dst_samples: The size of p_dst (in uint of 2 bytes) -** -** Returns The number of bytes used in p_dst -** The number of bytes used in p_src (in *p_ret) -** -*******************************************************************************/ -extern int bta_av_sbc_up_sample_16m (void *p_src, void *p_dst, - UINT32 src_samples, UINT32 dst_samples, - UINT32 *p_ret); - -/******************************************************************************* -** -** Function bta_av_sbc_up_sample_8s (8bits-stereo) -** -** Description Given the source (p_src) audio data and -** source speed (src_sps, samples per second), -** This function converts it to audio data in the desired format -** -** p_src: the data buffer that holds the source audio data -** p_dst: the data buffer to hold the converted audio data -** src_samples: The number of source samples (in uint of 2 bytes) -** dst_samples: The size of p_dst (in uint of 2 bytes) -** -** Returns The number of bytes used in p_dst -** The number of bytes used in p_src (in *p_ret) -** -*******************************************************************************/ -extern int bta_av_sbc_up_sample_8s (void *p_src, void *p_dst, - UINT32 src_samples, UINT32 dst_samples, - UINT32 *p_ret); - -/******************************************************************************* -** -** Function bta_av_sbc_up_sample_8m (8bits-mono) -** -** Description Given the source (p_src) audio data and -** source speed (src_sps, samples per second), -** This function converts it to audio data in the desired format -** -** p_src: the data buffer that holds the source audio data -** p_dst: the data buffer to hold the converted audio data -** src_samples: The number of source samples (number of bytes) -** dst_samples: The size of p_dst (number of bytes) -** -** Returns The number of bytes used in p_dst -** The number of bytes used in p_src (in *p_ret) -** -*******************************************************************************/ -extern int bta_av_sbc_up_sample_8m (void *p_src, void *p_dst, - UINT32 src_samples, UINT32 dst_samples, - UINT32 *p_ret); - -/******************************************************************************* -** -** Function bta_av_sbc_cfg_for_cap -** -** Description Determine the preferred SBC codec configuration for the -** given codec capabilities. The function is passed the -** preferred codec configuration and the peer codec -** capabilities for the stream. The function attempts to -** match the preferred capabilities with the configuration -** as best it can. The resulting codec configuration is -** returned in the same memory used for the capabilities. -** -** Returns 0 if ok, nonzero if error. -** Codec configuration in p_cap. -** -*******************************************************************************/ -extern UINT8 bta_av_sbc_cfg_for_cap(UINT8 *p_peer, tA2D_SBC_CIE *p_cap, tA2D_SBC_CIE *p_pref); - -/******************************************************************************* -** -** Function bta_av_sbc_cfg_in_cap -** -** Description This function checks whether an SBC codec configuration -** is allowable for the given codec capabilities. -** -** Returns 0 if ok, nonzero if error. -** -*******************************************************************************/ -extern UINT8 bta_av_sbc_cfg_in_cap(UINT8 *p_cfg, tA2D_SBC_CIE *p_cap); - -/******************************************************************************* -** -** Function bta_av_sbc_cfg_matches_cap -** -** Description This function checks whether an SBC codec configuration -** matched with capabilities. Here we check subset. -** -** Returns 0 if ok, nonzero if error. -** -*******************************************************************************/ -extern UINT8 bta_av_sbc_cfg_matches_cap(UINT8 *p_cfg, tA2D_SBC_CIE *p_cap); - -/******************************************************************************* -** -** Function bta_av_sbc_bld_hdr -** -** Description This function builds the packet header for MPF1. -** -** Returns void -** -*******************************************************************************/ -extern void bta_av_sbc_bld_hdr(BT_HDR *p_buf, UINT16 fr_per_pkt); - -#endif ///BTA_AV_INCLUDED == TRUE - -#endif /* BTA_AV_SBC_H */ - diff --git a/tools/sdk/include/bluedroid/bta/bta_dm_ci.h b/tools/sdk/include/bluedroid/bta/bta_dm_ci.h deleted file mode 100644 index cd15c86c..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_dm_ci.h +++ /dev/null @@ -1,68 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2006-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the interface file for device mananger call-in functions. - * - ******************************************************************************/ -#ifndef BTA_DM_CI_H -#define BTA_DM_CI_H - -#include "bta/bta_api.h" - -/***************************************************************************** -** Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/******************************************************************************* -** -** Function bta_dm_ci_io_req -** -** Description This function must be called in response to function -** bta_dm_co_io_req(), if *p_oob_data is set to BTA_OOB_UNKNOWN -** by bta_dm_co_io_req(). -** -** Returns void -** -*******************************************************************************/ -extern void bta_dm_ci_io_req(BD_ADDR bd_addr, tBTA_IO_CAP io_cap, - tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req); - -/******************************************************************************* -** -** Function bta_dm_ci_rmt_oob -** -** Description This function must be called in response to function -** bta_dm_co_rmt_oob() to provide the OOB data associated -** with the remote device. -** -** Returns void -** -*******************************************************************************/ -extern void bta_dm_ci_rmt_oob(BOOLEAN accept, BD_ADDR bd_addr, - BT_OCTET16 c, BT_OCTET16 r); -#ifdef __cplusplus -} -#endif - -#endif diff --git a/tools/sdk/include/bluedroid/bta/bta_dm_co.h b/tools/sdk/include/bluedroid/bta/bta_dm_co.h deleted file mode 100644 index 3d49a698..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_dm_co.h +++ /dev/null @@ -1,207 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2006-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the interface file for device mananger callout functions. - * - ******************************************************************************/ -#ifndef BTA_DM_CO_H -#define BTA_DM_CO_H - -#include "bta/bta_sys.h" - -/***************************************************************************** -** Function Declarations -*****************************************************************************/ - -/******************************************************************************* -** -** Function bta_dm_co_bt_set_io_cap -** -** Description This function is used to set IO capabilities -** -** Parameters bt_io_cap - IO capabilities -** -** @return - ESP_BT_STATUS_SUCCESS : success -** - other : failed -** -*******************************************************************************/ -extern esp_err_t bta_dm_co_bt_set_io_cap(UINT8 bt_io_cap); - -/******************************************************************************* -** -** Function bta_dm_co_io_req -** -** Description This callout function is executed by DM to get IO capabilities -** of the local device for the Simple Pairing process -** -** Parameters bd_addr - The peer device -** *p_io_cap - The local Input/Output capabilities -** *p_oob_data - TRUE, if OOB data is available for the peer device. -** *p_auth_req - TRUE, if MITM protection is required. -** -** Returns void. -** -*******************************************************************************/ -extern void bta_dm_co_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap, - tBTA_OOB_DATA *p_oob_data, tBTA_AUTH_REQ *p_auth_req, - BOOLEAN is_orig); - -/******************************************************************************* -** -** Function bta_dm_co_io_rsp -** -** Description This callout function is executed by DM to report IO capabilities -** of the peer device for the Simple Pairing process -** -** Parameters bd_addr - The peer device -** io_cap - The remote Input/Output capabilities -** oob_data - TRUE, if OOB data is available for the peer device. -** auth_req - TRUE, if MITM protection is required. -** -** Returns void. -** -*******************************************************************************/ -extern void bta_dm_co_io_rsp(BD_ADDR bd_addr, tBTA_IO_CAP io_cap, - tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req); - -/******************************************************************************* -** -** Function bta_dm_co_lk_upgrade -** -** Description This callout function is executed by DM to check if the -** platform wants allow link key upgrade -** -** Parameters bd_addr - The peer device -** *p_upgrade - TRUE, if link key upgrade is desired. -** -** Returns void. -** -*******************************************************************************/ -extern void bta_dm_co_lk_upgrade(BD_ADDR bd_addr, BOOLEAN *p_upgrade ); - -/******************************************************************************* -** -** Function bta_dm_co_loc_oob -** -** Description This callout function is executed by DM to report the OOB -** data of the local device for the Simple Pairing process -** -** Parameters valid - TRUE, if the local OOB data is retrieved from LM -** c - Simple Pairing Hash C -** r - Simple Pairing Randomnizer R -** -** Returns void. -** -*******************************************************************************/ -extern void bta_dm_co_loc_oob(BOOLEAN valid, BT_OCTET16 c, BT_OCTET16 r); - -/******************************************************************************* -** -** Function bta_dm_co_rmt_oob -** -** Description This callout function is executed by DM to request the OOB -** data for the remote device for the Simple Pairing process -** -** Parameters bd_addr - The peer device -** -** Returns void. -** -*******************************************************************************/ -extern void bta_dm_co_rmt_oob(BD_ADDR bd_addr); - - -/******************************************************************************* -** -** Function bta_dm_co_ble_io_req -** -** Description This callout function is executed by DM to get BLE IO capabilities -** before SMP pairing gets going. -** -** Parameters bd_addr - The peer device -** *p_io_cap - The local Input/Output capabilities -** *p_oob_data - TRUE, if OOB data is available for the peer device. -** *p_auth_req - Auth request setting (Bonding and MITM required or not) -** *p_max_key_size - max key size local device supported. -** *p_init_key - initiator keys. -** *p_resp_key - responder keys. -** -** Returns void. -** -*******************************************************************************/ -extern void bta_dm_co_ble_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap, - tBTA_OOB_DATA *p_oob_data, - tBTA_LE_AUTH_REQ *p_auth_req, - UINT8 *p_max_key_size, - tBTA_LE_KEY_TYPE *p_init_key, - tBTA_LE_KEY_TYPE *p_resp_key ); - - -/******************************************************************************* -** -** Function bta_dm_co_ble_local_key_reload -** -** Description This callout function is to load the local BLE keys if available -** on the device. -** -** Parameters none -** -** Returns void. -** -*******************************************************************************/ -extern void bta_dm_co_ble_load_local_keys (tBTA_DM_BLE_LOCAL_KEY_MASK *p_key_mask, BT_OCTET16 er, - tBTA_BLE_LOCAL_ID_KEYS *p_id_keys); - -// btla-specific ++ -/******************************************************************************* -** -** Function bta_dm_co_ble_io_req -** -** Description This callout function is executed by DM to get BLE IO capabilities -** before SMP pairing gets going. -** -** Parameters bd_addr - The peer device -** *p_io_cap - The local Input/Output capabilities -** *p_oob_data - TRUE, if OOB data is available for the peer device. -** *p_auth_req - Auth request setting (Bonding and MITM required or not) -** *p_max_key_size - max key size local device supported. -** *p_init_key - initiator keys. -** *p_resp_key - responder keys. -** -** Returns void. -** -*******************************************************************************/ -extern void bta_dm_co_ble_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap, - tBTA_OOB_DATA *p_oob_data, - tBTA_LE_AUTH_REQ *p_auth_req, - UINT8 *p_max_key_size, - tBTA_LE_KEY_TYPE *p_init_key, - tBTA_LE_KEY_TYPE *p_resp_key ); -// btla-specific -- - -extern void bta_dm_co_ble_set_io_cap(UINT8 ble_io_cap); - -extern void bta_dm_co_ble_set_auth_req(UINT8 ble_auth_req); - -extern void bta_dm_co_ble_set_init_key_req(UINT8 init_key); - -extern void bta_dm_co_ble_set_rsp_key_req(UINT8 rsp_key); - -extern void bta_dm_co_ble_set_max_key_size(UINT8 ble_key_size); -#endif diff --git a/tools/sdk/include/bluedroid/bta/bta_gatt_api.h b/tools/sdk/include/bluedroid/bta/bta_gatt_api.h deleted file mode 100644 index 9e599175..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_gatt_api.h +++ /dev/null @@ -1,1482 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2003-2013 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the public interface file for BTA GATT. - * - ******************************************************************************/ - -#ifndef BTA_GATT_API_H -#define BTA_GATT_API_H - -#include "bta/bta_api.h" -#include "stack/gatt_api.h" -#include "osi/list.h" - -#ifndef BTA_GATT_INCLUDED -#warning BTA_GATT_INCLUDED not defined -#define BTA_GATT_INCLUDED FALSE -#endif - -#if ((BLE_INCLUDED == FALSE) && (BTA_GATT_INCLUDED == TRUE)) -#undef BTA_GATT_INCLUDED -#define BTA_GATT_INCLUDED FALSE -#endif - - -#ifndef BTA_GATT_DEBUG -#define BTA_GATT_DEBUG FALSE -#endif - -typedef enum { - BTGATT_DB_PRIMARY_SERVICE, - BTGATT_DB_SECONDARY_SERVICE, - BTGATT_DB_CHARACTERISTIC, - BTGATT_DB_DESCRIPTOR, - BTGATT_DB_INCLUDED_SERVICE, -}bt_gatt_db_attribute_type_t; - -typedef enum { - GATT_OP_GET_SVC_BY_UUID, - GATT_OP_GET_ALL_CHAR, - GATT_OP_GET_ALL_DESCRI, - GATT_OP_GET_CHAR_BY_UUID, - GATT_OP_GET_DESCRI_BY_UUID, - GATT_OP_GET_DESCRI_BY_HANDLE, - GATT_OP_GET_INCLUDE_SVC, -}bt_gatt_get_db_op_t; - -typedef struct { - bt_gatt_db_attribute_type_t type; - UINT16 attribute_handle; - UINT16 start_handle; - UINT16 end_handle; - UINT16 id; - UINT8 properties; - bt_uuid_t uuid; -}btgatt_db_element_t; - -/***************************************************************************** -** Constants and data types -*****************************************************************************/ -/************************** -** Common Definitions -***************************/ -/* GATT ID */ -typedef struct { - tBT_UUID uuid; /* uuid of the attribute */ - UINT8 inst_id; /* instance ID */ -} __attribute__((packed)) tBTA_GATT_ID; - -/* relate to ESP_GATT_xxx in esp_gatt_def.h */ -/* Success code and error codes */ -#define BTA_GATT_OK GATT_SUCCESS -#define BTA_GATT_INVALID_HANDLE GATT_INVALID_HANDLE /* 0x0001 */ -#define BTA_GATT_READ_NOT_PERMIT GATT_READ_NOT_PERMIT /* 0x0002 */ -#define BTA_GATT_WRITE_NOT_PERMIT GATT_WRITE_NOT_PERMIT /* 0x0003 */ -#define BTA_GATT_INVALID_PDU GATT_INVALID_PDU /* 0x0004 */ -#define BTA_GATT_INSUF_AUTHENTICATION GATT_INSUF_AUTHENTICATION /* 0x0005 */ -#define BTA_GATT_REQ_NOT_SUPPORTED GATT_REQ_NOT_SUPPORTED /* 0x0006 */ -#define BTA_GATT_INVALID_OFFSET GATT_INVALID_OFFSET /* 0x0007 */ -#define BTA_GATT_INSUF_AUTHORIZATION GATT_INSUF_AUTHORIZATION /* 0x0008 */ -#define BTA_GATT_PREPARE_Q_FULL GATT_PREPARE_Q_FULL /* 0x0009 */ -#define BTA_GATT_NOT_FOUND GATT_NOT_FOUND /* 0x000a */ -#define BTA_GATT_NOT_LONG GATT_NOT_LONG /* 0x000b */ -#define BTA_GATT_INSUF_KEY_SIZE GATT_INSUF_KEY_SIZE /* 0x000c */ -#define BTA_GATT_INVALID_ATTR_LEN GATT_INVALID_ATTR_LEN /* 0x000d */ -#define BTA_GATT_ERR_UNLIKELY GATT_ERR_UNLIKELY /* 0x000e */ -#define BTA_GATT_INSUF_ENCRYPTION GATT_INSUF_ENCRYPTION /* 0x000f */ -#define BTA_GATT_UNSUPPORT_GRP_TYPE GATT_UNSUPPORT_GRP_TYPE /* 0x0010 */ -#define BTA_GATT_INSUF_RESOURCE GATT_INSUF_RESOURCE /* 0x0011 */ - - -#define BTA_GATT_NO_RESOURCES GATT_NO_RESOURCES /* 0x80 */ -#define BTA_GATT_INTERNAL_ERROR GATT_INTERNAL_ERROR /* 0x81 */ -#define BTA_GATT_WRONG_STATE GATT_WRONG_STATE /* 0x82 */ -#define BTA_GATT_DB_FULL GATT_DB_FULL /* 0x83 */ -#define BTA_GATT_BUSY GATT_BUSY /* 0x84 */ -#define BTA_GATT_ERROR GATT_ERROR /* 0x85 */ -#define BTA_GATT_CMD_STARTED GATT_CMD_STARTED /* 0x86 */ -#define BTA_GATT_ILLEGAL_PARAMETER GATT_ILLEGAL_PARAMETER /* 0x87 */ -#define BTA_GATT_PENDING GATT_PENDING /* 0x88 */ -#define BTA_GATT_AUTH_FAIL GATT_AUTH_FAIL /* 0x89 */ -#define BTA_GATT_MORE GATT_MORE /* 0x8a */ -#define BTA_GATT_INVALID_CFG GATT_INVALID_CFG /* 0x8b */ -#define BTA_GATT_SERVICE_STARTED GATT_SERVICE_STARTED /* 0x8c */ -#define BTA_GATT_ENCRYPED_MITM GATT_ENCRYPED_MITM /* GATT_SUCCESS */ -#define BTA_GATT_ENCRYPED_NO_MITM GATT_ENCRYPED_NO_MITM /* 0x8d */ -#define BTA_GATT_NOT_ENCRYPTED GATT_NOT_ENCRYPTED /* 0x8e */ -#define BTA_GATT_CONGESTED GATT_CONGESTED /* 0x8f */ - -#define BTA_GATT_DUP_REG GATT_DUP_REG /* 0x90 */ -#define BTA_GATT_ALREADY_OPEN GATT_ALREADY_OPEN /* 0x91 */ -#define BTA_GATT_CANCEL GATT_CANCEL /* 0x92 */ - -/* 0xE0 ~ 0xFC reserved for future use */ -#define BTA_GATT_STACK_RSP GATT_STACK_RSP /* 0xE0 */ -#define BTA_GATT_APP_RSP GATT_APP_RSP /* 0xE1 */ -//Error caused by customer application or stack bug -#define BTA_GATT_UNKNOWN_ERROR GATT_UNKNOWN_ERROR /* 0XEF */ - /* 0xE0 ~ 0xFC reserved for future use */ -#define BTA_GATT_CCC_CFG_ERR GATT_CCC_CFG_ERR /* 0xFD Client Characteristic Configuration Descriptor Improperly Configured */ -#define BTA_GATT_PRC_IN_PROGRESS GATT_PRC_IN_PROGRESS /* 0xFE Procedure Already in progress */ -#define BTA_GATT_OUT_OF_RANGE GATT_OUT_OF_RANGE /* 0xFFAttribute value out of range */ - -typedef UINT8 tBTA_GATT_STATUS; - -#define BTA_GATT_INVALID_CONN_ID GATT_INVALID_CONN_ID - - -/* Client callback function events */ -#define BTA_GATTC_REG_EVT 0 /* GATT client is registered. */ -#define BTA_GATTC_DEREG_EVT 1 /* GATT client deregistered event */ -#define BTA_GATTC_OPEN_EVT 2 /* GATTC open request status event */ -#define BTA_GATTC_READ_CHAR_EVT 3 /* GATT read characteristic event */ -#define BTA_GATTC_WRITE_CHAR_EVT 4 /* GATT write characteristic or char descriptor event */ -#define BTA_GATTC_CLOSE_EVT 5 /* GATTC close request status event */ -#define BTA_GATTC_SEARCH_CMPL_EVT 6 /* GATT discovery complete event */ -#define BTA_GATTC_SEARCH_RES_EVT 7 /* GATT discovery result event */ -#define BTA_GATTC_READ_DESCR_EVT 8 /* GATT read characterisitc descriptor event */ -#define BTA_GATTC_WRITE_DESCR_EVT 9 /* GATT write characteristic descriptor event */ -#define BTA_GATTC_NOTIF_EVT 10 /* GATT attribute notification event */ -#define BTA_GATTC_PREP_WRITE_EVT 11 /* GATT prepare write event */ -#define BTA_GATTC_EXEC_EVT 12 /* execute write complete event */ -#define BTA_GATTC_ACL_EVT 13 /* ACL up event */ -#define BTA_GATTC_CANCEL_OPEN_EVT 14 /* cancel open event */ -#define BTA_GATTC_SRVC_CHG_EVT 15 /* service change event */ -#define BTA_GATTC_LISTEN_EVT 16 /* listen event */ -#define BTA_GATTC_ENC_CMPL_CB_EVT 17 /* encryption complete callback event */ -#define BTA_GATTC_CFG_MTU_EVT 18 /* configure MTU complete event */ -#define BTA_GATTC_ADV_DATA_EVT 19 /* ADV data event */ -#define BTA_GATTC_MULT_ADV_ENB_EVT 20 /* Enable Multi ADV event */ -#define BTA_GATTC_MULT_ADV_UPD_EVT 21 /* Update parameter event */ -#define BTA_GATTC_MULT_ADV_DATA_EVT 22 /* Multi ADV data event */ -#define BTA_GATTC_MULT_ADV_DIS_EVT 23 /* Disable Multi ADV event */ -#define BTA_GATTC_CONGEST_EVT 24 /* Congestion event */ -#define BTA_GATTC_BTH_SCAN_ENB_EVT 25 /* Enable batch scan event */ -#define BTA_GATTC_BTH_SCAN_CFG_EVT 26 /* Config storage event */ -#define BTA_GATTC_BTH_SCAN_RD_EVT 27 /* Batch scan reports read event */ -#define BTA_GATTC_BTH_SCAN_THR_EVT 28 /* Batch scan threshold event */ -#define BTA_GATTC_BTH_SCAN_PARAM_EVT 29 /* Batch scan param event */ -#define BTA_GATTC_BTH_SCAN_DIS_EVT 30 /* Disable batch scan event */ -#define BTA_GATTC_SCAN_FLT_CFG_EVT 31 /* Scan filter config event */ -#define BTA_GATTC_SCAN_FLT_PARAM_EVT 32 /* Param filter event */ -#define BTA_GATTC_SCAN_FLT_STATUS_EVT 33 /* Filter status event */ -#define BTA_GATTC_ADV_VSC_EVT 34 /* ADV VSC event */ -#define BTA_GATTC_CONNECT_EVT 35 /* GATTC CONNECT event */ -#define BTA_GATTC_DISCONNECT_EVT 36 /* GATTC DISCONNECT event */ -#define BTA_GATTC_READ_MULTIPLE_EVT 37 /* GATTC Read mutiple event */ -#define BTA_GATTC_QUEUE_FULL_EVT 38 /* GATTC queue full event */ -#define BTA_GATTC_ASSOC_EVT 39 /* GATTC association address event */ -#define BTA_GATTC_GET_ADDR_LIST_EVT 40 /* GATTC get address list in the cache event */ - -typedef UINT8 tBTA_GATTC_EVT; - -typedef tGATT_IF tBTA_GATTC_IF; - -typedef UINT8 tBTA_ADDR_TYPE; - -typedef struct { - UINT16 unit; /* as UUIUD defined by SIG */ - UINT16 descr; /* as UUID as defined by SIG */ - tGATT_FORMAT format; - INT8 exp; - UINT8 name_spc; /* The name space of the description */ -} tBTA_GATT_CHAR_PRES; - -#define BTA_GATT_CLT_CONFIG_NONE GATT_CLT_CONFIG_NONE /* 0x0000 */ -#define BTA_GATT_CLT_CONFIG_NOTIFICATION GATT_CLT_CONFIG_NOTIFICATION /* 0x0001 */ -#define BTA_GATT_CLT_CONFIG_INDICATION GATT_CLT_CONFIG_INDICATION /* 0x0002 */ -typedef UINT16 tBTA_GATT_CLT_CHAR_CONFIG; - -/* characteristic descriptor: server configuration value -*/ -#define BTA_GATT_SVR_CONFIG_NONE GATT_SVR_CONFIG_NONE /* 0x0000 */ -#define BTA_GATT_SVR_CONFIG_BROADCAST GATT_SVR_CONFIG_BROADCAST /* 0x0001 */ -typedef UINT16 tBTA_GATT_SVR_CHAR_CONFIG; - -/* Characteristic Aggregate Format attribute value -*/ -#define BTA_GATT_AGGR_HANDLE_NUM_MAX 10 -typedef struct { - UINT8 num_handle; - UINT16 handle_list[BTA_GATT_AGGR_HANDLE_NUM_MAX]; -} tBTA_GATT_CHAR_AGGRE; -typedef tGATT_VALID_RANGE tBTA_GATT_VALID_RANGE; - -typedef struct { - UINT16 len; - UINT8 *p_value; -} tBTA_GATT_UNFMT; - -#define BTA_GATT_MAX_ATTR_LEN GATT_MAX_ATTR_LEN - -#define BTA_GATTC_TYPE_WRITE GATT_WRITE -#define BTA_GATTC_TYPE_WRITE_NO_RSP GATT_WRITE_NO_RSP -typedef UINT8 tBTA_GATTC_WRITE_TYPE; - -/* relate to ESP_GATT_CONN_xxx in esp_gatt_defs.h */ -#define BTA_GATT_CONN_UNKNOWN 0 -#define BTA_GATT_CONN_L2C_FAILURE GATT_CONN_L2C_FAILURE /* general l2cap resource failure */ -#define BTA_GATT_CONN_TIMEOUT GATT_CONN_TIMEOUT /* 0x08 connection timeout */ -#define BTA_GATT_CONN_TERMINATE_PEER_USER GATT_CONN_TERMINATE_PEER_USER /* 0x13 connection terminate by peer user */ -#define BTA_GATT_CONN_TERMINATE_LOCAL_HOST GATT_CONN_TERMINATE_LOCAL_HOST/* 0x16 connectionterminated by local host */ -#define BTA_GATT_CONN_FAIL_ESTABLISH GATT_CONN_FAIL_ESTABLISH /* 0x03E connection fail to establish */ -#define BTA_GATT_CONN_LMP_TIMEOUT GATT_CONN_LMP_TIMEOUT /* 0x22 connection fail for LMP response tout */ -#define BTA_GATT_CONN_CANCEL GATT_CONN_CANCEL /* 0x0100 L2CAP connection cancelled */ -#define BTA_GATT_CONN_NONE 0x0101 /* 0x0101 no connection to cancel */ -typedef UINT16 tBTA_GATT_REASON; - -typedef struct { - tBTA_GATT_ID id; - BOOLEAN is_primary; -} tBTA_GATT_SRVC_ID; - - -#define BTA_GATTC_MULTI_MAX GATT_MAX_READ_MULTI_HANDLES - -typedef struct { - UINT8 num_attr; - UINT16 handles[BTA_GATTC_MULTI_MAX]; -}tBTA_GATTC_MULTI; - -/* relate to ESP_GATT_xxx in esp_gatt_def.h */ -#define BTA_GATT_AUTH_REQ_NONE GATT_AUTH_REQ_NONE -#define BTA_GATT_AUTH_REQ_NO_MITM GATT_AUTH_REQ_NO_MITM /* unauthenticated encryption */ -#define BTA_GATT_AUTH_REQ_MITM GATT_AUTH_REQ_MITM /* authenticated encryption */ -#define BTA_GATT_AUTH_REQ_SIGNED_NO_MITM GATT_AUTH_REQ_SIGNED_NO_MITM -#define BTA_GATT_AUTH_REQ_SIGNED_MITM GATT_AUTH_REQ_SIGNED_MITM - -typedef tGATT_AUTH_REQ tBTA_GATT_AUTH_REQ; - -enum { - BTA_GATTC_ATTR_TYPE_INCL_SRVC, - BTA_GATTC_ATTR_TYPE_CHAR, - BTA_GATTC_ATTR_TYPE_CHAR_DESCR, - BTA_GATTC_ATTR_TYPE_SRVC -}; -typedef UINT8 tBTA_GATTC_ATTR_TYPE; - - -typedef struct { - tBT_UUID uuid; - UINT16 s_handle; - UINT16 e_handle; /* used for service only */ - UINT8 attr_type; - UINT8 id; - UINT8 prop; /* used when attribute type is characteristic */ - BOOLEAN is_primary; /* used when attribute type is service */ - UINT16 incl_srvc_s_handle; /* used when attribute type is included service */ - UINT16 incl_srvc_e_handle; /* used when attribute type is included service */ -}tBTA_GATTC_NV_ATTR; - -/* callback data structure */ -typedef struct { - tBTA_GATT_STATUS status; - tBTA_GATTC_IF client_if; - tBT_UUID app_uuid; -}tBTA_GATTC_REG; - -typedef struct { - UINT16 conn_id; - tBTA_GATT_STATUS status; - UINT16 handle; - tBTA_GATT_UNFMT *p_value; -}tBTA_GATTC_READ; - -typedef struct { - UINT16 conn_id; - tBTA_GATT_STATUS status; - UINT16 handle; - UINT16 offset; -}tBTA_GATTC_WRITE; - -typedef struct { - UINT16 conn_id; - tBTA_GATT_STATUS status; -} tBTA_GATTC_EXEC_CMPL; - -typedef struct { - UINT16 conn_id; - tBTA_GATT_STATUS status; -} tBTA_GATTC_SEARCH_CMPL; - -typedef struct { - UINT16 conn_id; - UINT16 start_handle; - UINT16 end_handle; - tBTA_GATT_ID service_uuid; - bool is_primary; -}tBTA_GATTC_SRVC_RES; - -typedef struct { - UINT16 conn_id; - tBTA_GATT_STATUS status; - UINT16 mtu; -} tBTA_GATTC_CFG_MTU; - -typedef struct { - tBTA_GATT_STATUS status; - UINT16 conn_id; - tBTA_GATTC_IF client_if; - BD_ADDR remote_bda; - tBTA_TRANSPORT transport; - UINT16 mtu; -} tBTA_GATTC_OPEN; - -typedef struct { - tBTA_GATT_STATUS status; - UINT16 conn_id; - tBTA_GATTC_IF client_if; - BD_ADDR remote_bda; - tBTA_GATT_REASON reason; /* disconnect reason code, not useful when connect event is reported */ -} tBTA_GATTC_CLOSE; - -typedef struct { - UINT16 conn_id; - BD_ADDR bda; - UINT16 handle; - UINT16 len; - UINT8 value[BTA_GATT_MAX_ATTR_LEN]; - BOOLEAN is_notify; -} tBTA_GATTC_NOTIFY; - -typedef struct { - UINT16 conn_id; - BOOLEAN congested; /* congestion indicator */ -} tBTA_GATTC_CONGEST; - -typedef struct { - tBTA_GATT_STATUS status; - UINT16 conn_id; - BOOLEAN is_full; -} tBTA_GATTC_QUEUE_FULL; - -typedef struct { - tBTA_GATT_STATUS status; - tBTA_GATTC_IF client_if; -} tBTA_GATTC_SET_ASSOC; - -typedef struct { - tBTA_GATT_STATUS status; - tBTA_GATTC_IF client_if; - UINT8 num_addr; - BD_ADDR *bda_list; -} tBTA_GATTC_GET_ADDR_LIST; - -typedef struct { - tBTA_GATT_STATUS status; - tBTA_GATTC_IF client_if; - UINT16 conn_id; - BD_ADDR remote_bda; -} tBTA_GATTC_OPEN_CLOSE; - -typedef struct { - tBTA_GATTC_IF client_if; - BD_ADDR remote_bda; -} tBTA_GATTC_ENC_CMPL_CB; - -typedef struct { - UINT16 conn_id; - tBTA_GATTC_IF client_if; - BD_ADDR remote_bda; -} tBTA_GATTC_CONNECT; - -typedef struct { - tGATT_DISCONN_REASON reason; - UINT16 conn_id; - tBTA_GATTC_IF client_if; - BD_ADDR remote_bda; -} tBTA_GATTC_DISCONNECT; - -typedef struct { - UINT16 conn_id; - BD_ADDR remote_bda; -} tBTA_GATTC_SERVICE_CHANGE; - -typedef union { - tBTA_GATT_STATUS status; - - tBTA_GATTC_SEARCH_CMPL search_cmpl; /* discovery complete */ - tBTA_GATTC_SRVC_RES srvc_res; /* discovery result */ - tBTA_GATTC_REG reg_oper; /* registration data */ - tBTA_GATTC_OPEN open; - tBTA_GATTC_CONNECT connect; - tBTA_GATTC_CLOSE close; - tBTA_GATTC_DISCONNECT disconnect; - tBTA_GATTC_READ read; /* read attribute/descriptor data */ - tBTA_GATTC_WRITE write; /* write complete data */ - tBTA_GATTC_EXEC_CMPL exec_cmpl; /* execute complete */ - tBTA_GATTC_NOTIFY notify; /* notification/indication event data */ - tBTA_GATTC_ENC_CMPL_CB enc_cmpl; - tBTA_GATTC_CFG_MTU cfg_mtu; /* configure MTU operation */ - tBTA_GATTC_CONGEST congest; - tBTA_GATTC_QUEUE_FULL queue_full; - tBTA_GATTC_SERVICE_CHANGE srvc_chg; /* service change event */ - tBTA_GATTC_SET_ASSOC set_assoc; - tBTA_GATTC_GET_ADDR_LIST get_addr_list; -} tBTA_GATTC; - -/* GATTC enable callback function */ -typedef void (tBTA_GATTC_ENB_CBACK)(tBTA_GATT_STATUS status); - -/* Client callback function */ -typedef void (tBTA_GATTC_CBACK)(tBTA_GATTC_EVT event, tBTA_GATTC *p_data); - -/* GATT Server Data Structure */ -/* Server callback function events */ -#define BTA_GATTS_REG_EVT 0 -#define BTA_GATTS_READ_EVT GATTS_REQ_TYPE_READ /* 1 */ -#define BTA_GATTS_WRITE_EVT GATTS_REQ_TYPE_WRITE /* 2 */ -#define BTA_GATTS_EXEC_WRITE_EVT GATTS_REQ_TYPE_WRITE_EXEC /* 3 */ -#define BTA_GATTS_MTU_EVT GATTS_REQ_TYPE_MTU /* 4 */ -#define BTA_GATTS_CONF_EVT GATTS_REQ_TYPE_CONF /* 5 */ -#define BTA_GATTS_DEREG_EVT 6 -#define BTA_GATTS_CREATE_EVT 7 -#define BTA_GATTS_ADD_INCL_SRVC_EVT 8 -#define BTA_GATTS_ADD_CHAR_EVT 9 -#define BTA_GATTS_ADD_CHAR_DESCR_EVT 10 -#define BTA_GATTS_DELELTE_EVT 11 -#define BTA_GATTS_START_EVT 12 -#define BTA_GATTS_STOP_EVT 13 -#define BTA_GATTS_CONNECT_EVT 14 -#define BTA_GATTS_DISCONNECT_EVT 15 -#define BTA_GATTS_OPEN_EVT 16 -#define BTA_GATTS_CANCEL_OPEN_EVT 17 -#define BTA_GATTS_CLOSE_EVT 18 -#define BTA_GATTS_LISTEN_EVT 19 -#define BTA_GATTS_CONGEST_EVT 20 -#define BTA_GATTS_SET_ATTR_VAL_EVT 23 - -typedef UINT8 tBTA_GATTS_EVT; -typedef tGATT_IF tBTA_GATTS_IF; - -/* Attribute permissions -*/ -#define BTA_GATT_PERM_READ GATT_PERM_READ /* bit 0 - 0x0001 */ -#define BTA_GATT_PERM_READ_ENCRYPTED GATT_PERM_READ_ENCRYPTED /* bit 1 - 0x0002 */ -#define BTA_GATT_PERM_READ_ENC_MITM GATT_PERM_READ_ENC_MITM /* bit 2 - 0x0004 */ -#define BTA_GATT_PERM_WRITE GATT_PERM_WRITE /* bit 4 - 0x0010 */ -#define BTA_GATT_PERM_WRITE_ENCRYPTED GATT_PERM_WRITE_ENCRYPTED /* bit 5 - 0x0020 */ -#define BTA_GATT_PERM_WRITE_ENC_MITM GATT_PERM_WRITE_ENC_MITM /* bit 6 - 0x0040 */ -#define BTA_GATT_PERM_WRITE_SIGNED GATT_PERM_WRITE_SIGNED /* bit 7 - 0x0080 */ -#define BTA_GATT_PERM_WRITE_SIGNED_MITM GATT_PERM_WRITE_SIGNED_MITM /* bit 8 - 0x0100 */ -typedef UINT16 tBTA_GATT_PERM; -typedef tGATT_ATTR_VAL tBTA_GATT_ATTR_VAL; -typedef tGATTS_ATTR_CONTROL tBTA_GATTS_ATTR_CONTROL; - -#define BTA_GATTS_INVALID_APP 0xff - -#define BTA_GATTS_INVALID_IF 0 - -/* definition of characteristic properties */ -#define BTA_GATT_CHAR_PROP_BIT_BROADCAST GATT_CHAR_PROP_BIT_BROADCAST /* 0x01 */ -#define BTA_GATT_CHAR_PROP_BIT_READ GATT_CHAR_PROP_BIT_READ /* 0x02 */ -#define BTA_GATT_CHAR_PROP_BIT_WRITE_NR GATT_CHAR_PROP_BIT_WRITE_NR /* 0x04 */ -#define BTA_GATT_CHAR_PROP_BIT_WRITE GATT_CHAR_PROP_BIT_WRITE /* 0x08 */ -#define BTA_GATT_CHAR_PROP_BIT_NOTIFY GATT_CHAR_PROP_BIT_NOTIFY /* 0x10 */ -#define BTA_GATT_CHAR_PROP_BIT_INDICATE GATT_CHAR_PROP_BIT_INDICATE /* 0x20 */ -#define BTA_GATT_CHAR_PROP_BIT_AUTH GATT_CHAR_PROP_BIT_AUTH /* 0x40 */ -#define BTA_GATT_CHAR_PROP_BIT_EXT_PROP GATT_CHAR_PROP_BIT_EXT_PROP /* 0x80 */ -typedef UINT8 tBTA_GATT_CHAR_PROP; - -#ifndef BTA_GATTC_CHAR_DESCR_MAX -#define BTA_GATTC_CHAR_DESCR_MAX 7 -#endif - -/*********************** NV callback Data Definitions ********************** -*/ -typedef struct { - tBT_UUID app_uuid128; - tBT_UUID svc_uuid; - UINT16 svc_inst; - UINT16 s_handle; - UINT16 e_handle; - BOOLEAN is_primary; /* primary service or secondary */ -} tBTA_GATTS_HNDL_RANGE; - -#define BTA_GATTS_SRV_CHG_CMD_ADD_CLIENT GATTS_SRV_CHG_CMD_ADD_CLIENT -#define BTA_GATTS_SRV_CHG_CMD_UPDATE_CLIENT GATTS_SRV_CHG_CMD_UPDATE_CLIENT -#define BTA_GATTS_SRV_CHG_CMD_REMOVE_CLIENT GATTS_SRV_CHG_CMD_REMOVE_CLIENT -#define BTA_GATTS_SRV_CHG_CMD_READ_NUM_CLENTS GATTS_SRV_CHG_CMD_READ_NUM_CLENTS -#define BTA_GATTS_SRV_CHG_CMD_READ_CLENT GATTS_SRV_CHG_CMD_READ_CLENT -typedef tGATTS_SRV_CHG_CMD tBTA_GATTS_SRV_CHG_CMD; - -typedef tGATTS_SRV_CHG tBTA_GATTS_SRV_CHG; -typedef tGATTS_SRV_CHG_REQ tBTA_GATTS_SRV_CHG_REQ; -typedef tGATTS_SRV_CHG_RSP tBTA_GATTS_SRV_CHG_RSP; - -#define BTA_GATT_TRANSPORT_LE GATT_TRANSPORT_LE -#define BTA_GATT_TRANSPORT_BR_EDR GATT_TRANSPORT_BR_EDR -#define BTA_GATT_TRANSPORT_LE_BR_EDR GATT_TRANSPORT_LE_BR_EDR -typedef UINT8 tBTA_GATT_TRANSPORT; - -/* attribute value */ -typedef tGATT_VALUE tBTA_GATT_VALUE; - -/* attribute response data */ -typedef tGATTS_RSP tBTA_GATTS_RSP; - -/* relate to ESP_GATT_PREP_WRITE_xxx in esp_gatt_defs.h */ -/* attribute request data from the client */ -#define BTA_GATT_PREP_WRITE_CANCEL 0x00 -#define BTA_GATT_PREP_WRITE_EXEC 0x01 -typedef tGATT_EXEC_FLAG tBTA_GATT_EXEC_FLAG; - -/* read request always based on UUID */ -typedef tGATT_READ_REQ tBTA_GATT_READ_REQ; - -/* write request data */ -typedef tGATT_WRITE_REQ tBTA_GATT_WRITE_REQ; - -/* callback data for server access request from client */ -typedef tGATTS_DATA tBTA_GATTS_REQ_DATA; - -typedef struct { - tBTA_GATT_STATUS status; - BD_ADDR remote_bda; - UINT32 trans_id; - UINT16 conn_id; - tBTA_GATTS_REQ_DATA *p_data; - UINT16 data_len; - UINT8 *value; -} tBTA_GATTS_REQ; - -typedef struct { - tBTA_GATTS_IF server_if; - tBTA_GATT_STATUS status; - tBT_UUID uuid; -}tBTA_GATTS_REG_OPER; - - -typedef struct { - tBTA_GATTS_IF server_if; - UINT16 service_id; - UINT16 svc_instance; - BOOLEAN is_primary; - tBTA_GATT_STATUS status; - tBT_UUID uuid; -}tBTA_GATTS_CREATE; - -typedef struct { - tBTA_GATTS_IF server_if; - UINT16 service_id; - UINT16 attr_id; - tBTA_GATT_STATUS status; - tBT_UUID char_uuid; -}tBTA_GATTS_ADD_RESULT; -typedef struct{ - tBTA_GATTS_IF server_if; - UINT16 service_id; - UINT16 attr_id; - tBTA_GATT_STATUS status; -}tBAT_GATTS_ATTR_VAL_RESULT; - -typedef struct { - tBTA_GATTS_IF server_if; - UINT16 service_id; - tBTA_GATT_STATUS status; -} tBTA_GATTS_SRVC_OPER; - - -typedef struct { - tBTA_GATTS_IF server_if; - BD_ADDR remote_bda; - UINT16 conn_id; - tBTA_GATT_REASON reason; /* report disconnect reason */ - tBTA_GATT_TRANSPORT transport; -} tBTA_GATTS_CONN; - -typedef struct { - UINT16 conn_id; - BOOLEAN congested; /* report channel congestion indicator */ -} tBTA_GATTS_CONGEST; - -typedef struct { - UINT16 conn_id; /* connection ID */ - tBTA_GATT_STATUS status; /* notification/indication status */ -} tBTA_GATTS_CONF; - -typedef struct { - tBTA_GATT_STATUS status; - UINT16 conn_id; /* connection ID */ -} tBTA_GATTS_CLOSE; - -typedef struct { - tBTA_GATT_STATUS status; - tBTA_GATTS_IF server_if; -} tBTA_GATTS_OPEN; - -typedef struct { - tBTA_GATT_STATUS status; - tBTA_GATTS_IF server_if; -} tBTA_GATTS_CANCEL_OPEN; -/* GATTS callback data */ -typedef union { - tBTA_GATTS_REG_OPER reg_oper; - tBTA_GATTS_CREATE create; - tBTA_GATTS_SRVC_OPER srvc_oper; - tBTA_GATT_STATUS status; /* BTA_GATTS_LISTEN_EVT */ - tBTA_GATTS_ADD_RESULT add_result; /* add included service: BTA_GATTS_ADD_INCL_SRVC_EVT - add char : BTA_GATTS_ADD_CHAR_EVT - add char descriptor: BTA_GATTS_ADD_CHAR_DESCR_EVT */ - tBAT_GATTS_ATTR_VAL_RESULT attr_val; - tBTA_GATTS_REQ req_data; - tBTA_GATTS_CONN conn; /* BTA_GATTS_CONN_EVT */ - tBTA_GATTS_CONGEST congest; /* BTA_GATTS_CONGEST_EVT callback data */ - tBTA_GATTS_CONF confirm; /* BTA_GATTS_CONF_EVT callback data */ - tBTA_GATTS_CLOSE close; /* BTA_GATTS_CLOSE_EVT callback data */ - tBTA_GATTS_OPEN open; /* BTA_GATTS_OPEN_EVT callback data */ - tBTA_GATTS_CANCEL_OPEN cancel_open; /* tBTA_GATTS_CANCEL_OPEN callback data */ - -} tBTA_GATTS; - -/* GATTC wait for service change ccc timer callback data */ -typedef struct { - UINT16 conn_id; - BD_ADDR remote_bda; - UINT8 count; - UINT8 last_status; -}tBTA_GATTC_WAIT_CCC_TIMER; - -/* GATTS enable callback function */ -typedef void (tBTA_GATTS_ENB_CBACK)(tBTA_GATT_STATUS status); - -/* Server callback function */ -typedef void (tBTA_GATTS_CBACK)(tBTA_GATTS_EVT event, tBTA_GATTS *p_data); -typedef struct -{ - tBT_UUID uuid; - BOOLEAN is_primary; - UINT16 handle; - UINT16 s_handle; - UINT16 e_handle; - list_t *characteristics; /* list of tBTA_GATTC_CHARACTERISTIC */ - list_t *included_svc; /* list of tBTA_GATTC_INCLUDED_SVC */ -} __attribute__((packed)) tBTA_GATTC_SERVICE; - -typedef struct -{ - tBT_UUID uuid; - UINT16 handle; - tBTA_GATT_CHAR_PROP properties; - tBTA_GATTC_SERVICE *service; /* owning service*/ - list_t *descriptors; /* list of tBTA_GATTC_DESCRIPTOR */ -} __attribute__((packed)) tBTA_GATTC_CHARACTERISTIC; - -typedef struct -{ - tBT_UUID uuid; - UINT16 handle; - tBTA_GATTC_CHARACTERISTIC *characteristic; /* owning characteristic */ -} __attribute__((packed)) tBTA_GATTC_DESCRIPTOR; - -typedef struct -{ - tBT_UUID uuid; - UINT16 handle; - UINT16 incl_srvc_s_handle; - UINT16 incl_srvc_e_handle; - tBTA_GATTC_SERVICE *owning_service; /* owning service*/ - tBTA_GATTC_SERVICE *included_service; -} __attribute__((packed)) tBTA_GATTC_INCLUDED_SVC; - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/************************** -** Client Functions -***************************/ - -/******************************************************************************* -** -** Function BTA_GATTC_Disable -** -** Description This function is called to disable the GATTC module -** -** Parameters None. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTC_Disable(void); - -/******************************************************************************* -** -** Function BTA_GATTC_AppRegister -** -** Description This function is called to register application callbacks -** with BTA GATTC module. -** -** Parameters p_app_uuid - applicaiton UUID -** p_client_cb - pointer to the application callback function. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTC_AppRegister(tBT_UUID *p_app_uuid, tBTA_GATTC_CBACK *p_client_cb); - -/******************************************************************************* -** -** Function BTA_GATTC_AppDeregister -** -** Description This function is called to deregister an application -** from BTA GATTC module. -** -** Parameters client_if - client interface identifier. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTC_AppDeregister (tBTA_GATTC_IF client_if); - -/******************************************************************************* -** -** Function BTA_GATTC_Open -** -** Description Open a direct connection or add a background auto connection -** bd address -** -** Parameters client_if: server interface. -** remote_bda: remote device BD address. -** remote_addr_type: remote device BD address type. -** is_direct: direct connection or background auto connection -** -** Returns void -** -*******************************************************************************/ -extern void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_ADDR_TYPE remote_addr_type, - BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport); - -/******************************************************************************* -** -** Function BTA_GATTC_CancelOpen -** -** Description Open a direct connection or add a background auto connection -** bd address -** -** Parameters client_if: server interface. -** remote_bda: remote device BD address. -** is_direct: direct connection or background auto connection -** -** Returns void -** -*******************************************************************************/ -extern void BTA_GATTC_CancelOpen(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_direct); - -/******************************************************************************* -** -** Function BTA_GATTC_Close -** -** Description Close a connection to a GATT server. -** -** Parameters conn_id: connection ID to be closed. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_GATTC_Close(UINT16 conn_id); - -/******************************************************************************* -** -** Function BTA_GATTC_ServiceSearchRequest -** -** Description This function is called to request a GATT service discovery -** on a GATT server. This function report service search result -** by a callback event, and followed by a service search complete -** event. -** -** Parameters conn_id: connection ID. -** p_srvc_uuid: a UUID of the service application is interested in. -** If Null, discover for all services. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTC_ServiceSearchRequest(UINT16 conn_id, tBT_UUID *p_srvc_uuid); - -/******************************************************************************* -** -** Function BTA_GATTC_GetServices -** -** Description This function is called to find the services on the given server. -** -** Parameters conn_id: connection ID which identify the server. -** -** Returns returns list_t of tBTA_GATTC_SERVICE or NULL. -** -*******************************************************************************/ -extern const list_t* BTA_GATTC_GetServices(UINT16 conn_id); - -/******************************************************************************* -** -** Function BTA_GATTC_GetCharacteristic -** -** Description This function is called to find the characteristic on the given server. -** -** Parameters conn_id: connection ID which identify the server. -** handle: characteristic handle -** -** Returns returns pointer to tBTA_GATTC_CHARACTERISTIC or NULL. -** -*******************************************************************************/ -extern const tBTA_GATTC_CHARACTERISTIC* BTA_GATTC_GetCharacteristic(UINT16 conn_id, UINT16 handle); - -/******************************************************************************* -** -** Function BTA_GATTC_GetDescriptor -** -** Description This function is called to find the characteristic on the given server. -** -** Parameters conn_id: connection ID which identify the server. -** handle: descriptor handle -** -** Returns returns pointer to tBTA_GATTC_DESCRIPTOR or NULL. -** -*******************************************************************************/ -extern const tBTA_GATTC_DESCRIPTOR* BTA_GATTC_GetDescriptor(UINT16 conn_id, UINT16 handle); - -extern void BTA_GATTC_GetServiceWithUUID(UINT16 conn_id, tBT_UUID *svc_uuid, - btgatt_db_element_t **db, int *count); - -extern void BTA_GATTC_GetAllChar(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, - btgatt_db_element_t **db, int *count); - -extern void BTA_GATTC_GetAllDescriptor(UINT16 conn_id, UINT16 char_handle, - btgatt_db_element_t **db, int *count); - -extern void BTA_GATTC_GetCharByUUID(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, tBT_UUID char_uuid, - btgatt_db_element_t **db, int *count); - -extern void BTA_GATTC_GetDescrByUUID(UINT16 conn_id, uint16_t start_handle, uint16_t end_handle, - tBT_UUID char_uuid, tBT_UUID descr_uuid, - btgatt_db_element_t **db, int *count); - -extern void BTA_GATTC_GetDescrByCharHandle(UINT16 conn_id, UINT16 char_handle, tBT_UUID descr_uuid, - btgatt_db_element_t **db, int *count); - -extern void BTA_GATTC_GetIncludeService(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, - tBT_UUID *incl_uuid, btgatt_db_element_t **db, int *count); - -extern void BTA_GATTC_GetDBSize(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, int *count); - -extern void BTA_GATTC_GetDBSizeByType(UINT16 conn_id, bt_gatt_db_attribute_type_t type, - UINT16 start_handle, UINT16 end_handle, UINT16 char_handle, int *count); - -/******************************************************************************* -** -** Function BTA_GATTC_GetGattDb -** -** Description This function is called to get gatt db. -** -** Parameters conn_id: connection ID which identify the server. -** db: output parameter which will contain gatt db copy. -** Caller is responsible for freeing it. -** count: number of elements in db. -** -*******************************************************************************/ -extern void BTA_GATTC_GetGattDb(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, - btgatt_db_element_t **db, int *count); - -/******************************************************************************* -** -** Function BTA_GATTC_ReadCharacteristic -** -** Description This function is called to read a characteristics value -** -** Parameters conn_id - connectino ID. -** handle - characteritic handle to read. -** -** Returns None -** -*******************************************************************************/ -void BTA_GATTC_ReadCharacteristic(UINT16 conn_id, UINT16 handle, tBTA_GATT_AUTH_REQ auth_req); - -/******************************************************************************* -** -** Function BTA_GATTC_ReadCharDescr -** -** Description This function is called to read a descriptor value. -** -** Parameters conn_id - connection ID. -** handle - descriptor handle to read. -** -** Returns None -** -*******************************************************************************/ -void BTA_GATTC_ReadCharDescr (UINT16 conn_id, UINT16 handle, tBTA_GATT_AUTH_REQ auth_req); - -/******************************************************************************* -** -** Function BTA_GATTC_WriteCharValue -** -** Description This function is called to write characteristic value. -** -** Parameters conn_id - connection ID. -** handle - characteristic handle to write. -** write_type - type of write. -** len: length of the data to be written. -** p_value - the value to be written. -** -** Returns None -** -*******************************************************************************/ -void BTA_GATTC_WriteCharValue ( UINT16 conn_id, - UINT16 handle, - tBTA_GATTC_WRITE_TYPE write_type, - UINT16 len, - UINT8 *p_value, - tBTA_GATT_AUTH_REQ auth_req); - -/******************************************************************************* -** -** Function BTA_GATTC_WriteCharDescr -** -** Description This function is called to write descriptor value. -** -** Parameters conn_id - connection ID -** handle - descriptor handle to write. -** write_type - type of write. -** p_value - the value to be written. -** -** Returns None -** -*******************************************************************************/ -void BTA_GATTC_WriteCharDescr (UINT16 conn_id, - UINT16 handle, - tBTA_GATTC_WRITE_TYPE write_type, - tBTA_GATT_UNFMT *p_data, - tBTA_GATT_AUTH_REQ auth_req); - -/******************************************************************************* -** -** Function BTA_GATTC_SendIndConfirm -** -** Description This function is called to send handle value confirmation. -** -** Parameters conn_id - connection ID. -** handle - characteristic handle to confirm. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTC_SendIndConfirm (UINT16 conn_id, UINT16 handle); - -/******************************************************************************* -** -** Function BTA_GATTC_RegisterForNotifications -** -** Description This function is called to register for notification of a service. -** -** Parameters client_if - client interface. -** remote_bda - target GATT server. -** handle - GATT characteristic handle. -** -** Returns OK if registration succeed, otherwise failed. -** -*******************************************************************************/ -extern tBTA_GATT_STATUS BTA_GATTC_RegisterForNotifications (tBTA_GATTC_IF client_if, - BD_ADDR remote_bda, - UINT16 handle); - -/******************************************************************************* -** -** Function BTA_GATTC_DeregisterForNotifications -** -** Description This function is called to de-register for notification of a servbice. -** -** Parameters client_if - client interface. -** remote_bda - target GATT server. -** handle - GATT characteristic handle. -** -** Returns OK if deregistration succeed, otherwise failed. -** -*******************************************************************************/ -extern tBTA_GATT_STATUS BTA_GATTC_DeregisterForNotifications (tBTA_GATTC_IF client_if, - BD_ADDR remote_bda, - UINT16 handle); - -/******************************************************************************* -** -** Function BTA_GATTC_PrepareWrite -** -** Description This function is called to prepare write a characteristic value. -** -** Parameters conn_id - connection ID. -** handle - GATT characteritic handle. -** offset - offset of the write value. -** len - length of the data to be written. -** p_value - the value to be written. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTC_PrepareWrite (UINT16 conn_id, - UINT16 handle, - UINT16 offset, - UINT16 len, - UINT8 *p_value, - tBTA_GATT_AUTH_REQ auth_req); - -/******************************************************************************* -** -** Function BTA_GATTC_PrepareWriteCharDescr -** -** Description This function is called to prepare write a characteristic descriptor value. -** -** Parameters conn_id - connection ID. -** p_char_descr_id - GATT characteritic descriptor ID of the service. -** offset - offset of the write value. -** len: length of the data to be written. -** p_value - the value to be written. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTC_PrepareWriteCharDescr (UINT16 conn_id, - UINT16 handle, - UINT16 offset, - tBTA_GATT_UNFMT *p_data, - tBTA_GATT_AUTH_REQ auth_req); -/******************************************************************************* -** -** Function BTA_GATTC_ExecuteWrite -** -** Description This function is called to execute write a prepare write sequence. -** -** Parameters conn_id - connection ID. -** is_execute - execute or cancel. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTC_ExecuteWrite (UINT16 conn_id, BOOLEAN is_execute); - -/******************************************************************************* -** -** Function BTA_GATTC_ReadMultiple -** -** Description This function is called to read multiple characteristic or -** characteristic descriptors. -** -** Parameters conn_id - connection ID. -** p_read_multi - read multiple parameters. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi, - tBTA_GATT_AUTH_REQ auth_req); - - -/******************************************************************************* -** -** Function BTA_GATTC_Refresh -** -** Description Refresh the server cache of the remote device -** -** Parameters remote_bda: remote device BD address. -** erase_flash: delete cache from nvs flash -** -** Returns void -** -*******************************************************************************/ -extern void BTA_GATTC_Refresh(BD_ADDR remote_bda, bool erase_flash); - -extern void BTA_GATTC_CacheAssoc(tBTA_GATTC_IF client_if, BD_ADDR src_addr, BD_ADDR assoc_addr, BOOLEAN is_assoc); - -extern void BTA_GATTC_CacheGetAddrList(tBTA_GATTC_IF client_if); - - -/******************************************************************************* -** -** Function BTA_GATTC_Listen -** -** Description Start advertisement to listen for connection request. -** -** Parameters client_if: server interface. -** start: to start or stop listening for connection -** remote_bda: remote device BD address, if listen to all device -** use NULL. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_GATTC_Listen(tBTA_GATTC_IF client_if, BOOLEAN start, BD_ADDR_PTR target_bda); - -/******************************************************************************* -** -** Function BTA_GATTC_Broadcast -** -** Description Start broadcasting (non-connectable advertisements) -** -** Parameters client_if: client interface. -** start: to start or stop listening for connection -** -** Returns void -** -*******************************************************************************/ -extern void BTA_GATTC_Broadcast(tBTA_GATTC_IF client_if, BOOLEAN start); - - -/******************************************************************************* -** -** Function BTA_GATTC_ConfigureMTU -** -** Description Configure the MTU size in the GATT channel. This can be done -** only once per connection. -** -** Parameters conn_id: connection ID. -** -** -** Returns void -** -*******************************************************************************/ -extern void BTA_GATTC_ConfigureMTU (UINT16 conn_id); - -/******************************************************************************* -** BTA GATT Server API -********************************************************************************/ - -/******************************************************************************* -** -** Function BTA_GATTS_Init -** -** Description This function is called to initalize GATTS module -** -** Parameters None -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTS_Init(); - -/******************************************************************************* -** -** Function BTA_GATTS_Disable -** -** Description This function is called to disable GATTS module -** -** Parameters None. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTS_Disable(void); - -/******************************************************************************* -** -** Function BTA_GATTS_AppRegister -** -** Description This function is called to register application callbacks -** with BTA GATTS module. -** -** Parameters p_app_uuid - applicaiton UUID -** p_cback - pointer to the application callback function. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTS_AppRegister(tBT_UUID *p_app_uuid, tBTA_GATTS_CBACK *p_cback); - - -/******************************************************************************* -** -** Function BTA_GATTS_AppDeregister -** -** Description De-register with BTA GATT Server. -** -** Parameters server_if: server interface -** -** Returns void -** -*******************************************************************************/ -extern void BTA_GATTS_AppDeregister(tBTA_GATTS_IF server_if); - -/******************************************************************************* -** -** Function BTA_GATTS_CreateService -** -** Description Create a service. When service creation is done, a callback -** event BTA_GATTS_CREATE_SRVC_EVT is called to report status -** and service ID to the profile. The service ID obtained in -** the callback function needs to be used when adding included -** service and characteristics/descriptors into the service. -** -** Parameters server_if: server interface. -** p_service_uuid: service UUID. -** inst: instance ID number of this service. -** num_handle: numble of handle requessted for this service. -** is_primary: is this service a primary one or not. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_GATTS_CreateService(tBTA_GATTS_IF server_if, tBT_UUID *p_service_uuid, - UINT8 inst, UINT16 num_handle, BOOLEAN is_primary); - -/******************************************************************************* -** -** Function BTA_GATTS_AddIncludeService -** -** Description This function is called to add an included service. After included -** service is included, a callback event BTA_GATTS_ADD_INCL_SRVC_EVT -** is reported the included service ID. -** -** Parameters service_id: service ID to which this included service is to -** be added. -** included_service_id: the service ID to be included. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_GATTS_AddIncludeService(UINT16 service_id, UINT16 included_service_id); - -/******************************************************************************* -** -** Function BTA_GATTS_AddCharacteristic -** -** Description This function is called to add a characteristic into a service. -** -** Parameters service_id: service ID to which this included service is to -** be added. -** p_char_uuid : Characteristic UUID. -** perm : Characteristic value declaration attribute permission. -** property : Characteristic Properties -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTS_AddCharacteristic (UINT16 service_id, tBT_UUID *p_char_uuid, - tBTA_GATT_PERM perm, tBTA_GATT_CHAR_PROP property, tGATT_ATTR_VAL *attr_val, - tBTA_GATTS_ATTR_CONTROL *control); - -/******************************************************************************* -** -** Function BTA_GATTS_AddCharDescriptor -** -** Description This function is called to add characteristic descriptor. When -** it's done, a callback event BTA_GATTS_ADD_DESCR_EVT is called -** to report the status and an ID number for this descriptor. -** -** Parameters service_id: service ID to which this charatceristic descriptor is to -** be added. -** perm: descriptor access permission. -** p_descr_uuid: descriptor UUID. -** p_descr_params: descriptor value if it's read only descriptor. -** -** Returns returns status. -** -*******************************************************************************/ -extern void BTA_GATTS_AddCharDescriptor (UINT16 service_id, - tBTA_GATT_PERM perm, - tBT_UUID *p_descr_uuid, tBTA_GATT_ATTR_VAL *attr_val, - tBTA_GATTS_ATTR_CONTROL *control); - -/******************************************************************************* -** -** Function BTA_GATTS_DeleteService -** -** Description This function is called to delete a service. When this is done, -** a callback event BTA_GATTS_DELETE_EVT is report with the status. -** -** Parameters service_id: service_id to be deleted. -** -** Returns returns none. -** -*******************************************************************************/ -extern void BTA_GATTS_DeleteService(UINT16 service_id); - -/******************************************************************************* -** -** Function BTA_GATTS_StartService -** -** Description This function is called to start a service. -** -** Parameters service_id: the service ID to be started. -** sup_transport: supported trasnport. -** -** Returns None. -** -*******************************************************************************/ -extern void BTA_GATTS_StartService(UINT16 service_id, tBTA_GATT_TRANSPORT sup_transport); - -/******************************************************************************* -** -** Function BTA_GATTS_StopService -** -** Description This function is called to stop a service. -** -** Parameters service_id - service to be topped. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTS_StopService(UINT16 service_id); - -/******************************************************************************* -** -** Function BTA_GATTS_HandleValueIndication -** -** Description This function is called to read a characteristics descriptor. -** -** Parameters conn_id - connection identifier. -** attr_id - attribute ID to indicate. -** data_len - indicate data length. -** p_data: data to indicate. -** need_confirm - if this indication expects a confirmation or not. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTS_HandleValueIndication (UINT16 conn_id, UINT16 attr_id, - UINT16 data_len, - UINT8 *p_data, - BOOLEAN need_confirm); - -/******************************************************************************* -** -** Function BTA_GATTS_SendRsp -** -** Description This function is called to send a response to a request. -** -** Parameters conn_id - connection identifier. -** trans_id - transaction ID. -** status - response status -** p_msg - response data. -** -** Returns None -** -*******************************************************************************/ -extern void BTA_GATTS_SendRsp (UINT16 conn_id, UINT32 trans_id, - tBTA_GATT_STATUS status, tBTA_GATTS_RSP *p_msg); - - - -/******************************************************************************* -** -** Function BTA_SetAttributeValue -** -** Description This function is called to set the attribute value in the gatt database -** -** Parameters attr_handle - the attribute value handle. -** length - the value length which has been set to the attribute. -** value - the pointer to the value -** -** Returns None -** -*******************************************************************************/ -extern void BTA_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value); - - -/******************************************************************************* -** -** Function BTA_GetAttributeValue -** -** Description This function is called to get the attribute value in the gatt database -** -** Parameters attr_handle - the attribute value handle. -** length - the value length which has been set to the attribute. -** value - the pointer to the value -** -** Returns tBTA_GATT_STATUS -** -*******************************************************************************/ -extern tBTA_GATT_STATUS BTA_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value); - -/******************************************************************************* -** -** Function BTA_GATTS_Open -** -** Description Open a direct open connection or add a background auto connection -** bd address -** -** Parameters server_if: server interface. -** remote_bda: remote device BD address. -** is_direct: direct connection or background auto connection -** -** Returns void -** -*******************************************************************************/ -extern void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, - BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport); - - -/******************************************************************************* -** -** Function BTA_GATTS_CancelOpen -** -** Description Cancel a direct open connection or remove a background auto connection -** bd address -** -** Parameters server_if: server interface. -** remote_bda: remote device BD address. -** is_direct: direct connection or background auto connection -** -** Returns void -** -*******************************************************************************/ -extern void BTA_GATTS_CancelOpen(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct); - - -/******************************************************************************* -** -** Function BTA_GATTS_Close -** -** Description Close a connection a remote device. -** -** Parameters conn_id: connection ID to be closed. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_GATTS_Close(UINT16 conn_id); - -/******************************************************************************* -** -** Function BTA_GATTS_Listen -** -** Description Start advertisement to listen for connection request for a -** GATT server -** -** Parameters server_if: server interface. -** start: to start or stop listening for connection -** remote_bda: remote device BD address, if listen to all device -** use NULL. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_GATTS_Listen(tBTA_GATTS_IF server_if, BOOLEAN start, - BD_ADDR_PTR target_bda); - - -#ifdef __cplusplus - -} -#endif - - -#endif /* BTA_GATT_API_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_gatt_common.h b/tools/sdk/include/bluedroid/bta/bta_gatt_common.h deleted file mode 100644 index 96bd3480..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_gatt_common.h +++ /dev/null @@ -1,36 +0,0 @@ -/****************************************************************************** -* Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at - -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains the action functions for gatts and gattc. - * - * - ******************************************************************************/ - -#include "stack/bt_types.h" - - -#ifdef __cplusplus -extern "C" -{ -#endif - -extern void BTA_GATT_SetLocalMTU(uint16_t mtu); - -#ifdef __cplusplus -} -#endif diff --git a/tools/sdk/include/bluedroid/bta/bta_gattc_ci.h b/tools/sdk/include/bluedroid/bta/bta_gattc_ci.h deleted file mode 100644 index d523e87b..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_gattc_ci.h +++ /dev/null @@ -1,117 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2003-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the interface file for GATT call-in functions. - * - ******************************************************************************/ -#ifndef BTA_GATTC_CI_H -#define BTA_GATTC_CI_H - -#include "bta/bta_gatt_api.h" - -/***************************************************************************** -** Constants and data types -*****************************************************************************/ - -/* Open Complete Event */ -typedef struct { - BT_HDR hdr; - tBTA_GATT_STATUS status; -} tBTA_GATTC_CI_EVT; - -#define BTA_GATTC_NV_LOAD_MAX 100 - -/* Read Ready Event */ -typedef struct { - BT_HDR hdr; - tBTA_GATT_STATUS status; - UINT16 num_attr; - tBTA_GATTC_NV_ATTR attr[BTA_GATTC_NV_LOAD_MAX]; -} tBTA_GATTC_CI_LOAD; - - -/***************************************************************************** -** Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/******************************************************************************* -** -** Function bta_gattc_ci_cache_open -** -** Description This function sends an event to indicate server cache open -** completed. -** -** Parameters server_bda - server BDA of this cache. -** status - BTA_GATT_OK if full buffer of data, -** BTA_GATT_FAIL if an error has occurred. -** -** Returns void -** -*******************************************************************************/ -extern void bta_gattc_ci_cache_open(BD_ADDR server_bda, UINT16 evt, - tBTA_GATT_STATUS status, UINT16 conn_id); - -/******************************************************************************* -** -** Function bta_gattc_ci_cache_load -** -** Description This function sends an event to BTA indicating the phone has -** load the servere cache and ready to send it to the stack. -** -** Parameters server_bda - server BDA of this cache. -** num_bytes_read - number of bytes read into the buffer -** specified in the read callout-function. -** status - BTA_GATT_OK if full buffer of data, -** BTA_GATT_FAIL if an error has occurred. -** -** Returns void -** -*******************************************************************************/ -extern void bta_gattc_ci_cache_load(BD_ADDR server_bda, UINT16 evt, - UINT16 num_attr, tBTA_GATTC_NV_ATTR *p_atrr, - tBTA_GATT_STATUS status, UINT16 conn_id); - -/******************************************************************************* -** -** Function bta_gattc_ci_save -** -** Description This function sends an event to BTA indicating the phone has -** save the server cache. -** -** Parameters server_bda - server BDA of this cache. -** status - BTA_GATT_OK if full buffer of data, -** BTA_GATT_FAIL if an error has occurred. -** -** Returns void -** -*******************************************************************************/ -extern void bta_gattc_ci_cache_save(BD_ADDR server_bda, UINT16 evt, - tBTA_GATT_STATUS status, UINT16 conn_id); - - -#ifdef __cplusplus -} -#endif - -#endif /* BTA_GATTC_CI_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_gattc_co.h b/tools/sdk/include/bluedroid/bta/bta_gattc_co.h deleted file mode 100644 index 44a0e18e..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_gattc_co.h +++ /dev/null @@ -1,140 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2009-2013 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the interface file for BTA GATT client call-out functions. - * - ******************************************************************************/ -#ifndef BTA_GATTC_CO_H -#define BTA_GATTC_CO_H - -#include "bta/bta_gatt_api.h" -#include "osi/hash_functions.h" - -/******************************************************************************* -** -** Function bta_gattc_co_cache_open -** -** Description This callout function is executed by GATTC when a GATT server -** cache is ready to be sent. -** -** Parameter server_bda: server bd address of this cache belongs to -** evt: call in event to be passed in when cache open is done. -** conn_id: connection ID of this cache operation attach to. -** to_save: open cache to save or to load. -** -** Returns void. -** -*******************************************************************************/ -extern tBTA_GATT_STATUS bta_gattc_co_cache_open(BD_ADDR server_bda, BOOLEAN to_save, UINT8 *index); - -/******************************************************************************* -** -** Function bta_gattc_co_cache_close -** -** Description This callout function is executed by GATTC when a GATT server -** cache is written completely. -** -** Parameter server_bda: server bd address of this cache belongs to -** conn_id: connection ID of this cache operation attach to. -** -** Returns void. -** -*******************************************************************************/ -extern void bta_gattc_co_cache_close(BD_ADDR server_bda, UINT16 conn_id); - -/******************************************************************************* -** -** Function bta_gattc_co_cache_save -** -** Description This callout function is executed by GATT when a server cache -** is available to save. -** -** Parameter server_bda: server bd address of this cache belongs to -** evt: call in event to be passed in when cache save is done. -** num_attr: number of attribute to be save. -** p_attr: pointer to the list of attributes to save. -** attr_index: starting attribute index of the save operation. -** conn_id: connection ID of this cache operation attach to. -** Returns -** -*******************************************************************************/ -extern void bta_gattc_co_cache_save (BD_ADDR server_bda, UINT16 num_attr, - tBTA_GATTC_NV_ATTR *p_attr_list); - -/******************************************************************************* -** -** Function bta_gattc_co_cache_load -** -** Description This callout function is executed by GATT when server cache -** is required to load. -** -** Parameter server_bda: server bd address of this cache belongs to -** evt: call in event to be passed in when cache save is done. -** num_attr: number of attribute to be save. -** attr_index: starting attribute index of the save operation. -** conn_id: connection ID of this cache operation attach to. -** Returns -** -*******************************************************************************/ -extern tBTA_GATT_STATUS bta_gattc_co_cache_load(tBTA_GATTC_NV_ATTR *attr, UINT8 index); - -/******************************************************************************* -** -** Function bta_gattc_co_cache_reset -** -** Description This callout function is executed by GATTC to reset cache in -** application -** -** Parameter server_bda: server bd address of this cache belongs to -** -** Returns void. -** -*******************************************************************************/ -extern void bta_gattc_co_cache_reset(BD_ADDR server_bda); - -extern size_t bta_gattc_get_cache_attr_length(UINT8 index); - -extern void bta_gattc_co_cache_addr_init(void); - -extern void bta_gattc_co_cache_addr_deinit(void); - -extern BOOLEAN bta_gattc_co_addr_in_cache(BD_ADDR bda); - -extern uint8_t bta_gattc_co_find_addr_in_cache(BD_ADDR bda); - -extern uint8_t bta_gattc_co_find_hash_in_cache(hash_key_t hash_key); - -extern UINT8 bta_gattc_co_get_addr_num(void); - -extern void bta_gattc_co_get_addr_list(BD_ADDR *addr_list); - -extern void bta_gattc_co_cache_addr_save(BD_ADDR bd_addr, hash_key_t hash_key); - -extern BOOLEAN bta_gattc_co_cache_new_assoc_list(BD_ADDR src_addr, uint8_t index); - -extern BOOLEAN bta_gattc_co_cache_append_assoc_addr(BD_ADDR src_addr, BD_ADDR assoc_addr); - -extern BOOLEAN bta_gattc_co_cache_remove_assoc_addr(BD_ADDR src_addr, BD_ADDR assoc_addr); - -uint8_t* bta_gattc_co_cache_find_src_addr(BD_ADDR assoc_addr, uint8_t *index); - -extern BOOLEAN bta_gattc_co_cache_clear_assoc_addr(BD_ADDR src_addr); - -#endif /* BTA_GATT_CO_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_gatts_co.h b/tools/sdk/include/bluedroid/bta/bta_gatts_co.h deleted file mode 100644 index 9d81d646..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_gatts_co.h +++ /dev/null @@ -1,81 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2010-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the interface file for BTA GATT server call-out functions. - * - ******************************************************************************/ -#ifndef BTA_GATTS_CO_H -#define BTA_GATTS_CO_H - -#include "bta/bta_gatt_api.h" - -/******************************************************************************* -** -** Function bta_gatts_co_update_handle_range -** -** Description This callout function is executed by GATTS when a GATT server -** handle range ios to be added or removed. -** -** Parameter is_add: true is to add a handle range; otherwise is to delete. -** p_hndl_range: handle range. -** -** Returns void. -** -*******************************************************************************/ -extern void bta_gatts_co_update_handle_range(BOOLEAN is_add, tBTA_GATTS_HNDL_RANGE *p_hndl_range); - -/******************************************************************************* -** -** Function bta_gatts_co_srv_chg -** -** Description This call-out is to read/write/remove service change related -** informaiton. The request consists of the cmd and p_req and the -** response is returned in p_rsp -** -** Parameter cmd - request command -** p_req - request paramters -** p_rsp - response data for the request -** -** Returns TRUE - if the request is processed successfully and -** the response is returned in p_rsp. -** FALSE - if the request can not be processed -** -*******************************************************************************/ -extern BOOLEAN bta_gatts_co_srv_chg(tBTA_GATTS_SRV_CHG_CMD cmd, - tBTA_GATTS_SRV_CHG_REQ *p_req, - tBTA_GATTS_SRV_CHG_RSP *p_rsp); - -/******************************************************************************* -** -** Function bta_gatts_co_load_handle_range -** -** Description This callout function is executed by GATTS when a GATT server -** handle range is requested to be loaded from NV. -** -** Parameter -** -** Returns void. -** -*******************************************************************************/ -extern BOOLEAN bta_gatts_co_load_handle_range(UINT8 index, - tBTA_GATTS_HNDL_RANGE *p_handle); - - -#endif /* BTA_GATTS_CO_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_hf_client_api.h b/tools/sdk/include/bluedroid/bta/bta_hf_client_api.h deleted file mode 100644 index ade9f63f..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_hf_client_api.h +++ /dev/null @@ -1,378 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 2014 The Android Open Source Project - * Copyright (C) 2003-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the public interface file for the handsfree (HF role) subsystem - * - ******************************************************************************/ -#ifndef BTA_HF_CLIENT_API_H -#define BTA_HF_CLIENT_API_H - -#include "bta_api.h" -#include "bta_hfp_defs.h" - -#if (BTA_HF_INCLUDED == TRUE) -/***************************************************************************** -** Constants and data types -*****************************************************************************/ - -/* HFP peer (AG) features*/ -#define BTA_HF_CLIENT_PEER_FEAT_3WAY 0x00000001 /* Three-way calling */ -#define BTA_HF_CLIENT_PEER_FEAT_ECNR 0x00000002 /* Echo cancellation and/or noise reduction */ -#define BTA_HF_CLIENT_PEER_FEAT_VREC 0x00000004 /* Voice recognition */ -#define BTA_HF_CLIENT_PEER_INBAND 0x00000008 /* In-band ring tone */ -#define BTA_HF_CLIENT_PEER_VTAG 0x00000010 /* Attach a phone number to a voice tag */ -#define BTA_HF_CLIENT_PEER_REJECT 0x00000020 /* Ability to reject incoming call */ -#define BTA_HF_CLIENT_PEER_ECS 0x00000040 /* Enhanced Call Status */ -#define BTA_HF_CLIENT_PEER_ECC 0x00000080 /* Enhanced Call Control */ -#define BTA_HF_CLIENT_PEER_EXTERR 0x00000100 /* Extended error codes */ -#define BTA_HF_CLIENT_PEER_CODEC 0x00000200 /* Codec Negotiation */ - -typedef UINT16 tBTA_HF_CLIENT_PEER_FEAT; - -/* HFP HF features */ -#define BTA_HF_CLIENT_FEAT_ECNR 0x00000001 /* Echo cancellation and/or noise reduction */ -#define BTA_HF_CLIENT_FEAT_3WAY 0x00000002 /* Call waiting and three-way calling */ -#define BTA_HF_CLIENT_FEAT_CLI 0x00000004 /* Caller ID presentation capability */ -#define BTA_HF_CLIENT_FEAT_VREC 0x00000008 /* Voice recognition activation */ -#define BTA_HF_CLIENT_FEAT_VOL 0x00000010 /* Remote volume control */ -#define BTA_HF_CLIENT_FEAT_ECS 0x00000020 /* Enhanced Call Status */ -#define BTA_HF_CLIENT_FEAT_ECC 0x00000040 /* Enhanced Call Control */ -#define BTA_HF_CLIENT_FEAT_CODEC 0x00000080 /* Codec Negotiation */ - -/* HFP HF extended call handling - masks not related to any spec */ -#define BTA_HF_CLIENT_CHLD_REL 0x00000001 /* 0 Release waiting call or held calls */ -#define BTA_HF_CLIENT_CHLD_REL_ACC 0x00000002 /* 1 Release active calls and accept other (waiting or held) cal */ -#define BTA_HF_CLIENT_CHLD_REL_X 0x00000004 /* 1x Release x call*/ -#define BTA_HF_CLIENT_CHLD_HOLD_ACC 0x00000008 /* 2 Active calls on hold and accept other call */ -#define BTA_HF_CLIENT_CHLD_PRIV_X 0x00000010 /* 2x Active multiparty call on hold except call x */ -#define BTA_HF_CLIENT_CHLD_MERGE 0x00000020 /* 3 Add held call to multiparty */ -#define BTA_HF_CLIENT_CHLD_MERGE_DETACH 0x00000040 /* 4 Add held call to multiparty */ - -typedef UINT16 tBTA_HF_CLIENT_CHLD_FEAT; - -/* HFP AG errors ot OK sent to HF Unit */ -#define BTA_HF_CLIENT_AT_RESULT_OK 0 -#define BTA_HF_CLIENT_AT_RESULT_ERROR 1 -#define BTA_HF_CLIENT_AT_RESULT_NO_CARRIER 2 -#define BTA_HF_CLIENT_AT_RESULT_BUSY 3 -#define BTA_HF_CLIENT_AT_RESULT_NO_ANSWER 4 -#define BTA_HF_CLIENT_AT_RESULT_DELAY 5 -#define BTA_HF_CLIENT_AT_RESULT_BLACKLISTED 6 -#define BTA_HF_CLIENT_AT_RESULT_CME 7 - -typedef UINT8 tBTA_HF_CLIENT_AT_RESULT_TYPE; - -/* HF Client callback events */ -#define BTA_HF_CLIENT_ENABLE_EVT 0 /* HF Client enabled */ -#define BTA_HF_CLIENT_REGISTER_EVT 1 /* HF Client registered */ -#define BTA_HF_CLIENT_OPEN_EVT 2 /* HF Client connection open */ -#define BTA_HF_CLIENT_CLOSE_EVT 3 /* HF Client connection closed */ -#define BTA_HF_CLIENT_CONN_EVT 4 /* Service level connection opened */ -#define BTA_HF_CLIENT_AUDIO_OPEN_EVT 5 /* Audio connection open */ -#define BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT 6 /* Audio connection with mSBC codec open */ -#define BTA_HF_CLIENT_AUDIO_CLOSE_EVT 7 /* Audio connection closed */ -#define BTA_HF_CLIENT_SPK_EVT 8 /* Speaker volume changed */ -#define BTA_HF_CLIENT_MIC_EVT 9 /* Microphone volume changed */ -#define BTA_HF_CLIENT_IND_EVT 10 /* Indicator */ -#define BTA_HF_CLIENT_VOICE_REC_EVT 11 /* AG changed voice recognition setting */ -#define BTA_HF_CLIENT_OPERATOR_NAME_EVT 12 /* Operator name acquired */ -#define BTA_HF_CLIENT_CLIP_EVT 13 /* Calling line identification event */ -#define BTA_HF_CLIENT_CCWA_EVT 14 /* Call waiting notification */ -#define BTA_HF_CLIENT_AT_RESULT_EVT 15 /* Call waiting notification */ -#define BTA_HF_CLIENT_CLCC_EVT 16 /* current call event */ -#define BTA_HF_CLIENT_CNUM_EVT 17 /* subscriber information event */ -#define BTA_HF_CLIENT_BTRH_EVT 18 /* bluetooth response and hold event */ -#define BTA_HF_CLIENT_BSIR_EVT 19 /* in-band ring tone setting changed event */ -#define BTA_HF_CLIENT_BINP_EVT 20 /* binp number event */ -#define BTA_HF_CLIENT_RING_INDICATION 21 /* HF Client ring indication */ -#define BTA_HF_CLIENT_DISABLE_EVT 30 /* HF Client disabled */ - -typedef UINT8 tBTA_HF_CLIENT_EVT; - -/* HF Client open status */ -#define BTA_HF_CLIENT_SUCCESS 0 /* Connection successfully opened */ -#define BTA_HF_CLIENT_FAIL_SDP 1 /* Open failed due to SDP */ -#define BTA_HF_CLIENT_FAIL_RFCOMM 2 /* Open failed due to RFCOMM */ -#define BTA_HF_CLIENT_FAIL_RESOURCES 3 /* out of resources failure */ - -typedef UINT8 tBTA_HF_CLIENT_STATUS; - -/* indicator type */ -#define BTA_HF_CLIENT_IND_BATTCH 0 /* Battery charge indicator */ -#define BTA_HF_CLIENT_IND_SIGNAL 1 /* Signal Strength indicator */ -#define BTA_HF_CLIENT_IND_SERVICE 2 /* Service availability indicator */ -#define BTA_HF_CLIENT_IND_CALL 3 /* Standard call status indicator*/ -#define BTA_HF_CLIENT_IND_ROAM 4 /* Roaming status indicator */ -#define BTA_HF_CLIENT_IND_CALLSETUP 5 /* Call setup status indicator */ -#define BTA_HF_CLIENT_IND_CALLHELD 6 /* Call hold status indicator */ - -typedef UINT8 tBTA_HF_CLIENT_IND_TYPE; - -/* AT commands */ -#define BTA_HF_CLIENT_AT_CMD_VTS 0 -#define BTA_HF_CLIENT_AT_CMD_BTRH 1 -#define BTA_HF_CLIENT_AT_CMD_CHUP 2 -#define BTA_HF_CLIENT_AT_CMD_CHLD 3 -#define BTA_HF_CLIENT_AT_CMD_BCC 4 -#define BTA_HF_CLIENT_AT_CMD_CNUM 5 -#define BTA_HF_CLIENT_AT_CMD_ATA 6 -#define BTA_HF_CLIENT_AT_CMD_COPS 7 -#define BTA_HF_CLIENT_AT_CMD_ATD 8 -#define BTA_HF_CLIENT_AT_CMD_VGM 9 -#define BTA_HF_CLIENT_AT_CMD_VGS 10 -#define BTA_HF_CLIENT_AT_CMD_BVRA 11 -#define BTA_HF_CLIENT_AT_CMD_CLCC 12 -#define BTA_HF_CLIENT_AT_CMD_BINP 13 -#define BTA_HF_CLIENT_AT_CMD_BLDN 14 -#define BTA_HF_CLIENT_AT_CMD_NREC 15 - -typedef UINT8 tBTA_HF_CLIENT_AT_CMD_TYPE; - -/* data associated with most non-AT events */ -/* placeholder, if not needed should be removed*/ -typedef struct { -} tBTA_HF_CLIENT_HDR; - -/* data associated with BTA_HF_CLIENT_REGISTER_EVT */ -typedef struct { - tBTA_HF_CLIENT_HDR hdr; - UINT16 handle; - tBTA_HF_CLIENT_STATUS status; -} tBTA_HF_CLIENT_REGISTER; - -/* data associated with BTA_HF_CLIENT_OPEN_EVT */ -typedef struct { - tBTA_HF_CLIENT_HDR hdr; - BD_ADDR bd_addr; - tBTA_HF_CLIENT_STATUS status; -} tBTA_HF_CLIENT_OPEN; - -/* data associated with BTA_HF_CLIENT_CONN_EVT */ -typedef struct { - tBTA_HF_CLIENT_HDR hdr; - tBTA_HF_CLIENT_PEER_FEAT peer_feat; - tBTA_HF_CLIENT_CHLD_FEAT chld_feat; -} tBTA_HF_CLIENT_CONN; - -/* data associated with BTA_HF_CLIENT_IND_EVT event */ -typedef struct { - tBTA_HF_CLIENT_HDR hdr; - tBTA_HF_CLIENT_IND_TYPE type; - UINT16 value; -} tBTA_HF_CLIENT_IND; - -/* data associated with BTA_HF_CLIENT_OPERATOR_NAME_EVT */ -#define BTA_HF_CLIENT_OPERATOR_NAME_LEN 16 -typedef struct { - char name[BTA_HF_CLIENT_OPERATOR_NAME_LEN + 1]; -} tBTA_HF_CLIENT_OPERATOR_NAME; - -/* data associated with BTA_HF_CLIENT_CLIP_EVT and BTA_HF_CLIENT_CCWA_EVT*/ -#define BTA_HF_CLIENT_NUMBER_LEN 32 -typedef struct { - char number[BTA_HF_CLIENT_NUMBER_LEN + 1]; -} tBTA_HF_CLIENT_NUMBER; - -/* data associated with BTA_HF_CLIENT_AT_RESULT_EVT event */ -typedef struct { - tBTA_HF_CLIENT_AT_RESULT_TYPE type; - UINT16 cme; -} tBTA_HF_CLIENT_AT_RESULT; - -/* data associated with BTA_HF_CLIENT_CLCC_EVT event */ -typedef struct { - UINT32 idx; - BOOLEAN inc; - UINT8 status; - BOOLEAN mpty; - BOOLEAN number_present; - char number[BTA_HF_CLIENT_NUMBER_LEN + 1]; -} tBTA_HF_CLIENT_CLCC; - -/* data associated with BTA_HF_CLIENT_CNUM_EVT event */ -typedef struct { - UINT16 service; - char number[BTA_HF_CLIENT_NUMBER_LEN + 1]; -} tBTA_HF_CLIENT_CNUM; - -/* data associated with other events */ -typedef struct { - UINT16 value; -} tBTA_HF_CLIENT_VAL; - -/* union of data associated with AG callback */ -typedef union { - tBTA_HF_CLIENT_HDR hdr; - tBTA_HF_CLIENT_REGISTER reg; - tBTA_HF_CLIENT_OPEN open; - tBTA_HF_CLIENT_CONN conn; - tBTA_HF_CLIENT_IND ind; - tBTA_HF_CLIENT_VAL val; - tBTA_HF_CLIENT_OPERATOR_NAME operator; - tBTA_HF_CLIENT_NUMBER number; - tBTA_HF_CLIENT_AT_RESULT result; - tBTA_HF_CLIENT_CLCC clcc; - tBTA_HF_CLIENT_CNUM cnum; -} tBTA_HF_CLIENT; - -typedef UINT32 tBTA_HF_CLIENT_FEAT; - -/* HF Client callback */ -typedef void (tBTA_HF_CLIENT_CBACK)(tBTA_HF_CLIENT_EVT event, void *p_data); - -#ifdef __cplusplus -extern "C" -{ -#endif - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ - -/******************************************************************************* -** -** Function BTA_HfClientEnable -** -** Description Enable the HF CLient service. When the enable -** operation is complete the callback function will be -** called with a BTA_HF_CLIENT_ENABLE_EVT. This function must -** be called before other function in the HF CLient API are -** called. -** -** Returns BTA_SUCCESS if OK, BTA_FAILURE otherwise. -** -*******************************************************************************/ -tBTA_STATUS BTA_HfClientEnable(tBTA_HF_CLIENT_CBACK *p_cback); - -/******************************************************************************* -** -** Function BTA_HfClientDisable -** -** Description Disable the HF Client service -** -** -** Returns void -** -*******************************************************************************/ -void BTA_HfClientDisable(void); - -/******************************************************************************* -** -** Function BTA_HfClientRegister -** -** Description Register an HF Client service. -** -** -** Returns void -** -*******************************************************************************/ -void BTA_HfClientRegister(tBTA_SEC sec_mask, tBTA_HF_CLIENT_FEAT features, - char *p_service_name); - -/******************************************************************************* -** -** Function BTA_HfClientDeregister -** -** Description Deregister an HF Client service. -** -** -** Returns void -** -*******************************************************************************/ -void BTA_HfClientDeregister(UINT16 handle); - -/******************************************************************************* -** -** Function BTA_HfClientOpen -** -** Description Opens a connection to an audio gateway. -** When connection is open callback function is called -** with a BTA_HF_CLIENT_OPEN_EVT. Only the data connection is -** opened. The audio connection is not opened. -** -** -** Returns void -** -*******************************************************************************/ -void BTA_HfClientOpen(UINT16 handle, BD_ADDR bd_addr, tBTA_SEC sec_mask); - -/******************************************************************************* -** -** Function BTA_HfClientClose -** -** Description Close the current connection to an audio gateway. -** Any current audio connection will also be closed -** -** -** Returns void -** -*******************************************************************************/ -void BTA_HfClientClose(UINT16 handle); - -/******************************************************************************* -** -** Function BTA_HfCllientAudioOpen -** -** Description Opens an audio connection to the currently connected -** audio gateway -** -** -** Returns void -** -*******************************************************************************/ -void BTA_HfClientAudioOpen(UINT16 handle); - -/******************************************************************************* -** -** Function BTA_HfClientAudioClose -** -** Description Close the currently active audio connection to an audio -** gateway. The data connection remains open -** -** -** Returns void -** -*******************************************************************************/ -void BTA_HfClientAudioClose(UINT16 handle); - -/******************************************************************************* -** -** Function BTA_HfClientSendAT -** -** Description send AT command -** -** -** Returns void -** -*******************************************************************************/ -void BTA_HfClientSendAT(UINT16 handle, tBTA_HF_CLIENT_AT_CMD_TYPE at, UINT32 val1, UINT32 val2, const char *str); - -#if (BTM_SCO_HCI_INCLUDED == TRUE ) -void BTA_HfClientCiData(void); -#endif /*#if (BTM_SCO_HCI_INCLUDED == TRUE ) */ - -int BTA_HfClientGetCbDataSize(tBTA_HF_CLIENT_EVT event); - -#ifdef __cplusplus -} -#endif -#endif /* #if (BTA_HF_INCLUDED == TRUE) */ -#endif /* BTA_HF_CLIENT_API_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_hf_client_co.h b/tools/sdk/include/bluedroid/bta/bta_hf_client_co.h deleted file mode 100644 index af53e6e3..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_hf_client_co.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -/****************************************************************************** - * - * This is the interface file for hf client call-out functions. - * - ******************************************************************************/ -#ifndef BTA_HF_CLIENT_CO_H -#define BTA_HF_CLIENT_CO_H - -#include "common/bt_target.h" -#include "bta/bta_hf_client_api.h" - -#if (BTA_HF_INCLUDED == TRUE) - -#if (BTM_SCO_HCI_INCLUDED == TRUE) -/******************************************************************************* -** -** Function bta_hf_client_co_audio_state -** -** Description This function is called by the HF CLIENT before the audio connection -** is brought up, after it comes up, and after it goes down. -** -** Parameters handle - handle of the AG instance -** state - Audio state -** codec - if WBS support is compiled in, codec to going to be used is provided -** and when in SCO_STATE_SETUP, BTM_I2SPCMConfig() must be called with -** the correct platform parameters. -** in the other states codec type should not be ignored -** -** Returns void -** -*******************************************************************************/ -void bta_hf_client_co_audio_state(UINT16 handle, UINT8 state, tBTA_HFP_PEER_CODEC codec); - - -/******************************************************************************* -** -** Function bta_hf_client_sco_co_init -** -** Description This function can be used by the phone to initialize audio -** codec or for other initialization purposes before SCO connection -** is opened. -** -** -** Returns Void. -** -*******************************************************************************/ -tBTA_HFP_SCO_ROUTE_TYPE bta_hf_client_sco_co_init(UINT32 rx_bw, UINT32 tx_bw, - tBTA_HFP_CODEC_INFO *p_codec_info, UINT8 app_id); - - -/******************************************************************************* -** -** Function bta_hf_client_sco_co_open -** -** Description This function is executed when a SCO connection is open. -** -** -** Returns void -** -*******************************************************************************/ -void bta_hf_client_sco_co_open(UINT16 handle, UINT8 pkt_size, UINT16 event); - -/******************************************************************************* -** -** Function bta_hf_client_sco_co_close -** -** Description This function is called when a SCO connection is closed -** -** -** Returns void -** -*******************************************************************************/ -void bta_hf_client_sco_co_close(void); - -/******************************************************************************* -** -** Function bta_hf_client_sco_co_out_data -** -** Description This function is called to send SCO data over HCI. -** -** Returns number of bytes got from application -** -*******************************************************************************/ -uint32_t bta_hf_client_sco_co_out_data(uint8_t *p_buf, uint32_t sz); - -/******************************************************************************* -** -** Function bta_hf_client_sco_co_in_data -** -** Description This function is called to send incoming SCO data to application. -** -** Returns void -** -*******************************************************************************/ -extern void bta_hf_client_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status); - -#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */ - -#endif /* #if (BTA_HF_INCLUDED == TRUE) */ -#endif /* BTA_HF_CLIENT_CO_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_hfp_defs.h b/tools/sdk/include/bluedroid/bta/bta_hfp_defs.h deleted file mode 100644 index 46448197..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_hfp_defs.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTA_HFP_DEFS_H__ -#define __BTA_HFP_DEFS_H__ - -#include "stack/btm_api.h" - -#define BTA_HFP_CODEC_NONE BTM_SCO_CODEC_NONE -#define BTA_HFP_CODEC_CVSD BTM_SCO_CODEC_CVSD /* CVSD */ -#define BTA_HFP_CODEC_MSBC BTM_SCO_CODEC_MSBC /* mSBC */ - -typedef UINT16 tBTA_HFP_PEER_CODEC; - -#ifndef BTA_HFP_SCO_OUT_PKT_SIZE -#define BTA_HFP_SCO_OUT_PKT_SIZE BTM_SCO_DATA_SIZE_MAX -#endif - -#define BTA_HFP_SCO_CODEC_PCM 0 /* used for regular SCO */ -#define BTA_HFP_SCO_CODEC_SBC 1 /* used for WBS */ -typedef UINT8 tBTA_HFP_SCO_CODEC_TYPE; - -#define BTA_HFP_SCO_SAMP_RATE_8K 8000 -#define BTA_HFP_SCO_SAMP_RATE_16K 16000 - -/* SCO codec information */ -typedef struct { - tBTA_HFP_SCO_CODEC_TYPE codec_type; -} tBTA_HFP_CODEC_INFO; - -#define BTA_HFP_SCO_ROUTE_PCM BTM_SCO_ROUTE_PCM -#define BTA_HFP_SCO_ROUTE_HCI BTM_SCO_ROUTE_HCI - -typedef tBTM_SCO_ROUTE_TYPE tBTA_HFP_SCO_ROUTE_TYPE; - -#endif /* __BTA_HFP_DEFS_H__ */ diff --git a/tools/sdk/include/bluedroid/bta/bta_hh_api.h b/tools/sdk/include/bluedroid/bta/bta_hh_api.h deleted file mode 100644 index e1bf4017..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_hh_api.h +++ /dev/null @@ -1,545 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2002-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef BTA_HH_API_H -#define BTA_HH_API_H - -#include "bta/bta_api.h" -#include "stack/hidh_api.h" -#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE) - -#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE) -#include "stack/gatt_api.h" -#endif - -/***************************************************************************** -** Constants and Type Definitions -*****************************************************************************/ -#ifndef BTA_HH_DEBUG -#define BTA_HH_DEBUG TRUE -#endif - -#ifndef BTA_HH_SSR_MAX_LATENCY_DEF -#define BTA_HH_SSR_MAX_LATENCY_DEF 800 /* 500 ms*/ -#endif - -#ifndef BTA_HH_SSR_MIN_TOUT_DEF -#define BTA_HH_SSR_MIN_TOUT_DEF 2 -#endif - -/* BTA HID Host callback events */ -#define BTA_HH_ENABLE_EVT 0 /* HH enabled */ -#define BTA_HH_DISABLE_EVT 1 /* HH disabled */ -#define BTA_HH_OPEN_EVT 2 /* connection opened */ -#define BTA_HH_CLOSE_EVT 3 /* connection closed */ -#define BTA_HH_GET_RPT_EVT 4 /* BTA_HhGetReport callback */ -#define BTA_HH_SET_RPT_EVT 5 /* BTA_HhSetReport callback */ -#define BTA_HH_GET_PROTO_EVT 6 /* BTA_GetProtoMode callback */ -#define BTA_HH_SET_PROTO_EVT 7 /* BTA_HhSetProtoMode callback */ -#define BTA_HH_GET_IDLE_EVT 8 /* BTA_HhGetIdle comes callback */ -#define BTA_HH_SET_IDLE_EVT 9 /* BTA_HhSetIdle finish callback */ -#define BTA_HH_GET_DSCP_EVT 10 /* Get report descriptor */ -#define BTA_HH_ADD_DEV_EVT 11 /* Add Device callback */ -#define BTA_HH_RMV_DEV_EVT 12 /* remove device finished */ -#define BTA_HH_VC_UNPLUG_EVT 13 /* virtually unplugged */ -#define BTA_HH_DATA_EVT 15 -#define BTA_HH_API_ERR_EVT 16 /* API error is caught */ -#define BTA_HH_UPDATE_SCPP_EVT 17 /* update scan paramter complete */ - -typedef UINT16 tBTA_HH_EVT; - -/* application ID(none-zero) for each type of device */ -#define BTA_HH_APP_ID_MI 1 -#define BTA_HH_APP_ID_KB 2 -#define BTA_HH_APP_ID_RMC 3 -#define BTA_HH_APP_ID_3DSG 4 -#define BTA_HH_APP_ID_JOY 5 -#define BTA_HH_APP_ID_GPAD 6 -#define BTA_HH_APP_ID_LE 0xff - -/* defined the minimum offset */ -#define BTA_HH_MIN_OFFSET L2CAP_MIN_OFFSET+1 - -/* HID_HOST_MAX_DEVICES can not exceed 15 for th design of BTA HH */ -#define BTA_HH_IDX_INVALID 0xff -#define BTA_HH_MAX_KNOWN HID_HOST_MAX_DEVICES - -#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE) -/* GATT_MAX_PHY_CHANNEL can not exceed 14 for the design of BTA HH */ -#define BTA_HH_LE_MAX_KNOWN GATT_MAX_PHY_CHANNEL -#define BTA_HH_MAX_DEVICE (HID_HOST_MAX_DEVICES + GATT_MAX_PHY_CHANNEL) -#else -#define BTA_HH_MAX_DEVICE HID_HOST_MAX_DEVICES -#endif -/* invalid device handle */ -#define BTA_HH_INVALID_HANDLE 0xff - -/* type of protocol mode */ -#define BTA_HH_PROTO_RPT_MODE (0x00) -#define BTA_HH_PROTO_BOOT_MODE (0x01) -#define BTA_HH_PROTO_UNKNOWN (0xff) -typedef UINT8 tBTA_HH_PROTO_MODE; - -enum { - BTA_HH_KEYBD_RPT_ID = 1, - BTA_HH_MOUSE_RPT_ID -}; -typedef UINT8 tBTA_HH_BOOT_RPT_ID; - -/* type of devices, bit mask */ -#define BTA_HH_DEVT_UNKNOWN 0x00 -#define BTA_HH_DEVT_JOS 0x01 /* joy stick */ -#define BTA_HH_DEVT_GPD 0x02 /* game pad */ -#define BTA_HH_DEVT_RMC 0x03 /* remote control */ -#define BTA_HH_DEVT_SED 0x04 /* sensing device */ -#define BTA_HH_DEVT_DGT 0x05 /* Digitizer tablet */ -#define BTA_HH_DEVT_CDR 0x06 /* card reader */ -#define BTA_HH_DEVT_KBD 0x10 /* keyboard */ -#define BTA_HH_DEVT_MIC 0x20 /* pointing device */ -#define BTA_HH_DEVT_COM 0x30 /* Combo keyboard/pointing */ -#define BTA_HH_DEVT_OTHER 0x80 -typedef UINT8 tBTA_HH_DEVT; - -enum { - BTA_HH_OK, - BTA_HH_HS_HID_NOT_READY, /* handshake error : device not ready */ - BTA_HH_HS_INVALID_RPT_ID, /* handshake error : invalid report ID */ - BTA_HH_HS_TRANS_NOT_SPT, /* handshake error : transaction not spt */ - BTA_HH_HS_INVALID_PARAM, /* handshake error : invalid paremter */ - BTA_HH_HS_ERROR, /* handshake error : unspecified HS error */ - BTA_HH_ERR, /* general BTA HH error */ - BTA_HH_ERR_SDP, /* SDP error */ - BTA_HH_ERR_PROTO, /* SET_Protocol error, - only used in BTA_HH_OPEN_EVT callback */ - - BTA_HH_ERR_DB_FULL, /* device database full error, used in - BTA_HH_OPEN_EVT/BTA_HH_ADD_DEV_EVT */ - BTA_HH_ERR_TOD_UNSPT, /* type of device not supported */ - BTA_HH_ERR_NO_RES, /* out of system resources */ - BTA_HH_ERR_AUTH_FAILED, /* authentication fail */ - BTA_HH_ERR_HDL, - BTA_HH_ERR_SEC -}; -typedef UINT8 tBTA_HH_STATUS; - - -#define BTA_HH_VIRTUAL_CABLE HID_VIRTUAL_CABLE -#define BTA_HH_NORMALLY_CONNECTABLE HID_NORMALLY_CONNECTABLE -#define BTA_HH_RECONN_INIT HID_RECONN_INIT -#define BTA_HH_SDP_DISABLE HID_SDP_DISABLE -#define BTA_HH_BATTERY_POWER HID_BATTERY_POWER -#define BTA_HH_REMOTE_WAKE HID_REMOTE_WAKE -#define BTA_HH_SUP_TOUT_AVLBL HID_SUP_TOUT_AVLBL -#define BTA_HH_SEC_REQUIRED HID_SEC_REQUIRED -typedef UINT16 tBTA_HH_ATTR_MASK; - -/* supported type of device and corresponding application ID */ -typedef struct { - tBTA_HH_DEVT tod; /* type of device */ - UINT8 app_id; /* corresponding application ID */ -} tBTA_HH_SPT_TOD; - -/* configuration struct */ -typedef struct { - UINT8 max_devt_spt; /* max number of types of devices spt */ - tBTA_HH_SPT_TOD *p_devt_list; /* supported types of device list */ - UINT16 sdp_db_size; -} tBTA_HH_CFG; - -enum { - BTA_HH_RPTT_RESRV, /* reserved */ - BTA_HH_RPTT_INPUT, /* input report */ - BTA_HH_RPTT_OUTPUT, /* output report */ - BTA_HH_RPTT_FEATURE /* feature report */ -}; -typedef UINT8 tBTA_HH_RPT_TYPE; - -/* HID_CONTROL operation code used in BTA_HhSendCtrl() -*/ -enum { - BTA_HH_CTRL_NOP = 0 + HID_PAR_CONTROL_NOP ,/* mapping from BTE */ - BTA_HH_CTRL_HARD_RESET, /* hard reset */ - BTA_HH_CTRL_SOFT_RESET, /* soft reset */ - BTA_HH_CTRL_SUSPEND, /* enter suspend */ - BTA_HH_CTRL_EXIT_SUSPEND, /* exit suspend */ - BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG /* virtual unplug */ -}; -typedef UINT8 tBTA_HH_TRANS_CTRL_TYPE; - -typedef tHID_DEV_DSCP_INFO tBTA_HH_DEV_DESCR; - -#define BTA_HH_SSR_PARAM_INVALID HID_SSR_PARAM_INVALID - -/* id DI is not existing in remote device, vendor_id in tBTA_HH_DEV_DSCP_INFO will be set to 0xffff */ -#define BTA_HH_VENDOR_ID_INVALID 0xffff - - -/* report descriptor information */ -typedef struct { - UINT16 vendor_id; /* vendor ID */ - UINT16 product_id; /* product ID */ - UINT16 version; /* version */ - UINT16 ssr_max_latency; /* SSR max latency, BTA_HH_SSR_PARAM_INVALID if unknown */ - UINT16 ssr_min_tout; /* SSR min timeout, BTA_HH_SSR_PARAM_INVALID if unknown */ - UINT8 ctry_code; /*Country Code.*/ -#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE) -#define BTA_HH_LE_REMOTE_WAKE 0x01 -#define BTA_HH_LE_NORMAL_CONN 0x02 - - UINT8 flag; -#endif - tBTA_HH_DEV_DESCR descriptor; -} tBTA_HH_DEV_DSCP_INFO; - -/* callback event data for BTA_HH_OPEN_EVT */ -typedef struct { - BD_ADDR bda; /* HID device bd address */ - tBTA_HH_STATUS status; /* operation status */ - UINT8 handle; /* device handle */ -#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE) - BOOLEAN le_hid; /* is LE devices? */ - BOOLEAN scps_supported; /* scan parameter service supported */ -#endif - -} tBTA_HH_CONN; - -typedef tBTA_HH_CONN tBTA_HH_DEV_INFO; - -/* callback event data */ -typedef struct { - tBTA_HH_STATUS status; /* operation status */ - UINT8 handle; /* device handle */ -} tBTA_HH_CBDATA; - -enum { - BTA_HH_MOD_CTRL_KEY, - BTA_HH_MOD_SHFT_KEY, - BTA_HH_MOD_ALT_KEY, - BTA_HH_MOD_GUI_KEY, - BTA_HH_MOD_MAX_KEY -}; - -/* parsed boot mode keyboard report */ -typedef struct { - UINT8 this_char[6]; /* virtual key code */ - BOOLEAN mod_key[BTA_HH_MOD_MAX_KEY]; - /* ctrl, shift, Alt, GUI */ - /* modifier key: is Shift key pressed */ - /* modifier key: is Ctrl key pressed */ - /* modifier key: is Alt key pressed */ - /* modifier key: GUI up/down */ - BOOLEAN caps_lock; /* is caps locked */ - BOOLEAN num_lock; /* is Num key pressed */ -} tBTA_HH_KEYBD_RPT; - -/* parsed boot mode mouse report */ -typedef struct { - UINT8 mouse_button; /* mouse button is clicked */ - INT8 delta_x; /* displacement x */ - INT8 delta_y; /* displacement y */ -} tBTA_HH_MICE_RPT; - -/* parsed Boot report */ -typedef struct { - tBTA_HH_BOOT_RPT_ID dev_type; /* type of device report */ - union { - tBTA_HH_KEYBD_RPT keybd_rpt; /* keyboard report */ - tBTA_HH_MICE_RPT mice_rpt; /* mouse report */ - } data_rpt; -} tBTA_HH_BOOT_RPT; - -/* handshake data */ -typedef struct { - tBTA_HH_STATUS status; /* handshake status */ - UINT8 handle; /* device handle */ - union { - tBTA_HH_PROTO_MODE proto_mode; /* GET_PROTO_EVT :protocol mode */ - BT_HDR *p_rpt_data; /* GET_RPT_EVT : report data */ - UINT8 idle_rate; /* GET_IDLE_EVT : idle rate */ - } rsp_data; - -} tBTA_HH_HSDATA; - -/* union of data associated with HD callback */ -typedef union { - tBTA_HH_DEV_INFO dev_info; /* BTA_HH_ADD_DEV_EVT, BTA_HH_RMV_DEV_EVT */ - tBTA_HH_CONN conn; /* BTA_HH_OPEN_EVT */ - tBTA_HH_CBDATA dev_status; /* BTA_HH_CLOSE_EVT, - BTA_HH_SET_PROTO_EVT - BTA_HH_SET_RPT_EVT - BTA_HH_SET_IDLE_EVT - BTA_HH_UPDATE_SCPP_EVT */ - - tBTA_HH_STATUS status; /* BTA_HH_ENABLE_EVT */ - tBTA_HH_DEV_DSCP_INFO dscp_info; /* BTA_HH_GET_DSCP_EVT */ - tBTA_HH_HSDATA hs_data; /* GET_ transaction callback - BTA_HH_GET_RPT_EVT - BTA_HH_GET_PROTO_EVT - BTA_HH_GET_IDLE_EVT */ -} tBTA_HH; - -/* BTA HH callback function */ -typedef void (tBTA_HH_CBACK) (tBTA_HH_EVT event, tBTA_HH *p_data); - - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/******************************************************************************* -** -** Function BTA_HhRegister -** -** Description This function enable HID host and registers HID-Host with -** lower layers. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhEnable(tBTA_SEC sec_mask, tBTA_HH_CBACK *p_cback); - -/******************************************************************************* -** -** Function BTA_HhDeregister -** -** Description This function is called when the host is about power down. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhDisable(void); - -/******************************************************************************* -** -** Function BTA_HhOpen -** -** Description This function is called to start an inquiry and read SDP -** record of responding devices; connect to a device if only -** one active HID device is found. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhOpen (BD_ADDR dev_bda, tBTA_HH_PROTO_MODE mode, - tBTA_SEC sec_mask); - -/******************************************************************************* -** -** Function BTA_HhClose -** -** Description This function disconnects the device. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhClose(UINT8 dev_handle); - -/******************************************************************************* -** -** Function BTA_HhSetProtoMode -** -** Description This function set the protocol mode at specified HID handle -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhSetProtoMode(UINT8 handle, tBTA_HH_PROTO_MODE t_type); - -/******************************************************************************* -** -** Function BTA_HhGetProtoMode -** -** Description This function get the protocol mode of a specified HID device. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhGetProtoMode(UINT8 dev_handle); -/******************************************************************************* -** -** Function BTA_HhSetReport -** -** Description send SET_REPORT to device. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhSetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type, - BT_HDR *p_data); - -/******************************************************************************* -** -** Function BTA_HhGetReport -** -** Description Send a GET_REPORT to HID device. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhGetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type, - UINT8 rpt_id, UINT16 buf_size); -/******************************************************************************* -** -** Function BTA_HhSetIdle -** -** Description send SET_IDLE to device. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhSetIdle(UINT8 dev_handle, UINT16 idle_rate); - -/******************************************************************************* -** -** Function BTA_HhGetIdle -** -** Description Send a GET_IDLE to HID device. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhGetIdle(UINT8 dev_handle); - -/******************************************************************************* -** -** Function BTA_HhSendCtrl -** -** Description Send HID_CONTROL request to a HID device. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhSendCtrl(UINT8 dev_handle, - tBTA_HH_TRANS_CTRL_TYPE c_type); - -/******************************************************************************* -** -** Function BTA_HhSetIdle -** -** Description send SET_IDLE to device. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhSetIdle(UINT8 dev_handle, UINT16 idle_rate); - - -/******************************************************************************* -** -** Function BTA_HhGetIdle -** -** Description Send a GET_IDLE from HID device. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhGetIdle(UINT8 dev_handle); - -/******************************************************************************* -** -** Function BTA_HhSendData -** -** Description Send DATA transaction to a HID device. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhSendData(UINT8 dev_handle, BD_ADDR dev_bda, BT_HDR *p_buf); - -/******************************************************************************* -** -** Function BTA_HhGetDscpInfo -** -** Description Get report descriptor of the device -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhGetDscpInfo(UINT8 dev_handle); - -/******************************************************************************* -** Function BTA_HhAddDev -** -** Description Add a virtually cabled device into HID-Host device list -** to manage and assign a device handle for future API call, -** host applciation call this API at start-up to initialize its -** virtually cabled devices. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhAddDev(BD_ADDR bda, tBTA_HH_ATTR_MASK attr_mask, - UINT8 sub_class, UINT8 app_id, - tBTA_HH_DEV_DSCP_INFO dscp_info); -/******************************************************************************* -** -** Function BTA_HhRemoveDev -** -** Description Remove a device from the HID host devices list. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhRemoveDev(UINT8 dev_handle ); - -/******************************************************************************* -** -** Parsing Utility Functions -** -*******************************************************************************/ -/******************************************************************************* -** -** Function BTA_HhParseBootRpt -** -** Description This utility function parse a boot mode report. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhParseBootRpt(tBTA_HH_BOOT_RPT *p_data, UINT8 *p_report, - UINT16 report_len); - -#if BTA_HH_LE_INCLUDED == TRUE -/******************************************************************************* -** -** Function BTA_HhUpdateLeScanParam -** -** Description Update the scan paramteters if connected to a LE hid device as -** report host. -** -** Returns void -** -*******************************************************************************/ -extern void BTA_HhUpdateLeScanParam(UINT8 dev_handle, UINT16 scan_int, UINT16 scan_win); -#endif -/* test commands */ -extern void bta_hh_le_hid_read_rpt_clt_cfg(BD_ADDR bd_addr, UINT8 rpt_id); - - - -#ifdef __cplusplus -} -#endif - -#endif ///defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE) - - -#endif /* BTA_HH_API_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_hh_co.h b/tools/sdk/include/bluedroid/bta/bta_hh_co.h deleted file mode 100644 index f0fef370..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_hh_co.h +++ /dev/null @@ -1,132 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2005-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the interface file for hid host call-out functions. - * - ******************************************************************************/ -#ifndef BTA_HH_CO_H -#define BTA_HH_CO_H - -#include "bta/bta_hh_api.h" - -typedef struct { - UINT16 rpt_uuid; - UINT8 rpt_id; - tBTA_HH_RPT_TYPE rpt_type; - UINT8 inst_id; - UINT8 prop; -} tBTA_HH_RPT_CACHE_ENTRY; - -/******************************************************************************* -** -** Function bta_hh_co_data -** -** Description This callout function is executed by HH when data is received -** in interupt channel. -** -** -** Returns void. -** -*******************************************************************************/ -extern void bta_hh_co_data(UINT8 dev_handle, UINT8 *p_rpt, UINT16 len, - tBTA_HH_PROTO_MODE mode, UINT8 sub_class, - UINT8 ctry_code, BD_ADDR peer_addr, UINT8 app_id); - -/******************************************************************************* -** -** Function bta_hh_co_open -** -** Description This callout function is executed by HH when connection is -** opened, and application may do some device specific -** initialization. -** -** Returns void. -** -*******************************************************************************/ -extern void bta_hh_co_open(UINT8 dev_handle, UINT8 sub_class, - UINT16 attr_mask, UINT8 app_id); - -/******************************************************************************* -** -** Function bta_hh_co_close -** -** Description This callout function is executed by HH when connection is -** closed, and device specific finalizatio nmay be needed. -** -** Returns void. -** -*******************************************************************************/ -extern void bta_hh_co_close(UINT8 dev_handle, UINT8 app_id); - -#if (BLE_INCLUDED == TRUE && BTA_HH_LE_INCLUDED == TRUE) -/******************************************************************************* -** -** Function bta_hh_le_co_rpt_info -** -** Description This callout function is to convey the report information on -** a HOGP device to the application. Application can save this -** information in NV if device is bonded and load it back when -** stack reboot. -** -** Parameters remote_bda - remote device address -** p_entry - report entry pointer -** app_id - application id -** -** Returns void. -** -*******************************************************************************/ -extern void bta_hh_le_co_rpt_info(BD_ADDR remote_bda, - tBTA_HH_RPT_CACHE_ENTRY *p_entry, - UINT8 app_id); - -/******************************************************************************* -** -** Function bta_hh_le_co_cache_load -** -** Description This callout function is to request the application to load the -** cached HOGP report if there is any. When cache reading is completed, -** bta_hh_le_ci_cache_load() is called by the application. -** -** Parameters remote_bda - remote device address -** p_num_rpt: number of cached report -** app_id - application id -** -** Returns the acched report array -** -*******************************************************************************/ -extern tBTA_HH_RPT_CACHE_ENTRY *bta_hh_le_co_cache_load (BD_ADDR remote_bda, - UINT8 *p_num_rpt, - UINT8 app_id); - -/******************************************************************************* -** -** Function bta_hh_le_co_reset_rpt_cache -** -** Description This callout function is to reset the HOGP device cache. -** -** Parameters remote_bda - remote device address -** -** Returns none -** -*******************************************************************************/ -extern void bta_hh_le_co_reset_rpt_cache (BD_ADDR remote_bda, UINT8 app_id); - -#endif /* #if (BLE_INCLUDED == TRUE && BTA_HH_LE_INCLUDED == TRUE) */ -#endif /* BTA_HH_CO_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_jv_api.h b/tools/sdk/include/bluedroid/bta/bta_jv_api.h deleted file mode 100644 index bf23aab4..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_jv_api.h +++ /dev/null @@ -1,884 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2006-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the public interface file the BTA Java I/F - * - ******************************************************************************/ -#ifndef BTA_JV_API_H -#define BTA_JV_API_H - -#include "common/bt_target.h" -#include "stack/bt_types.h" -#include "bta/bta_api.h" -#include "stack/btm_api.h" -#include "stack/l2c_api.h" -#include "stack/rfcdefs.h" -#include "stack/sdp_api.h" - -#if (defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE) -/***************************************************************************** -** Constants and data types -*****************************************************************************/ -/* status values */ -#define BTA_JV_SUCCESS 0 /* Successful operation. */ -#define BTA_JV_FAILURE 1 /* Generic failure. */ -#define BTA_JV_BUSY 2 /* Temporarily can not handle this request. */ -#define BTA_JV_NO_DATA 3 /* no data. */ -#define BTA_JV_NO_RESOURCE 4 /* No more set pm control block */ - -typedef UINT8 tBTA_JV_STATUS; -#define BTA_JV_INTERNAL_ERR (-1) /* internal error. */ - -#define BTA_JV_MAX_UUIDS SDP_MAX_UUID_FILTERS -#define BTA_JV_MAX_ATTRS SDP_MAX_ATTR_FILTERS -#define BTA_JV_MAX_SDP_REC SDP_MAX_RECORDS -#define BTA_JV_MAX_L2C_CONN GAP_MAX_CONNECTIONS /* GAP handle is used as index, hence do not change this value */ -#define BTA_JV_MAX_SCN PORT_MAX_RFC_PORTS /* same as BTM_MAX_SCN (in btm_int.h) */ -#define BTA_JV_MAX_RFC_CONN MAX_RFC_PORTS - -#ifndef BTA_JV_DEF_RFC_MTU -#define BTA_JV_DEF_RFC_MTU (3*330) -#endif - -#ifndef BTA_JV_MAX_RFC_SR_SESSION -#define BTA_JV_MAX_RFC_SR_SESSION MAX_BD_CONNECTIONS -#endif - -/* BTA_JV_MAX_RFC_SR_SESSION can not be bigger than MAX_BD_CONNECTIONS */ -#if (BTA_JV_MAX_RFC_SR_SESSION > MAX_BD_CONNECTIONS) -#undef BTA_JV_MAX_RFC_SR_SESSION -#define BTA_JV_MAX_RFC_SR_SESSION MAX_BD_CONNECTIONS -#endif - -#define BTA_JV_FIRST_SERVICE_ID BTA_FIRST_JV_SERVICE_ID -#define BTA_JV_LAST_SERVICE_ID BTA_LAST_JV_SERVICE_ID -#define BTA_JV_NUM_SERVICE_ID (BTA_LAST_JV_SERVICE_ID - BTA_FIRST_JV_SERVICE_ID + 1) - -/* Discoverable modes */ -enum { - BTA_JV_DISC_NONE, - BTA_JV_DISC_LIMITED, - BTA_JV_DISC_GENERAL -}; -typedef UINT16 tBTA_JV_DISC; - -#define BTA_JV_ROLE_SLAVE BTM_ROLE_SLAVE -#define BTA_JV_ROLE_MASTER BTM_ROLE_MASTER -typedef UINT32 tBTA_JV_ROLE; - -#define BTA_JV_SERVICE_LMTD_DISCOVER BTM_COD_SERVICE_LMTD_DISCOVER /* 0x0020 */ -#define BTA_JV_SERVICE_POSITIONING BTM_COD_SERVICE_POSITIONING /* 0x0100 */ -#define BTA_JV_SERVICE_NETWORKING BTM_COD_SERVICE_NETWORKING /* 0x0200 */ -#define BTA_JV_SERVICE_RENDERING BTM_COD_SERVICE_RENDERING /* 0x0400 */ -#define BTA_JV_SERVICE_CAPTURING BTM_COD_SERVICE_CAPTURING /* 0x0800 */ -#define BTA_JV_SERVICE_OBJ_TRANSFER BTM_COD_SERVICE_OBJ_TRANSFER /* 0x1000 */ -#define BTA_JV_SERVICE_AUDIO BTM_COD_SERVICE_AUDIO /* 0x2000 */ -#define BTA_JV_SERVICE_TELEPHONY BTM_COD_SERVICE_TELEPHONY /* 0x4000 */ -#define BTA_JV_SERVICE_INFORMATION BTM_COD_SERVICE_INFORMATION /* 0x8000 */ - -/* JV ID type */ -#define BTA_JV_PM_ID_1 1 /* PM example profile 1 */ -#define BTA_JV_PM_ID_2 2 /* PM example profile 2 */ -#define BTA_JV_PM_ID_CLEAR 0 /* Special JV ID used to clear PM profile */ -#define BTA_JV_PM_ALL 0xFF /* Generic match all id, see bta_dm_cfg.c */ -typedef UINT8 tBTA_JV_PM_ID; - -#define BTA_JV_PM_HANDLE_CLEAR 0xFF /* Special JV ID used to clear PM profile */ - -/* define maximum number of registered PM entities. should be in sync with bta pm! */ -#ifndef BTA_JV_PM_MAX_NUM -#define BTA_JV_PM_MAX_NUM 5 -#endif - -/* JV pm connection states */ -enum { - BTA_JV_CONN_OPEN = 0, /* Connection opened state */ - BTA_JV_CONN_CLOSE, /* Connection closed state */ - BTA_JV_APP_OPEN, /* JV Application opened state */ - BTA_JV_APP_CLOSE, /* JV Application closed state */ - BTA_JV_SCO_OPEN, /* SCO connection opened state */ - BTA_JV_SCO_CLOSE, /* SCO connection opened state */ - BTA_JV_CONN_IDLE, /* Connection idle state */ - BTA_JV_CONN_BUSY, /* Connection busy state */ - BTA_JV_MAX_CONN_STATE /* Max number of connection state */ -}; -typedef UINT8 tBTA_JV_CONN_STATE; - -/* JV Connection types */ -#define BTA_JV_CONN_TYPE_RFCOMM 0 -#define BTA_JV_CONN_TYPE_L2CAP 1 -#define BTA_JV_CONN_TYPE_L2CAP_LE 2 - -/* Java I/F callback events */ -/* events received by tBTA_JV_DM_CBACK */ -#define BTA_JV_ENABLE_EVT 0 /* JV enabled */ -#define BTA_JV_GET_SCN_EVT 6 /* Reserved an SCN */ -#define BTA_JV_GET_PSM_EVT 7 /* Reserved a PSM */ -#define BTA_JV_DISCOVERY_COMP_EVT 8 /* SDP discovery complete */ -#define BTA_JV_CREATE_RECORD_EVT 11 /* the result for BTA_JvCreateRecord */ -/* events received by tBTA_JV_L2CAP_CBACK */ -#define BTA_JV_L2CAP_OPEN_EVT 16 /* open status of L2CAP connection */ -#define BTA_JV_L2CAP_CLOSE_EVT 17 /* L2CAP connection closed */ -#define BTA_JV_L2CAP_START_EVT 18 /* L2CAP server started */ -#define BTA_JV_L2CAP_CL_INIT_EVT 19 /* L2CAP client initiated a connection */ -#define BTA_JV_L2CAP_DATA_IND_EVT 20 /* L2CAP connection received data */ -#define BTA_JV_L2CAP_CONG_EVT 21 /* L2CAP connection congestion status changed */ -#define BTA_JV_L2CAP_READ_EVT 22 /* the result for BTA_JvL2capRead */ -#define BTA_JV_L2CAP_RECEIVE_EVT 23 /* the result for BTA_JvL2capReceive*/ -#define BTA_JV_L2CAP_WRITE_EVT 24 /* the result for BTA_JvL2capWrite*/ -#define BTA_JV_L2CAP_WRITE_FIXED_EVT 25 /* the result for BTA_JvL2capWriteFixed */ - -/* events received by tBTA_JV_RFCOMM_CBACK */ -#define BTA_JV_RFCOMM_OPEN_EVT 26 /* open status of RFCOMM Client connection */ -#define BTA_JV_RFCOMM_CLOSE_EVT 27 /* RFCOMM connection closed */ -#define BTA_JV_RFCOMM_START_EVT 28 /* RFCOMM server started */ -#define BTA_JV_RFCOMM_CL_INIT_EVT 29 /* RFCOMM client initiated a connection */ -#define BTA_JV_RFCOMM_DATA_IND_EVT 30 /* RFCOMM connection received data */ -#define BTA_JV_RFCOMM_CONG_EVT 31 /* RFCOMM connection congestion status changed */ -#define BTA_JV_RFCOMM_READ_EVT 32 /* the result for BTA_JvRfcommRead */ -#define BTA_JV_RFCOMM_WRITE_EVT 33 /* the result for BTA_JvRfcommWrite*/ -#define BTA_JV_RFCOMM_SRV_OPEN_EVT 34 /* open status of Server RFCOMM connection */ -#define BTA_JV_MAX_EVT 35 /* max number of JV events */ - -typedef UINT16 tBTA_JV_EVT; - -/* data associated with BTA_JV_SET_DISCOVER_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - tBTA_JV_DISC disc_mode; /* The current discoverable mode */ -} tBTA_JV_SET_DISCOVER; - -/* data associated with BTA_JV_DISCOVERY_COMP_EVT_ */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT8 scn_num; /* num of channel */ - UINT8 scn[BTA_JV_MAX_SCN]; /* channel # */ -} tBTA_JV_DISCOVERY_COMP; - -/* data associated with BTA_JV_CREATE_RECORD_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The SDP handle */ -} tBTA_JV_CREATE_RECORD; - -/* data associated with BTA_JV_L2CAP_OPEN_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - BD_ADDR rem_bda; /* The peer address */ - INT32 tx_mtu; /* The transmit MTU */ -} tBTA_JV_L2CAP_OPEN; - -/* data associated with BTA_JV_L2CAP_OPEN_EVT for LE sockets */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - BD_ADDR rem_bda; /* The peer address */ - INT32 tx_mtu; /* The transmit MTU */ - void **p_p_cback; /* set them for new socket */ - void **p_user_data;/* set them for new socket */ - -} tBTA_JV_L2CAP_LE_OPEN; - - -/* data associated with BTA_JV_L2CAP_CLOSE_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - BOOLEAN async; /* FALSE, if local initiates disconnect */ -} tBTA_JV_L2CAP_CLOSE; - -/* data associated with BTA_JV_L2CAP_START_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - UINT8 sec_id; /* security ID used by this server */ -} tBTA_JV_L2CAP_START; - -/* data associated with BTA_JV_L2CAP_CL_INIT_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - UINT8 sec_id; /* security ID used by this client */ -} tBTA_JV_L2CAP_CL_INIT; - -/* data associated with BTA_JV_L2CAP_CONG_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - BOOLEAN cong; /* TRUE, congested. FALSE, uncongested */ -} tBTA_JV_L2CAP_CONG; - -/* data associated with BTA_JV_L2CAP_READ_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - UINT32 req_id; /* The req_id in the associated BTA_JvL2capRead() */ - UINT8 *p_data; /* This points the same location as the p_data - * parameter in BTA_JvL2capRead () */ - UINT16 len; /* The length of the data read. */ -} tBTA_JV_L2CAP_READ; - -/* data associated with BTA_JV_L2CAP_RECEIVE_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - UINT32 req_id; /* The req_id in the associated BTA_JvL2capReceive() */ - UINT8 *p_data; /* This points the same location as the p_data - * parameter in BTA_JvL2capReceive () */ - UINT16 len; /* The length of the data read. */ -} tBTA_JV_L2CAP_RECEIVE; - -/* data associated with BTA_JV_L2CAP_WRITE_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - UINT32 req_id; /* The req_id in the associated BTA_JvL2capWrite() */ - UINT16 len; /* The length of the data written. */ - BOOLEAN cong; /* congestion status */ -} tBTA_JV_L2CAP_WRITE; - - -/* data associated with BTA_JV_L2CAP_WRITE_FIXED_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT16 channel; /* The connection channel */ - BD_ADDR addr; /* The peer address */ - UINT32 req_id; /* The req_id in the associated BTA_JvL2capWrite() */ - UINT16 len; /* The length of the data written. */ - BOOLEAN cong; /* congestion status */ -} tBTA_JV_L2CAP_WRITE_FIXED; - -/* data associated with BTA_JV_RFCOMM_OPEN_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - BD_ADDR rem_bda; /* The peer address */ -} tBTA_JV_RFCOMM_OPEN; -/* data associated with BTA_JV_RFCOMM_SRV_OPEN_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - UINT32 new_listen_handle; /* The new listen handle */ - BD_ADDR rem_bda; /* The peer address */ -} tBTA_JV_RFCOMM_SRV_OPEN; - - -/* data associated with BTA_JV_RFCOMM_CLOSE_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 port_status; /* PORT status */ - UINT32 handle; /* The connection handle */ - BOOLEAN async; /* FALSE, if local initiates disconnect */ -} tBTA_JV_RFCOMM_CLOSE; - -/* data associated with BTA_JV_RFCOMM_START_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - UINT8 sec_id; /* security ID used by this server */ - BOOLEAN use_co; /* TRUE to use co_rfc_data */ -} tBTA_JV_RFCOMM_START; - -/* data associated with BTA_JV_RFCOMM_CL_INIT_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - UINT8 sec_id; /* security ID used by this client */ - BOOLEAN use_co; /* TRUE to use co_rfc_data */ -} tBTA_JV_RFCOMM_CL_INIT; -/*data associated with BTA_JV_L2CAP_DATA_IND_EVT & BTA_JV_RFCOMM_DATA_IND_EVT */ -typedef struct { - UINT32 handle; /* The connection handle */ - BT_HDR *p_buf; /* The incoming data */ -} tBTA_JV_DATA_IND; - -/*data associated with BTA_JV_L2CAP_DATA_IND_EVT if used for LE */ -typedef struct { - UINT32 handle; /* The connection handle */ - BT_HDR *p_buf; /* The incoming data */ -} tBTA_JV_LE_DATA_IND; - - -/* data associated with BTA_JV_RFCOMM_CONG_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - BOOLEAN cong; /* TRUE, congested. FALSE, uncongested */ -} tBTA_JV_RFCOMM_CONG; - -/* data associated with BTA_JV_RFCOMM_READ_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - UINT32 req_id; /* The req_id in the associated BTA_JvRfcommRead() */ - UINT8 *p_data; /* This points the same location as the p_data - * parameter in BTA_JvRfcommRead () */ - UINT16 len; /* The length of the data read. */ -} tBTA_JV_RFCOMM_READ; - -/* data associated with BTA_JV_RFCOMM_WRITE_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ - UINT32 handle; /* The connection handle */ - UINT32 req_id; /* The req_id in the associated BTA_JvRfcommWrite() */ - int len; /* The length of the data written. */ - BOOLEAN cong; /* congestion status */ -} tBTA_JV_RFCOMM_WRITE; - -/* data associated with BTA_JV_API_SET_PM_PROFILE_EVT */ -typedef struct { - tBTA_JV_STATUS status; /* Status of the operation */ - UINT32 handle; /* Connection handle */ - tBTA_JV_PM_ID app_id; /* JV app ID */ -} tBTA_JV_SET_PM_PROFILE; - -/* data associated with BTA_JV_API_NOTIFY_PM_STATE_CHANGE_EVT */ -typedef struct { - UINT32 handle; /* Connection handle */ - tBTA_JV_CONN_STATE state; /* JV connection stata */ -} tBTA_JV_NOTIFY_PM_STATE_CHANGE; - - -/* union of data associated with JV callback */ -typedef union { - tBTA_JV_STATUS status; /* BTA_JV_ENABLE_EVT */ - tBTA_JV_DISCOVERY_COMP disc_comp; /* BTA_JV_DISCOVERY_COMP_EVT */ - tBTA_JV_SET_DISCOVER set_discover; /* BTA_JV_SET_DISCOVER_EVT */ - UINT8 scn; /* BTA_JV_GET_SCN_EVT */ - UINT16 psm; /* BTA_JV_GET_PSM_EVT */ - tBTA_JV_CREATE_RECORD create_rec; /* BTA_JV_CREATE_RECORD_EVT */ - tBTA_JV_L2CAP_OPEN l2c_open; /* BTA_JV_L2CAP_OPEN_EVT */ - tBTA_JV_L2CAP_CLOSE l2c_close; /* BTA_JV_L2CAP_CLOSE_EVT */ - tBTA_JV_L2CAP_START l2c_start; /* BTA_JV_L2CAP_START_EVT */ - tBTA_JV_L2CAP_CL_INIT l2c_cl_init; /* BTA_JV_L2CAP_CL_INIT_EVT */ - tBTA_JV_L2CAP_CONG l2c_cong; /* BTA_JV_L2CAP_CONG_EVT */ - tBTA_JV_L2CAP_READ l2c_read; /* BTA_JV_L2CAP_READ_EVT */ - tBTA_JV_L2CAP_WRITE l2c_write; /* BTA_JV_L2CAP_WRITE_EVT */ - tBTA_JV_RFCOMM_OPEN rfc_open; /* BTA_JV_RFCOMM_OPEN_EVT */ - tBTA_JV_RFCOMM_SRV_OPEN rfc_srv_open; /* BTA_JV_RFCOMM_SRV_OPEN_EVT */ - tBTA_JV_RFCOMM_CLOSE rfc_close; /* BTA_JV_RFCOMM_CLOSE_EVT */ - tBTA_JV_RFCOMM_START rfc_start; /* BTA_JV_RFCOMM_START_EVT */ - tBTA_JV_RFCOMM_CL_INIT rfc_cl_init; /* BTA_JV_RFCOMM_CL_INIT_EVT */ - tBTA_JV_RFCOMM_CONG rfc_cong; /* BTA_JV_RFCOMM_CONG_EVT */ - tBTA_JV_RFCOMM_READ rfc_read; /* BTA_JV_RFCOMM_READ_EVT */ - tBTA_JV_RFCOMM_WRITE rfc_write; /* BTA_JV_RFCOMM_WRITE_EVT */ - tBTA_JV_DATA_IND data_ind; /* BTA_JV_L2CAP_DATA_IND_EVT - BTA_JV_RFCOMM_DATA_IND_EVT */ - tBTA_JV_LE_DATA_IND le_data_ind; /* BTA_JV_L2CAP_LE_DATA_IND_EVT */ - tBTA_JV_L2CAP_LE_OPEN l2c_le_open; /* BTA_JV_L2CAP_OPEN_EVT */ - tBTA_JV_L2CAP_WRITE_FIXED l2c_write_fixed; /* BTA_JV_L2CAP_WRITE_FIXED_EVT */ -} tBTA_JV; - -/* JAVA DM Interface callback */ -typedef void (tBTA_JV_DM_CBACK)(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data); - -/* JAVA RFCOMM interface callback */ -typedef void *(tBTA_JV_RFCOMM_CBACK)(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data); - -/* JAVA L2CAP interface callback */ -typedef void (tBTA_JV_L2CAP_CBACK)(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_Data); - -/* JV configuration structure */ -typedef struct { - UINT16 sdp_raw_size; /* The size of p_sdp_raw_data */ - UINT16 sdp_db_size; /* The size of p_sdp_db */ - UINT8 *p_sdp_raw_data; /* The data buffer to keep raw data */ - tSDP_DISCOVERY_DB *p_sdp_db; /* The data buffer to keep SDP database */ -} tBTA_JV_CFG; - -/******************************************************************************* -** -** Function BTA_JvEnable -** -** Description Enable the Java I/F service. When the enable -** operation is complete the callback function will be -** called with a BTA_JV_ENABLE_EVT. This function must -** be called before other functions in the JV API are -** called. -** -** Returns BTA_JV_SUCCESS if successful. -** BTA_JV_FAIL if internal failure. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvEnable(tBTA_JV_DM_CBACK *p_cback); - -/******************************************************************************* -** -** Function BTA_JvDisable -** -** Description Disable the Java I/F -** -** Returns void -** -*******************************************************************************/ -extern void BTA_JvDisable(void); - -/******************************************************************************* -** -** Function BTA_JvIsEnable -** -** Description Get the JV registration status. -** -** Returns TRUE, if registered -** -*******************************************************************************/ -extern BOOLEAN BTA_JvIsEnable(void); - -/******************************************************************************* -** -** Function BTA_JvIsEncrypted -** -** Description This function checks if the link to peer device is encrypted -** -** Returns TRUE if encrypted. -** FALSE if not. -** -*******************************************************************************/ -extern BOOLEAN BTA_JvIsEncrypted(BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function BTA_JvGetChannelId -** -** Description This function reserves a SCN/PSM for applications running -** over RFCOMM or L2CAP. It is primarily called by -** server profiles/applications to register their SCN/PSM into the -** SDP database. The SCN is reported by the tBTA_JV_DM_CBACK -** callback with a BTA_JV_GET_SCN_EVT. -** If the SCN/PSM reported is 0, that means all SCN resources are -** exhausted. -** The channel parameter can be used to request a specific -** channel. If the request on the specific channel fails, the -** SCN/PSM returned in the EVT will be 0 - no attempt to request -** a new channel will be made. set channel to <= 0 to automatically -** assign an channel ID. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvGetChannelId(int conn_type, void *user_data, - INT32 channel); - -/******************************************************************************* -** -** Function BTA_JvFreeChannel -** -** Description This function frees a SCN/PSM that was used -** by an application running over RFCOMM or L2CAP. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvFreeChannel(UINT16 channel, int conn_type); - -/******************************************************************************* -** -** Function BTA_JvStartDiscovery -** -** Description This function performs service discovery for the services -** provided by the given peer device. When the operation is -** complete the tBTA_JV_DM_CBACK callback function will be -** called with a BTA_JV_DISCOVERY_COMP_EVT. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvStartDiscovery(BD_ADDR bd_addr, UINT16 num_uuid, - tSDP_UUID *p_uuid_list, void *user_data); - -/******************************************************************************* -** -** Function BTA_JvCreateRecordByUser -** -** Description Create a service record in the local SDP database by user in -** tBTA_JV_DM_CBACK callback with a BTA_JV_CREATE_RECORD_EVT. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvCreateRecordByUser(const char *name, UINT32 channel, void *user_data); - -/******************************************************************************* -** -** Function BTA_JvDeleteRecord -** -** Description Delete a service record in the local SDP database. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvDeleteRecord(UINT32 handle); - -/******************************************************************************* -** -** Function BTA_JvL2capConnectLE -** -** Description Initiate a connection as an LE L2CAP client to the given BD -** Address. -** When the connection is initiated or failed to initiate, -** tBTA_JV_L2CAP_CBACK is called with BTA_JV_L2CAP_CL_INIT_EVT -** When the connection is established or failed, -** tBTA_JV_L2CAP_CBACK is called with BTA_JV_L2CAP_OPEN_EVT -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvL2capConnectLE(tBTA_SEC sec_mask, tBTA_JV_ROLE role, - const tL2CAP_ERTM_INFO *ertm_info, UINT16 remote_chan, - UINT16 rx_mtu, tL2CAP_CFG_INFO *cfg, - BD_ADDR peer_bd_addr, tBTA_JV_L2CAP_CBACK *p_cback, void *user_data); - -/******************************************************************************* -** -** Function BTA_JvL2capConnect -** -** Description Initiate a connection as a L2CAP client to the given BD -** Address. -** When the connection is initiated or failed to initiate, -** tBTA_JV_L2CAP_CBACK is called with BTA_JV_L2CAP_CL_INIT_EVT -** When the connection is established or failed, -** tBTA_JV_L2CAP_CBACK is called with BTA_JV_L2CAP_OPEN_EVT -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvL2capConnect(tBTA_SEC sec_mask, tBTA_JV_ROLE role, - const tL2CAP_ERTM_INFO *ertm_info, UINT16 remote_psm, - UINT16 rx_mtu, tL2CAP_CFG_INFO *cfg, - BD_ADDR peer_bd_addr, tBTA_JV_L2CAP_CBACK *p_cback, void *user_data); - -/******************************************************************************* -** -** Function BTA_JvL2capClose -** -** Description This function closes an L2CAP client connection -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvL2capClose(UINT32 handle); - -/******************************************************************************* -** -** Function BTA_JvL2capCloseLE -** -** Description This function closes an L2CAP client connection for Fixed Channels -** Function is idempotent and no callbacks are called! -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvL2capCloseLE(UINT32 handle); - -/******************************************************************************* -** -** Function BTA_JvL2capStartServer -** -** Description This function starts an L2CAP server and listens for an L2CAP -** connection from a remote Bluetooth device. When the server -** is started successfully, tBTA_JV_L2CAP_CBACK is called with -** BTA_JV_L2CAP_START_EVT. When the connection is established, -** tBTA_JV_L2CAP_CBACK is called with BTA_JV_L2CAP_OPEN_EVT. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvL2capStartServer(tBTA_SEC sec_mask, tBTA_JV_ROLE role, - const tL2CAP_ERTM_INFO *ertm_info, - UINT16 local_psm, UINT16 rx_mtu, tL2CAP_CFG_INFO *cfg, - tBTA_JV_L2CAP_CBACK *p_cback, void *user_data); - -/******************************************************************************* -** -** Function BTA_JvL2capStartServerLE -** -** Description This function starts an LE L2CAP server and listens for an L2CAP -** connection from a remote Bluetooth device on a fixed channel -** over an LE link. When the server -** is started successfully, tBTA_JV_L2CAP_CBACK is called with -** BTA_JV_L2CAP_START_EVT. When the connection is established, -** tBTA_JV_L2CAP_CBACK is called with BTA_JV_L2CAP_OPEN_EVT. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvL2capStartServerLE(tBTA_SEC sec_mask, tBTA_JV_ROLE role, - const tL2CAP_ERTM_INFO *ertm_info, - UINT16 local_chan, UINT16 rx_mtu, tL2CAP_CFG_INFO *cfg, - tBTA_JV_L2CAP_CBACK *p_cback, void *user_data); - -/******************************************************************************* -** -** Function BTA_JvL2capStopServerLE -** -** Description This function stops the LE L2CAP server. If the server has an -** active connection, it would be closed. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvL2capStopServerLE(UINT16 local_chan, void *user_data); - -/******************************************************************************* -** -** Function BTA_JvL2capStopServerLE -** -** Description This function stops the LE L2CAP server. If the server has an -** active connection, it would be closed. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvL2capStopServer(UINT16 local_psm, void *user_data); - -/******************************************************************************* -** -** Function BTA_JvL2capRead -** -** Description This function reads data from an L2CAP connection -** When the operation is complete, tBTA_JV_L2CAP_CBACK is -** called with BTA_JV_L2CAP_READ_EVT. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvL2capRead(UINT32 handle, UINT32 req_id, - UINT8 *p_data, UINT16 len); - -/******************************************************************************* -** -** Function BTA_JvL2capReceive -** -** Description This function reads data from an L2CAP connection -** When the operation is complete, tBTA_JV_L2CAP_CBACK is -** called with BTA_JV_L2CAP_RECEIVE_EVT. -** If there are more data queued in L2CAP than len, the extra data will be discarded. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvL2capReceive(UINT32 handle, UINT32 req_id, - UINT8 *p_data, UINT16 len); - -/******************************************************************************* -** -** Function BTA_JvL2capReady -** -** Description This function determined if there is data to read from -** an L2CAP connection -** -** Returns BTA_JV_SUCCESS, if data queue size is in *p_data_size. -** BTA_JV_FAILURE, if error. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvL2capReady(UINT32 handle, UINT32 *p_data_size); - -/******************************************************************************* -** -** Function BTA_JvL2capWrite -** -** Description This function writes data to an L2CAP connection -** When the operation is complete, tBTA_JV_L2CAP_CBACK is -** called with BTA_JV_L2CAP_WRITE_EVT. Works for -** PSM-based connections -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvL2capWrite(UINT32 handle, UINT32 req_id, - UINT8 *p_data, UINT16 len, void *user_data); - - -/******************************************************************************* -** -** Function BTA_JvL2capWriteFixed -** -** Description This function writes data to an L2CAP connection -** When the operation is complete, tBTA_JV_L2CAP_CBACK is -** called with BTA_JV_L2CAP_WRITE_FIXED_EVT. Works for -** fixed-channel connections -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvL2capWriteFixed(UINT16 channel, BD_ADDR *addr, UINT32 req_id, - tBTA_JV_L2CAP_CBACK *p_cback, - UINT8 *p_data, UINT16 len, void *user_data); - -/******************************************************************************* -** -** Function BTA_JvRfcommConnect -** -** Description This function makes an RFCOMM conection to a remote BD -** Address. -** When the connection is initiated or failed to initiate, -** tBTA_JV_RFCOMM_CBACK is called with BTA_JV_RFCOMM_CL_INIT_EVT -** When the connection is established or failed, -** tBTA_JV_RFCOMM_CBACK is called with BTA_JV_RFCOMM_OPEN_EVT -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvRfcommConnect(tBTA_SEC sec_mask, - tBTA_JV_ROLE role, UINT8 remote_scn, BD_ADDR peer_bd_addr, - tBTA_JV_RFCOMM_CBACK *p_cback, void *user_data); - -/******************************************************************************* -** -** Function BTA_JvRfcommClose -** -** Description This function closes an RFCOMM connection -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvRfcommClose(UINT32 handle, void *user_data); - -/******************************************************************************* -** -** Function BTA_JvRfcommStartServer -** -** Description This function starts listening for an RFCOMM connection -** request from a remote Bluetooth device. When the server is -** started successfully, tBTA_JV_RFCOMM_CBACK is called -** with BTA_JV_RFCOMM_START_EVT. -** When the connection is established, tBTA_JV_RFCOMM_CBACK -** is called with BTA_JV_RFCOMM_OPEN_EVT. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvRfcommStartServer(tBTA_SEC sec_mask, - tBTA_JV_ROLE role, UINT8 local_scn, UINT8 max_session, - tBTA_JV_RFCOMM_CBACK *p_cback, void *user_data); - -/******************************************************************************* -** -** Function BTA_JvRfcommStopServer -** -** Description This function stops the RFCOMM server. If the server has an -** active connection, it would be closed. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvRfcommStopServer(UINT32 handle, void *user_data); - -/******************************************************************************* -** -** Function BTA_JvRfcommRead -** -** Description This function reads data from an RFCOMM connection -** When the operation is complete, tBTA_JV_RFCOMM_CBACK is -** called with BTA_JV_RFCOMM_READ_EVT. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvRfcommRead(UINT32 handle, UINT32 req_id, - UINT8 *p_data, UINT16 len); - -/******************************************************************************* -** -** Function BTA_JvRfcommReady -** -** Description This function determined if there is data to read from -** an RFCOMM connection -** -** Returns BTA_JV_SUCCESS, if data queue size is in *p_data_size. -** BTA_JV_FAILURE, if error. -** -*******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvRfcommReady(UINT32 handle, UINT32 *p_data_size); - -/******************************************************************************* -** -** Function BTA_JvRfcommWrite -** -** Description This function writes data to an RFCOMM connection -** When the operation is complete, tBTA_JV_RFCOMM_CBACK is -** called with BTA_JV_RFCOMM_WRITE_EVT. -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -// extern tBTA_JV_STATUS BTA_JvRfcommWrite(UINT32 handle, UINT32 req_id); -extern tBTA_JV_STATUS BTA_JvRfcommWrite(UINT32 handle, UINT32 req_id, int len, UINT8 *p_data); - -/******************************************************************************* - ** - ** Function BTA_JVSetPmProfile - ** - ** Description This function set or free power mode profile for different JV application - ** - ** Parameters: handle, JV handle from RFCOMM or L2CAP - ** app_id: app specific pm ID, can be BTA_JV_PM_ALL, see bta_dm_cfg.c for details - ** BTA_JV_PM_ID_CLEAR: removes pm management on the handle. init_st is ignored and - ** BTA_JV_CONN_CLOSE is called implicitely - ** init_st: state after calling this API. typically it should be BTA_JV_CONN_OPEN - ** - ** Returns BTA_JV_SUCCESS, if the request is being processed. - ** BTA_JV_FAILURE, otherwise. - ** - ** NOTE: BTA_JV_PM_ID_CLEAR: In general no need to be called as jv pm calls automatically - ** BTA_JV_CONN_CLOSE to remove in case of connection close! - ** - *******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvSetPmProfile(UINT32 handle, tBTA_JV_PM_ID app_id, - tBTA_JV_CONN_STATE init_st); - -/******************************************************************************* -** -** Function BTA_JvRfcommGetPortHdl -** -** Description This function fetches the rfcomm port handle -** -** Returns BTA_JV_SUCCESS, if the request is being processed. -** BTA_JV_FAILURE, otherwise. -** -*******************************************************************************/ -UINT16 BTA_JvRfcommGetPortHdl(UINT32 handle); - -#endif ///defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE -#endif /* BTA_JV_API_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_jv_co.h b/tools/sdk/include/bluedroid/bta/bta_jv_co.h deleted file mode 100644 index b37625cf..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_jv_co.h +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2007-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the interface file for java interface call-out functions. - * - ******************************************************************************/ -#ifndef BTA_JV_CO_H -#define BTA_JV_CO_H - -#include "bta/bta_jv_api.h" - -#if (defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE) -/***************************************************************************** -** Function Declarations -*****************************************************************************/ - - -/******************************************************************************* -** -** Function bta_jv_co_rfc_data -** -** Description This function is called by JV to send data to the java glue -** code when the RX data path is configured to use a call-out -** -** Returns void -** -*******************************************************************************/ - -extern int bta_co_rfc_data_incoming(void *user_data, BT_HDR *p_buf); -extern int bta_co_rfc_data_outgoing_size(void *user_data, int *size); -extern int bta_co_rfc_data_outgoing(void *user_data, UINT8 *buf, UINT16 size); - -extern int bta_co_l2cap_data_incoming(void *user_data, BT_HDR *p_buf); -extern int bta_co_l2cap_data_outgoing_size(void *user_data, int *size); -extern int bta_co_l2cap_data_outgoing(void *user_data, UINT8 *buf, UINT16 size); - -#endif ///defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE -#endif /* BTA_DG_CO_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_sdp_api.h b/tools/sdk/include/bluedroid/bta/bta_sdp_api.h deleted file mode 100644 index b88c0c26..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_sdp_api.h +++ /dev/null @@ -1,147 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the public interface file for the BTA SDP I/F - * - ******************************************************************************/ -#ifndef BTA_SDP_API_H -#define BTA_SDP_API_H - -#include "bt_sdp.h" -#include "common/bt_target.h" -#include "stack/bt_types.h" -#include "bta/bta_api.h" -#include "stack/btm_api.h" - -#if (SDP_INCLUDED == TRUE) -/* status values */ -#define BTA_SDP_SUCCESS 0 /* Successful operation. */ -#define BTA_SDP_FAILURE 1 /* Generic failure. */ -#define BTA_SDP_BUSY 2 /* Temporarily can not handle this request. */ - -typedef UINT8 tBTA_SDP_STATUS; - -/* SDP I/F callback events */ -/* events received by tBTA_SDP_DM_CBACK */ -#define BTA_SDP_ENABLE_EVT 0 /* SDP service i/f enabled*/ -#define BTA_SDP_SEARCH_EVT 1 /* SDP Service started */ -#define BTA_SDP_SEARCH_COMP_EVT 2 /* SDP search complete */ -#define BTA_SDP_CREATE_RECORD_USER_EVT 3 /* SDP search complete */ -#define BTA_SDP_REMOVE_RECORD_USER_EVT 4 /* SDP search complete */ -#define BTA_SDP_MAX_EVT 5 /* max number of SDP events */ - -#define BTA_SDP_MAX_RECORDS 15 - -typedef UINT16 tBTA_SDP_EVT; - -/* data associated with BTA_SDP_DISCOVERY_COMP_EVT */ -typedef struct { - tBTA_SDP_STATUS status; - BD_ADDR remote_addr; - tBT_UUID uuid; - int record_count; - bluetooth_sdp_record records[BTA_SDP_MAX_RECORDS]; -} tBTA_SDP_SEARCH_COMP; - -typedef union { - tBTA_SDP_STATUS status; /* BTA_SDP_SEARCH_EVT */ - tBTA_SDP_SEARCH_COMP sdp_search_comp; /* BTA_SDP_SEARCH_COMP_EVT */ -} tBTA_SDP; - -/* SDP DM Interface callback */ -typedef void (tBTA_SDP_DM_CBACK)(tBTA_SDP_EVT event, tBTA_SDP *p_data, void *user_data); - -/* MCE configuration structure */ -typedef struct { - UINT16 sdp_db_size; /* The size of p_sdp_db */ -#if (SDP_INCLUDED == TRUE) - tSDP_DISCOVERY_DB *p_sdp_db; /* The data buffer to keep SDP database */ -#endif ///SDP_INCLUDED == TRUE -} tBTA_SDP_CFG; - -#ifdef __cplusplus -extern "C" -{ -#endif -/******************************************************************************* -** -** Function BTA_SdpEnable -** -** Description Enable the SDP I/F service. When the enable -** operation is complete the callback function will be -** called with a BTA_SDP_ENABLE_EVT. This function must -** be called before other functions in the MCE API are -** called. -** -** Returns BTA_SDP_SUCCESS if successful. -** BTA_SDP_FAIL if internal failure. -** -*******************************************************************************/ -extern tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback); - -/******************************************************************************* -** -** Function BTA_SdpSearch -** -** Description Start a search for sdp records for a specific BD_ADDR with a -** specific profile uuid. -** When the search operation is completed, the callback function -** will be called with a BTA_SDP_SEARCH_EVT. -** Returns BTA_SDP_SUCCESS if successful. -** BTA_SDP_FAIL if internal failure. -** -*******************************************************************************/ -extern tBTA_SDP_STATUS BTA_SdpSearch(BD_ADDR bd_addr, tSDP_UUID *uuid); - -/******************************************************************************* -** -** Function BTA_SdpCreateRecordByUser -** -** Description This function is used to request a callback to create a SDP -** record. The registered callback will be called with event -** BTA_SDP_CREATE_RECORD_USER_EVT. -** -** Returns BTA_SDP_SUCCESS, if the request is being processed. -** BTA_SDP_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_SDP_STATUS BTA_SdpCreateRecordByUser(void *user_data); - -/******************************************************************************* -** -** Function BTA_SdpRemoveRecordByUser -** -** Description This function is used to request a callback to remove a SDP -** record. The registered callback will be called with event -** BTA_SDP_REMOVE_RECORD_USER_EVT. -** -** Returns BTA_SDP_SUCCESS, if the request is being processed. -** BTA_SDP_FAILURE, otherwise. -** -*******************************************************************************/ -extern tBTA_SDP_STATUS BTA_SdpRemoveRecordByUser(void *user_data); - -#ifdef __cplusplus -} -#endif - -#endif ///SDP_INCLUDED == TRUE - -#endif /* BTA_SDP_API_H */ diff --git a/tools/sdk/include/bluedroid/bta/bta_sys.h b/tools/sdk/include/bluedroid/bta/bta_sys.h deleted file mode 100644 index a58773de..00000000 --- a/tools/sdk/include/bluedroid/bta/bta_sys.h +++ /dev/null @@ -1,283 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2003-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the public interface file for the BTA system manager. - * - ******************************************************************************/ -#ifndef BTA_SYS_H -#define BTA_SYS_H - -#include "common/bt_target.h" -#include "common/bt_defs.h" - -/***************************************************************************** -** Constants and data types -*****************************************************************************/ - -/* vendor specific event handler function type */ -typedef BOOLEAN (tBTA_SYS_VS_EVT_HDLR)(UINT16 evt, void *p); - -/* event handler function type */ -typedef BOOLEAN (tBTA_SYS_EVT_HDLR)(BT_HDR *p_msg); - -/* disable function type */ -typedef void (tBTA_SYS_DISABLE)(void); - - -/* HW modules */ -enum { - BTA_SYS_HW_BLUETOOTH, - BTA_SYS_HW_RT, - - BTA_SYS_MAX_HW_MODULES -}; - -typedef UINT16 tBTA_SYS_HW_MODULE; - -#ifndef BTA_DM_NUM_JV_ID -#define BTA_DM_NUM_JV_ID 2 -#endif - -/* SW sub-systems */ -#define BTA_ID_SYS 0 /* system manager */ -/* BLUETOOTH PART - from 0 to BTA_ID_BLUETOOTH_MAX */ -#define BTA_ID_DM 1 /* device manager */ -#define BTA_ID_DM_SEARCH 2 /* device manager search */ -#define BTA_ID_DM_SEC 3 /* device manager security */ -#define BTA_ID_DG 4 /* data gateway */ -#define BTA_ID_AG 5 /* audio gateway */ -#define BTA_ID_OPC 6 /* object push client */ -#define BTA_ID_OPS 7 /* object push server */ -#define BTA_ID_FTS 8 /* file transfer server */ -#define BTA_ID_CT 9 /* cordless telephony terminal */ -#define BTA_ID_FTC 10 /* file transfer client */ -#define BTA_ID_SS 11 /* synchronization server */ -#define BTA_ID_PR 12 /* Printer client */ -#define BTA_ID_BIC 13 /* Basic Imaging Client */ -#define BTA_ID_PAN 14 /* Personal Area Networking */ -#define BTA_ID_BIS 15 /* Basic Imaging Server */ -#define BTA_ID_ACC 16 /* Advanced Camera Client */ -#define BTA_ID_SC 17 /* SIM Card Access server */ -#define BTA_ID_AV 18 /* Advanced audio/video */ -#define BTA_ID_AVK 19 /* Audio/video sink */ -#define BTA_ID_HD 20 /* HID Device */ -#define BTA_ID_CG 21 /* Cordless Gateway */ -#define BTA_ID_BP 22 /* Basic Printing Client */ -#define BTA_ID_HH 23 /* Human Interface Device Host */ -#define BTA_ID_PBS 24 /* Phone Book Access Server */ -#define BTA_ID_PBC 25 /* Phone Book Access Client */ -#define BTA_ID_JV 26 /* Java */ -#define BTA_ID_HS 27 /* Headset */ -#define BTA_ID_MSE 28 /* Message Server Equipment */ -#define BTA_ID_MCE 29 /* Message Client Equipment */ -#define BTA_ID_HL 30 /* Health Device Profile*/ -#define BTA_ID_GATTC 31 /* GATT Client */ -#define BTA_ID_GATTS 32 /* GATT Client */ -#define BTA_ID_SDP 33 /* SDP Client */ -#define BTA_ID_BLUETOOTH_MAX 34 /* last BT profile */ - -/* GENERIC */ -#define BTA_ID_PRM 38 -#define BTA_ID_SYSTEM 39 /* platform-specific */ -#define BTA_ID_SWRAP 40 /* Insight script wrapper */ -#define BTA_ID_MIP 41 /* Multicase Individual Polling */ -#define BTA_ID_RT 42 /* Audio Routing module: This module is always on. */ - - -/* JV */ -#define BTA_ID_JV1 44 /* JV1 */ -#define BTA_ID_JV2 45 /* JV2 */ - -#define BTA_ID_MAX (44 + BTA_DM_NUM_JV_ID) - -typedef UINT8 tBTA_SYS_ID; - - -#define BTA_SYS_CONN_OPEN 0x00 -#define BTA_SYS_CONN_CLOSE 0x01 -#define BTA_SYS_APP_OPEN 0x02 -#define BTA_SYS_APP_CLOSE 0x03 -#define BTA_SYS_SCO_OPEN 0x04 -#define BTA_SYS_SCO_CLOSE 0x05 -#define BTA_SYS_CONN_IDLE 0x06 -#define BTA_SYS_CONN_BUSY 0x07 - -/* for link policy */ -#define BTA_SYS_PLCY_SET 0x10 /* set the link policy to the given addr */ -#define BTA_SYS_PLCY_CLR 0x11 /* clear the link policy to the given addr */ -#define BTA_SYS_PLCY_DEF_SET 0x12 /* set the default link policy */ -#define BTA_SYS_PLCY_DEF_CLR 0x13 /* clear the default link policy */ -#define BTA_SYS_ROLE_CHANGE 0x14 /* role change */ - -typedef UINT8 tBTA_SYS_CONN_STATUS; - -/* Bitmask of sys features */ -#define BTA_SYS_FEAT_PCM2 0x0001 -#define BTA_SYS_FEAT_PCM2_MASTER 0x0002 - -/* tBTA_PREF_ROLES */ -typedef UINT8 tBTA_SYS_PREF_ROLES; - -/* conn callback for role / low power manager*/ -typedef void (tBTA_SYS_CONN_CBACK)(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr); - -/* conn callback for role / low power manager*/ -typedef void (tBTA_SYS_SSR_CFG_CBACK)(UINT8 id, UINT8 app_id, UINT16 latency, UINT16 tout); - -#if (BTA_EIR_CANNED_UUID_LIST != TRUE) -/* eir callback for adding/removeing UUID */ -typedef void (tBTA_SYS_EIR_CBACK)(UINT16 uuid16, BOOLEAN adding); -#endif - -/* registration structure */ -typedef struct { - tBTA_SYS_EVT_HDLR *evt_hdlr; - tBTA_SYS_DISABLE *disable; -} tBTA_SYS_REG; - -/* data type to send events to BTA SYS HW manager */ -typedef struct { - BT_HDR hdr; - tBTA_SYS_HW_MODULE hw_module; -} tBTA_SYS_HW_MSG; - -/***************************************************************************** -** Global data -*****************************************************************************/ - -/* trace level */ -extern UINT8 appl_trace_level; - -/***************************************************************************** -** Macros -*****************************************************************************/ - -/* Calculate start of event enumeration; id is top 8 bits of event */ -#define BTA_SYS_EVT_START(id) ((id) << 8) - -/***************************************************************************** -** events for BTA SYS HW manager -*****************************************************************************/ - -/* events sent to SYS HW manager - must be kept synchronized with tables in bta_sys_main.c */ -enum { - /* device manager local device API events */ - BTA_SYS_API_ENABLE_EVT = BTA_SYS_EVT_START(BTA_ID_SYS), - BTA_SYS_EVT_ENABLED_EVT, - BTA_SYS_EVT_STACK_ENABLED_EVT, - BTA_SYS_API_DISABLE_EVT, - BTA_SYS_EVT_DISABLED_EVT, - BTA_SYS_ERROR_EVT, - - BTA_SYS_MAX_EVT -}; - - - -/* SYS HW status events - returned by SYS HW manager to other modules. */ -enum { - BTA_SYS_HW_OFF_EVT, - BTA_SYS_HW_ON_EVT, - BTA_SYS_HW_STARTING_EVT, - BTA_SYS_HW_STOPPING_EVT, - BTA_SYS_HW_ERROR_EVT - -}; -typedef UINT8 tBTA_SYS_HW_EVT; - -/* HW enable callback type */ -typedef void (tBTA_SYS_HW_CBACK)(tBTA_SYS_HW_EVT status); - -/***************************************************************************** -** Function declarations -*****************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -extern void bta_sys_init(void); -extern void bta_sys_free(void); -extern void bta_sys_event(BT_HDR *p_msg); -extern void bta_sys_set_trace_level(UINT8 level); -extern void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg); -extern void bta_sys_deregister(UINT8 id); -extern BOOLEAN bta_sys_is_register(UINT8 id); -extern UINT16 bta_sys_get_sys_features(void); -extern void bta_sys_sendmsg(void *p_msg); -extern void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms); -extern void bta_sys_stop_timer(TIMER_LIST_ENT *p_tle); -extern void bta_sys_free_timer(TIMER_LIST_ENT *p_tle); -extern void bta_sys_disable(tBTA_SYS_HW_MODULE module); -extern UINT32 bta_sys_get_remaining_ticks(TIMER_LIST_ENT *p_target_tle); - -extern void bta_sys_hw_register( tBTA_SYS_HW_MODULE module, tBTA_SYS_HW_CBACK *cback); -extern void bta_sys_hw_unregister( tBTA_SYS_HW_MODULE module ); - - -extern void bta_sys_rm_register(tBTA_SYS_CONN_CBACK *p_cback); -extern void bta_sys_pm_register(tBTA_SYS_CONN_CBACK *p_cback); - -extern void bta_sys_policy_register(tBTA_SYS_CONN_CBACK *p_cback); -extern void bta_sys_sco_register(tBTA_SYS_CONN_CBACK *p_cback); - - -extern void bta_sys_conn_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr); -extern void bta_sys_conn_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr); -extern void bta_sys_app_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr); -extern void bta_sys_app_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr); -extern void bta_sys_sco_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr); -extern void bta_sys_sco_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr); -extern void bta_sys_sco_use(UINT8 id, UINT8 app_id, BD_ADDR peer_addr); -extern void bta_sys_sco_unuse(UINT8 id, UINT8 app_id, BD_ADDR peer_addr); -extern void bta_sys_idle(UINT8 id, UINT8 app_id, BD_ADDR peer_addr); -extern void bta_sys_busy(UINT8 id, UINT8 app_id, BD_ADDR peer_addr); - -#if (BTM_SSR_INCLUDED == TRUE) -extern void bta_sys_ssr_cfg_register(tBTA_SYS_SSR_CFG_CBACK *p_cback); -extern void bta_sys_chg_ssr_config (UINT8 id, UINT8 app_id, UINT16 max_latency, UINT16 min_tout); -#endif - -extern void bta_sys_role_chg_register(tBTA_SYS_CONN_CBACK *p_cback); -extern void bta_sys_notify_role_chg(BD_ADDR_PTR p_bda, UINT8 new_role, UINT8 hci_status); -extern void bta_sys_collision_register(UINT8 bta_id, tBTA_SYS_CONN_CBACK *p_cback); -extern void bta_sys_notify_collision (BD_ADDR_PTR p_bda); - -#if (BTA_EIR_CANNED_UUID_LIST != TRUE) -extern void bta_sys_eir_register(tBTA_SYS_EIR_CBACK *p_cback); -extern void bta_sys_add_uuid(UINT16 uuid16); -extern void bta_sys_remove_uuid(UINT16 uuid16); -#else -#define bta_sys_eir_register(ut) -#define bta_sys_add_uuid(ut) -#define bta_sys_remove_uuid(ut) -#endif - -extern void bta_sys_set_policy (UINT8 id, UINT8 policy, BD_ADDR peer_addr); -extern void bta_sys_clear_policy (UINT8 id, UINT8 policy, BD_ADDR peer_addr); -extern void bta_sys_set_default_policy (UINT8 id, UINT8 policy); -extern void bta_sys_clear_default_policy (UINT8 id, UINT8 policy); -extern BOOLEAN bta_sys_vs_hdl(UINT16 evt, void *p); - -#ifdef __cplusplus -} -#endif - -#endif /* BTA_SYS_H */ diff --git a/tools/sdk/include/bluedroid/bta/utl.h b/tools/sdk/include/bluedroid/bta/utl.h deleted file mode 100644 index a140832f..00000000 --- a/tools/sdk/include/bluedroid/bta/utl.h +++ /dev/null @@ -1,184 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2003-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Basic utility functions. - * - ******************************************************************************/ -#ifndef UTL_H -#define UTL_H - -#include "stack/bt_types.h" -// #include "bt_utils.h" - -/***************************************************************************** -** Constants -*****************************************************************************/ -/*** class of device settings ***/ -#define BTA_UTL_SET_COD_MAJOR_MINOR 0x01 -#define BTA_UTL_SET_COD_SERVICE_CLASS 0x02 /* only set the bits in the input */ -#define BTA_UTL_CLR_COD_SERVICE_CLASS 0x04 -#define BTA_UTL_SET_COD_ALL 0x08 /* take service class as the input (may clear some set bits!!) */ -#define BTA_UTL_INIT_COD 0x0a - -/***************************************************************************** -** Type Definitions -*****************************************************************************/ - -/** for utl_set_device_class() **/ -typedef struct { - UINT8 minor; - UINT8 major; - UINT16 service; -} tBTA_UTL_COD; - - -#ifdef __cplusplus -extern "C" -{ -#endif - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ - -/******************************************************************************* -** -** Function utl_str2int -** -** Description This utility function converts a character string to an -** integer. Acceptable values in string are 0-9. If invalid -** string or string value too large, -1 is returned. -** -** -** Returns Integer value or -1 on error. -** -*******************************************************************************/ -extern INT16 utl_str2int(const char *p_s); - -/******************************************************************************* -** -** Function utl_strucmp -** -** Description This utility function compares two strings in uppercase. -** String p_s must be uppercase. String p_t is converted to -** uppercase if lowercase. If p_s ends first, the substring -** match is counted as a match. -** -** -** Returns 0 if strings match, nonzero otherwise. -** -*******************************************************************************/ -extern int utl_strucmp(const char *p_s, const char *p_t); - -/******************************************************************************* -** -** Function utl_itoa -** -** Description This utility function converts a UINT16 to a string. The -** string is NULL-terminated. The length of the string is -** returned. -** -** -** Returns Length of string. -** -*******************************************************************************/ -extern UINT8 utl_itoa(UINT16 i, char *p_s); - -/******************************************************************************* -** -** Function utl_freebuf -** -** Description This function calls osi_free to free the buffer passed -** in, if buffer pointer is not NULL, and also initializes -** buffer pointer to NULL. -** -** -** Returns Nothing. -** -*******************************************************************************/ -extern void utl_freebuf(void **p); - -/******************************************************************************* -** -** Function utl_set_device_class -** -** Description This function updates the local Device Class. -** -** Parameters: -** p_cod - Pointer to the device class to set to -** -** cmd - the fields of the device class to update. -** BTA_UTL_SET_COD_MAJOR_MINOR, - overwrite major, minor class -** BTA_UTL_SET_COD_SERVICE_CLASS - set the bits in the input -** BTA_UTL_CLR_COD_SERVICE_CLASS - clear the bits in the input -** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class -** BTA_UTL_INIT_COD - overwrite major, minor, and service class -** -** Returns TRUE if successful, Otherwise FALSE -** -*******************************************************************************/ -extern BOOLEAN utl_set_device_class(tBTA_UTL_COD *p_cod, UINT8 cmd); - -/******************************************************************************* -** -** Function utl_get_device_class -** -** Description This function get the local Device Class. -** -** Parameters: -** p_cod - Pointer to the device class to get to -** -** -** Returns TRUE if successful, Otherwise FALSE -** -*******************************************************************************/ -extern BOOLEAN utl_get_device_class(tBTA_UTL_COD *p_cod); - -/******************************************************************************* -** -** Function utl_isintstr -** -** Description This utility function checks if the given string is an -** integer string or not -** -** -** Returns TRUE if successful, Otherwise FALSE -** -*******************************************************************************/ -extern BOOLEAN utl_isintstr(const char *p_s); - -/******************************************************************************* -** -** Function utl_isdialstr -** -** Description This utility function checks if the given string contains -** only dial digits or not -** -** -** Returns TRUE if successful, Otherwise FALSE -** -*******************************************************************************/ -extern BOOLEAN utl_isdialstr(const char *p_s); - -#ifdef __cplusplus -} -#endif - -#endif /* UTL_H */ diff --git a/tools/sdk/include/bluedroid/bta_sys_int.h b/tools/sdk/include/bluedroid/bta_sys_int.h deleted file mode 100644 index aa2596d9..00000000 --- a/tools/sdk/include/bluedroid/bta_sys_int.h +++ /dev/null @@ -1,101 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2003-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the private interface file for the BTA system manager. - * - ******************************************************************************/ -#ifndef BTA_SYS_INT_H -#define BTA_SYS_INT_H - -/***************************************************************************** -** Constants and data types -*****************************************************************************/ - -/***************************************************************************** -** state table -*****************************************************************************/ - -/* SYS HW state */ -enum { - BTA_SYS_HW_OFF, - BTA_SYS_HW_STARTING, - BTA_SYS_HW_ON, - BTA_SYS_HW_STOPPING -}; -typedef UINT8 tBTA_SYS_HW_STATE; - -/* Collision callback */ -#define MAX_COLLISION_REG 5 - -typedef struct { - UINT8 id[MAX_COLLISION_REG]; - tBTA_SYS_CONN_CBACK *p_coll_cback[MAX_COLLISION_REG]; -} tBTA_SYS_COLLISION; - -/* system manager control block */ -typedef struct { - tBTA_SYS_REG *reg[BTA_ID_MAX]; /* registration structures */ - BOOLEAN is_reg[BTA_ID_MAX]; /* registration structures */ - tBTA_SYS_HW_STATE state; - tBTA_SYS_HW_CBACK *sys_hw_cback[BTA_SYS_MAX_HW_MODULES]; /* enable callback for each HW modules */ - UINT32 sys_hw_module_active; /* bitmask of all active modules */ - UINT16 sys_features; /* Bitmask of sys features */ - - tBTA_SYS_CONN_CBACK *prm_cb; /* role management callback registered by DM */ - tBTA_SYS_CONN_CBACK *ppm_cb; /* low power management callback registered by DM */ - tBTA_SYS_CONN_CBACK *p_policy_cb; /* link policy change callback registered by DM */ - tBTA_SYS_CONN_CBACK *p_sco_cb; /* SCO connection change callback registered by AV */ - tBTA_SYS_CONN_CBACK *p_role_cb; /* role change callback registered by AV */ - tBTA_SYS_COLLISION colli_reg; /* collision handling module */ -#if (BTA_EIR_CANNED_UUID_LIST != TRUE) - tBTA_SYS_EIR_CBACK *eir_cb; /* add/remove UUID into EIR */ -#endif -#if (BTM_SSR_INCLUDED == TRUE) - tBTA_SYS_SSR_CFG_CBACK *p_ssr_cb; -#endif - /* VS event handler */ - tBTA_SYS_VS_EVT_HDLR *p_vs_evt_hdlr; - -} tBTA_SYS_CB; - -/***************************************************************************** -** Global variables -*****************************************************************************/ - -/* system manager control block */ -#if BTA_DYNAMIC_MEMORY == FALSE -extern tBTA_SYS_CB bta_sys_cb; -#else -extern tBTA_SYS_CB *bta_sys_cb_ptr; -#define bta_sys_cb (*bta_sys_cb_ptr) -#endif - -/* functions used for BTA SYS HW state machine */ -void bta_sys_hw_btm_cback( tBTM_DEV_STATUS status ); -void bta_sys_hw_error(tBTA_SYS_HW_MSG *p_sys_hw_msg); -void bta_sys_hw_api_enable( tBTA_SYS_HW_MSG *p_sys_hw_msg ); -void bta_sys_hw_api_disable(tBTA_SYS_HW_MSG *p_sys_hw_msg); -void bta_sys_hw_evt_enabled(tBTA_SYS_HW_MSG *p_sys_hw_msg); -void bta_sys_hw_evt_disabled(tBTA_SYS_HW_MSG *p_sys_hw_msg); -void bta_sys_hw_evt_stack_enabled(tBTA_SYS_HW_MSG *p_sys_hw_msg); - -BOOLEAN bta_sys_sm_execute(BT_HDR *p_msg); - -#endif /* BTA_SYS_INT_H */ diff --git a/tools/sdk/include/bluedroid/btc/btc_ble_storage.h b/tools/sdk/include/bluedroid/btc/btc_ble_storage.h deleted file mode 100644 index 9b336815..00000000 --- a/tools/sdk/include/bluedroid/btc/btc_ble_storage.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (C) 2014 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#ifndef __BTC_BLE_STORAGE_H__ -#define __BTC_BLE_STORAGE_H__ -#include "stack/bt_types.h" -#include "common/bt_target.h" -#include "esp_gap_ble_api.h" - -#if (SMP_INCLUDED == TRUE) -#define BTC_LE_LOCAL_KEY_IR (1<<0) -#define BTC_LE_LOCAL_KEY_IRK (1<<1) -#define BTC_LE_LOCAL_KEY_DHK (1<<2) -#define BTC_LE_LOCAL_KEY_ER (1<<3) - -#define BTC_BLE_STORAGE_DEV_TYPE_STR "DevType" -#define BTC_BLE_STORAGE_ADDR_TYPE_STR "AddrType" -#define BTC_BLE_STORAGE_LINK_KEY_STR "LinkKey" -#define BTC_BLE_STORAGE_LE_KEY_PENC_STR "LE_KEY_PENC" -#define BTC_BLE_STORAGE_LE_KEY_PID_STR "LE_KEY_PID" -#define BTC_BLE_STORAGE_LE_KEY_PCSRK_STR "LE_KEY_PCSRK" -#define BTC_BLE_STORAGE_LE_KEY_LENC_STR "LE_KEY_LENC" -#define BTC_BLE_STORAGE_LE_KEY_LID_STR "LE_KEY_LID" -#define BTC_BLE_STORAGE_LE_KEY_LCSRK_STR "LE_KEY_LCSRK" - -#define BTC_BLE_STORAGE_LOCAL_ADAPTER_STR "Adapter" -#define BTC_BLE_STORAGE_LE_LOCAL_KEY_IR_STR "LE_LOCAL_KEY_IR" -#define BTC_BLE_STORAGE_LE_LOCAL_KEY_IRK_STR "LE_LOCAL_KEY_IRK" -#define BTC_BLE_STORAGE_LE_LOCAL_KEY_DHK_STR "LE_LOCAL_KEY_DHK" -#define BTC_BLE_STORAGE_LE_LOCAL_KEY_ER_STR "LE_LOCAL_KEY_ER" - -/************************************************************************************ -** Local type definitions -************************************************************************************/ -typedef struct -{ - BT_OCTET16 sp_c; - BT_OCTET16 sp_r; - BD_ADDR oob_bdaddr; /* peer bdaddr*/ -} btc_dm_oob_cb_t; - - -void btc_storage_save(void); - -bt_status_t btc_storage_add_ble_bonding_key( bt_bdaddr_t *remote_bd_addr, char *key, uint8_t key_type, uint8_t key_length); - -bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, uint8_t key_type, char *key_value, int key_length); - -bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr); - -bool btc_storage_compare_address_key_value(bt_bdaddr_t *remote_bd_addr, uint8_t key_type, void *key_value, int key_length); - -bt_status_t btc_storage_add_ble_local_key(char *key, uint8_t key_type, uint8_t key_length); - -bt_status_t btc_storage_remove_ble_local_keys(void); - -bt_status_t btc_storage_get_ble_local_key(uint8_t key_type, char *key_value, int key_len); - -bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr, int *addr_type); - -bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, uint8_t addr_type, bool flush); - -bt_status_t btc_storage_remove_remote_addr_type(bt_bdaddr_t *remote_bd_addr, bool flush); - -bt_status_t btc_storage_set_ble_dev_type(bt_bdaddr_t *bd_addr, bool flush); - -bt_status_t btc_storage_remove_ble_dev_type(bt_bdaddr_t *remote_bd_addr, bool flush); - -bt_status_t btc_storage_load_bonded_ble_devices(void); - -bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev, int dev_num); - -int btc_storage_get_num_ble_bond_devices(void); - -#endif ///SMP_INCLUDED == TRUE -#endif ///__BTC_BLE_STORAGE_H__ diff --git a/tools/sdk/include/bluedroid/btc/btc_common.h b/tools/sdk/include/bluedroid/btc/btc_common.h deleted file mode 100644 index ae4501b5..00000000 --- a/tools/sdk/include/bluedroid/btc/btc_common.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -#ifndef __BTC_COMMON_H__ -#define __BTC_COMMON_H__ - -#include "common/bt_trace.h" -#include "stack/bt_types.h" -#include "osi/osi.h" - -#define BTC_ASSERTC(cond, msg, val) if (!(cond)) { LOG_ERROR( \ - "### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, val);} - -#define BTC_HAL_CBACK(P_CB, P_CBACK, ...)\ - if (P_CB && P_CB->P_CBACK) { \ - LOG_INFO("HAL %s->%s", #P_CB, #P_CBACK); \ - P_CB->P_CBACK(__VA_ARGS__); \ - } \ - else { \ - BTC_ASSERTC(0, "Callback is NULL", 0); \ - } - -#endif /* __BTC_COMMON_H__ */ diff --git a/tools/sdk/include/bluedroid/btc/btc_config.h b/tools/sdk/include/bluedroid/btc/btc_config.h deleted file mode 100644 index 6aec264b..00000000 --- a/tools/sdk/include/bluedroid/btc/btc_config.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_CONFIG_H__ -#define __BTC_CONFIG_H__ - -#include -#include - -#include "stack/bt_types.h" - -typedef struct btc_config_section_iter_t btc_config_section_iter_t; - -bool btc_config_init(void); -bool btc_config_shut_down(void); -bool btc_config_clean_up(void); - -bool btc_config_has_section(const char *section); -bool btc_config_exist(const char *section, const char *key); -bool btc_config_get_int(const char *section, const char *key, int *value); -bool btc_config_set_int(const char *section, const char *key, int value); -bool btc_config_get_str(const char *section, const char *key, char *value, int *size_bytes); -bool btc_config_set_str(const char *section, const char *key, const char *value); -bool btc_config_get_bin(const char *section, const char *key, uint8_t *value, size_t *length); -bool btc_config_set_bin(const char *section, const char *key, const uint8_t *value, size_t length); -bool btc_config_remove(const char *section, const char *key); -bool btc_config_remove_section(const char *section); - -size_t btc_config_get_bin_length(const char *section, const char *key); - -const btc_config_section_iter_t *btc_config_section_begin(void); -const btc_config_section_iter_t *btc_config_section_end(void); -const btc_config_section_iter_t *btc_config_section_next(const btc_config_section_iter_t *section); -const char *btc_config_section_name(const btc_config_section_iter_t *section); - -void btc_config_flush(void); -int btc_config_clear(void); - -// TODO(zachoverflow): Eww...we need to move these out. These are peer specific, not config general. -bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type); -bool btc_compare_address_key_value(const char *section, const char *key_type, void *key_value, int key_length); -bool btc_get_device_type(const BD_ADDR bd_addr, int *p_device_type); - -void btc_config_lock(void); -void btc_config_unlock(void); - -#endif diff --git a/tools/sdk/include/bluedroid/btc/btc_dm.h b/tools/sdk/include/bluedroid/btc/btc_dm.h deleted file mode 100644 index b6e7741e..00000000 --- a/tools/sdk/include/bluedroid/btc/btc_dm.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_DM_H__ -#define __BTC_DM_H__ - -#include "btc/btc_task.h" -#include "esp_bt_defs.h" -#include "bta/bta_api.h" - -typedef enum { - BTC_DM_SEC_ACT -} btc_dm_sec_act_t; - -/* btc_dm_args_t */ -typedef union { - //BTC_DM_SEC_ACT - tBTA_DM_SEC sec; -} btc_dm_sec_args_t; - -typedef struct -{ - bool is_penc_key_rcvd; - tBTM_LE_PENC_KEYS penc_key; /* received peer encryption key */ - bool is_pcsrk_key_rcvd; - tBTM_LE_PCSRK_KEYS pcsrk_key; /* received peer device SRK */ - bool is_pid_key_rcvd; - tBTM_LE_PID_KEYS pid_key; /* peer device ID key */ - bool is_lenc_key_rcvd; - tBTM_LE_LENC_KEYS lenc_key; /* local encryption reproduction keys LTK = = d1(ER,DIV,0)*/ - bool is_lcsrk_key_rcvd; - tBTM_LE_LCSRK_KEYS lcsrk_key; /* local device CSRK = d1(ER,DIV,1)*/ - bool is_lidk_key_rcvd; /* local identity key received */ -} btc_dm_ble_cb_t; - -typedef struct -{ - bt_bdaddr_t static_bdaddr; - BD_ADDR bd_addr; - btc_dm_ble_cb_t ble; -} btc_dm_pairing_cb_t; - -typedef struct -{ - uint8_t ir[BT_OCTET16_LEN]; - uint8_t irk[BT_OCTET16_LEN]; - uint8_t dhk[BT_OCTET16_LEN]; -} btc_dm_local_key_id_t; - -typedef struct -{ - bool is_er_rcvd; - uint8_t er[BT_OCTET16_LEN]; - bool is_id_keys_rcvd; - btc_dm_local_key_id_t id_keys; /* ID kyes */ -} btc_dm_local_key_cb_t; - - - -// void btc_dm_call_handler(btc_msg_t *msg); -void btc_dm_sec_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *data); -void btc_dm_sec_cb_handler(btc_msg_t *msg); -void btc_dm_sec_arg_deep_copy(btc_msg_t *msg, void *dst, void *src); - -bt_status_t btc_dm_enable_service(tBTA_SERVICE_ID service_id); -bt_status_t btc_dm_disable_service(tBTA_SERVICE_ID service_id); - -#if (SMP_INCLUDED == TRUE) -void btc_dm_load_ble_local_keys(void); - -void btc_dm_get_ble_local_keys(tBTA_DM_BLE_LOCAL_KEY_MASK *p_key_mask, BT_OCTET16 er, - tBTA_BLE_LOCAL_ID_KEYS *p_id_keys); -#endif - -#endif /* __BTC_DM_H__ */ diff --git a/tools/sdk/include/bluedroid/btc/btc_main.h b/tools/sdk/include/bluedroid/btc/btc_main.h deleted file mode 100644 index 40b9ef32..00000000 --- a/tools/sdk/include/bluedroid/btc/btc_main.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_BT_MAIN_H__ -#define __BTC_BT_MAIN_H__ - -#include "osi/future.h" -#include "stack/bt_types.h" -#include "bta/bta_api.h" -#include "btc/btc_main.h" -#include "btc/btc_task.h" - -typedef enum { - BTC_MAIN_ACT_INIT = 0, - BTC_MAIN_ACT_DEINIT, - BTC_MAIN_ACT_ENABLE, - BTC_MAIN_ACT_DISABLE, -} btc_main_act_t; - -typedef enum { - BTC_MAIN_INIT_FUTURE = 0, - BTC_MAIN_DEINIT_FUTURE, - BTC_MAIN_ENABLE_FUTURE, - BTC_MAIN_DISABLE_FUTURE, - BTC_MAIN_FUTURE_NUM, -} btc_main_future_type_t; - -future_t **btc_main_get_future_p(btc_main_future_type_t type); - -#if 0 -typedef union { - struct btc_main_init_args { - future_t *future; - } init; - struct btc_main_deinit_args { - future_t *future; - } deinit; - struct btc_main_init_args { - future_t *future; - } enable; - struct btc_main_init_args { - future_t *future; - } disable; -} btc_main_args_t; - -bt_status_t btc_enable_bluetooth(future_t *future); -void btc_disable_bluetooth(future_t *future); -bt_status_t btc_init_bluetooth(future_t *future); -void btc_deinit_bluetooth(future_t *future); -#endif - -void btc_main_call_handler(btc_msg_t *msg); -#endif /* __BTC_BT_MAIN_H__ */ diff --git a/tools/sdk/include/bluedroid/btc/btc_profile_queue.h b/tools/sdk/include/bluedroid/btc/btc_profile_queue.h deleted file mode 100644 index 93270ff4..00000000 --- a/tools/sdk/include/bluedroid/btc/btc_profile_queue.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/******************************************************************************* - * - * Filename: btc/btc_profile_queue.h - * - * Description: Bluetooth remote device connection queuing - * - *******************************************************************************/ - -#ifndef __BTC_PROFILE_QUEUE_H__ -#define __BTC_PROFILE_QUEUE_H__ - -#include "common/bt_defs.h" -#include "btc/btc_task.h" - -typedef enum { - BTC_PRF_QUE_CONNECT = 0, - BTC_PRF_QUE_ADVANCE -} btc_prf_que_act_t; - -typedef bt_status_t (*btc_connect_cb_t) (bt_bdaddr_t *bda, uint16_t uuid); - -typedef struct connect_node_t { - bt_bdaddr_t bda; - uint16_t uuid; - bool busy; - btc_connect_cb_t connect_cb; -} connect_node_t; - -/* btc_prf_que_args_t */ -typedef union { - // BTC_PRF_QUE_CONNECT - connect_node_t connect_node; -} btc_prf_que_args_t; - -bt_status_t btc_queue_connect(uint16_t uuid, const bt_bdaddr_t *bda, btc_connect_cb_t connect_cb); -void btc_queue_advance(void); -bt_status_t btc_queue_connect_next(void); -void btc_queue_release(void); - -void btc_profile_queue_handler(btc_msg_t *msg); -#endif /* __BTC_PROFILE_QUEUE_H__ */ diff --git a/tools/sdk/include/bluedroid/btc/btc_sm.h b/tools/sdk/include/bluedroid/btc/btc_sm.h deleted file mode 100644 index 92acc6a1..00000000 --- a/tools/sdk/include/bluedroid/btc/btc_sm.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -/***************************************************************************** - * - * Filename: btc/btc_sm.h - * - * Description: Generic BTC state machine API - * - *****************************************************************************/ - -#ifndef __BTC_SM_H__ -#define __BTC_SM_H__ - -/***************************************************************************** -** Constants & Macros -******************************************************************************/ - -/* Generic Enter/Exit state machine events */ -#define BTC_SM_ENTER_EVT 0xFFFF -#define BTC_SM_EXIT_EVT 0xFFFE - - -/***************************************************************************** -** Type definitions and return values -******************************************************************************/ -typedef UINT32 btc_sm_state_t; -typedef UINT32 btc_sm_event_t; -typedef void *btc_sm_handle_t; -typedef BOOLEAN (* btc_sm_handler_t)(btc_sm_event_t event, void *data); - - -/***************************************************************************** -** Functions -** -** NOTE: THESE APIs SHOULD BE INVOKED ONLY IN THE BTC CONTEXT -** -******************************************************************************/ - -/***************************************************************************** -** -** Function btc_sm_init -** -** Description Initializes the state machine with the state handlers -** The caller should ensure that the table and the corresponding -** states match. The location that 'p_handlers' points to shall -** be available until the btc_sm_shutdown API is invoked. -** -** Returns Returns a pointer to the initialized state machine handle. -** -******************************************************************************/ -btc_sm_handle_t btc_sm_init(const btc_sm_handler_t *p_handlers, - btc_sm_state_t initial_state); - -/***************************************************************************** -** -** Function btc_sm_shutdown -** -** Description Tears down the state machine -** -** Returns None -** -******************************************************************************/ -void btc_sm_shutdown(btc_sm_handle_t handle); - -/***************************************************************************** -** -** Function btc_sm_get_state -** -** Description Fetches the current state of the state machine -** -** Returns Current state -** -******************************************************************************/ -btc_sm_state_t btc_sm_get_state(btc_sm_handle_t handle); - -/***************************************************************************** -** -** Function btc_sm_dispatch -** -** Description Dispatches the 'event' along with 'data' to the current state handler -** -** Returns Returns BT_STATUS_OK on success, BT_STATUS_FAIL otherwise -** -******************************************************************************/ -bt_status_t btc_sm_dispatch(btc_sm_handle_t handle, btc_sm_event_t event, - void *data); - -/***************************************************************************** -** -** Function btc_sm_change_state -** -** Description Make a transition to the new 'state'. The 'BTC_SM_EXIT_EVT' -** shall be invoked before exiting the current state. The -** 'BTC_SM_ENTER_EVT' shall be invoked before entering the new state -** -** -** Returns Returns BT_STATUS_OK on success, BT_STATUS_FAIL otherwise -** -******************************************************************************/ -bt_status_t btc_sm_change_state(btc_sm_handle_t handle, btc_sm_state_t state); - -#endif /* __BTC_SM_H__ */ diff --git a/tools/sdk/include/bluedroid/btc/btc_storage.h b/tools/sdk/include/bluedroid/btc/btc_storage.h deleted file mode 100644 index f40b169d..00000000 --- a/tools/sdk/include/bluedroid/btc/btc_storage.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_STORAGE_H__ -#define __BTC_STORAGE_H__ - -#include -#include "common/bt_defs.h" -#include "stack/bt_types.h" -#include "esp_gap_bt_api.h" - - -#define BTC_STORAGE_DEV_CLASS_STR "DevClass" -#define BTC_STORAGE_LINK_KEY_STR "LinkKey" /* same as the ble */ -#define BTC_STORAGE_LINK_KEY_TYPE_STR "LinkKeyType" -#define BTC_STORAGE_PIN_LENGTH_STR "PinLength" - -/******************************************************************************* -** -** Function btc_storage_add_bonded_device -** -** Description BTC storage API - Adds the newly bonded device to NVRAM -** along with the link-key, Key type and Pin key length -** -** Returns BT_STATUS_SUCCESS if the store was successful, -** BT_STATUS_FAIL otherwise -** -*******************************************************************************/ -bt_status_t btc_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr, - LINK_KEY link_key, - uint8_t key_type, - uint8_t pin_length); - -/******************************************************************************* -** -** Function btc_storage_remove_bonded_device -** -** Description BTC storage API - Deletes the bonded device from NVRAM -** -** Returns BT_STATUS_SUCCESS if the deletion was successful, -** BT_STATUS_FAIL otherwise -** -*******************************************************************************/ -bt_status_t btc_storage_remove_bonded_device(bt_bdaddr_t *remote_bd_addr); - -/******************************************************************************* -** -** Function btc_storage_remove_bonded_device -** -** Description BTC storage API - Deletes the bonded device from NVRAM -** -** Returns BT_STATUS_SUCCESS if the deletion was successful, -** BT_STATUS_FAIL otherwise -** -*******************************************************************************/ -bt_status_t btc_storage_load_bonded_devices(void); - -/******************************************************************************* -** -** Function btc_storage_get_num_bt_bond_devices -** -** Description BTC storage API - get the num of the bonded device from NVRAM -** -** Returns the num of the bonded device -** -*******************************************************************************/ -int btc_storage_get_num_bt_bond_devices(void); - -/******************************************************************************* -** -** Function btc_storage_get_bonded_bt_devices_list -** -** Description BTC storage API - get the list of the bonded device from NVRAM -** -** Returns BT_STATUS_SUCCESS if get the list successful, -** BT_STATUS_FAIL otherwise -** -*******************************************************************************/ -bt_status_t btc_storage_get_bonded_bt_devices_list(bt_bdaddr_t *bond_dev, int dev_num); - -#endif /* BTC_STORAGE_H */ diff --git a/tools/sdk/include/bluedroid/btc/btc_task.h b/tools/sdk/include/bluedroid/btc/btc_task.h deleted file mode 100644 index 5813c521..00000000 --- a/tools/sdk/include/bluedroid/btc/btc_task.h +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_TASK_H__ -#define __BTC_TASK_H__ - -#include -#include "common/bt_target.h" -#include "common/bt_defs.h" -#include "osi/thread.h" - -typedef struct btc_msg { - uint8_t sig; //event signal - uint8_t aid; //application id - uint8_t pid; //profile id - uint8_t act; //profile action, defined in seprerate header files - void *arg; //param for btc function or function param -} btc_msg_t; - -typedef struct btc_adv_packet { - uint8_t addr[6]; - uint8_t addr_type; -} btc_adv_packet_t; - -typedef enum { - BTC_SIG_API_CALL = 0, // APP TO STACK - BTC_SIG_API_CB, // STACK TO APP - BTC_SIG_NUM, -} btc_sig_t; //btc message type - -typedef enum { - BTC_PID_MAIN_INIT = 0, - BTC_PID_DEV, - BTC_PID_GATTS, -#if (GATTC_INCLUDED == TRUE) - BTC_PID_GATTC, -#endif ///GATTC_INCLUDED == TRUE - BTC_PID_GATT_COMMON, - BTC_PID_GAP_BLE, - BTC_PID_BLE_HID, - BTC_PID_SPPLIKE, - BTC_PID_BLUFI, - BTC_PID_DM_SEC, - BTC_PID_ALARM, -#if CONFIG_CLASSIC_BT_ENABLED - BTC_PID_GAP_BT, - BTC_PID_PRF_QUE, - BTC_PID_A2DP, - BTC_PID_AVRC, - BTC_PID_SPP, -#if BTC_HF_CLIENT_INCLUDED - BTC_PID_HF_CLIENT, -#endif /* BTC_HF_CLIENT_INCLUDED */ -#endif /* CONFIG_CLASSIC_BT_ENABLED */ - BTC_PID_NUM, -} btc_pid_t; //btc profile id - -typedef struct { - void (* btc_call)(btc_msg_t *msg); - void (* btc_cb)(btc_msg_t *msg); -} btc_func_t; - -typedef void (* btc_arg_deep_copy_t)(btc_msg_t *msg, void *dst, void *src); - -bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func); - -int btc_init(void); -void btc_deinit(void); -bool btc_check_queue_is_congest(void); - -#endif /* __BTC_TASK_H__ */ diff --git a/tools/sdk/include/bluedroid/btc/btc_util.h b/tools/sdk/include/bluedroid/btc/btc_util.h deleted file mode 100644 index df44297c..00000000 --- a/tools/sdk/include/bluedroid/btc/btc_util.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_UTIL_H__ -#define __BTC_UTIL_H__ - -#include -#include "stack/bt_types.h" -#include "common/bt_defs.h" -#include "esp_bt_defs.h" - -/******************************************************************************* -** Constants & Macros -********************************************************************************/ -#define CASE_RETURN_STR(const) case const: return #const; - -/******************************************************************************* -** Type definitions for callback functions -********************************************************************************/ -typedef char bdstr_t[18]; - - -/******************************************************************************* -** Functions -********************************************************************************/ -const char *dump_rc_event(UINT8 event); -const char *dump_rc_notification_event_id(UINT8 event_id); -const char *dump_rc_pdu(UINT8 pdu); - -UINT32 devclass2uint(DEV_CLASS dev_class); -void uint2devclass(UINT32 dev, DEV_CLASS dev_class); -void uuid128_be_to_esp_uuid(esp_bt_uuid_t *u, uint8_t* uuid128); - -void uuid_to_string_legacy(bt_uuid_t *p_uuid, char *str); - -esp_bt_status_t btc_hci_to_esp_status(uint8_t hci_status); -esp_bt_status_t btc_btm_status_to_esp_status (uint8_t btm_status); - -#endif /* __BTC_UTIL_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_a2dp.h b/tools/sdk/include/bluedroid/btc_a2dp.h deleted file mode 100644 index 8421cc46..00000000 --- a/tools/sdk/include/bluedroid/btc_a2dp.h +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/******************************************************************************* - * - * Filename: btc_a2dp.h - * - * Description: Common definitions for A2DP - * - *******************************************************************************/ - -#ifndef __BTC_A2DP_H__ -#define __BTC_A2DP_H__ - -#include -#include "common/bt_target.h" -#include "bta/bta_api.h" -#include "btc_av_api.h" -#include "esp_a2dp_api.h" - -#if BTC_AV_INCLUDED - -/******************************************************************************* - ** Constants - *******************************************************************************/ -#define BTC_AV_SUCCESS (0) -/** - * AV (Audio Video source) Errors - */ -#define BTC_ERROR_SRV_AV_NOT_ENABLED 700 /* AV is not enabled */ -#define BTC_ERROR_SRV_AV_FEEDING_NOT_SUPPORTED 701 /* Requested Feeding not supported */ -#define BTC_ERROR_SRV_AV_BUSY 702 /* Another operation ongoing */ -#define BTC_ERROR_SRV_AV_NOT_OPENED 703 /* No AV link opened */ -#define BTC_ERROR_SRV_AV_NOT_STARTED 704 /* AV is not started */ -#define BTC_ERROR_SRV_AV_CP_NOT_SUPPORTED 705 /* Content protection is not supported by all headsets */ - -/* Transcoding definition for TxTranscoding and RxTranscoding */ -#define BTC_MEDIA_TRSCD_OFF 0 -#define BTC_MEDIA_TRSCD_PCM_2_SBC 1 /* Tx */ - - -/******************************************************************************* - ** Data types - *******************************************************************************/ -typedef int tBTC_AV_STATUS; - -/******************************************************************************* - ** Public functions - *******************************************************************************/ - -void btc_a2dp_on_init(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_on_idle - ** - ** Description Process 'idle' request from BTC AV state machine during - ** initialization - ** - *******************************************************************************/ -void btc_a2dp_on_idle(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_on_started - ** - ** Description Process 'start' request from BTC AV state machine to prepare - ** for A2DP streaming - ** - ** Return TRUE if an ACK for the local command is sent - ** - *******************************************************************************/ -BOOLEAN btc_a2dp_on_started(tBTA_AV_START *p_av, BOOLEAN pending_start); - -/******************************************************************************* - ** - ** Function btc_a2dp_on_stopped - ** - ** Description Process 'stop' request from BTC AV state machine to stop - ** A2DP streaming - ** - *******************************************************************************/ -void btc_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av); - -/******************************************************************************* - ** - ** Function btc_a2dp_on_suspended - ** - ** Description Process 'stop' request from BTC AV state machine to suspend - ** A2DP streaming - ** - *******************************************************************************/ -void btc_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av); - -#endif /* #if BTC_AV_INCLUDED */ - -#endif /* __BTC_A2DP_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_a2dp_control.h b/tools/sdk/include/bluedroid/btc_a2dp_control.h deleted file mode 100644 index a3ba5432..00000000 --- a/tools/sdk/include/bluedroid/btc_a2dp_control.h +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/******************************************************************************* - * - * Filename: btc_a2dp_control.h - * - *******************************************************************************/ - -#ifndef __BTC_A2DP_CONTROL_H__ -#define __BTC_A2DP_CONTROL_H__ - -#include -#include "common/bt_target.h" -#include "bta/bta_api.h" -#include "btc_av_api.h" -#include "esp_a2dp_api.h" - -#if BTC_AV_INCLUDED -/******************************************************************************* - ** Public functions - *******************************************************************************/ - -/******************************************************************************* - ** - ** Function btc_a2dp_control_media_ctrl - ** - ** Description Handle the media_ctrl command - ** - *******************************************************************************/ -void btc_a2dp_control_media_ctrl(esp_a2d_media_ctrl_t ctrl); - - -/******************************************************************************* - ** - ** Function btc_a2dp_control_datapath_ctrl - ** - ** Description Handle the media datapath event, which is adapted from UIPC - ** data channel from bluedroid - ** - *******************************************************************************/ -void btc_a2dp_control_datapath_ctrl(uint32_t dp_evt); - - -/******************************************************************************* - ** - ** Function btc_a2dp_control_command_ack - ** - ** Description Acknowledge the pending media_ctrl command - ** - *******************************************************************************/ -void btc_a2dp_control_command_ack(int status); - - -/******************************************************************************* - ** - ** Function btc_a2dp_control_get_datachnl_stat - ** - ** Description Check whether the data channel state is open - ** - ** Return TRUE if the data channel state is open - ** - *******************************************************************************/ -BOOLEAN btc_a2dp_control_get_datachnl_stat(void); - - -/******************************************************************************* - ** - ** Function btc_a2dp_control_set_datachnl_stat - ** - ** Description Set the data channel state flag - ** - *******************************************************************************/ -void btc_a2dp_control_set_datachnl_stat(BOOLEAN open); - - -/******************************************************************************* - ** - ** Function btc_a2dp_control_init - ** - ** Description Initialize the A2DP control module. It should be called during - ** the startup stage of A2DP streaming. - ** - *******************************************************************************/ -bool btc_a2dp_control_init(void); - - -/******************************************************************************* - ** - ** Function btc_a2dp_control_cleanup - ** - ** Description Cleanup the A2DP control module - ** - *******************************************************************************/ -void btc_a2dp_control_cleanup(void); - -#endif /* #if BTC_AV_INCLUDED */ - -#endif /* __BTC_A2DP_CONTROL_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_a2dp_sink.h b/tools/sdk/include/bluedroid/btc_a2dp_sink.h deleted file mode 100644 index baf5b65a..00000000 --- a/tools/sdk/include/bluedroid/btc_a2dp_sink.h +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/******************************************************************************* - * - * Filename: btc_a2dp_sink.h - * - *******************************************************************************/ - -#ifndef __BTC_A2DP_SINK_H__ -#define __BTC_A2DP_SINK_H__ - -#include -#include "common/bt_target.h" -#include "bta/bta_api.h" -#include "btc_av_api.h" -#include "esp_a2dp_api.h" - -#if BTC_AV_SINK_INCLUDED -/******************************************************************************* - ** Data types - *******************************************************************************/ -typedef struct { - BT_HDR hdr; - UINT8 codec_info[AVDT_CODEC_SIZE]; -} tBTC_MEDIA_SINK_CFG_UPDATE; - -/******************************************************************************* - ** Public functions - *******************************************************************************/ - -/******************************************************************************* - ** - ** Function btc_a2dp_sink_startup - ** - ** Description Initialize and startup the A2DP sink module. This function - ** should be called by the BTC AV state machine prior to using - ** the module. - ** - ** Returns true if success - ** - *******************************************************************************/ -bool btc_a2dp_sink_startup(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_sink_shutdown - ** - ** Description Shutdown and cleanup the A2DP sink module - ** - *******************************************************************************/ -void btc_a2dp_sink_shutdown(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_sink_rx_flush_req - ** - ** Description Request to flush audio decoding pipe - ** - ** Returns TRUE if success - ** - *******************************************************************************/ -BOOLEAN btc_a2dp_sink_rx_flush_req(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_sink_enque_buf - ** - ** Description Enqueue a Advance Audio media buffer to be processed by btc media task. - ** - ** Returns size of the queue - ** - *******************************************************************************/ -UINT8 btc_a2dp_sink_enque_buf(BT_HDR *p_buf); - - -/******************************************************************************* - ** - ** Function btc_a2dp_sink_on_idle - ** - ** Description Process 'idle' request from the BTC AV state machine during - ** initialization - ** - *******************************************************************************/ -void btc_a2dp_sink_on_idle(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_sink_on_stopped - ** - ** Description Process 'stop' request from the BTC AV state machine to stop - ** A2DP streaming - ** - *******************************************************************************/ -void btc_a2dp_sink_on_stopped(tBTA_AV_SUSPEND *p_av); - -/******************************************************************************* - ** - ** Function btc_a2dp_sink_on_suspended - ** - ** Description Process 'suspend' request from the BTC AV state machine to - ** suspend A2DP streaming - ** - *******************************************************************************/ -void btc_a2dp_sink_on_suspended(tBTA_AV_SUSPEND *p_av); - -/******************************************************************************* - ** - ** Function btc_a2dp_sink_set_rx_flush - ** - ** Description enable/disabel discarding of received A2DP frames - ** - *******************************************************************************/ -void btc_a2dp_sink_set_rx_flush(BOOLEAN enable); - -/******************************************************************************* - ** - ** Function btc_a2dp_sink_reset_decoder - ** - ** Description Reset decoder parameters according to configuration from remote - ** device - ** - *******************************************************************************/ -void btc_a2dp_sink_reset_decoder(UINT8 *p_av); - -#endif /* #if BTC_AV_SINK_INCLUDED */ - -#endif /* __BTC_A2DP_SINK_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_a2dp_source.h b/tools/sdk/include/bluedroid/btc_a2dp_source.h deleted file mode 100644 index cfde0216..00000000 --- a/tools/sdk/include/bluedroid/btc_a2dp_source.h +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/******************************************************************************* - * - * Filename: btc_a2dp_source.h - * - *******************************************************************************/ - -#ifndef __BTC_A2DP_SOURCE_H__ -#define __BTC_A2DP_SOURCE_H__ - -#include -#include "common/bt_target.h" -#include "bta/bta_api.h" -#include "btc_av_api.h" -#include "esp_a2dp_api.h" - -#if BTC_AV_SRC_INCLUDED -/******************************************************************************* - ** Data types - *******************************************************************************/ - -/* tBTC_MEDIA_INIT_AUDIO msg structure */ -typedef struct { - BT_HDR hdr; - UINT16 SamplingFreq; /* 16k, 32k, 44.1k or 48k*/ - UINT8 ChannelMode; /* mono, dual, stereo or joint stereo*/ - UINT8 NumOfSubBands; /* 4 or 8 */ - UINT8 NumOfBlocks; /* 4, 8, 12 or 16*/ - UINT8 AllocationMethod; /* loudness or SNR*/ - UINT16 MtuSize; /* peer mtu size */ -} tBTC_MEDIA_INIT_AUDIO; - -/* tBTC_MEDIA_UPDATE_AUDIO msg structure */ -typedef struct { - BT_HDR hdr; - UINT16 MinMtuSize; /* Minimum peer mtu size */ - UINT8 MaxBitPool; /* Maximum peer bitpool */ - UINT8 MinBitPool; /* Minimum peer bitpool */ -} tBTC_MEDIA_UPDATE_AUDIO; - -/* tBTC_MEDIA_INIT_AUDIO_FEEDING msg structure */ -typedef struct { - BT_HDR hdr; - tBTC_AV_FEEDING_MODE feeding_mode; - tBTC_AV_MEDIA_FEEDINGS feeding; -} tBTC_MEDIA_INIT_AUDIO_FEEDING; - -/******************************************************************************* - ** Public functions - *******************************************************************************/ - -/******************************************************************************* - ** - ** Function btc_a2dp_source_startup - ** - ** Description Initialize and startup the A2DP source module. This function - ** should be called by the BTC AV state machine prior to using - ** the module - ** - ** Returns TRUE is success - ** - *******************************************************************************/ -bool btc_a2dp_source_startup(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_source_shutdown - ** - ** Description Shutdown and cleanup the A2DP source module. - ** - *******************************************************************************/ -void btc_a2dp_source_shutdown(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_source_enc_init_req - ** - ** Description Request to initialize the media task encoder - ** - ** Returns TRUE is success - ** - *******************************************************************************/ -BOOLEAN btc_a2dp_source_enc_init_req(tBTC_MEDIA_INIT_AUDIO *p_msg); - -/******************************************************************************* - ** - ** Function btc_a2dp_source_enc_udpate_req - ** - ** Description Request to update the media task encoder - ** - ** Returns TRUE is success - ** - *******************************************************************************/ -BOOLEAN btc_a2dp_source_enc_update_req(tBTC_MEDIA_UPDATE_AUDIO *p_msg); - - -/******************************************************************************* - ** - ** Function btc_a2dp_source_start_audio_req - ** - ** Description Request to start audio encoding task - ** - ** Returns TRUE is success - ** - *******************************************************************************/ -BOOLEAN btc_a2dp_source_start_audio_req(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_source_stop_audio_req - ** - ** Description Request to stop audio encoding task - ** - ** Returns TRUE is success - ** - *******************************************************************************/ -BOOLEAN btc_a2dp_source_stop_audio_req(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_source_tx_flush_req - ** - ** Description Request to flush audio encoding pipe - ** - ** Returns TRUE is success - ** - *******************************************************************************/ -BOOLEAN btc_a2dp_source_tx_flush_req(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_source_audio_readbuf - ** - ** Description Read an audio buffer from the BTC media TX queue - ** - ** Returns pointer on a aa buffer ready to send - ** - *******************************************************************************/ -BT_HDR *btc_a2dp_source_audio_readbuf(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_source_audio_feeding_init_req - ** - ** Description Request to initialize audio feeding - ** - ** Returns TRUE if success - ** - *******************************************************************************/ - -BOOLEAN btc_a2dp_source_audio_feeding_init_req(tBTC_MEDIA_INIT_AUDIO_FEEDING *p_msg); - -/******************************************************************************* - ** - ** Function btc_a2dp_source_is_streaming - ** - ** Description Check whether A2DP source is in streaming state - ** - *******************************************************************************/ -bool btc_a2dp_source_is_streaming(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_source_is_task_shutting_down - ** - ** Description Check whether A2DP source media task is shutting down - ** - *******************************************************************************/ -bool btc_a2dp_source_is_task_shutting_down(void); - - -/******************************************************************************* - ** - ** Function btc_a2dp_source_on_idle - ** - ** Description Request 'idle' request from BTC AV state machine during - ** initialization - ** - *******************************************************************************/ -void btc_a2dp_source_on_idle(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_source_on_stopped - ** - ** Description Process 'stop' request from the BTC AV state machine to stop - ** A2DP streaming - ** - *******************************************************************************/ -void btc_a2dp_source_on_stopped(tBTA_AV_SUSPEND *p_av); - -/******************************************************************************* - ** - ** Function btc_a2dp_source_on_suspended - ** - ** Description Process 'suspend' request from the BTC AV state machine to stop - ** A2DP streaming - ** - *******************************************************************************/ -void btc_a2dp_source_on_suspended(tBTA_AV_SUSPEND *p_av); - -/******************************************************************************* - ** - ** Function btc_a2dp_source_setup_codec - ** - ** Description initialize the encoder parameters - ** - *******************************************************************************/ -void btc_a2dp_source_setup_codec(void); - -/******************************************************************************* - ** - ** Function btc_a2dp_source_set_tx_flush - ** - ** Description enable/disable discarding of transmitted frames - ** - *******************************************************************************/ -void btc_a2dp_source_set_tx_flush(BOOLEAN enable); - -/******************************************************************************* - ** - ** Function btc_a2dp_source_encoder_update - ** - ** Description update changed SBC encoder parameters - ** - *******************************************************************************/ -void btc_a2dp_source_encoder_update(void); - -#endif /* #if BTC_AV_SRC_INCLUDED */ - -#endif /* __BTC_A2DP_SOURCE_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_av.h b/tools/sdk/include/bluedroid/btc_av.h deleted file mode 100644 index 4f3554bb..00000000 --- a/tools/sdk/include/bluedroid/btc_av.h +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -/******************************************************************************* - * - * Filename: btc_av.h - * - * Description: Main API header file for all BTC AV functions accessed - * from internal stack. - * - *******************************************************************************/ - -#ifndef __BTC_AV_H__ -#define __BTC_AV_H__ - -#include "common/bt_target.h" -#include "esp_a2dp_api.h" -#include "btc/btc_task.h" -#include "btc/btc_common.h" -#include "btc/btc_sm.h" -#include "bta/bta_av_api.h" - -#if (BTC_AV_INCLUDED == TRUE) -/******************************************************************************* -** Type definitions for callback functions -********************************************************************************/ - -enum { - BTC_AV_DATAPATH_OPEN_EVT, // original UIPC_OPEN_EVT for data channel in bluedroid - BTC_AV_DATAPATH_MAX_EVT, -}; - -typedef enum { - BTC_AV_CONNECT_REQ_EVT = BTA_AV_MAX_EVT, - BTC_AV_DISCONNECT_REQ_EVT, - BTC_AV_START_STREAM_REQ_EVT, - BTC_AV_STOP_STREAM_REQ_EVT, - BTC_AV_SUSPEND_STREAM_REQ_EVT, - BTC_AV_SINK_CONFIG_REQ_EVT, -} btc_av_sm_event_t; - -typedef enum { -#if BTC_AV_SINK_INCLUDED - BTC_AV_SINK_API_INIT_EVT = 0, - BTC_AV_SINK_API_DEINIT_EVT, - BTC_AV_SINK_API_CONNECT_EVT, - BTC_AV_SINK_API_DISCONNECT_EVT, - BTC_AV_SINK_API_REG_DATA_CB_EVT, -#endif /* BTC_AV_SINK_INCLUDED */ -#if BTC_AV_SRC_INCLUDED - BTC_AV_SRC_API_INIT_EVT, - BTC_AV_SRC_API_DEINIT_EVT, - BTC_AV_SRC_API_CONNECT_EVT, - BTC_AV_SRC_API_DISCONNECT_EVT, - BTC_AV_SRC_API_REG_DATA_CB_EVT, -#endif /* BTC_AV_SRC_INCLUDED */ - BTC_AV_API_MEDIA_CTRL_EVT, - BTC_AV_DATAPATH_CTRL_EVT, -} btc_av_act_t; - -/* btc_av_args_t */ -typedef union { -#if BTC_AV_SINK_INCLUDED - // BTC_AV_SINK_CONFIG_REQ_EVT -- internal event - esp_a2d_mcc_t mcc; - // BTC_AV_SINK_API_CONNECT_EVT - bt_bdaddr_t connect; - // BTC_AV_SINK_API_REG_DATA_CB_EVT - esp_a2d_sink_data_cb_t data_cb; -#endif /* BTC_AV_SINK_INCLUDED */ -#if BTC_AV_SRC_INCLUDED - // BTC_AV_SRC_API_REG_DATA_CB_EVT - esp_a2d_source_data_cb_t src_data_cb; - // BTC_AV_SRC_API_CONNECT - bt_bdaddr_t src_connect; -#endif /* BTC_AV_SRC_INCLUDED */ - // BTC_AV_API_MEDIA_CTRL_EVT - esp_a2d_media_ctrl_t ctrl; - // BTC_AV_DATAPATH_CTRL_EVT - uint32_t dp_evt; -} btc_av_args_t; - -/******************************************************************************* -** BTC AV API -********************************************************************************/ - -void btc_a2dp_call_handler(btc_msg_t *msg); - -void btc_a2dp_cb_handler(btc_msg_t *msg); - -void btc_a2dp_sink_reg_data_cb(esp_a2d_sink_data_cb_t callback); - -void btc_a2dp_src_reg_data_cb(esp_a2d_source_data_cb_t callback); -/******************************************************************************* -** -** Function btc_av_get_sm_handle -** -** Description Fetches current av SM handle -** -** Returns None -** -*******************************************************************************/ - -btc_sm_handle_t btc_av_get_sm_handle(void); - -/******************************************************************************* -** -** Function btc_av_stream_ready -** -** Description Checks whether AV is ready for starting a stream -** -** Returns None -** -*******************************************************************************/ - -BOOLEAN btc_av_stream_ready(void); - -/******************************************************************************* -** -** Function btc_av_stream_started_ready -** -** Description Checks whether AV ready for media start in streaming state -** -** Returns None -** -*******************************************************************************/ - -BOOLEAN btc_av_stream_started_ready(void); - -/******************************************************************************* -** -** Function btc_dispatch_sm_event -** -** Description Send event to AV statemachine -** -** Returns None -** -*******************************************************************************/ - -/* used to pass events to AV statemachine from other tasks */ -void btc_dispatch_sm_event(btc_av_sm_event_t event, void *p_data, int len); - -/******************************************************************************* -** -** Function btc_av_is_connected -** -** Description Checks if av has a connected sink -** -** Returns BOOLEAN -** -*******************************************************************************/ - -BOOLEAN btc_av_is_connected(void); - - -/******************************************************************************* - * - * Function btc_av_get_peer_sep - * - * Description Get the stream endpoint type. - * - * Returns The stream endpoint type: either AVDT_TSEP_SRC or - * AVDT_TSEP_SNK. - * - ******************************************************************************/ - -uint8_t btc_av_get_peer_sep(void); - -/******************************************************************************* -** -** Function btc_av_is_peer_edr -** -** Description Check if the connected a2dp device supports -** EDR or not. Only when connected this function -** will accurately provide a true capability of -** remote peer. If not connected it will always be false. -** -** Returns TRUE if remote device is capable of EDR -** -*******************************************************************************/ - -BOOLEAN btc_av_is_peer_edr(void); - -/****************************************************************************** -** -** Function btc_av_clear_remote_suspend_flag -** -** Description Clears remote suspended flag -** -** Returns Void -********************************************************************************/ -void btc_av_clear_remote_suspend_flag(void); - -/******************************************************************************* - * - * Function btc_av_get_service_id - * - * Description Get the current AV service ID. - * - * Returns The stream endpoint type: either BTA_A2DP_SOURCE_SERVICE_ID or - * BTA_A2DP_SINK_SERVICE_ID. - * - ******************************************************************************/ -uint8_t btc_av_get_service_id(void); - -#endif ///BTC_AV_INCLUDED == TRUE - -#endif /* __BTC_AV_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_av_api.h b/tools/sdk/include/bluedroid/btc_av_api.h deleted file mode 100644 index 39dafa23..00000000 --- a/tools/sdk/include/bluedroid/btc_av_api.h +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -/***************************************************************************** - ** - ** Name: btc_av_api.h - ** - ** Description: This is the public interface file for the advanced - ** audio/video streaming (AV) subsystem of BTC. - ** - *****************************************************************************/ - -#ifndef __BTC_AV_API_H__ -#define __BTC_AV_API_H__ - -#include "common/bt_target.h" -#include "bta/bta_av_api.h" -#include "stack/a2d_api.h" -#include "stack/a2d_sbc.h" - -#if (BTC_AV_INCLUDED == TRUE) -/***************************************************************************** - ** Constants and data types - *****************************************************************************/ - -/* Codec type */ -#define BTC_AV_CODEC_NONE 0xFF -#define BTC_AV_CODEC_SBC A2D_MEDIA_CT_SBC /* SBC media codec type */ - -#define BTC_AV_CODEC_PCM 0x5 /* Raw PCM */ - -typedef UINT8 tBTC_AV_CODEC_ID; - -/* AV features masks */ -#define BTC_AV_FEAT_RCTG BTA_AV_FEAT_RCTG /* remote control target */ -#define BTC_AV_FEAT_RCCT BTA_AV_FEAT_RCCT /* remote control controller */ -#define BTC_AV_FEAT_METADATA BTA_AV_FEAT_METADATA /* remote control Metadata Transfer command/response */ - -typedef UINT16 tBTC_AV_FEAT; - -/* AV channel values */ -#define BTC_AV_CHNL_MSK BTA_AV_CHNL_MSK -#define BTC_AV_CHNL_AUDIO BTA_AV_CHNL_AUDIO /* audio channel */ -#define BTC_AV_CHNL_VIDEO BTA_AV_CHNL_VIDEO /* video channel */ -typedef UINT8 tBTC_AV_CHNL; - -typedef UINT8 tBTC_AV_HNDL; - -/* Operation id list for BTC_AvRemoteCmd */ -#define BTC_AV_ID_SELECT 0x00 /* select */ -#define BTC_AV_ID_UP 0x01 /* up */ -#define BTC_AV_ID_DOWN 0x02 /* down */ -#define BTC_AV_ID_LEFT 0x03 /* left */ -#define BTC_AV_ID_RIGHT 0x04 /* right */ -#define BTC_AV_ID_RIGHT_UP 0x05 /* right-up */ -#define BTC_AV_ID_RIGHT_DOWN 0x06 /* right-down */ -#define BTC_AV_ID_LEFT_UP 0x07 /* left-up */ -#define BTC_AV_ID_LEFT_DOWN 0x08 /* left-down */ -#define BTC_AV_ID_ROOT_MENU 0x09 /* root menu */ -#define BTC_AV_ID_SETUP_MENU 0x0A /* setup menu */ -#define BTC_AV_ID_CONT_MENU 0x0B /* contents menu */ -#define BTC_AV_ID_FAV_MENU 0x0C /* favorite menu */ -#define BTC_AV_ID_EXIT 0x0D /* exit */ -#define BTC_AV_ID_0 0x20 /* 0 */ -#define BTC_AV_ID_1 0x21 /* 1 */ -#define BTC_AV_ID_2 0x22 /* 2 */ -#define BTC_AV_ID_3 0x23 /* 3 */ -#define BTC_AV_ID_4 0x24 /* 4 */ -#define BTC_AV_ID_5 0x25 /* 5 */ -#define BTC_AV_ID_6 0x26 /* 6 */ -#define BTC_AV_ID_7 0x27 /* 7 */ -#define BTC_AV_ID_8 0x28 /* 8 */ -#define BTC_AV_ID_9 0x29 /* 9 */ -#define BTC_AV_ID_DOT 0x2A /* dot */ -#define BTC_AV_ID_ENTER 0x2B /* enter */ -#define BTC_AV_ID_CLEAR 0x2C /* clear */ -#define BTC_AV_ID_CHAN_UP 0x30 /* channel up */ -#define BTC_AV_ID_CHAN_DOWN 0x31 /* channel down */ -#define BTC_AV_ID_PREV_CHAN 0x32 /* previous channel */ -#define BTC_AV_ID_SOUND_SEL 0x33 /* sound select */ -#define BTC_AV_ID_INPUT_SEL 0x34 /* input select */ -#define BTC_AV_ID_DISP_INFO 0x35 /* display information */ -#define BTC_AV_ID_HELP 0x36 /* help */ -#define BTC_AV_ID_PAGE_UP 0x37 /* page up */ -#define BTC_AV_ID_PAGE_DOWN 0x38 /* page down */ -#define BTC_AV_ID_POWER 0x40 /* power */ -#define BTC_AV_ID_VOL_UP 0x41 /* volume up */ -#define BTC_AV_ID_VOL_DOWN 0x42 /* volume down */ -#define BTC_AV_ID_MUTE 0x43 /* mute */ -#define BTC_AV_ID_PLAY 0x44 /* play */ -#define BTC_AV_ID_STOP 0x45 /* stop */ -#define BTC_AV_ID_PAUSE 0x46 /* pause */ -#define BTC_AV_ID_RECORD 0x47 /* record */ -#define BTC_AV_ID_REWIND 0x48 /* rewind */ -#define BTC_AV_ID_FAST_FOR 0x49 /* fast forward */ -#define BTC_AV_ID_EJECT 0x4A /* eject */ -#define BTC_AV_ID_FORWARD 0x4B /* forward */ -#define BTC_AV_ID_BACKWARD 0x4C /* backward */ -#define BTC_AV_ID_ANGLE 0x50 /* angle */ -#define BTC_AV_ID_SUBPICT 0x51 /* subpicture */ -#define BTC_AV_ID_F1 0x71 /* F1 */ -#define BTC_AV_ID_F2 0x72 /* F2 */ -#define BTC_AV_ID_F3 0x73 /* F3 */ -#define BTC_AV_ID_F4 0x74 /* F4 */ -#define BTC_AV_ID_F5 0x75 /* F5 */ -#define BTC_AV_ID_VENDOR 0x7E /* vendor unique */ -#define BTC_AV_KEYPRESSED_RELEASE 0x80 - -typedef UINT8 tBTC_AV_RC; - -/* State flag for pass through command */ -#define BTC_AV_STATE_PRESS 0 /* key pressed */ -#define BTC_AV_STATE_RELEASE 1 /* key released */ - -typedef UINT8 tBTC_AV_STATE; - -typedef UINT8 tBTC_AV_RC_HNDL; - -/* Command codes for BTC_AvVendorCmd */ -#define BTC_AV_CMD_CTRL 0 -#define BTC_AV_CMD_STATUS 1 -#define BTC_AV_CMD_SPEC_INQ 2 -#define BTC_AV_CMD_NOTIF 3 -#define BTC_AV_CMD_GEN_INQ 4 - -typedef UINT8 tBTC_AV_CMD; - -/* AV callback events */ -#define BTC_AV_OPEN_EVT 0 /* connection opened */ -#define BTC_AV_CLOSE_EVT 1 /* connection closed */ -#define BTC_AV_START_EVT 2 /* stream data transfer started */ -#define BTC_AV_STOP_EVT 3 /* stream data transfer stopped */ -#define BTC_AV_RC_OPEN_EVT 4 /* remote control channel open */ -#define BTC_AV_RC_CLOSE_EVT 5 /* remote control channel closed */ -#define BTC_AV_REMOTE_CMD_EVT 6 /* remote control command */ -#define BTC_AV_REMOTE_RSP_EVT 7 /* remote control response */ -#define BTC_AV_META_MSG_EVT 8 /* metadata messages */ - -typedef UINT8 tBTC_AV_EVT; - -#define BTC_AV_FEEDING_ASYNCHRONOUS 0 /* asynchronous feeding, use tx av timer */ -#define BTC_AV_FEEDING_SYNCHRONOUS 1 /* synchronous feeding, no av tx timer */ - -#define BTC_AV_MAX_SYNCHRONOUS_LATENCY 80 /* max latency in ms for BTC_AV_FEEDING_SYNCHRONOUS */ -#define BTC_AV_MIN_SYNCHRONOUS_LATENCY 4 /* min latency in ms for BTC_AV_FEEDING_SYNCHRONOUS */ - -typedef UINT8 tBTC_AV_FEEDING_MODE; - -#define BTC_AV_CHANNEL_MODE_MONO A2D_SBC_IE_CH_MD_MONO -#define BTC_AV_CHANNEL_MODE_STEREO A2D_SBC_IE_CH_MD_STEREO -#define BTC_AV_CHANNEL_MODE_JOINT A2D_SBC_IE_CH_MD_JOINT -#define BTC_AV_CHANNEL_MODE_DUAL A2D_SBC_IE_CH_MD_DUAL - -typedef UINT8 tBTC_AV_CHANNEL_MODE; - -/** - * Structure used to configure the AV codec capabilities/config - */ -typedef struct { - tBTC_AV_CODEC_ID id; /* Codec ID (in terms of BTC) */ - UINT8 info[AVDT_CODEC_SIZE]; /* Codec info (can be config or capabilities) */ -} tBTC_AV_CODEC_INFO; - -/** - * Structure used to configure the AV media feeding - */ -typedef struct { - UINT16 sampling_freq; /* 44100, 48000 etc */ - UINT16 num_channel; /* 1 for mono or 2 stereo */ - UINT8 bit_per_sample; /* Number of bits per sample (8, 16) */ -} tBTC_AV_MEDIA_FEED_CFG_PCM; - -typedef union { - tBTC_AV_MEDIA_FEED_CFG_PCM pcm; /* Raw PCM feeding format */ -} tBTC_AV_MEDIA_FEED_CFG; - -typedef struct { - tBTC_AV_CODEC_ID format; /* Media codec identifier */ - tBTC_AV_MEDIA_FEED_CFG cfg; /* Media codec configuration */ -} tBTC_AV_MEDIA_FEEDINGS; - - -#ifdef __cplusplus -} -#endif - -#endif ///BTC_AV_INCLUDED == TRUE - -#endif /* __BTC_AV_API_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_av_co.h b/tools/sdk/include/bluedroid/btc_av_co.h deleted file mode 100644 index cacaa01d..00000000 --- a/tools/sdk/include/bluedroid/btc_av_co.h +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_AV_CO_H__ -#define __BTC_AV_CO_H__ - -#include "btc_a2dp.h" - -#if (BTA_AV_INCLUDED == TRUE) -/******************************************************************************* -** Constants & Macros -********************************************************************************/ - -enum { - BTC_SV_AV_AA_SBC_INDEX = 0, - BTC_SV_AV_AA_SBC_SINK_INDEX, - BTC_SV_AV_AA_SEP_INDEX /* Last index */ -}; - - -/******************************************************************************* -** Functions -********************************************************************************/ - -/******************************************************************************* - ** - ** Function bta_av_co_cp_is_active - ** - ** Description Get the current configuration of content protection - ** - ** Returns TRUE if the current streaming has CP, FALSE otherwise - ** - *******************************************************************************/ -BOOLEAN bta_av_co_cp_is_active(void); - -/******************************************************************************* - ** - ** Function bta_av_co_cp_get_flag - ** - ** Description Get content protection flag - ** BTA_AV_CP_SCMS_COPY_NEVER - ** BTA_AV_CP_SCMS_COPY_ONCE - ** BTA_AV_CP_SCMS_COPY_FREE - ** - ** Returns The current flag value - ** - *******************************************************************************/ -UINT8 bta_av_co_cp_get_flag(void); - -/******************************************************************************* - ** - ** Function bta_av_co_cp_set_flag - ** - ** Description Set content protection flag - ** BTA_AV_CP_SCMS_COPY_NEVER - ** BTA_AV_CP_SCMS_COPY_ONCE - ** BTA_AV_CP_SCMS_COPY_FREE - ** - ** Returns TRUE if setting the SCMS flag is supported else FALSE - ** - *******************************************************************************/ -BOOLEAN bta_av_co_cp_set_flag(UINT8 cp_flag); - -/******************************************************************************* - ** - ** Function bta_av_co_audio_codec_reset - ** - ** Description Reset the current codec configuration - ** - ** Returns void - ** - *******************************************************************************/ -void bta_av_co_audio_codec_reset(void); - -/******************************************************************************* - ** - ** Function bta_av_co_audio_codec_supported - ** - ** Description Check if all opened connections are compatible with a codec - ** configuration - ** - ** Returns TRUE if all opened devices support this codec, FALSE otherwise - ** - *******************************************************************************/ -BOOLEAN bta_av_co_audio_codec_supported(tBTC_AV_STATUS *p_status); - -/******************************************************************************* - ** - ** Function bta_av_co_audio_set_codec - ** - ** Description Set the current codec configuration from the feeding type. - ** This function is starting to modify the configuration, it - ** should be protected. - ** - ** Returns TRUE if successful, FALSE otherwise - ** - *******************************************************************************/ -BOOLEAN bta_av_co_audio_set_codec(const tBTC_AV_MEDIA_FEEDINGS *p_feeding, tBTC_AV_STATUS *p_status); - -/******************************************************************************* - ** - ** Function bta_av_co_audio_get_sbc_config - ** - ** Description Retrieves the SBC codec configuration. If the codec in use - ** is not SBC, return the default SBC codec configuration. - ** - ** Returns TRUE if codec is SBC, FALSE otherwise - ** - *******************************************************************************/ -BOOLEAN bta_av_co_audio_get_sbc_config(tA2D_SBC_CIE *p_sbc_config, UINT16 *p_minmtu); - -/******************************************************************************* - ** - ** Function bta_av_co_audio_discard_config - ** - ** Description Discard the codec configuration of a connection - ** - ** Returns Nothing - ** - *******************************************************************************/ -void bta_av_co_audio_discard_config(tBTA_AV_HNDL hndl); - -/******************************************************************************* - ** - ** Function bta_av_co_init - ** - ** Description Initialization - ** - ** Returns Nothing - ** - *******************************************************************************/ -void bta_av_co_init(void); - - -/******************************************************************************* - ** - ** Function bta_av_co_peer_cp_supported - ** - ** Description Checks if the peer supports CP - ** - ** Returns TRUE if the peer supports CP - ** - *******************************************************************************/ -BOOLEAN bta_av_co_peer_cp_supported(tBTA_AV_HNDL hndl); - -/******************************************************************************* - ** - ** Function bta_av_co_get_remote_bitpool_pref - ** - ** Description Check if remote side did a setconfig within the limits - ** of our exported bitpool range. If set we will set the - ** remote preference. - ** - ** Returns TRUE if config set, FALSE otherwize - ** - *******************************************************************************/ -BOOLEAN bta_av_co_get_remote_bitpool_pref(UINT8 *min, UINT8 *max); - -#endif ///BTA_AV_INCLUDED == TRUE - -#endif diff --git a/tools/sdk/include/bluedroid/btc_avrc.h b/tools/sdk/include/bluedroid/btc_avrc.h deleted file mode 100644 index 2a66b8b2..00000000 --- a/tools/sdk/include/bluedroid/btc_avrc.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __BTC_AVRC_H__ -#define __BTC_AVRC_H__ - -#include -#include -#include "common/bt_defs.h" -#include "stack/bt_types.h" -#include "bta/bta_av_api.h" - -#if (BTC_AV_INCLUDED == TRUE) -#ifndef BTC_AVRC_TGT_INCLUDED -#define BTC_AVRC_TGT_INCLUDED FALSE -#endif - -typedef enum { - BTC_AVRC_CTRL_API_INIT_EVT = 0, - BTC_AVRC_CTRL_API_DEINIT_EVT, - BTC_AVRC_CTRL_API_SND_PTCMD_EVT, - BTC_AVRC_STATUS_API_SND_META_EVT, - BTC_AVRC_STATUS_API_SND_PLAY_STATUS_EVT, - BTC_AVRC_NOTIFY_API_SND_REG_NOTIFY_EVT, - BTC_AVRC_CTRL_API_SET_PLAYER_SETTING_EVT -} btc_avrc_act_t; - -typedef struct { - uint8_t tl; /* transaction label */ - uint8_t key_code; - uint8_t key_state; -} pt_cmd_t; - -typedef struct { - uint8_t tl; - uint8_t attr_mask; -} md_cmd_t; - -typedef struct { - uint8_t tl; - uint8_t event_id; - uint32_t event_parameter; -} rn_cmd_t; - -typedef struct { - uint8_t tl; - uint8_t attr_id; - uint8_t value_id; -} ps_cmd_t; - -/* btc_avrc_args_t */ -typedef union { - pt_cmd_t pt_cmd; - md_cmd_t md_cmd; - rn_cmd_t rn_cmd; - ps_cmd_t ps_cmd; -} btc_avrc_args_t; - -/** BT-RC Controller callback structure. */ -typedef void (* btrc_passthrough_rsp_callback) (int id, int key_state); - -typedef void (* btrc_connection_state_callback) (bool state, bt_bdaddr_t *bd_addr); - -void btc_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data); - -BOOLEAN btc_rc_get_connected_peer(BD_ADDR peer_addr); - -/******************************************************************************* -** BTC AVRC API -********************************************************************************/ -void btc_avrc_call_handler(btc_msg_t *msg); - -#endif ///BTC_AV_INCLUDED == TRUE - -#endif /* __BTC_AVRC_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_blufi_prf.h b/tools/sdk/include/bluedroid/btc_blufi_prf.h deleted file mode 100644 index e79b896f..00000000 --- a/tools/sdk/include/bluedroid/btc_blufi_prf.h +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_BLUFI_PRF_H__ -#define __BTC_BLUFI_PRF_H__ - -#include "common/bt_target.h" -#include "btc/btc_task.h" -#include "esp_blufi_api.h" - -typedef enum { - BTC_BLUFI_ACT_INIT = 0, - BTC_BLUFI_ACT_DEINIT, - BTC_BLUFI_ACT_SEND_CFG_REPORT, - BTC_BLUFI_ACT_SEND_WIFI_LIST, - BTC_BLUFI_ACT_SEND_ERR_INFO, - BTC_BLUFI_ACT_SEND_CUSTOM_DATA, -} btc_blufi_act_t; - -typedef union { - struct blufi_cfg_report { - wifi_mode_t opmode; - esp_blufi_sta_conn_state_t sta_conn_state; - uint8_t softap_conn_num; - esp_blufi_extra_info_t *extra_info; - int extra_info_len; - } wifi_conn_report; - /* - BTC_BLUFI_ACT_SEND_WIFI_LIST - */ - struct blufi_wifi_list { - uint16_t apCount; - esp_blufi_ap_record_t *list; - } wifi_list; - /* - BTC_BLUFI_ACT_SEND_ERR_INFO - */ - struct blufi_error_infor { - esp_blufi_error_state_t state; - } blufi_err_infor; - /* - BTC_BLUFI_ACT_SEND_CUSTOM_DATA - */ - struct blufi_custom_data { - uint8_t *data; - uint32_t data_len; - } custom_data; -} btc_blufi_args_t; - -void btc_blufi_cb_handler(btc_msg_t *msg); -void btc_blufi_call_handler(btc_msg_t *msg); -void btc_blufi_set_callbacks(esp_blufi_callbacks_t *callbacks); - -void btc_blufi_call_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); -void btc_blufi_call_deep_free(btc_msg_t *msg); - -uint16_t btc_blufi_get_version(void); - -#endif /* __BTC_BLUFI_PRF_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_gap_ble.h b/tools/sdk/include/bluedroid/btc_gap_ble.h deleted file mode 100644 index c9e0f564..00000000 --- a/tools/sdk/include/bluedroid/btc_gap_ble.h +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_GAP_BLE_H__ -#define __BTC_GAP_BLE_H__ - -#include "esp_bt_defs.h" -#include "esp_gap_ble_api.h" - -#define BLE_ISVALID_PARAM(x, min, max) (((x) >= (min) && (x) <= (max)) || ((x) == ESP_BLE_CONN_PARAM_UNDEF)) - -typedef enum { - BTC_GAP_BLE_ACT_CFG_ADV_DATA = 0, - BTC_GAP_BLE_ACT_SET_SCAN_PARAM, - BTC_GAP_BLE_ACT_START_SCAN, - BTC_GAP_BLE_ACT_STOP_SCAN, - BTC_GAP_BLE_ACT_START_ADV, - BTC_GAP_BLE_ACT_STOP_ADV, - BTC_GAP_BLE_ACT_UPDATE_CONN_PARAM, - BTC_GAP_BLE_ACT_SET_PKT_DATA_LEN, - BTC_GAP_BLE_ACT_SET_RAND_ADDRESS, - BTC_GAP_BLE_ACT_CONFIG_LOCAL_PRIVACY, - BTC_GAP_BLE_ACT_CONFIG_LOCAL_ICON, - BTC_GAP_BLE_ACT_UPDATE_WHITE_LIST, - BTC_GAP_BLE_ACT_SET_CONN_PARAMS, - BTC_GAP_BLE_ACT_SET_DEV_NAME, - BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW, - BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW, - BTC_GAP_BLE_ACT_READ_RSSI, - BTC_GAP_BLE_SET_ENCRYPTION_EVT, - BTC_GAP_BLE_SET_SECURITY_PARAM_EVT, - BTC_GAP_BLE_SECURITY_RSP_EVT, - BTC_GAP_BLE_PASSKEY_REPLY_EVT, - BTC_GAP_BLE_CONFIRM_REPLY_EVT, - BTC_GAP_BLE_DISCONNECT_EVT, - BTC_GAP_BLE_REMOVE_BOND_DEV_EVT, -} btc_gap_ble_act_t; - -/* btc_ble_gap_args_t */ -typedef union { - //BTC_GAP_BLE_ACT_CFG_ADV_DATA = 0, - struct config_adv_data_args { - esp_ble_adv_data_t adv_data; - } cfg_adv_data; - //BTC_GAP_BLE_ACT_SET_SCAN_PARAM, - struct set_scan_params_args { - esp_ble_scan_params_t scan_params; - } set_scan_param; - //BTC_GAP_BLE_ACT_START_SCAN, - struct start_scan_args { - uint32_t duration; - } start_scan; - //BTC_GAP_BLE_ACT_STOP_SCAN, no args - //BTC_GAP_BLE_ACT_START_ADV, - struct start_adv_args { - esp_ble_adv_params_t adv_params; - } start_adv; - //BTC_GAP_BLE_ACT_STOP_ADV, no args - //BTC_GAP_BLE_ACT_UPDATE_CONN_PARAM, - struct conn_update_params_args { - esp_ble_conn_update_params_t conn_params; - } conn_update_params; - //BTC_GAP_BLE_ACT_SET_PKT_DATA_LEN - struct set_pkt_data_len_args { - esp_bd_addr_t remote_device; - uint16_t tx_data_length; - } set_pkt_data_len; - //BTC_GAP_BLE_ACT_SET_RAND_ADDRESS, - struct set_rand_addr_args { - esp_bd_addr_t rand_addr; - } set_rand_addr; - //BTC_GAP_BLE_ACT_CONFIG_LOCAL_PRIVACY, - struct cfg_local_privacy_args { - bool privacy_enable; - } cfg_local_privacy; - //BTC_GAP_BLE_ACT_CONFIG_LOCAL_ICON, - struct cfg_local_icon_args { - uint16_t icon; - } cfg_local_icon; - //BTC_GAP_BLE_ACT_UPDATE_WHITE_LIST - struct update_white_list_args { - bool add_remove; - esp_bd_addr_t remote_bda; - }update_white_list; - //BTC_GAP_BLE_ACT_SET_CONN_PARAMS - struct set_conn_params_args { - esp_bd_addr_t bd_addr; - uint16_t min_conn_int; - uint16_t max_conn_int; - uint16_t slave_latency; - uint16_t supervision_tout; - }set_conn_params; - //BTC_GAP_BLE_ACT_SET_DEV_NAME, - struct set_dev_name_args { -#define ESP_GAP_DEVICE_NAME_MAX (32) - char device_name[ESP_GAP_DEVICE_NAME_MAX + 1]; - } set_dev_name; - //BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW, - struct config_adv_data_raw_args { - uint8_t *raw_adv; - uint32_t raw_adv_len; - } cfg_adv_data_raw; - //BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW, - struct config_scan_rsp_data_raw_args { - uint8_t *raw_scan_rsp; - uint32_t raw_scan_rsp_len; - } cfg_scan_rsp_data_raw; - //BTC_GAP_BLE_SET_ENCRYPTION_EVT - struct set_encryption_args { - esp_bd_addr_t bd_addr; - esp_ble_sec_act_t sec_act; - } set_encryption; - //BTC_GAP_BLE_SET_SECURITY_PARAM_EVT - struct set_security_param_args { - esp_ble_sm_param_t param_type; - uint8_t len; - uint8_t *value; - } set_security_param; - //BTC_GAP_BLE_SECURITY_RSP_EVT - struct enc_rsp_args { - esp_bd_addr_t bd_addr; - bool accept; - } sec_rsp; - //BTC_GAP_BLE_PASSKEY_REPLY_EVT - struct enc_passkey_reply_args { - esp_bd_addr_t bd_addr; - bool accept; - uint32_t passkey; - } enc_passkey_replay; - //BTC_GAP_BLE_CONFIRM_REPLY_EVT - struct enc_comfirm_reply_args { - esp_bd_addr_t bd_addr; - bool accept; - } enc_comfirm_replay; - //BTC_GAP_BLE_DISCONNECT_EVT - struct disconnect_args { - esp_bd_addr_t remote_device; - } disconnect; - //BTC_GAP_BLE_REMOVE_BOND_DEV_EVT - struct remove_bond_device_args { - esp_bd_addr_t bd_addr; - } remove_bond_device; - //BTC_GAP_BLE_ACT_READ_RSSI - struct read_rssi_args { - esp_bd_addr_t remote_addr; - } read_rssi; -} btc_ble_gap_args_t; - -void btc_gap_ble_call_handler(btc_msg_t *msg); -void btc_gap_ble_cb_handler(btc_msg_t *msg); -void btc_get_whitelist_size(uint16_t *length); -void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); -void btc_gap_ble_arg_deep_free(btc_msg_t *msg); -void btc_gap_ble_cb_deep_free(btc_msg_t *msg); -void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); -void btc_gap_callback_init(void); -void btc_gap_ble_deinit(void); -void btc_adv_list_init(void); -void btc_adv_list_deinit(void); - -#endif /* __BTC_GAP_BLE_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_gap_bt.h b/tools/sdk/include/bluedroid/btc_gap_bt.h deleted file mode 100644 index 67e03cb3..00000000 --- a/tools/sdk/include/bluedroid/btc_gap_bt.h +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_GAP_BT_H__ -#define __BTC_GAP_BT_H__ - -#include "common/bt_target.h" -#include "esp_bt_defs.h" -#include "esp_gap_bt_api.h" -#include "btc/btc_task.h" -#include "bta/utl.h" - -#if (BTC_GAP_BT_INCLUDED == TRUE) -typedef enum { - BTC_GAP_BT_SEARCH_DEVICES_EVT = 0, - BTC_GAP_BT_SEARCH_SERVICES_EVT, - BTC_GAP_BT_SEARCH_SERVICE_RECORD_EVT, - BTC_GAP_BT_AUTH_CMPL_EVT, - BTC_GAP_BT_PIN_REQ_EVT, - BTC_GAP_BT_CFM_REQ_EVT, - BTC_GAP_BT_KEY_NOTIF_EVT, - BTC_GAP_BT_KEY_REQ_EVT, - BTC_GAP_BT_READ_RSSI_DELTA_EVT, -}btc_gap_bt_evt_t; - -typedef enum { - BTC_GAP_BT_ACT_SET_SCAN_MODE = 0, - BTC_GAP_BT_ACT_START_DISCOVERY, - BTC_GAP_BT_ACT_CANCEL_DISCOVERY, - BTC_GAP_BT_ACT_GET_REMOTE_SERVICES, - BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD, - BTC_GAP_BT_ACT_SET_COD, - BTC_GAP_BT_ACT_READ_RSSI_DELTA, - BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE, - BTC_GAP_BT_ACT_SET_PIN_TYPE, - BTC_GAP_BT_ACT_PIN_REPLY, - BTC_GAP_BT_ACT_SET_SECURITY_PARAM, - BTC_GAP_BT_ACT_PASSKEY_REPLY, - BTC_GAP_BT_ACT_CONFIRM_REPLY, -} btc_gap_bt_act_t; - -/* btc_bt_gap_args_t */ -typedef union { - // BTC_BT_GAP_ACT_SET_SCAN_MODE, - struct set_bt_scan_mode_args { - esp_bt_scan_mode_t mode; - } set_scan_mode; - - // BTC_GAP_BT_ACT_START_DISCOVERY - struct start_disc_args { - esp_bt_inq_mode_t mode; - uint8_t inq_len; - uint8_t num_rsps; - } start_disc; - - // BTC_GAP_BT_ACT_GET_REMOTE_SERVICES - bt_bdaddr_t bda; - - // BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD - struct get_rmt_srv_rcd_args { - bt_bdaddr_t bda; - esp_bt_uuid_t uuid; - } get_rmt_srv_rcd; - - // BTC_GAP_BT_ACT_SET_COD - struct set_cod_args { - esp_bt_cod_t cod; - esp_bt_cod_mode_t mode; - } set_cod; - - //BTC_GAP_BT_ACT_READ_RSSI_DELTA, - struct bt_read_rssi_delta_args { - bt_bdaddr_t bda; - } read_rssi_delta; - - // BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE - struct rm_bond_device_args { - bt_bdaddr_t bda; - } rm_bond_device; - - // BTC_GAP_BT_ACT_SET_PIN_TYPE - struct set_pin_type_args { - esp_bt_pin_type_t pin_type; - uint8_t pin_code_len; - esp_bt_pin_code_t pin_code; - } set_pin_type; - - // BTC_GAP_BT_ACT_PIN_REPLY - struct pin_reply_args { - bt_bdaddr_t bda; - bool accept; - uint8_t pin_code_len; - esp_bt_pin_code_t pin_code; - } pin_reply; - - // BTC_GAP_BT_ACT_SET_SECURITY_PARAM - struct set_sec_param_args { - esp_bt_sp_param_t param_type; - uint8_t len; - uint8_t *value; - } set_security_param; - - // BTC_GAP_BT_ACT_PASSKEY_REPLY - struct passkey_reply_args { - bt_bdaddr_t bda; - bool accept; - uint32_t passkey; - } passkey_reply; - - // BTC_GAP_BT_ACT_CONFIRM_REPLY - struct confirm_reply_args { - bt_bdaddr_t bda; - bool accept; - } confirm_reply; -} btc_gap_bt_args_t; - -void btc_gap_bt_call_handler(btc_msg_t *msg); -void btc_gap_bt_cb_handler(btc_msg_t *msg); -void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); -void btc_gap_bt_busy_level_updated(uint8_t bl_flags); - -esp_err_t btc_gap_bt_get_cod(esp_bt_cod_t *cod); -#endif /* #if BTC_GAP_BT_INCLUDED */ - -#endif /* __BTC_GAP_BT_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_gatt_common.h b/tools/sdk/include/bluedroid/btc_gatt_common.h deleted file mode 100644 index 4cb6e927..00000000 --- a/tools/sdk/include/bluedroid/btc_gatt_common.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_GATT_COMMON_H__ -#define __BTC_GATT_COMMON_H__ - -#include "osi/future.h" -#include "stack/bt_types.h" -#include "bta/bta_api.h" -#include "btc/btc_main.h" -#include "btc/btc_task.h" - -typedef enum { - BTC_GATT_ACT_SET_LOCAL_MTU = 0, -} btc_gatt_com_act_t; - -/* btc_ble_gattc_args_t */ -typedef union { - //BTC_GATT_ACT_SET_LOCAL_MTU, - struct set_mtu_arg { - uint16_t mtu; - } set_mtu; -} btc_ble_gatt_com_args_t; - -void btc_gatt_com_call_handler(btc_msg_t *msg); -#endif /* __BTC_GATT_COMMON_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_gatt_util.h b/tools/sdk/include/bluedroid/btc_gatt_util.h deleted file mode 100644 index 3daffa15..00000000 --- a/tools/sdk/include/bluedroid/btc_gatt_util.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_GATT_UTIL_H__ -#define __BTC_GATT_UTIL_H__ - -#include "stack/bt_types.h" -#include "bta/bta_gatt_api.h" -#include "esp_bt_defs.h" -#include "esp_gatt_defs.h" -#include "esp_gattc_api.h" - -#define BTC_GATT_CREATE_CONN_ID(gatt_if, conn_id) ((uint16_t) ((((uint8_t)(conn_id)) << 8) | ((uint8_t)(gatt_if)))) -#define BTC_GATT_GET_CONN_ID(conn_id) (((uint16_t)(conn_id)) >> 8) -#define BTC_GATT_GET_GATT_IF(conn_id) ((uint8_t)(conn_id)) - -void btc128_to_bta_uuid(tBT_UUID *p_dest, uint8_t *p_src); -void btc_to_bta_uuid(tBT_UUID *p_dest, esp_bt_uuid_t *p_src); -void btc_to_bta_gatt_id(tBTA_GATT_ID *p_dest, esp_gatt_id_t *p_src); -void btc_to_bta_srvc_id(tBTA_GATT_SRVC_ID *p_dest, esp_gatt_srvc_id_t *p_src); -void btc_to_bta_response(tBTA_GATTS_RSP *rsp_struct, esp_gatt_rsp_t *p_rsp); - -void bta_to_btc_uuid(esp_bt_uuid_t *p_dest, tBT_UUID *p_src); -void bta_to_btc_gatt_id(esp_gatt_id_t *p_dest, tBTA_GATT_ID *p_src); -void bta_to_btc_srvc_id(esp_gatt_srvc_id_t *p_dest, tBTA_GATT_SRVC_ID *p_src); - -uint16_t set_read_value(uint8_t *gattc_if, esp_ble_gattc_cb_param_t *p_dest, tBTA_GATTC_READ *p_src); - -#endif /* __BTC_GATT_UTIL_H__*/ diff --git a/tools/sdk/include/bluedroid/btc_gattc.h b/tools/sdk/include/bluedroid/btc_gattc.h deleted file mode 100644 index afc3e4ba..00000000 --- a/tools/sdk/include/bluedroid/btc_gattc.h +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_GATTC_H__ -#define __BTC_GATTC_H__ - -#include "btc/btc_task.h" -#include "esp_bt_defs.h" -#include "esp_gatt_defs.h" -#include "esp_gattc_api.h" - -typedef enum { - BTC_GATTC_ACT_APP_REGISTER = 0, - BTC_GATTC_ACT_APP_UNREGISTER, - BTC_GATTC_ACT_OPEN, - BTC_GATTC_ACT_CLOSE, - BTC_GATTC_ACT_CFG_MTU, - BTC_GATTC_ACT_SEARCH_SERVICE, - BTC_GATTC_ACT_READ_CHAR, - BTC_GATTC_ACT_READ_MULTIPLE_CHAR, - BTC_GATTC_ACT_READ_CHAR_DESCR, - BTC_GATTC_ACT_WRITE_CHAR, - BTC_GATTC_ACT_WRITE_CHAR_DESCR, - BTC_GATTC_ACT_PREPARE_WRITE, - BTC_GATTC_ACT_PREPARE_WRITE_CHAR_DESCR, - BTC_GATTC_ACT_EXECUTE_WRITE, - BTC_GATTC_ACT_REG_FOR_NOTIFY, - BTC_GATTC_ACT_UNREG_FOR_NOTIFY, - BTC_GATTC_ACT_CACHE_REFRESH, - BTC_GATTC_ACT_CACHE_ASSOC, - BTC_GATTC_ATC_CACHE_GET_ADDR_LIST, -} btc_gattc_act_t; - -/* btc_ble_gattc_args_t */ -typedef union { - //BTC_GATTC_ACT_APP_REGISTER, - struct app_reg_arg { - uint16_t app_id; - } app_reg; - //BTC_GATTC_ACT_APP_UNREGISTER, - struct app_unreg_arg { - esp_gatt_if_t gattc_if; - } app_unreg; - //BTC_GATTC_ACT_OPEN, - struct open_arg { - esp_gatt_if_t gattc_if; - esp_bd_addr_t remote_bda; - esp_ble_addr_type_t remote_addr_type; - bool is_direct; - } open; - //BTC_GATTC_ACT_CLOSE, - struct close_arg { - uint16_t conn_id; - } close; - //BTC_GATTC_ACT_CFG_MTU, - struct cfg_mtu_arg { - uint16_t conn_id; - } cfg_mtu; - //BTC_GATTC_ACT_SEARCH_SERVICE, - struct search_srvc_arg { - uint16_t conn_id; - bool filter_uuid_enable; - esp_bt_uuid_t filter_uuid; - } search_srvc; - //BTC_GATTC_ACT_GET_CHAR, - struct get_char_arg { - uint16_t conn_id; - uint16_t handle; - } get_char; - //BTC_GATTC_ACT_GET_DESCR, - struct get_descr_arg { - uint16_t conn_id; - uint16_t handle; - } get_descr; - //BTC_GATTC_ACT_GET_FIRST_INCL_SERVICE, - struct get_first_incl_srvc_arg { - uint16_t conn_id; - uint16_t handle; - } get_first_incl_srvc; - //BTC_GATTC_ACT_GET_NEXT_INCL_SERVICE, - struct get_next_incl_srvc_arg { - uint16_t conn_id; - uint16_t handle; - } get_next_incl_srvc; - //BTC_GATTC_ACT_READ_CHAR, - struct read_char_arg { - uint16_t conn_id; - uint16_t handle; - esp_gatt_auth_req_t auth_req; - } read_char; - //BTC_GATTC_ACT_READ_MULTIPLE_CHAR - struct read_multiple_arg { - uint16_t conn_id; - uint8_t num_attr; - uint16_t handles[ESP_GATT_MAX_READ_MULTI_HANDLES]; - esp_gatt_auth_req_t auth_req; - } read_multiple; - //BTC_GATTC_ACT_READ_CHAR_DESCR, - struct read_descr_arg { - uint16_t conn_id; - uint16_t handle; - esp_gatt_auth_req_t auth_req; - } read_descr; - //BTC_GATTC_ACT_WRITE_CHAR, - struct write_char_arg { - uint16_t conn_id; - uint16_t value_len; - uint16_t handle; - uint8_t *value; - esp_gatt_write_type_t write_type; - esp_gatt_auth_req_t auth_req; - } write_char; - //BTC_GATTC_ACT_WRITE_CHAR_DESCR, - struct write_descr_arg { - uint16_t conn_id; - uint16_t value_len; - uint16_t handle; - uint8_t *value; - esp_gatt_write_type_t write_type; - esp_gatt_auth_req_t auth_req; - } write_descr; - //BTC_GATTC_ACT_PREPARE_WRITE, - struct prep_write_arg { - uint16_t conn_id; - uint16_t handle; - uint16_t offset; - uint16_t value_len; - uint8_t *value; - esp_gatt_auth_req_t auth_req; - } prep_write; - //BTC_GATTC_ACT_PREPARE_WRITE_CHAR_DESCR, - struct prep_write_descr_arg { - uint16_t conn_id; - uint16_t handle; - uint16_t offset; - uint16_t value_len; - uint8_t *value; - esp_gatt_auth_req_t auth_req; - } prep_write_descr; - //BTC_GATTC_ACT_EXECUTE_WRITE, - struct exec_write_arg { - uint16_t conn_id; - bool is_execute; - } exec_write; - //BTC_GATTC_ACT_REG_FOR_NOTIFY, - struct reg_for_notify_arg { - esp_gatt_if_t gattc_if; - esp_bd_addr_t remote_bda; - uint16_t handle; - } reg_for_notify; - //BTC_GATTC_ACT_UNREG_FOR_NOTIFY - struct unreg_for_notify_arg { - esp_gatt_if_t gattc_if; - esp_bd_addr_t remote_bda; - uint16_t handle; - } unreg_for_notify; - //BTC_GATTC_ACT_CACHE_REFRESH, - struct cache_refresh_arg { - esp_bd_addr_t remote_bda; - } cache_refresh; - //BTC_GATTC_ACT_CACHE_ASSOC - struct cache_assoc_arg { - esp_gatt_if_t gattc_if; - esp_bd_addr_t src_addr; - esp_bd_addr_t assoc_addr; - bool is_assoc; - } cache_assoc; - //BTC_GATTC_ATC_CACHE_GET_ADDR_LIST - struct cache_get_addr_list_arg { - esp_gatt_if_t gattc_if; - }get_addr_list; -} btc_ble_gattc_args_t; - -void btc_gattc_call_handler(btc_msg_t *msg); -void btc_gattc_cb_handler(btc_msg_t *msg); -void btc_gattc_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); -esp_gatt_status_t btc_ble_gattc_get_service(uint16_t conn_id, esp_bt_uuid_t *svc_uuid, - esp_gattc_service_elem_t *result, - uint16_t *count, uint16_t offset); -esp_gatt_status_t btc_ble_gattc_get_all_char(uint16_t conn_id, - uint16_t start_handle, - uint16_t end_handle, - esp_gattc_char_elem_t *result, - uint16_t *count, uint16_t offset); -esp_gatt_status_t btc_ble_gattc_get_all_descr(uint16_t conn_id, - uint16_t char_handle, - esp_gattc_descr_elem_t *result, - uint16_t *count, uint16_t offset); -esp_gatt_status_t btc_ble_gattc_get_char_by_uuid(uint16_t conn_id, - uint16_t start_handle, - uint16_t end_handle, - esp_bt_uuid_t char_uuid, - esp_gattc_char_elem_t *result, - uint16_t *count); -esp_gatt_status_t btc_ble_gattc_get_descr_by_uuid(uint16_t conn_id, - uint16_t start_handle, - uint16_t end_handle, - esp_bt_uuid_t char_uuid, - esp_bt_uuid_t descr_uuid, - esp_gattc_descr_elem_t *result, - uint16_t *count); - -esp_gatt_status_t btc_ble_gattc_get_descr_by_char_handle(uint16_t conn_id, - uint16_t char_handle, - esp_bt_uuid_t descr_uuid, - esp_gattc_descr_elem_t *result, - uint16_t *count); - -esp_gatt_status_t btc_ble_gattc_get_include_service(uint16_t conn_id, - uint16_t start_handle, - uint16_t end_handle, - esp_bt_uuid_t *incl_uuid, - esp_gattc_incl_svc_elem_t *result, - uint16_t *count); - -esp_gatt_status_t btc_ble_gattc_get_attr_count(uint16_t conn_id, - esp_gatt_db_attr_type_t type, - uint16_t start_handle, - uint16_t end_handle, - uint16_t char_handle, - uint16_t *count); - -esp_gatt_status_t btc_ble_gattc_get_db(uint16_t conn_id, uint16_t start_handle, uint16_t end_handle, - esp_gattc_db_elem_t *db, uint16_t *count); - - - - -#endif /* __BTC_GATTC_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_gatts.h b/tools/sdk/include/bluedroid/btc_gatts.h deleted file mode 100644 index e4b57589..00000000 --- a/tools/sdk/include/bluedroid/btc_gatts.h +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_GATTS_H__ -#define __BTC_GATTS_H__ - -#include "btc/btc_task.h" -#include "esp_bt_defs.h" -#include "esp_gatt_defs.h" -#include "esp_gatts_api.h" - -typedef enum { - BTC_GATTS_ACT_APP_REGISTER = 0, - BTC_GATTS_ACT_APP_UNREGISTER, - BTC_GATTS_ACT_CREATE_SERVICE, - BTC_GATTS_ACT_CREATE_ATTR_TAB, - BTC_GATTS_ACT_DELETE_SERVICE, - BTC_GATTS_ACT_START_SERVICE, - BTC_GATTS_ACT_STOP_SERVICE, - BTC_GATTS_ACT_ADD_INCLUDE_SERVICE, - BTC_GATTS_ACT_ADD_CHAR, - BTC_GATTS_ACT_ADD_CHAR_DESCR, - BTC_GATTS_ACT_SEND_INDICATE, - BTC_GATTS_ACT_SEND_RESPONSE, - BTC_GATTS_ACT_SET_ATTR_VALUE, - BTC_GATTS_ACT_OPEN, - BTC_GATTS_ACT_CLOSE, -} btc_gatts_act_t; - -/* btc_ble_gatts_args_t */ -typedef union { - //BTC_GATTS_ACT_APP_REGISTER = 0, - struct app_reg_args { - uint16_t app_id; - } app_reg; - - //BTC_GATTS_ACT_APP_UNREGISTER, - struct app_unreg_args { - esp_gatt_if_t gatts_if; - } app_unreg; - - //BTC_GATTS_ACT_CREATE_SERVICE, - struct create_srvc_args { - esp_gatt_if_t gatts_if; - esp_gatt_srvc_id_t service_id; - uint16_t num_handle; - } create_srvc; - - //BTC_GATTS_ACT_CREATE_ATTR_TAB - struct create_attr_tab_args{ - esp_gatt_if_t gatts_if; - uint8_t srvc_inst_id; - uint8_t max_nb_attr; - esp_gatts_attr_db_t *gatts_attr_db; - }create_attr_tab; - - //BTC_GATTS_ACT_DELETE_SERVICE, - struct delete_srvc_args { - uint16_t service_handle; - } delete_srvc; - - //BTC_GATTS_ACT_START_SERVICE, - struct start_srvc_args { - uint16_t service_handle; - } start_srvc; - - //BTC_GATTS_ACT_STOP_SERVICE, - struct stop_srvc_args { - uint16_t service_handle; - } stop_srvc; - - //BTC_GATTS_ACT_ADD_INCLUDE_SERVICE, - struct add_incl_srvc_args { - uint16_t service_handle; - uint16_t included_service_handle; - } add_incl_srvc; - - //BTC_GATTS_ACT_ADD_CHAR, - struct add_char_args { - uint16_t service_handle; - esp_bt_uuid_t char_uuid; - esp_gatt_perm_t perm; - esp_gatt_char_prop_t property; - esp_attr_control_t attr_control; - esp_attr_value_t char_val; - } add_char; - - //BTC_GATTS_ACT_ADD_CHAR_DESCR, - struct add_descr_args { - uint16_t service_handle; - esp_bt_uuid_t descr_uuid; - esp_gatt_perm_t perm; - esp_attr_control_t attr_control; - esp_attr_value_t descr_val; - } add_descr; - - //BTC_GATTS_ACT_SEND_INDICATE, - struct send_indicate_args { - uint16_t conn_id; - uint16_t attr_handle; - bool need_confirm; - uint16_t value_len; - uint8_t *value; - } send_ind; - - //BTC_GATTS_ACT_SEND_RESPONSE, - struct send_rsp_args { - uint16_t conn_id; - uint32_t trans_id; - esp_gatt_status_t status; - esp_gatt_rsp_t *rsp; - } send_rsp; - - //BTC_GATTS_SET_ATTR_VALUE - struct set_attr_val_args { - uint16_t handle; - uint16_t length; - uint8_t *value; - } set_attr_val; - - //BTC_GATTS_ACT_OPEN, - struct open_args { - esp_gatt_if_t gatts_if; - esp_bd_addr_t remote_bda; - bool is_direct; - } open; - - //BTC_GATTS_ACT_CLOSE, - struct close_args { - uint16_t conn_id; - } close; - -} btc_ble_gatts_args_t; - - -void btc_gatts_call_handler(btc_msg_t *msg); -void btc_gatts_cb_handler(btc_msg_t *msg); -void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); -esp_gatt_status_t btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, uint8_t **value); - - -#endif /* __BTC_GATTS_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_hf_client.h b/tools/sdk/include/bluedroid/btc_hf_client.h deleted file mode 100644 index 6500b9d8..00000000 --- a/tools/sdk/include/bluedroid/btc_hf_client.h +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -/******************************************************************************* - * - * Filename: btc_hf_client.h - * - * Description: Main API header file for all BTC HF client functions accessed - * from internal stack. - * - *******************************************************************************/ - -#ifndef __BTC_HF_CLIENT_H__ -#define __BTC_HF_CLIENT_H__ - -#include "common/bt_target.h" -#include "esp_hf_client_api.h" -#include "btc/btc_task.h" -#include "btc/btc_common.h" -#include "bta/bta_hf_client_api.h" - -#if (BTC_HF_CLIENT_INCLUDED == TRUE) -/******************************************************************************* -** Type definitions for callback functions -********************************************************************************/ -typedef enum { - BTC_HF_CLIENT_INIT_EVT, - BTC_HF_CLIENT_DEINIT_EVT, - BTC_HF_CLIENT_CONNECT_EVT, - BTC_HF_CLIENT_DISCONNECT_EVT, - BTC_HF_CLIENT_CONNECT_AUDIO_EVT, - BTC_HF_CLIENT_DISCONNECT_AUDIO_EVT, - BTC_HF_CLIENT_START_VOICE_RECOGNITION_EVT, - BTC_HF_CLIENT_STOP_VOICE_RECOGNITION_EVT, - BTC_HF_CLIENT_VOLUME_UPDATE_EVT, - BTC_HF_CLIENT_DIAL_EVT, - BTC_HF_CLIENT_DIAL_MEMORY_EVT, - BTC_HF_CLIENT_SEND_CHLD_CMD_EVT, - BTC_HF_CLIENT_SEND_BTRH_CMD_EVT, - BTC_HF_CLIENT_ANSWER_CALL_EVT, - BTC_HF_CLIENT_REJECT_CALL_EVT, - BTC_HF_CLIENT_QUERY_CURRENT_CALLS_EVT, - BTC_HF_CLIENT_QUERY_CURRENT_OPERATOR_NAME_EVT, - BTC_HF_CLIENT_RETRIEVE_SUBSCRIBER_INFO_EVT, - BTC_HF_CLIENT_SEND_DTMF_EVT, - BTC_HF_CLIENT_REQUEST_LAST_VOICE_TAG_NUMBER_EVT, - BTC_HF_CLIENT_REGISTER_DATA_CALLBACK_EVT, -} btc_hf_client_act_t; - -/* btc_hf_client_args_t */ -typedef union { - // BTC_HF_CLIENT_CONNECT_EVT - bt_bdaddr_t connect; - - // BTC_HF_CLIENT_DISCONNECT_EVT - bt_bdaddr_t disconnect; - - // BTC_HF_CLIENT_CONNECT_AUDIO_EVT - bt_bdaddr_t connect_audio; - - // BTC_HF_CLIENT_DISCONNECT_AUDIO_EVT - bt_bdaddr_t disconnect_audio; - - // BTC_HF_CLIENT_VOLUME_UPDATE_EVT, - struct volume_update_args { - esp_hf_volume_control_target_t type; - int volume; - } volume_update; - - // BTC_HF_CLIENT_DIAL_EVT - struct dial_args { - char number[ESP_BT_HF_CLIENT_NUMBER_LEN + 1]; - } dial; - - // BTC_HF_CLIENT_DIAL_MEMORY_EVT - struct dial_memory_args { - int location; - } dial_memory; - - // BTC_HF_CLIENT_SEND_CHLD_CMD_EVT - struct send_chld_cmd_args { - esp_hf_chld_type_t type; - int idx; - } chld; - - // BTC_HF_CLIENT_SEND_BTRH_CMD_EVT - struct send_btrh_cmd_args { - esp_hf_btrh_cmd_t cmd; - } btrh; - - // BTC_HF_CLIENT_SEND_DTMF_EVT - struct send_dtmf { - char code; - } send_dtmf; - - // BTC_HF_CLIENT_REGISTER_DATA_CALLBACK_EVT - struct reg_data_callback { - esp_hf_client_incoming_data_cb_t recv; - esp_hf_client_outgoing_data_cb_t send; - } reg_data_cb; -} btc_hf_client_args_t; - -/******************************************************************************* -** BTC HF AG API -********************************************************************************/ - -void btc_hf_client_call_handler(btc_msg_t *msg); - -void btc_hf_client_cb_handler(btc_msg_t *msg); - -void btc_hf_client_incoming_data_cb_to_app(const uint8_t *data, uint32_t len); - -uint32_t btc_hf_client_outgoing_data_cb_to_app(uint8_t *data, uint32_t len); -#endif ///BTC_HF_CLIENT_INCLUDED == TRUE - -#endif /* __BTC_HF_CLIENT_H__ */ diff --git a/tools/sdk/include/bluedroid/btc_spp.h b/tools/sdk/include/bluedroid/btc_spp.h deleted file mode 100644 index a8b409e0..00000000 --- a/tools/sdk/include/bluedroid/btc_spp.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __BTC_SPP_H__ -#define __BTC_SPP_H__ - -#include "btc/btc_task.h" -#include "esp_bt_defs.h" -#include "esp_spp_api.h" -#include "common/bt_target.h" -#include "bta/bta_jv_api.h" - -#if (defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE) - -#define ESP_SPP_MAX_SESSION BTA_JV_MAX_RFC_SR_SESSION -#define ESP_SPP_SERVER_NAME_MAX 32 - -#define ESP_SPP_RINGBUF_SIZE 1000 - -typedef enum { - BTC_SPP_ACT_INIT = 0, - BTC_SPP_ACT_UNINIT, - BTC_SPP_ACT_START_DISCOVERY, - BTC_SPP_ACT_CONNECT, - BTC_SPP_ACT_DISCONNECT, - BTC_SPP_ACT_START_SRV, - BTC_SPP_ACT_WRITE, -} btc_spp_act_t; - -/* btc_spp_args_t */ -typedef union { - //BTC_SPP_ACT_INIT - struct init_arg { - esp_spp_mode_t mode; - } init; - //BTC_SPP_ACT_UNINIT - struct uninit_arg { - } uninit; - - //BTC_SPP_ACT_START_DISCOVERY - struct start_discovery_arg { - BD_ADDR bd_addr; - UINT16 num_uuid; - tSDP_UUID *p_uuid_list; - } start_discovery; - //BTC_SPP_ACT_CONNECT - struct connect_arg { - esp_spp_sec_t sec_mask; - esp_spp_role_t role; - UINT8 remote_scn; - esp_bd_addr_t peer_bd_addr; - } connect; - //BTC_SPP_ACT_DISCONNECT - struct disconnect_arg { - UINT32 handle; - } disconnect; - //BTC_SPP_ACT_START_SRV - struct start_srv_arg { - esp_spp_sec_t sec_mask; - esp_spp_role_t role; - UINT8 local_scn; - UINT8 max_session; - char name[ESP_SPP_SERVER_NAME_MAX + 1]; - } start_srv; - //BTC_SPP_ACT_WRITE - struct write_arg { - UINT32 handle; - int len; - UINT8 *p_data; - } write; - -} btc_spp_args_t; - - -void btc_spp_call_handler(btc_msg_t *msg); -void btc_spp_cb_handler(btc_msg_t *msg); -void btc_spp_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); - -esp_err_t btc_spp_vfs_register(void); -#endif ///defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE -#endif ///__BTC_SPP_H__ diff --git a/tools/sdk/include/bluedroid/button_pro.h b/tools/sdk/include/bluedroid/button_pro.h deleted file mode 100644 index 489acf59..00000000 --- a/tools/sdk/include/bluedroid/button_pro.h +++ /dev/null @@ -1,120 +0,0 @@ -#include "prf_defs.h" -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -#if (BUT_PROFILE_CFG) -#include "common/bt_target.h" -#include "stack/gatt_api.h" -#include "stack/gattdefs.h" -#include "esp_gatt_api.h" - -#define KEY_SUCCESS GATT_SUCCESS -#define KEY_ILLEGAL_PARAM GATT_ILLEGAL_PARAMETER -#define KEY_NO_RESOURCES GATT_NO_RESOURCES - -//define the key serivce uuid -#define ATT_SVC_BUTTON 0xFFFF -//define the key Char uuid -#define ATT_CHAR_BUTTON_WIT 0xFF01 -#define ATT_CHAR_BUTTON_NTF 0xFF02 - -#define BUTTON_PRESS_NTF_CFG 0x01 - -#define BUTTON_VAL_MAX_LEN (10) - -#define BUTT_MAX_APPS GATT_CL_MAX_LCB - -#define BUT_MAX_STRING_DATA 7 - -typedef void (*but_prf_cb_t)(uint8_t app_id, uint8_t event, uint16_t len, uint8_t *value); - -#ifndef BUT_MAX_INT_NUM -#define BUT_MAX_INT_NUM 4 -#endif - -enum { - RECEIVE_NET_PASSWD_EVT, - RECEIVE_NET_SSD_EVT, - RECEIVE_EVT_MAX -}; - -/// button Service Attributes Indexes -enum { - KEY_IDX_SVC, - KEY_IDX_BUTTON_WIT_CHAR, - KEY_IDX_BUTTON_WIT_VAL, - KEY_IDX_BUTTON_NTF_CHAR, - KEY_IDX_BUTTON_NTF_VAL, - KEY_IDX_BUTTON_NTF_CFG, - - KEY_IDX_NB, -}; - -typedef struct { - BD_ADDR remote_bda; - BOOLEAN need_rsp; - uint16_t clt_cfg; -} but_write_data_t; - -typedef struct { - BOOLEAN in_use; - BOOLEAN congest; - uint16_t conn_id; - BOOLEAN connected; - BD_ADDR remote_bda; - uint32_t trans_id; - uint8_t cur_srvc_id; - -} but_clcb_t; - - -typedef struct { - uint8_t app_id; - uint16_t but_wirt_hdl; - uint16_t but_ntf_hdl; - uint16_t but_cfg_hdl; - - but_prf_cb_t p_cback; - -} but_inst_t; - - -/* service engine control block */ -typedef struct { - but_clcb_t clcb; /* connection link*/ - esp_gatt_if_t gatt_if; - BOOLEAN enabled; - BOOLEAN is_primery; - but_inst_t button_inst; - uint8_t inst_id; -} button_env_cb_t; - -void Button_CreateService(void); - -but_clcb_t *button_env_clcb_alloc(uint16_t conn_id, BD_ADDR bda); - -uint16_t button_env_find_conn_id_by_bd_adddr(BD_ADDR bda); - -BOOLEAN button_env_clcb_dealloc(uint16_t conn_id); - -esp_gatt_status_t button_init(but_prf_cb_t call_back); - -void button_disable(uint16_t connid); - -void button_msg_notify(uint16_t len, uint8_t *button_msg); - -extern button_env_cb_t button_cb_env; - -#endif ///BUT_PROFILE_CFG diff --git a/tools/sdk/include/bluedroid/common/bt_common_types.h b/tools/sdk/include/bluedroid/common/bt_common_types.h deleted file mode 100644 index a6b34918..00000000 --- a/tools/sdk/include/bluedroid/common/bt_common_types.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - - - - -#ifndef _BT_COMMON_TYPES_H_ -#define _BT_COMMON_TYPES_H_ - -#include "common/bt_defs.h" -#include "osi/thread.h" - -typedef void (* bluedroid_init_done_cb_t)(void); - -typedef struct { - uint8_t client_if; - uint8_t filt_index; - uint8_t advertiser_state; - uint8_t advertiser_info_present; - uint8_t addr_type; - uint8_t tx_power; - int8_t rssi_value; - uint16_t time_stamp; - bt_bdaddr_t bd_addr; - uint8_t adv_pkt_len; - uint8_t *p_adv_pkt_data; - uint8_t scan_rsp_len; - uint8_t *p_scan_rsp_data; -} btgatt_track_adv_info_t; - -#endif diff --git a/tools/sdk/include/bluedroid/common/bt_defs.h b/tools/sdk/include/bluedroid/common/bt_defs.h deleted file mode 100644 index 77719bc8..00000000 --- a/tools/sdk/include/bluedroid/common/bt_defs.h +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * common/bt_defs.h Defines useful API for whole Bluedroid - * - */ -#ifndef _BT_DEFS_H_ -#define _BT_DEFS_H_ - -#include -#include -#include "common/bt_trace.h" -#include "common/bt_target.h" - -#define UNUSED(x) (void)(x) - -/*Timer Related Defination*/ - -//by Snake.T -typedef void (TIMER_CBACK)(void *p_tle); -typedef struct _tle { - struct _tle *p_next; - struct _tle *p_prev; - TIMER_CBACK *p_cback; - INT32 ticks; - INT32 ticks_initial; - TIMER_PARAM_TYPE param; - TIMER_PARAM_TYPE data; - UINT16 event; - UINT8 in_use; -} TIMER_LIST_ENT; - -#define alarm_timer_t uint32_t -#define alarm_timer_setfn(timer, cb, data) \ -do { \ -} while (0) -#define alarm_timer_arm(timer, to, periodic) \ -do { \ -} while (0) -#define alarm_timer_disarm(timer) \ -do { \ -} while (0) -#define alarm_timer_now() (0) - - -/*Bluetooth Address*/ -typedef struct { - uint8_t address[6]; -} __attribute__ ((__packed__)) bt_bdaddr_t; - -/** Bluetooth 128-bit UUID */ -typedef struct { - uint8_t uu[16]; -} bt_uuid_t; - -/** Bluetooth Error Status */ -/** We need to build on this */ - -/* relate to ESP_BT_STATUS_xxx in esp_bt_defs.h */ -typedef enum { - BT_STATUS_SUCCESS = 0, - BT_STATUS_FAIL, - BT_STATUS_NOT_READY, - BT_STATUS_NOMEM, - BT_STATUS_BUSY, - BT_STATUS_DONE, /* request already completed */ - BT_STATUS_UNSUPPORTED, - BT_STATUS_PARM_INVALID, - BT_STATUS_UNHANDLED, - BT_STATUS_AUTH_FAILURE, - BT_STATUS_RMT_DEV_DOWN, - BT_STATUS_AUTH_REJECTED, - BT_STATUS_INVALID_STATIC_RAND_ADDR, - BT_STATUS_PENDING, - BT_STATUS_UNACCEPT_CONN_INTERVAL, - BT_STATUS_PARAM_OUT_OF_RANGE, - BT_STATUS_TIMEOUT, - BT_STATUS_MEMORY_FULL, -} bt_status_t; - -#ifndef CPU_LITTLE_ENDIAN -#define CPU_LITTLE_ENDIAN -#endif - -inline uint16_t swap_byte_16(uint16_t x) -{ - return (((x & 0x00ffU) << 8) | - ((x & 0xff00U) >> 8)); -} - -inline uint32_t swap_byte_32(uint32_t x) -{ - return (((x & 0x000000ffUL) << 24) | - ((x & 0x0000ff00UL) << 8) | - ((x & 0x00ff0000UL) >> 8) | - ((x & 0xff000000UL) >> 24)); -} - -#ifndef ntohs -inline uint16_t ntohs(uint16_t x) -{ -#ifdef CPU_LITTLE_ENDIAN - return swap_byte_16(x); -#else - return x; -#endif -} -#endif /* #ifndef ntohs */ - -#ifndef htons -inline uint16_t htons(uint16_t x) -{ -#ifdef CPU_LITTLE_ENDIAN - return swap_byte_16(x); -#else - return x; -#endif -} -#endif /* #ifndef htons */ - -#ifndef ntohl -inline uint32_t ntohl(uint32_t x) -{ -#ifdef CPU_LITTLE_ENDIAN - return swap_byte_32(x); -#else - return x; -#endif -} -#endif /* #ifndef ntohl*/ - -#ifndef htonl -inline uint32_t htonl(uint32_t x) -{ -#ifdef CPU_LITTLE_ENDIAN - return swap_byte_32(x); -#else - return x; -#endif -} -#endif /* #ifndef htonl*/ - -#endif /* _BT_DEFS_H_ */ diff --git a/tools/sdk/include/bluedroid/common/bt_target.h b/tools/sdk/include/bluedroid/common/bt_target.h deleted file mode 100644 index 331ff20e..00000000 --- a/tools/sdk/include/bluedroid/common/bt_target.h +++ /dev/null @@ -1,1967 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 2014 The Android Open Source Project - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef BT_TARGET_H -#define BT_TARGET_H - -#ifndef BUILDCFG -#define BUILDCFG -#endif - -/* -#if !defined(HAS_BDROID_BUILDCFG) && !defined(HAS_NO_BDROID_BUILDCFG) -#error "An Android.mk file did not include bdroid_CFLAGS and possibly not bdorid_C_INCLUDES" -#endif -*/ - -#ifdef HAS_BDROID_BUILDCFG -#include "bdroid_buildcfg.h" -#endif - -#include "sdkconfig.h" -#include "stack/bt_types.h" /* This must be defined AFTER buildcfg.h */ - -#include "stack/dyn_mem.h" /* defines static and/or dynamic memory for components */ - -/****************************************************************************** -** -** Classic BT features -** -******************************************************************************/ -#if CONFIG_CLASSIC_BT_ENABLED -#define CLASSIC_BT_INCLUDED TRUE -#define BTC_SM_INCLUDED TRUE -#define BTC_PRF_QUEUE_INCLUDED TRUE -#define BTC_GAP_BT_INCLUDED TRUE -#define BTA_SDP_INCLUDED TRUE -#define BTA_DM_PM_INCLUDED TRUE -#define SDP_INCLUDED TRUE -#define BT_SSP_INCLUDED TRUE - -#if CONFIG_A2DP_ENABLE -#define BTA_AR_INCLUDED TRUE -#define BTA_AV_INCLUDED TRUE -#define AVDT_INCLUDED TRUE -#define A2D_INCLUDED TRUE -#define AVCT_INCLUDED TRUE -#define AVRC_INCLUDED TRUE -#define BTC_AV_INCLUDED TRUE -#define BTA_AV_SINK_INCLUDED TRUE -#define BTC_AV_SINK_INCLUDED TRUE -#define SBC_DEC_INCLUDED TRUE -#define BTC_AV_SRC_INCLUDED TRUE -#define SBC_ENC_INCLUDED TRUE -#endif /* CONFIG_A2DP_ENABLE */ - -#if CONFIG_BT_SPP_ENABLED -#define RFCOMM_INCLUDED TRUE -#define BTA_JV_INCLUDED TRUE -#define BTC_SPP_INCLUDED TRUE -#endif /* CONFIG_BT_SPP_ENABLED */ - -#if CONFIG_HFP_CLIENT_ENABLE -#define BTC_HF_CLIENT_INCLUDED TRUE -#define BTA_HF_INCLUDED TRUE -#ifndef RFCOMM_INCLUDED -#define RFCOMM_INCLUDED TRUE -#endif -#ifndef BTM_SCO_INCLUDED -#define BTM_SCO_INCLUDED TRUE -#endif -#ifndef BTM_MAX_SCO_LINKS -#define BTM_MAX_SCO_LINKS (1) -#endif -#endif /* CONFIG_HFP_HF_ENABLE */ - -#endif /* #if CONFIG_CLASSIC_BT_ENABLED */ - -#ifndef CLASSIC_BT_INCLUDED -#define CLASSIC_BT_INCLUDED FALSE -#endif /* CLASSIC_BT_INCLUDED */ - -#ifndef CONFIG_GATTC_CACHE_NVS_FLASH -#define CONFIG_GATTC_CACHE_NVS_FLASH FALSE -#endif /* CONFIG_GATTC_CACHE_NVS_FLASH */ - -/****************************************************************************** -** -** BLE features -** -******************************************************************************/ -#if (CONFIG_GATTS_ENABLE) -#define GATTS_INCLUDED TRUE -#else -#define GATTS_INCLUDED FALSE -#endif /* CONFIG_GATTS_ENABLE */ - -#if (CONFIG_GATTC_ENABLE) -#define GATTC_INCLUDED TRUE -#else -#define GATTC_INCLUDED FALSE -#endif /* CONFIG_GATTC_ENABLE */ - -#if (CONFIG_GATTC_ENABLE && CONFIG_GATTC_CACHE_NVS_FLASH) -#define GATTC_CACHE_NVS TRUE -#else -#define GATTC_CACHE_NVS FALSE -#endif /* CONFIG_GATTC_CACHE_NVS_FLASH */ - -#if (CONFIG_SMP_ENABLE) -#define SMP_INCLUDED TRUE -#define BLE_PRIVACY_SPT TRUE -#else -#define SMP_INCLUDED FALSE -#define BLE_PRIVACY_SPT FALSE -#endif /* CONFIG_SMP_ENABLE */ - -#if (CONFIG_BT_ACL_CONNECTIONS) -#define MAX_ACL_CONNECTIONS CONFIG_BT_ACL_CONNECTIONS -#define GATT_MAX_PHY_CHANNEL CONFIG_BT_ACL_CONNECTIONS -#endif /* CONFIG_BT_ACL_CONNECTIONS */ - -//------------------Added from bdroid_buildcfg.h--------------------- -#ifndef L2CAP_EXTFEA_SUPPORTED_MASK -#define L2CAP_EXTFEA_SUPPORTED_MASK (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE | L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_FIXED_CHNLS) -#endif - -#ifndef BTUI_OPS_FORMATS -#define BTUI_OPS_FORMATS (BTA_OP_VCARD21_MASK | BTA_OP_ANY_MASK) -#endif - -#ifndef BTA_RFC_MTU_SIZE -#define BTA_RFC_MTU_SIZE (L2CAP_MTU_SIZE-L2CAP_MIN_OFFSET-RFCOMM_DATA_OVERHEAD) -#endif - -#ifndef SBC_NO_PCM_CPY_OPTION -#define SBC_NO_PCM_CPY_OPTION FALSE -#endif - -#ifndef BT_APP_DEMO -#define BT_APP_DEMO TRUE -#endif - -#ifndef BTIF_INCLUDED -#define BTIF_INCLUDED FALSE -#endif - -/****************************************************************************** -** -** BTC-layer components -** -******************************************************************************/ -#ifndef BTC_GAP_BT_INCLUDED -#define BTC_GAP_BT_INCLUDED FALSE -#endif - -#ifndef BTC_PRF_QUEUE_INCLUDED -#define BTC_PRF_QUEUE_INCLUDED FALSE -#endif - -#ifndef BTC_SM_INCLUDED -#define BTC_SM_INCLUDED FALSE -#endif - -#ifndef BTC_AV_INCLUDED -#define BTC_AV_INCLUDED FALSE -#endif - -#ifndef BTC_AV_SINK_INCLUDED -#define BTC_AV_SINK_INCLUDED FALSE -#endif - -#ifndef BTC_AV_SRC_INCLUDED -#define BTC_AV_SRC_INCLUDED FALSE -#endif - -#ifndef BTC_SPP_INCLUDED -#define BTC_SPP_INCLUDED FALSE -#endif - -#ifndef SBC_DEC_INCLUDED -#define SBC_DEC_INCLUDED FALSE -#endif - -#ifndef SBC_ENC_INCLUDED -#define SBC_ENC_INCLUDED FALSE -#endif - -/****************************************************************************** -** -** BTA-layer components -** -******************************************************************************/ -#ifndef BTA_INCLUDED -#define BTA_INCLUDED TRUE -#endif - -#ifndef BTA_DM_PM_INCLUDED -#define BTA_DM_PM_INCLUDED FALSE -#endif - -#ifndef BTA_PAN_INCLUDED -#define BTA_PAN_INCLUDED FALSE -#endif - -#ifndef BTA_HH_INCLUDED -#define BTA_HH_INCLUDED FALSE -#endif - -#ifndef BTA_HH_ROLE -#define BTA_HH_ROLE BTA_MASTER_ROLE_PREF -#endif - -#ifndef BTA_HH_LE_INCLUDED -#define BTA_HH_LE_INCLUDED FALSE -#endif - -#ifndef BTA_AR_INCLUDED -#define BTA_AR_INCLUDED FALSE -#endif - -#ifndef BTA_AV_INCLUDED -#define BTA_AV_INCLUDED FALSE -#endif - -#ifndef BTA_AV_SINK_INCLUDED -#define BTA_AV_SINK_INCLUDED FALSE -#endif - -#ifndef BTA_JV_INCLUDED -#define BTA_JV_INCLUDED FALSE -#endif - -#ifndef BTA_SDP_INCLUDED -#define BTA_SDP_INCLUDED FALSE -#endif - -/****************************************************************************** -** -** Stack-layer components -** -******************************************************************************/ -#ifndef AVCT_INCLUDED -#define AVCT_INCLUDED FALSE -#endif - -#ifndef AVDT_INCLUDED -#define AVDT_INCLUDED FALSE -#endif - -/****************************************************************************** -** -** Parameter Configurations for components -** -******************************************************************************/ -#ifndef BTA_DISABLE_DELAY -#define BTA_DISABLE_DELAY 200 /* in milliseconds */ -#endif - -#ifndef BTA_SYS_TIMER_PERIOD -#define BTA_SYS_TIMER_PERIOD 100 -#endif - -#ifndef SBC_FOR_EMBEDDED_LINUX -#define SBC_FOR_EMBEDDED_LINUX TRUE -#endif - -#ifndef AVDT_VERSION -#define AVDT_VERSION 0x0102 -#endif - -#ifndef BTA_AG_AT_MAX_LEN -#define BTA_AG_AT_MAX_LEN 512 -#endif - -#ifndef BTA_AVRCP_FF_RW_SUPPORT -#define BTA_AVRCP_FF_RW_SUPPORT FALSE//TRUE -#endif - -#ifndef BTA_AG_SCO_PKT_TYPES -#define BTA_AG_SCO_PKT_TYPES (BTM_SCO_LINK_ONLY_MASK | BTM_SCO_PKT_TYPES_MASK_EV3 | BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | BTM_SCO_PKT_TYPES_MASK_NO_3_EV5) -#endif - -#ifndef BTA_AV_RET_TOUT -#define BTA_AV_RET_TOUT 15 -#endif - -#ifndef PORCHE_PAIRING_CONFLICT -#define PORCHE_PAIRING_CONFLICT TRUE -#endif - -#ifndef BTA_AV_CO_CP_SCMS_T -#define BTA_AV_CO_CP_SCMS_T FALSE//FALSE -#endif - -#ifndef QUEUE_CONGEST_SIZE -#define QUEUE_CONGEST_SIZE 40 -#endif - -#ifndef CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK -#define SCAN_QUEUE_CONGEST_CHECK FALSE -#else -#define SCAN_QUEUE_CONGEST_CHECK CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK -#endif - -/* This feature is used to eanble interleaved scan*/ -#ifndef BTA_HOST_INTERLEAVE_SEARCH -#define BTA_HOST_INTERLEAVE_SEARCH FALSE//FALSE -#endif - -#ifndef BT_USE_TRACES -#define BT_USE_TRACES FALSE -#endif - -#ifndef BT_TRACE_BTIF -#define BT_TRACE_BTIF TRUE -#endif - -#ifndef BT_TRACE_VERBOSE -#define BT_TRACE_VERBOSE FALSE -#endif - -#ifndef BTA_DM_SDP_DB_SIZE -#define BTA_DM_SDP_DB_SIZE 8000 -#endif - -#ifndef HL_INCLUDED -#define HL_INCLUDED TRUE -#endif - -#ifndef AG_VOICE_SETTINGS -#define AG_VOICE_SETTINGS HCI_DEFAULT_VOICE_SETTINGS -#endif - -#ifndef BTIF_DM_OOB_TEST -#define BTIF_DM_OOB_TEST FALSE//TRUE -#endif - -// How long to wait before activating sniff mode after entering the -// idle state for FTS, OPS connections -#ifndef BTA_FTS_OPS_IDLE_TO_SNIFF_DELAY_MS -#define BTA_FTS_OPS_IDLE_TO_SNIFF_DELAY_MS 7000 -#endif - -//------------------End added from bdroid_buildcfg.h--------------------- - - -/****************************************************************************** -** -** Buffer Size -** -******************************************************************************/ - -#ifndef BT_DEFAULT_BUFFER_SIZE -#define BT_DEFAULT_BUFFER_SIZE (4096 + 16) -#endif - -#ifndef BT_SMALL_BUFFER_SIZE -#define BT_SMALL_BUFFER_SIZE 660 -#endif - -/* Receives HCI events from the lower-layer. */ -#ifndef HCI_CMD_BUF_SIZE -#define HCI_CMD_BUF_SIZE BT_SMALL_BUFFER_SIZE -#endif - -/* Sends SDP data packets. */ -#ifndef SDP_DATA_BUF_SIZE -#define SDP_DATA_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/* Sends RFCOMM command packets. */ -#ifndef RFCOMM_CMD_BUF_SIZE -#define RFCOMM_CMD_BUF_SIZE BT_SMALL_BUFFER_SIZE -#endif - -/* Sends RFCOMM data packets. */ -#ifndef RFCOMM_DATA_BUF_SIZE -#define RFCOMM_DATA_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/* Sends L2CAP packets to the peer and HCI messages to the controller. */ -#ifndef L2CAP_CMD_BUF_SIZE -#define L2CAP_CMD_BUF_SIZE BT_SMALL_BUFFER_SIZE -#endif - -#ifndef L2CAP_USER_TX_BUF_SIZE -#define L2CAP_USER_TX_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -#ifndef L2CAP_USER_RX_BUF_SIZE -#define L2CAP_USER_RX_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/* Sends L2CAP segmented packets in ERTM mode */ -#ifndef L2CAP_FCR_TX_BUF_SIZE -#define L2CAP_FCR_TX_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/* Receives L2CAP segmented packets in ERTM mode */ -#ifndef L2CAP_FCR_RX_BUF_SIZE -#define L2CAP_FCR_RX_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -#ifndef L2CAP_FCR_ERTM_BUF_SIZE -#define L2CAP_FCR_ERTM_BUF_SIZE (10240 + 24) -#endif - -/* Number of ACL buffers to assign to LE - if the HCI buffer pool is shared with BR/EDR */ -#ifndef L2C_DEF_NUM_BLE_BUF_SHARED -#define L2C_DEF_NUM_BLE_BUF_SHARED 1 -#endif - -/* Used by BTM when it sends HCI commands to the controller. */ -#ifndef BTM_CMD_BUF_SIZE -#define BTM_CMD_BUF_SIZE BT_SMALL_BUFFER_SIZE -#endif - -#ifndef OBX_LRG_DATA_BUF_SIZE -#define OBX_LRG_DATA_BUF_SIZE (8080 + 26) -#endif - -/* Used to send data to L2CAP. */ -#ifndef GAP_DATA_BUF_SIZE -#define GAP_DATA_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/* BNEP data and protocol messages. */ -#ifndef BNEP_BUF_SIZE -#define BNEP_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/* AVDTP buffer size for protocol messages */ -#ifndef AVDT_CMD_BUF_SIZE -#define AVDT_CMD_BUF_SIZE BT_SMALL_BUFFER_SIZE -#endif - -/* AVDTP buffer size for media packets in case of fragmentation */ -#ifndef AVDT_DATA_BUF_SIZE -#define AVDT_DATA_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -#ifndef PAN_BUF_SIZE -#define PAN_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/* Maximum number of buffers to allocate for PAN */ -#ifndef PAN_BUF_MAX -#define PAN_BUF_MAX 100 -#endif - -/* AVCTP buffer size for protocol messages */ -#ifndef AVCT_CMD_BUF_SIZE -#define AVCT_CMD_BUF_SIZE 288 -#endif - -/* AVRCP buffer size for protocol messages */ -#ifndef AVRC_CMD_BUF_SIZE -#define AVRC_CMD_BUF_SIZE 288 -#endif - -/* AVRCP Metadata buffer size for protocol messages */ -#ifndef AVRC_META_CMD_BUF_SIZE -#define AVRC_META_CMD_BUF_SIZE BT_SMALL_BUFFER_SIZE -#endif - -#ifndef BTA_HL_LRG_DATA_BUF_SIZE -#define BTA_HL_LRG_DATA_BUF_SIZE (10240 + 24) -#endif - -/* GATT Server Database buffer size */ -#ifndef GATT_DB_BUF_SIZE -#define GATT_DB_BUF_SIZE 128 -#endif - -/* GATT Data sending buffer size */ -#ifndef GATT_DATA_BUF_SIZE -#define GATT_DATA_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/****************************************************************************** -** -** HCI Services (H4) -** -******************************************************************************/ - -/* Use 2 second for low-resolution systems, override to 1 for high-resolution systems */ -#ifndef BT_1SEC_TIMEOUT -#define BT_1SEC_TIMEOUT (2) -#endif - -/* Quick Timer */ -/* if L2CAP_FCR_INCLUDED is TRUE then it should have 100 millisecond resolution */ -/* if none of them is included then QUICK_TIMER_TICKS_PER_SEC is set to 0 to exclude quick timer */ -#ifndef QUICK_TIMER_TICKS_PER_SEC -#define QUICK_TIMER_TICKS_PER_SEC 10 /* 100ms timer */ -#endif - -/****************************************************************************** -** -** BTM -** -******************************************************************************/ - -/* Cancel Inquiry on incoming SSP */ -#ifndef BTM_NO_SSP_ON_INQUIRY -#define BTM_NO_SSP_ON_INQUIRY FALSE -#endif - -/* Includes SCO if TRUE */ -#ifndef BTM_SCO_INCLUDED -#define BTM_SCO_INCLUDED FALSE /* TRUE includes SCO code */ -#endif - -/* Includes SCO if TRUE */ -#ifndef BTM_SCO_HCI_INCLUDED -#if CONFIG_HFP_AUDIO_DATA_PATH_HCI -#define BTM_SCO_HCI_INCLUDED TRUE /* TRUE includes SCO over HCI code */ -#else -#define BTM_SCO_HCI_INCLUDED FALSE -#endif /* CONFIG_HFP_AUDIO_DATA_PATH_HCI */ -#endif - -/* Includes WBS if TRUE */ -#ifndef BTM_WBS_INCLUDED -#define BTM_WBS_INCLUDED FALSE /* TRUE includes WBS code */ -#endif - -/* This is used to work around a controller bug that doesn't like Disconnect -** issued while there is a role switch in progress -*/ -#ifndef BTM_DISC_DURING_RS -#define BTM_DISC_DURING_RS TRUE -#endif - -/************************** -** Initial SCO TX credit -*************************/ -/* max TX SCO data packet size */ -#ifndef BTM_SCO_DATA_SIZE_MAX -#define BTM_SCO_DATA_SIZE_MAX 120 //240 -#endif - -/* The size in bytes of the BTM inquiry database. 5 As Default */ -#ifndef BTM_INQ_DB_SIZE -#define BTM_INQ_DB_SIZE 5 -#endif - -/* The default scan mode */ -#ifndef BTM_DEFAULT_SCAN_TYPE -#define BTM_DEFAULT_SCAN_TYPE BTM_SCAN_TYPE_INTERLACED -#endif - -/* Should connections to unknown devices be allowed when not discoverable? */ -#ifndef BTM_ALLOW_CONN_IF_NONDISCOVER -#define BTM_ALLOW_CONN_IF_NONDISCOVER TRUE -#endif - -/* Sets the Page_Scan_Window: the length of time that the device is performing a page scan. */ -#ifndef BTM_DEFAULT_CONN_WINDOW -#define BTM_DEFAULT_CONN_WINDOW 0x0012 -#endif - -/* Sets the Page_Scan_Activity: the interval between the start of two consecutive page scans. */ -#ifndef BTM_DEFAULT_CONN_INTERVAL -#define BTM_DEFAULT_CONN_INTERVAL 0x0800 -#endif - -/* When automatic inquiry scan is enabled, this sets the inquiry scan window. */ -#ifndef BTM_DEFAULT_DISC_WINDOW -#define BTM_DEFAULT_DISC_WINDOW 0x0012 -#endif - -/* When automatic inquiry scan is enabled, this sets the inquiry scan interval. */ -#ifndef BTM_DEFAULT_DISC_INTERVAL -#define BTM_DEFAULT_DISC_INTERVAL 0x0800 -#endif - -/* -* {SERVICE_CLASS, MAJOR_CLASS, MINOR_CLASS} -* -* SERVICE_CLASS:0x5A (Bit17 -Networking,Bit19 - Capturing,Bit20 -Object Transfer,Bit22 -Telephony) -* MAJOR_CLASS:0x02 - PHONE -* MINOR_CLASS:0x0C - SMART_PHONE -* -*/ -#define BTA_DM_COD_SMARTPHONE {0x5A, 0x02, 0x0C} - -/* -* {SERVICE_CLASS, MAJOR_CLASS, MINOR_CLASS} -* -* SERVICE_CLASS:0x2C (Bit21 - Audio, Bit19 - Capturing) -* MAJOR_CLASS:0x04 - Audio/Video -* MINOR_CLASS:0x05 - LoudSpeaker -*/ -#define BTA_DM_COD_LOUDSPEAKER {0x2C, 0x04, 0x14} - -/* Default class of device */ -#ifndef BTA_DM_COD -#define BTA_DM_COD BTA_DM_COD_LOUDSPEAKER -#endif - -/* The number of SCO links. */ -#ifndef BTM_MAX_SCO_LINKS -#define BTM_MAX_SCO_LINKS 0 //3 -#endif - -/* The preferred type of SCO links (2-eSCO, 0-SCO). */ -#ifndef BTM_DEFAULT_SCO_MODE -#define BTM_DEFAULT_SCO_MODE 2 -#endif - -/* The number of security records for peer devices. 100 AS Default*/ -#ifndef BTM_SEC_MAX_DEVICE_RECORDS -#if SMP_INCLUDED == TRUE -#define BTM_SEC_MAX_DEVICE_RECORDS 15 // 100 -#else -#define BTM_SEC_MAX_DEVICE_RECORDS 8 -#endif /* SMP_INCLUDED == TRUE */ -#endif - -/* The number of security records for services. 32 AS Default*/ -#ifndef BTM_SEC_MAX_SERVICE_RECORDS -#define BTM_SEC_MAX_SERVICE_RECORDS 8 // 32 -#endif - -/* If True, force a retrieval of remote device name for each bond in case it's changed */ -#ifndef BTM_SEC_FORCE_RNR_FOR_DBOND -#define BTM_SEC_FORCE_RNR_FOR_DBOND FALSE -#endif - -/* Maximum device name length used in btm database. Up to 248*/ -#ifndef BTM_MAX_REM_BD_NAME_LEN -#define BTM_MAX_REM_BD_NAME_LEN 64 -#endif - -/* Maximum local device name length stored btm database. - '0' disables storage of the local name in BTM */ -#ifndef BTM_MAX_LOC_BD_NAME_LEN -#define BTM_MAX_LOC_BD_NAME_LEN 64 -#endif - -/* Fixed Default String. When this is defined as null string, the device's - * product model name is used as the default local name. - */ -#ifndef BTM_DEF_LOCAL_NAME -#define BTM_DEF_LOCAL_NAME "" -#endif - -/* Maximum service name stored with security authorization (0 if not needed) */ -#ifndef BTM_SEC_SERVICE_NAME_LEN -#define BTM_SEC_SERVICE_NAME_LEN BT_MAX_SERVICE_NAME_LEN -#endif - -/* Maximum length of the service name. */ -#ifndef BT_MAX_SERVICE_NAME_LEN -#define BT_MAX_SERVICE_NAME_LEN 21 -#endif - -/* ACL buffer size in HCI Host Buffer Size command. */ -#ifndef BTM_ACL_BUF_SIZE -#define BTM_ACL_BUF_SIZE 0 -#endif - -/* The maximum number of clients that can register with the power manager. */ -#ifndef BTM_MAX_PM_RECORDS -#define BTM_MAX_PM_RECORDS 2 -#endif - -/* This is set to show debug trace messages for the power manager. */ -#ifndef BTM_PM_DEBUG -#define BTM_PM_DEBUG FALSE -#endif - -/* This is set to TRUE if link is to be unparked due to BTM_CreateSCO API. */ -#ifndef BTM_SCO_WAKE_PARKED_LINK -#define BTM_SCO_WAKE_PARKED_LINK FALSE -#endif - -/* If the user does not respond to security process requests within this many seconds, - * a negative response would be sent automatically. - * 30 is LMP response timeout value */ -#ifndef BTM_SEC_TIMEOUT_VALUE -#define BTM_SEC_TIMEOUT_VALUE 35 -#endif - -/* Maximum number of callbacks that can be registered using BTM_RegisterForVSEvents */ -#ifndef BTM_MAX_VSE_CALLBACKS -#define BTM_MAX_VSE_CALLBACKS 3 -#endif - -/****************************************** -** Lisbon Features -*******************************************/ -/* This is set to TRUE if the FEC is required for EIR packet. */ -#ifndef BTM_EIR_DEFAULT_FEC_REQUIRED -#define BTM_EIR_DEFAULT_FEC_REQUIRED TRUE -#endif - -/* The IO capability of the local device (for Simple Pairing) */ -#ifndef BTM_LOCAL_IO_CAPS -#define BTM_LOCAL_IO_CAPS BTM_IO_CAP_NONE -#endif - -#ifndef BTM_LOCAL_IO_CAPS_BLE -#if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE) -#define BTM_LOCAL_IO_CAPS_BLE BTM_IO_CAP_KBDISP -#else -#define BTM_LOCAL_IO_CAPS_BLE 4 -#endif ///BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE -#endif - -/* The default MITM Protection Requirement (for Simple Pairing) - * Possible values are BTM_AUTH_SP_YES or BTM_AUTH_SP_NO */ -#ifndef BTM_DEFAULT_AUTH_REQ -#define BTM_DEFAULT_AUTH_REQ BTM_AUTH_SP_NO -#endif - -/* The default MITM Protection Requirement for dedicated bonding using Simple Pairing - * Possible values are BTM_AUTH_AP_YES or BTM_AUTH_AP_NO */ -#ifndef BTM_DEFAULT_DD_AUTH_REQ -#define BTM_DEFAULT_DD_AUTH_REQ BTM_AUTH_AP_YES -#endif - -/* Include Out-of-Band implementation for Simple Pairing */ -#ifndef BTM_OOB_INCLUDED -#define BTM_OOB_INCLUDED TRUE -#endif - -/* TRUE to include Sniff Subrating */ -#if (BTA_DM_PM_INCLUDED == TRUE) -#ifndef BTM_SSR_INCLUDED -#define BTM_SSR_INCLUDED FALSE -#endif -#endif /* BTA_DM_PM_INCLUDED */ - -/************************* -** End of Lisbon Features -**************************/ - -/* 4.1/4.2 secure connections feature */ -#ifndef SC_MODE_INCLUDED -// Disable AES-CCM (BT 4.1) for BT Classic to workaround controller AES issue. E0 encryption (BT 4.0) will be used. -#define SC_MODE_INCLUDED FALSE -#endif - -/* Used for conformance testing ONLY */ -#ifndef BTM_BLE_CONFORMANCE_TESTING -#define BTM_BLE_CONFORMANCE_TESTING FALSE -#endif - -/****************************************************************************** -** -** CONTROLLER TO HOST FLOW CONTROL -** -******************************************************************************/ - -#define C2H_FLOW_CONTROL_INCLUDED TRUE - -/****************************************************************************** -** -** L2CAP -** -******************************************************************************/ - -#ifndef L2CAP_CLIENT_INCLUDED -#define L2CAP_CLIENT_INCLUDED FALSE -#endif - -/* The maximum number of simultaneous applications that can register with LE L2CAP. */ -#ifndef BLE_MAX_L2CAP_CLIENTS -#define BLE_MAX_L2CAP_CLIENTS 15 -#endif - - -/* The maximum number of simultaneous links that L2CAP can support. Up to 7*/ -#ifndef MAX_ACL_CONNECTIONS -#define MAX_L2CAP_LINKS 5 -#else -#define MAX_L2CAP_LINKS MAX_ACL_CONNECTIONS -#endif - -/* The maximum number of simultaneous channels that L2CAP can support. Up to 16*/ -#ifndef MAX_L2CAP_CHANNELS -#if (CLASSIC_BT_INCLUDED == TRUE) -#define MAX_L2CAP_CHANNELS 16 -#else -#if (SMP_INCLUDED == FALSE) -#define MAX_L2CAP_CHANNELS MAX_ACL_CONNECTIONS //This is used in the BLE client when start connected with the peer device -#else -#define MAX_L2CAP_CHANNELS (MAX_ACL_CONNECTIONS * 2) //This is used in the BLE client when start connected with the peer device and in SMP -#endif ///SMP_INCLUDED == FALSE -#endif ///CLASSIC_BT_INCLUDED == TRUE -#endif ///MAX_L2CAP_CHANNELS - -/* The maximum number of simultaneous applications that can register with L2CAP. */ -#ifndef MAX_L2CAP_CLIENTS -#if (CLASSIC_BT_INCLUDED == TRUE) -#define MAX_L2CAP_CLIENTS 8 -#else -#define MAX_L2CAP_CLIENTS 1 //Not support to allocate a channel control block in BLE only mode -#endif ///CLASSIC_BT_INCLUDED == TRUE -#endif - -/* The number of seconds of link inactivity before a link is disconnected. */ -#ifndef L2CAP_LINK_INACTIVITY_TOUT -#define L2CAP_LINK_INACTIVITY_TOUT 4 -#endif - -/* The number of seconds of link inactivity after bonding before a link is disconnected. */ -#ifndef L2CAP_BONDING_TIMEOUT -#define L2CAP_BONDING_TIMEOUT 3 -#endif - -/* The time from the HCI connection complete to disconnect if no channel is established. */ -#ifndef L2CAP_LINK_STARTUP_TOUT -#define L2CAP_LINK_STARTUP_TOUT 60 -#endif - -/* The L2CAP MTU; must be in accord with the HCI ACL pool size. */ -#ifndef L2CAP_MTU_SIZE -#define L2CAP_MTU_SIZE 1691 -#endif - -/* The L2CAP MPS over Bluetooth; must be in accord with the FCR tx pool size and ACL down buffer size. */ -#ifndef L2CAP_MPS_OVER_BR_EDR -#define L2CAP_MPS_OVER_BR_EDR 1010 -#endif - -/* If host flow control enabled, this is the number of buffers the controller can have unacknowledged. */ -#ifndef L2CAP_HOST_FC_ACL_BUFS -#define L2CAP_HOST_FC_ACL_BUFS 20 -#endif - -/* This is set to enable L2CAP to take the ACL link out of park mode when ACL data is to be sent. */ -#ifndef L2CAP_WAKE_PARKED_LINK -#define L2CAP_WAKE_PARKED_LINK TRUE -#endif - -/* Whether link wants to be the master or the slave. */ -#ifndef L2CAP_DESIRED_LINK_ROLE -#define L2CAP_DESIRED_LINK_ROLE HCI_ROLE_SLAVE -#endif - -/* Include Non-Flushable Packet Boundary Flag feature of Lisbon */ -#ifndef L2CAP_NON_FLUSHABLE_PB_INCLUDED -#define L2CAP_NON_FLUSHABLE_PB_INCLUDED TRUE -#endif - -/* Minimum number of ACL credit for high priority link */ -#ifndef L2CAP_HIGH_PRI_MIN_XMIT_QUOTA -#define L2CAP_HIGH_PRI_MIN_XMIT_QUOTA 5 -#endif - -/* used for monitoring HCI ACL credit management */ -#ifndef L2CAP_HCI_FLOW_CONTROL_DEBUG -#define L2CAP_HCI_FLOW_CONTROL_DEBUG TRUE -#endif - -/* Used for calculating transmit buffers off of */ -#ifndef L2CAP_NUM_XMIT_BUFFS -#define L2CAP_NUM_XMIT_BUFFS HCI_ACL_BUF_MAX -#endif - -/* Unicast Connectionless Data */ -#ifndef L2CAP_UCD_INCLUDED -#define L2CAP_UCD_INCLUDED FALSE -#endif - -/* Unicast Connectionless Data MTU */ -#ifndef L2CAP_UCD_MTU -#define L2CAP_UCD_MTU L2CAP_MTU_SIZE -#endif - -/* Unicast Connectionless Data Idle Timeout */ -#ifndef L2CAP_UCD_IDLE_TIMEOUT -#define L2CAP_UCD_IDLE_TIMEOUT 2 -#endif - -/* Unicast Connectionless Data Idle Timeout */ -#ifndef L2CAP_UCD_CH_PRIORITY -#define L2CAP_UCD_CH_PRIORITY L2CAP_CHNL_PRIORITY_MEDIUM -#endif - -/* Used for features using fixed channels; set to zero if no fixed channels supported (BLE, etc.) */ -/* Excluding L2CAP signaling channel and UCD */ -#ifndef L2CAP_NUM_FIXED_CHNLS -#if (CLASSIC_BT_INCLUDED == TRUE) -#define L2CAP_NUM_FIXED_CHNLS 32 -#else -#define L2CAP_NUM_FIXED_CHNLS 3 //There are just three fix channel in the BLE only mode(gatt,signal,smp) -#endif ///CLASSIC_BT_INCLUDED == TRUE -#endif - -/* First fixed channel supported */ -#ifndef L2CAP_FIRST_FIXED_CHNL -#define L2CAP_FIRST_FIXED_CHNL 4 -#endif - -#ifndef L2CAP_LAST_FIXED_CHNL -#define L2CAP_LAST_FIXED_CHNL (L2CAP_FIRST_FIXED_CHNL + L2CAP_NUM_FIXED_CHNLS - 1) -#endif - -/* Round Robin service channels in link */ -#ifndef L2CAP_ROUND_ROBIN_CHANNEL_SERVICE -#define L2CAP_ROUND_ROBIN_CHANNEL_SERVICE TRUE -#endif - -/* Used for calculating transmit buffers off of */ -#ifndef L2CAP_NUM_XMIT_BUFFS -#define L2CAP_NUM_XMIT_BUFFS HCI_ACL_BUF_MAX -#endif - -/* used for monitoring eL2CAP data flow */ -#ifndef L2CAP_ERTM_STATS -#define L2CAP_ERTM_STATS FALSE -#endif - -/* Used for conformance testing ONLY: When TRUE lets scriptwrapper overwrite info response */ -#ifndef L2CAP_CONFORMANCE_TESTING -#define L2CAP_CONFORMANCE_TESTING FALSE -#endif - -/* - * Max bytes per connection to buffer locally before dropping the - * connection if local client does not receive it - default is 1MB - */ -#ifndef L2CAP_MAX_RX_BUFFER -#define L2CAP_MAX_RX_BUFFER 0x100000 -#endif - - -#ifndef TIMER_PARAM_TYPE -#define TIMER_PARAM_TYPE UINT32 -#endif - -/****************************************************************************** -** -** BLE -** -******************************************************************************/ - -#ifndef BLE_INCLUDED -#define BLE_INCLUDED TRUE -#endif - -#ifndef BLE_ANDROID_CONTROLLER_SCAN_FILTER -#define BLE_ANDROID_CONTROLLER_SCAN_FILTER TRUE -#endif - -#ifndef LOCAL_BLE_CONTROLLER_ID -#define LOCAL_BLE_CONTROLLER_ID (1) -#endif - -/* - * Toggles support for general LE privacy features such as remote address - * resolution, local address rotation etc. - */ -#ifndef BLE_PRIVACY_SPT -#define BLE_PRIVACY_SPT FALSE -#endif - -/* - * Enables or disables support for local privacy (ex. address rotation) - */ -#ifndef BLE_LOCAL_PRIVACY_ENABLED -#define BLE_LOCAL_PRIVACY_ENABLED TRUE -#endif - -/* - * Toggles support for vendor specific extensions such as RPA offloading, - * feature discovery, multi-adv etc. - */ -#ifndef BLE_VND_INCLUDED -#define BLE_VND_INCLUDED FALSE -#endif - -#ifndef BTM_BLE_ADV_TX_POWER -#define BTM_BLE_ADV_TX_POWER {-12, -9, -6, -3, 0, 3, 6, 9} -#endif - - -#ifndef BLE_BATCH_SCAN_INCLUDED -#define BLE_BATCH_SCAN_INCLUDED TRUE -#endif - -/****************************************************************************** -** -** ATT/GATT Protocol/Profile Settings -** -******************************************************************************/ -#ifndef GATT_INCLUDED -#if BLE_INCLUDED == TRUE -#define GATT_INCLUDED TRUE -#else -#define GATT_INCLUDED FALSE -#endif -#endif - -#ifndef BTA_GATT_INCLUDED -#if BLE_INCLUDED == TRUE -#define BTA_GATT_INCLUDED TRUE -#else -#define BTA_GATT_INCLUDED FALSE -#endif -#endif - -#if BTA_GATT_INCLUDED == TRUE && BLE_INCLUDED == FALSE -#error "can't have GATT without BLE" -#endif - -#ifndef BLE_LLT_INCLUDED -#define BLE_LLT_INCLUDED TRUE -#endif - -/* Added this marco to fixed the android 7.0 will lead to update connection parameters - collision when the slave sent the HCI_BLE_UPD_LL_CONN_PARAMS comment to the controller - request the master to update connection parameters directly. */ -#ifndef BLE_SLAVE_UPD_CONN_PARAMS -#define BLE_SLAVE_UPD_CONN_PARAMS FALSE -#endif - -#ifndef ATT_INCLUDED -#define ATT_INCLUDED TRUE -#endif - -#ifndef ATT_DEBUG -#define ATT_DEBUG FALSE//TRUE -#endif - -#ifndef BLE_PERIPHERAL_MODE_SUPPORT -#define BLE_PERIPHERAL_MODE_SUPPORT TRUE -#endif - -#ifndef BLE_DELAY_REQUEST_ENC -/* This flag is to work around IPHONE problem, We need to wait for iPhone ready - before send encryption request to iPhone */ -#define BLE_DELAY_REQUEST_ENC FALSE -#endif - -#ifndef GAP_TRANSPORT_SUPPORTED -#define GAP_TRANSPORT_SUPPORTED GATT_TRANSPORT_LE_BR_EDR -#endif - -#ifndef GATTP_TRANSPORT_SUPPORTED -#define GATTP_TRANSPORT_SUPPORTED GATT_TRANSPORT_LE_BR_EDR -#endif - -#ifndef GATT_MAX_SR_PROFILES -#define GATT_MAX_SR_PROFILES 8 /* max is 32 */ -#endif - -#ifndef GATT_MAX_APPS -#define GATT_MAX_APPS 8 /* MAX is 32 note: 2 apps used internally GATT and GAP */ -#endif - -#ifndef GATT_MAX_PHY_CHANNEL -#define GATT_MAX_PHY_CHANNEL 7 -#endif - -/* Used for conformance testing ONLY */ -#ifndef GATT_CONFORMANCE_TESTING -#define GATT_CONFORMANCE_TESTING FALSE -#endif - -/* number of background connection device allowence, ideally to be the same as WL size -*/ -#ifndef GATT_MAX_BG_CONN_DEV -#define GATT_MAX_BG_CONN_DEV 8 /*MAX is 32*/ -#endif - -/****************************************************************************** -** -** GATT -** -******************************************************************************/ -#ifndef GATTC_INCLUDED -#if BLE_INCLUDED == TRUE -#define GATTC_INCLUDED FALSE -#else -#define GATTC_INCLUDED FALSE -#endif -#endif - -#ifndef GATTS_INCLUDED -#if BLE_INCLUDED == TRUE -#define GATTS_INCLUDED TRUE -#else -#define GATTS_INCLUDED FALSE -#endif -#endif - - -#if SMP_INCLUDED == TRUE && BLE_INCLUDED == FALSE -#error "can't have SMP without BLE" -#endif - - -/****************************************************************************** -** -** SMP -** -******************************************************************************/ -#ifndef SMP_INCLUDED -#if BLE_INCLUDED == TRUE -#define SMP_INCLUDED FALSE -#else -#define SMP_INCLUDED FALSE -#endif -#endif - -#if SMP_INCLUDED == TRUE && BLE_INCLUDED == FALSE -#error "can't have SMP without BLE" -#endif - -#ifndef SMP_DEBUG -#define SMP_DEBUG FALSE -#endif - -#ifndef SMP_DEFAULT_AUTH_REQ -#define SMP_DEFAULT_AUTH_REQ SMP_AUTH_NB_ENC_ONLY -#endif - -#ifndef SMP_MAX_ENC_KEY_SIZE -#define SMP_MAX_ENC_KEY_SIZE 16 -#endif - -#ifndef SMP_MIN_ENC_KEY_SIZE -#define SMP_MIN_ENC_KEY_SIZE 7 -#endif - -/* minimum link timeout after SMP pairing is done, leave room for key exchange - and racing condition for the following service connection. - Prefer greater than 0 second, and no less than default inactivity link idle - timer(L2CAP_LINK_INACTIVITY_TOUT) in l2cap) */ -#ifndef SMP_LINK_TOUT_MIN -#if (L2CAP_LINK_INACTIVITY_TOUT > 0) -#define SMP_LINK_TOUT_MIN L2CAP_LINK_INACTIVITY_TOUT -#else -#define SMP_LINK_TOUT_MIN 2 -#endif -#endif - -/****************************************************************************** -** -** BT_SSP -** -******************************************************************************/ -#ifndef BT_SSP_INCLUDED -#define BT_SSP_INCLUDED FALSE -#endif - -#if BT_SSP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == FALSE -#error "Can't have SSP without CLASSIC BT" -#endif - -/****************************************************************************** -** -** SDP -** -******************************************************************************/ - -#ifndef SDP_INCLUDED -#define SDP_INCLUDED FALSE -#endif - -/* This is set to enable SDP server functionality. */ -#ifndef SDP_SERVER_ENABLED -#if SDP_INCLUDED == TRUE -#define SDP_SERVER_ENABLED TRUE -#else -#define SDP_SERVER_ENABLED FALSE -#endif -#endif - -/* This is set to enable SDP client functionality. */ -#ifndef SDP_CLIENT_ENABLED -#if SDP_INCLUDED == TRUE -#define SDP_CLIENT_ENABLED TRUE -#else -#define SDP_CLIENT_ENABLED FALSE -#endif -#endif - -/* The maximum number of SDP records the server can support. */ -#ifndef SDP_MAX_RECORDS -#define SDP_MAX_RECORDS 6 /*max is 30*/ -#endif - -/* The maximum number of attributes in each record. */ -#ifndef SDP_MAX_REC_ATTR -#define SDP_MAX_REC_ATTR 8 -#endif - -#ifndef SDP_MAX_PAD_LEN -#define SDP_MAX_PAD_LEN 300 -#endif - -/* The maximum length, in bytes, of an attribute. */ -#ifndef SDP_MAX_ATTR_LEN -#define SDP_MAX_ATTR_LEN 400 -#endif - -/* The maximum number of attribute filters supported by SDP databases. */ -#ifndef SDP_MAX_ATTR_FILTERS -#define SDP_MAX_ATTR_FILTERS 15 -#endif - -/* The maximum number of UUID filters supported by SDP databases. */ -#ifndef SDP_MAX_UUID_FILTERS -#define SDP_MAX_UUID_FILTERS 3 -#endif - -/* The maximum number of record handles retrieved in a search. */ -#ifndef SDP_MAX_DISC_SERVER_RECS -#define SDP_MAX_DISC_SERVER_RECS 21 -#endif - -/* The size of a scratchpad buffer, in bytes, for storing the response to an attribute request. */ -#ifndef SDP_MAX_LIST_BYTE_COUNT -#define SDP_MAX_LIST_BYTE_COUNT 4096 -#endif - -/* The maximum number of parameters in an SDP protocol element. */ -#ifndef SDP_MAX_PROTOCOL_PARAMS -#define SDP_MAX_PROTOCOL_PARAMS 2 -#endif - -/* The maximum number of simultaneous client and server connections. */ -#ifndef SDP_MAX_CONNECTIONS -#define SDP_MAX_CONNECTIONS 2 // 4 -#endif - -/* The MTU size for the L2CAP configuration. */ -#ifndef SDP_MTU_SIZE -#define SDP_MTU_SIZE 672 -#endif - -/* The flush timeout for the L2CAP configuration. */ -#ifndef SDP_FLUSH_TO -#define SDP_FLUSH_TO 0xFFFF -#endif - -/* The name for security authorization. */ -#ifndef SDP_SERVICE_NAME -#define SDP_SERVICE_NAME "Service Discovery" -#endif - -/* The security level for BTM. */ -#ifndef SDP_SECURITY_LEVEL -#define SDP_SECURITY_LEVEL BTM_SEC_NONE -#endif - -/****************************************************************************** -** -** RFCOMM -** -******************************************************************************/ -#ifndef RFCOMM_INCLUDED -#define RFCOMM_INCLUDED FALSE -#endif - -/* The maximum number of ports supported. */ -#ifndef MAX_RFC_PORTS -#define MAX_RFC_PORTS 16 /*max is 30*/ -#endif - -/* The maximum simultaneous links to different devices. */ -#ifndef MAX_ACL_CONNECTIONS -#define MAX_BD_CONNECTIONS 3 /*max is 7*/ -#else -#define MAX_BD_CONNECTIONS MAX_ACL_CONNECTIONS -#endif - -/* The port receive queue low watermark level, in bytes. */ -#ifndef PORT_RX_LOW_WM -#define PORT_RX_LOW_WM (BTA_RFC_MTU_SIZE * PORT_RX_BUF_LOW_WM) -#endif - -/* The port receive queue high watermark level, in bytes. */ -#ifndef PORT_RX_HIGH_WM -#define PORT_RX_HIGH_WM (BTA_RFC_MTU_SIZE * PORT_RX_BUF_HIGH_WM) -#endif - -/* The port receive queue critical watermark level, in bytes. */ -#ifndef PORT_RX_CRITICAL_WM -#define PORT_RX_CRITICAL_WM (BTA_RFC_MTU_SIZE * PORT_RX_BUF_CRITICAL_WM) -#endif - -/* The port receive queue low watermark level, in number of buffers. */ -#ifndef PORT_RX_BUF_LOW_WM -#define PORT_RX_BUF_LOW_WM 4 -#endif - -/* The port receive queue high watermark level, in number of buffers. */ -#ifndef PORT_RX_BUF_HIGH_WM -#define PORT_RX_BUF_HIGH_WM 10 -#endif - -/* The port receive queue critical watermark level, in number of buffers. */ -#ifndef PORT_RX_BUF_CRITICAL_WM -#define PORT_RX_BUF_CRITICAL_WM 15 -#endif - -/* The port transmit queue high watermark level, in bytes. */ -#ifndef PORT_TX_HIGH_WM -#define PORT_TX_HIGH_WM (BTA_RFC_MTU_SIZE * PORT_TX_BUF_HIGH_WM) -#endif - -/* The port transmit queue critical watermark level, in bytes. */ -#ifndef PORT_TX_CRITICAL_WM -#define PORT_TX_CRITICAL_WM (BTA_RFC_MTU_SIZE * PORT_TX_BUF_CRITICAL_WM) -#endif - -/* The port transmit queue high watermark level, in number of buffers. */ -#ifndef PORT_TX_BUF_HIGH_WM -#define PORT_TX_BUF_HIGH_WM 10 -#endif - -/* The port transmit queue high watermark level, in number of buffers. */ -#ifndef PORT_TX_BUF_CRITICAL_WM -#define PORT_TX_BUF_CRITICAL_WM 15 -#endif - -/* The RFCOMM multiplexer preferred flow control mechanism. */ -#ifndef PORT_FC_DEFAULT -#define PORT_FC_DEFAULT PORT_FC_CREDIT -#endif - -/* The maximum number of credits receiver sends to peer when using credit-based flow control. */ -#ifndef PORT_CREDIT_RX_MAX -#define PORT_CREDIT_RX_MAX 16 -#endif - -/* The credit low watermark level. */ -#ifndef PORT_CREDIT_RX_LOW -#define PORT_CREDIT_RX_LOW 8 -#endif - -/****************************************************************************** -** -** OBEX -** -******************************************************************************/ - -/* - * Buffer size to reassemble the SDU. - * It will allow buffers to be used that are larger than the L2CAP_MAX_MTU. - */ -#ifndef OBX_USER_RX_BUF_SIZE -#define OBX_USER_RX_BUF_SIZE OBX_LRG_DATA_BUF_SIZE -#endif - -/* - * Buffer size to hold the SDU. - * It will allow buffers to be used that are larger than the L2CAP_MAX_MTU. - */ -#ifndef OBX_USER_TX_BUF_SIZE -#define OBX_USER_TX_BUF_SIZE OBX_LRG_DATA_BUF_SIZE -#endif - -/* Buffer size used to hold MPS segments during SDU reassembly. */ -#ifndef OBX_FCR_RX_BUF_SIZE -#define OBX_FCR_RX_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/* - * Buffer size used to hold MPS segments used in (re)transmissions. - * The size of each buffer must be able to hold the maximum MPS segment size - * passed in L2CA_SetFCROptions plus BT_HDR (8) + HCI preamble (4) + - * L2CAP_MIN_OFFSET (11 - as of BT 2.1 + EDR Spec). - */ -#ifndef OBX_FCR_TX_BUF_SIZE -#define OBX_FCR_TX_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/* This option is application when OBX_14_INCLUDED=TRUE -Size of the transmission window when using enhanced retransmission mode. Not used -in basic and streaming modes. Range: 1 - 63 -*/ -#ifndef OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR -#define OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR 20 -#endif - -/* This option is application when OBX_14_INCLUDED=TRUE -Number of transmission attempts for a single I-Frame before taking -Down the connection. Used In ERTM mode only. Value is Ignored in basic and -Streaming modes. -Range: 0, 1-0xFF -0 - infinite retransmissions -1 - single transmission -*/ -#ifndef OBX_FCR_OPT_MAX_TX_B4_DISCNT -#define OBX_FCR_OPT_MAX_TX_B4_DISCNT 20 -#endif - -/* This option is application when OBX_14_INCLUDED=TRUE -Retransmission Timeout -Range: Minimum 2000 (2 secs) on BR/EDR when supporting PBF. - */ -#ifndef OBX_FCR_OPT_RETX_TOUT -#define OBX_FCR_OPT_RETX_TOUT 2000 -#endif - -/* This option is application when OBX_14_INCLUDED=TRUE -Monitor Timeout -Range: Minimum 12000 (12 secs) on BR/EDR when supporting PBF. -*/ -#ifndef OBX_FCR_OPT_MONITOR_TOUT -#define OBX_FCR_OPT_MONITOR_TOUT 12000 -#endif - -/* This option is application when OBX_14_INCLUDED=TRUE -Maximum PDU payload size. -Suggestion: The maximum amount of data that will fit into a 3-DH5 packet. -Range: 2 octets -*/ -#ifndef OBX_FCR_OPT_MAX_PDU_SIZE -#define OBX_FCR_OPT_MAX_PDU_SIZE L2CAP_MPS_OVER_BR_EDR -#endif - - -/****************************************************************************** -** -** BNEP -** -******************************************************************************/ - -#ifndef BNEP_INCLUDED -#define BNEP_INCLUDED FALSE//TRUE -#endif - -/* BNEP status API call is used mainly to get the L2CAP handle */ -#ifndef BNEP_SUPPORTS_STATUS_API -#define BNEP_SUPPORTS_STATUS_API FALSE//TRUE -#endif - -/* -** When BNEP connection changes roles after the connection is established -** we will do an authentication check again on the new role -*/ -#ifndef BNEP_DO_AUTH_FOR_ROLE_SWITCH -#define BNEP_DO_AUTH_FOR_ROLE_SWITCH FALSE//TRUE -#endif - - -/* Maximum number of protocol filters supported. */ -#ifndef BNEP_MAX_PROT_FILTERS -#define BNEP_MAX_PROT_FILTERS 5 -#endif - -/* Maximum number of multicast filters supported. */ -#ifndef BNEP_MAX_MULTI_FILTERS -#define BNEP_MAX_MULTI_FILTERS 5 -#endif - -/* Minimum MTU size. */ -#ifndef BNEP_MIN_MTU_SIZE -#define BNEP_MIN_MTU_SIZE L2CAP_MTU_SIZE -#endif - -/* Preferred MTU size. */ -#ifndef BNEP_MTU_SIZE -#define BNEP_MTU_SIZE BNEP_MIN_MTU_SIZE -#endif - -/* Maximum number of buffers allowed in transmit data queue. */ -#ifndef BNEP_MAX_XMITQ_DEPTH -#define BNEP_MAX_XMITQ_DEPTH 20 -#endif - -/* Maximum number BNEP of connections supported. */ -#ifndef BNEP_MAX_CONNECTIONS -#define BNEP_MAX_CONNECTIONS 7 -#endif - - -/****************************************************************************** -** -** AVDTP -** -******************************************************************************/ - -#ifndef AVDT_INCLUDED -#define AVDT_INCLUDED TRUE -#endif - -/* Include reporting capability in AVDTP */ -#ifndef AVDT_REPORTING -#define AVDT_REPORTING TRUE -#endif - -/* Include multiplexing capability in AVDTP */ -#ifndef AVDT_MULTIPLEXING -#define AVDT_MULTIPLEXING TRUE -#endif - -/* Number of simultaneous links to different peer devices. */ -#ifndef AVDT_NUM_LINKS -#define AVDT_NUM_LINKS 2 -#endif - -/* Number of simultaneous stream endpoints. */ -#ifndef AVDT_NUM_SEPS -#define AVDT_NUM_SEPS 3 -#endif - -/* Number of transport channels setup per media stream(audio or video) */ -#ifndef AVDT_NUM_CHANNELS - -#if AVDT_REPORTING == TRUE -/* signaling, media and reporting channels */ -#define AVDT_NUM_CHANNELS 3 -#else -/* signaling and media channels */ -#define AVDT_NUM_CHANNELS 2 -#endif // AVDT_REPORTING - -#endif // AVDT_NUM_CHANNELS - -/* Number of transport channels setup by AVDT for all media streams - * AVDT_NUM_CHANNELS * Number of simultaneous streams. - */ -#ifndef AVDT_NUM_TC_TBL -#define AVDT_NUM_TC_TBL 6 -#endif - -/* Maximum size in bytes of the codec capabilities information element. */ -#ifndef AVDT_CODEC_SIZE -#define AVDT_CODEC_SIZE 10 -#endif - -/* Maximum size in bytes of the content protection information element. */ -#ifndef AVDT_PROTECT_SIZE -#define AVDT_PROTECT_SIZE 90 -#endif - -/* Maximum number of GKI buffers in the fragment queue (for video frames). - * Must be less than the number of buffers in the buffer pool of size AVDT_DATA_POOL_SIZE */ -#ifndef AVDT_MAX_FRAG_COUNT -#define AVDT_MAX_FRAG_COUNT 15 -#endif - -/****************************************************************************** -** -** PAN -** -******************************************************************************/ - -#ifndef PAN_INCLUDED -#define PAN_INCLUDED FALSE -#endif - -/* This will enable the PANU role */ -#ifndef PAN_SUPPORTS_ROLE_PANU -#define PAN_SUPPORTS_ROLE_PANU FALSE//TRUE -#endif - -/* This will enable the GN role */ -#ifndef PAN_SUPPORTS_ROLE_GN -#define PAN_SUPPORTS_ROLE_GN FALSE//TRUE -#endif - -/* This will enable the NAP role */ -#ifndef PAN_SUPPORTS_ROLE_NAP -#define PAN_SUPPORTS_ROLE_NAP FALSE//TRUE -#endif - -/* This is just for debugging purposes */ -#ifndef PAN_SUPPORTS_DEBUG_DUMP -#define PAN_SUPPORTS_DEBUG_DUMP FALSE//TRUE -#endif - -/* Maximum number of PAN connections allowed */ -#ifndef MAX_PAN_CONNS -#define MAX_PAN_CONNS 7 -#endif - -/* Default service name for NAP role */ -#ifndef PAN_NAP_DEFAULT_SERVICE_NAME -#define PAN_NAP_DEFAULT_SERVICE_NAME "Network Access Point Service" -#endif - -/* Default service name for GN role */ -#ifndef PAN_GN_DEFAULT_SERVICE_NAME -#define PAN_GN_DEFAULT_SERVICE_NAME "Group Network Service" -#endif - -/* Default service name for PANU role */ -#ifndef PAN_PANU_DEFAULT_SERVICE_NAME -#define PAN_PANU_DEFAULT_SERVICE_NAME "PAN User Service" -#endif - -/* Default description for NAP role service */ -#ifndef PAN_NAP_DEFAULT_DESCRIPTION -#define PAN_NAP_DEFAULT_DESCRIPTION "NAP" -#endif - -/* Default description for GN role service */ -#ifndef PAN_GN_DEFAULT_DESCRIPTION -#define PAN_GN_DEFAULT_DESCRIPTION "GN" -#endif - -/* Default description for PANU role service */ -#ifndef PAN_PANU_DEFAULT_DESCRIPTION -#define PAN_PANU_DEFAULT_DESCRIPTION "PANU" -#endif - -/* Default Security level for PANU role. */ -#ifndef PAN_PANU_SECURITY_LEVEL -#define PAN_PANU_SECURITY_LEVEL 0 -#endif - -/* Default Security level for GN role. */ -#ifndef PAN_GN_SECURITY_LEVEL -#define PAN_GN_SECURITY_LEVEL 0 -#endif - -/* Default Security level for NAP role. */ -#ifndef PAN_NAP_SECURITY_LEVEL -#define PAN_NAP_SECURITY_LEVEL 0 -#endif - -/****************************************************************************** -** -** GAP -** -******************************************************************************/ - -#ifndef GAP_INCLUDED -#define GAP_INCLUDED TRUE -#endif - -/* This is set to enable use of GAP L2CAP connections. */ -#ifndef GAP_CONN_INCLUDED -#if (GAP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == TRUE) -#define GAP_CONN_INCLUDED TRUE -#else -#define GAP_CONN_INCLUDED FALSE -#endif -#endif - -/* This is set to enable posting event for data write */ -#ifndef GAP_CONN_POST_EVT_INCLUDED -#define GAP_CONN_POST_EVT_INCLUDED FALSE -#endif - -/* The maximum number of simultaneous GAP L2CAP connections. */ -#ifndef GAP_MAX_CONNECTIONS -#define GAP_MAX_CONNECTIONS 10 // 30 -#endif - -/* keep the raw data received from SDP server in database. */ -#ifndef SDP_RAW_DATA_INCLUDED -#define SDP_RAW_DATA_INCLUDED TRUE -#endif - -/* Inquiry duration in 1.28 second units. */ -#ifndef SDP_DEBUG -#define SDP_DEBUG TRUE -#endif - -/****************************************************************************** -** -** HID -** -******************************************************************************/ - -#ifndef HID_CONTROL_BUF_SIZE -#define HID_CONTROL_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -#ifndef HID_INTERRUPT_BUF_SIZE -#define HID_INTERRUPT_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/************************************************************************* -** Definitions for Both HID-Host & Device -*/ -#ifndef HID_MAX_SVC_NAME_LEN -#define HID_MAX_SVC_NAME_LEN 32 -#endif - -#ifndef HID_MAX_SVC_DESCR_LEN -#define HID_MAX_SVC_DESCR_LEN 32 -#endif - -#ifndef HID_MAX_PROV_NAME_LEN -#define HID_MAX_PROV_NAME_LEN 32 -#endif - -/************************************************************************* -** Definitions for HID-Host -*/ -#ifndef HID_HOST_INCLUDED -#define HID_HOST_INCLUDED FALSE -#endif - -#ifndef HID_HOST_MAX_DEVICES -#define HID_HOST_MAX_DEVICES 7 -#endif - -#ifndef HID_HOST_MTU -#define HID_HOST_MTU 640 -#endif - -#ifndef HID_HOST_FLUSH_TO -#define HID_HOST_FLUSH_TO 0xffff -#endif - -#ifndef HID_HOST_MAX_CONN_RETRY -#define HID_HOST_MAX_CONN_RETRY (3) -#endif - -#ifndef HID_HOST_REPAGE_WIN -#define HID_HOST_REPAGE_WIN (2) -#endif - -/************************************************************************* - * A2DP Definitions - */ -#ifndef A2D_INCLUDED -#define A2D_INCLUDED FALSE -#endif - -/****************************************************************************** -** -** AVCTP -** -******************************************************************************/ - -/* Number of simultaneous ACL links to different peer devices. */ -#ifndef AVCT_NUM_LINKS -#define AVCT_NUM_LINKS 2 -#endif - -/* Number of simultaneous AVCTP connections. */ -#ifndef AVCT_NUM_CONN -#define AVCT_NUM_CONN 3 -#endif - -/****************************************************************************** -** -** AVRCP -** -******************************************************************************/ -#ifndef AVRC_INCLUDED -#define AVRC_INCLUDED FALSE -#endif - -#ifndef AVRC_METADATA_INCLUDED -#if AVRC_INCLUDED == TRUE -#define AVRC_METADATA_INCLUDED TRUE -#else -#define AVRC_METADATA_INCLUDED FALSE -#endif -#endif - -#ifndef AVRC_ADV_CTRL_INCLUDED -#if AVRC_INCLUDED == TRUE -#define AVRC_ADV_CTRL_INCLUDED TRUE -#else -#define AVRC_ADV_CTRL_INCLUDED FALSE -#endif -#endif - -#ifndef AVRC_CTLR_INCLUDED -#if AVRC_INCLUDED == TRUE -#define AVRC_CTLR_INCLUDED TRUE -#else -#define AVRC_CTLR_INCLUDED FALSE -#endif -#endif - -/****************************************************************************** -** -** MCAP -** -******************************************************************************/ -#ifndef MCA_INCLUDED -#define MCA_INCLUDED FALSE -#endif - -/* The MTU size for the L2CAP configuration on control channel. 48 is the minimal */ -#ifndef MCA_CTRL_MTU -#define MCA_CTRL_MTU 60 -#endif - -/* The maximum number of registered MCAP instances. */ -#ifndef MCA_NUM_REGS -#define MCA_NUM_REGS 12 -#endif - -/* The maximum number of control channels (to difference devices) per registered MCAP instances. */ -#ifndef MCA_NUM_LINKS -#define MCA_NUM_LINKS 3 -#endif - -/* The maximum number of MDEP (including HDP echo) per registered MCAP instances. */ -#ifndef MCA_NUM_DEPS -#define MCA_NUM_DEPS 13 -#endif - -/* The maximum number of MDL link per control channel. */ -#ifndef MCA_NUM_MDLS -#define MCA_NUM_MDLS 4 -#endif - -/* Buffer size to reassemble the SDU. */ -#ifndef MCA_USER_RX_BUF_SIZE -#define MCA_USER_RX_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/* Buffer size to hold the SDU. */ -#ifndef MCA_USER_TX_BUF_SIZE -#define MCA_USER_TX_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/* - * Buffer size used to hold MPS segments during SDU reassembly - */ -#ifndef MCA_FCR_RX_BUF_SIZE -#define MCA_FCR_RX_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/* - * Default buffer size used to hold MPS segments used in (re)transmissions. - * The size of each buffer must be able to hold the maximum MPS segment size - * passed in tL2CAP_FCR_OPTIONS plus BT_HDR (8) + HCI preamble (4) + - * L2CAP_MIN_OFFSET (11 - as of BT 2.1 + EDR Spec). - */ -#ifndef MCA_FCR_TX_BUF_SIZE -#define MCA_FCR_TX_BUF_SIZE BT_DEFAULT_BUFFER_SIZE -#endif - -/* MCAP control channel FCR Option: -Size of the transmission window when using enhanced retransmission mode. -1 is defined by HDP specification for control channel. -*/ -#ifndef MCA_FCR_OPT_TX_WINDOW_SIZE -#define MCA_FCR_OPT_TX_WINDOW_SIZE 1 -#endif - -/* MCAP control channel FCR Option: -Number of transmission attempts for a single I-Frame before taking -Down the connection. Used In ERTM mode only. Value is Ignored in basic and -Streaming modes. -Range: 0, 1-0xFF -0 - infinite retransmissions -1 - single transmission -*/ -#ifndef MCA_FCR_OPT_MAX_TX_B4_DISCNT -#define MCA_FCR_OPT_MAX_TX_B4_DISCNT 20 -#endif - -/* MCAP control channel FCR Option: Retransmission Timeout -The AVRCP specification set a value in the range of 300 - 2000 ms -Timeout (in msecs) to detect Lost I-Frames. Only used in Enhanced retransmission mode. -Range: Minimum 2000 (2 secs) when supporting PBF. - */ -#ifndef MCA_FCR_OPT_RETX_TOUT -#define MCA_FCR_OPT_RETX_TOUT 2000 -#endif - -/* MCAP control channel FCR Option: Monitor Timeout -The AVRCP specification set a value in the range of 300 - 2000 ms -Timeout (in msecs) to detect Lost S-Frames. Only used in Enhanced retransmission mode. -Range: Minimum 12000 (12 secs) when supporting PBF. -*/ -#ifndef MCA_FCR_OPT_MONITOR_TOUT -#define MCA_FCR_OPT_MONITOR_TOUT 12000 -#endif - -/* MCAP control channel FCR Option: Maximum PDU payload size. -The maximum number of payload octets that the local device can receive in a single PDU. -*/ -#ifndef MCA_FCR_OPT_MPS_SIZE -#define MCA_FCR_OPT_MPS_SIZE 1000 -#endif - -/* Shared transport */ -#ifndef NFC_SHARED_TRANSPORT_ENABLED -#define NFC_SHARED_TRANSPORT_ENABLED FALSE -#endif - -/****************************************************************************** -** -** Sleep Mode (Low Power Mode) -** -******************************************************************************/ - -#ifndef HCILP_INCLUDED -#define HCILP_INCLUDED FALSE//TRUE -#endif - -/****************************************************************************** -** -** APPL - Application Task -** -******************************************************************************/ - -#define L2CAP_FEATURE_REQ_ID 73 -#define L2CAP_FEATURE_RSP_ID 173 - -/****************************************************************************** -** -** BTA -** -******************************************************************************/ -/* BTA EIR canned UUID list (default is dynamic) */ -#ifndef BTA_EIR_CANNED_UUID_LIST -#define BTA_EIR_CANNED_UUID_LIST FALSE -#endif - -/* Number of supported customer UUID in EIR */ -#ifndef BTA_EIR_SERVER_NUM_CUSTOM_UUID -#define BTA_EIR_SERVER_NUM_CUSTOM_UUID 8 -#endif - -/* CHLD override for bluedroid */ -#ifndef BTA_AG_CHLD_VAL_ECC -#define BTA_AG_CHLD_VAL_ECC "(0,1,1x,2,2x,3)" -#endif - -#ifndef BTA_AG_CHLD_VAL -#define BTA_AG_CHLD_VAL "(0,1,2,3)" -#endif - -/* Set the CIND to match HFP 1.5 */ -#ifndef BTA_AG_CIND_INFO -#define BTA_AG_CIND_INFO "(\"call\",(0,1)),(\"callsetup\",(0-3)),(\"service\",(0-1)),(\"signal\",(0-5)),(\"roam\",(0,1)),(\"battchg\",(0-5)),(\"callheld\",(0-2))" -#endif - -#ifndef BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY -#define BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY FALSE//TRUE -#endif - -/****************************************************************************** -** -** Tracing: Include trace header file here. -** -******************************************************************************/ - -/* Enable/disable BTSnoop memory logging */ -#ifndef BTSNOOP_MEM -#define BTSNOOP_MEM FALSE//TRUE -#endif - -#include "common/bt_trace.h" - -#endif /* BT_TARGET_H */ diff --git a/tools/sdk/include/bluedroid/common/bt_trace.h b/tools/sdk/include/bluedroid/common/bt_trace.h deleted file mode 100644 index 7583479b..00000000 --- a/tools/sdk/include/bluedroid/common/bt_trace.h +++ /dev/null @@ -1,748 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _BT_TRACE_H_ -#define _BT_TRACE_H_ - -#include "sdkconfig.h" - -#include -#include "stack/bt_types.h" - -#ifndef LOG_LOCAL_LEVEL -#ifndef BOOTLOADER_BUILD -#define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL -#else -#define LOG_LOCAL_LEVEL CONFIG_LOG_BOOTLOADER_LEVEL -#endif -#endif - -#include "esp_log.h" - -// Mapping between ESP_LOG_LEVEL and BT_TRACE_LEVEL -#if (LOG_LOCAL_LEVEL >= 4) -#define LOG_LOCAL_LEVEL_MAPPING (LOG_LOCAL_LEVEL+1) -#else -#define LOG_LOCAL_LEVEL_MAPPING LOG_LOCAL_LEVEL -#endif - -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define BT_LOG_LEVEL_CHECK(LAYER, LEVEL) (MAX(LAYER##_INITIAL_TRACE_LEVEL, LOG_LOCAL_LEVEL_MAPPING) >= BT_TRACE_LEVEL_##LEVEL) - -//#define TAG "BT" - -#define BT_PRINT_E(tag, format, ...) {esp_log_write(ESP_LOG_ERROR, tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } -#define BT_PRINT_W(tag, format, ...) {esp_log_write(ESP_LOG_WARN, tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } -#define BT_PRINT_I(tag, format, ...) {esp_log_write(ESP_LOG_INFO, tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } -#define BT_PRINT_D(tag, format, ...) {esp_log_write(ESP_LOG_DEBUG, tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } -#define BT_PRINT_V(tag, format, ...) {esp_log_write(ESP_LOG_VERBOSE, tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } - -#ifndef assert -#define assert(x) do { if (!(x)) BT_PRINT_E("bt host error %s %u\n", __FILE__, __LINE__); } while (0) -#endif - -inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t len) -{ - uint16_t i; - - if (!data || !len) { - return; - } - - if (prefix) { - printf("%s: len %d\r\n", prefix, len); - } - - for (i = 0; i < len; i+=16) { - printf("%02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x\r\n", - *(data + i), *(data + i + 1), *(data + i + 2), *(data + i + 3), *(data + i + 4), *(data + i + 5), *(data + i + 6), *(data + i + 7), - *(data + i + 8), *(data + i + 9), *(data + i + 10), *(data + i + 11), *(data + i + 12), *(data + i + 13), *(data + i + 14), *(data + i + 15)); - } - printf("\r\n"); -} - -#ifdef BTTRC_DUMP_BUFFER -#define BTTRC_DUMP_BUFFER(_prefix, _data, _len) trc_dump_buffer(_prefix, _data, _len) -#else -#define BTTRC_DUMP_BUFFER(_prefix, _data, _len) -#endif - -//static const char BTE_LOGMSG_MODULE[] = "bte_logmsg_module"; - -/* BTrgs);E tracing IDs for debug purposes */ -/* LayerIDs for stack */ -#define BTTRC_ID_STK_GKI 1 -#define BTTRC_ID_STK_BTU 2 -#define BTTRC_ID_STK_HCI 3 -#define BTTRC_ID_STK_L2CAP 4 -#define BTTRC_ID_STK_RFCM_MX 5 -#define BTTRC_ID_STK_RFCM_PRT 6 -#define BTTRC_ID_STK_OBEX_C 7 -#define BTTRC_ID_STK_OBEX_S 8 -#define BTTRC_ID_STK_AVCT 9 -#define BTTRC_ID_STK_AVDT 10 -#define BTTRC_ID_STK_AVRC 11 -#define BTTRC_ID_STK_BIC 12 -#define BTTRC_ID_STK_BIS 13 -#define BTTRC_ID_STK_BNEP 14 -#define BTTRC_ID_STK_BPP 15 -#define BTTRC_ID_STK_BTM_ACL 16 -#define BTTRC_ID_STK_BTM_PM 17 -#define BTTRC_ID_STK_BTM_DEV_CTRL 18 -#define BTTRC_ID_STK_BTM_SVC_DSC 19 -#define BTTRC_ID_STK_BTM_INQ 20 -#define BTTRC_ID_STK_BTM_SCO 21 -#define BTTRC_ID_STK_BTM_SEC 22 -#define BTTRC_ID_STK_HID 24 -#define BTTRC_ID_STK_HSP2 25 -#define BTTRC_ID_STK_CTP 26 -#define BTTRC_ID_STK_FTC 27 -#define BTTRC_ID_STK_FTS 28 -#define BTTRC_ID_STK_GAP 29 -#define BTTRC_ID_STK_HCRP 31 -#define BTTRC_ID_STK_ICP 32 -#define BTTRC_ID_STK_OPC 33 -#define BTTRC_ID_STK_OPS 34 -#define BTTRC_ID_STK_PAN 35 -#define BTTRC_ID_STK_SAP 36 -#define BTTRC_ID_STK_SDP 37 -#define BTTRC_ID_STK_SLIP 38 -#define BTTRC_ID_STK_SPP 39 -#define BTTRC_ID_STK_TCS 40 -#define BTTRC_ID_STK_VDP 41 -#define BTTRC_ID_STK_MCAP 42 -#define BTTRC_ID_STK_GATT 43 -#define BTTRC_ID_STK_SMP 44 -#define BTTRC_ID_STK_NFC 45 -#define BTTRC_ID_STK_NCI 46 -#define BTTRC_ID_STK_IDEP 47 -#define BTTRC_ID_STK_NDEP 48 -#define BTTRC_ID_STK_LLCP 49 -#define BTTRC_ID_STK_RW 50 -#define BTTRC_ID_STK_CE 51 -#define BTTRC_ID_STK_SNEP 52 -#define BTTRC_ID_STK_NDEF 53 - -/* LayerIDs for BTA */ -#define BTTRC_ID_BTA_ACC 55 /* Advanced Camera Client */ -#define BTTRC_ID_BTA_AG 56 /* audio gateway */ -#define BTTRC_ID_BTA_AV 57 /* Advanced audio */ -#define BTTRC_ID_BTA_BIC 58 /* Basic Imaging Client */ -#define BTTRC_ID_BTA_BIS 59 /* Basic Imaging Server */ -#define BTTRC_ID_BTA_BP 60 /* Basic Printing Client */ -#define BTTRC_ID_BTA_CG 61 -#define BTTRC_ID_BTA_CT 62 /* cordless telephony terminal */ -#define BTTRC_ID_BTA_DG 63 /* data gateway */ -#define BTTRC_ID_BTA_DM 64 /* device manager */ -#define BTTRC_ID_BTA_DM_SRCH 65 /* device manager search */ -#define BTTRC_ID_BTA_DM_SEC 66 /* device manager security */ -#define BTTRC_ID_BTA_FM 67 -#define BTTRC_ID_BTA_FTC 68 /* file transfer client */ -#define BTTRC_ID_BTA_FTS 69 /* file transfer server */ -#define BTTRC_ID_BTA_HIDH 70 -#define BTTRC_ID_BTA_HIDD 71 -#define BTTRC_ID_BTA_JV 72 -#define BTTRC_ID_BTA_OPC 73 /* object push client */ -#define BTTRC_ID_BTA_OPS 74 /* object push server */ -#define BTTRC_ID_BTA_PAN 75 /* Personal Area Networking */ -#define BTTRC_ID_BTA_PR 76 /* Printer client */ -#define BTTRC_ID_BTA_SC 77 /* SIM Card Access server */ -#define BTTRC_ID_BTA_SS 78 /* synchronization server */ -#define BTTRC_ID_BTA_SYS 79 /* system manager */ -#define BTTRC_ID_AVDT_SCB 80 /* avdt scb */ -#define BTTRC_ID_AVDT_CCB 81 /* avdt ccb */ - -// btla-specific ++ -/* LayerIDs added for BTL-A. Probably should modify bte_logmsg.c in future. */ -#define BTTRC_ID_STK_RFCOMM 82 -#define BTTRC_ID_STK_RFCOMM_DATA 83 -#define BTTRC_ID_STK_OBEX 84 -#define BTTRC_ID_STK_A2D 85 -#define BTTRC_ID_STK_BIP 86 - -/* LayerIDs for BT APP */ -#define BTTRC_ID_BTAPP 87 -#define BTTRC_ID_BT_PROTOCOL 88 /* this is a temporary solution to allow dynamic - enable/disable of BT_PROTOCOL_TRACE */ -#define BTTRC_ID_MAX_ID BTTRC_ID_BT_PROTOCOL -// btla-specific -- -#define BTTRC_ID_ALL_LAYERS 0xFF /* all trace layers */ -/* Parameter datatypes used in Trace APIs */ -#define BTTRC_PARAM_UINT8 1 -#define BTTRC_PARAM_UINT16 2 -#define BTTRC_PARAM_UINT32 3 - -/* Enables or disables verbose trace information. */ -#ifndef BT_TRACE_VERBOSE -#define BT_TRACE_VERBOSE FALSE -#endif - -/* Enables or disables all trace messages. */ -#ifndef BT_USE_TRACES -#define BT_USE_TRACES FALSE -#endif - -#ifndef BT_TRACE_APPL -#define BT_TRACE_APPL BT_USE_TRACES -#endif - -/****************************************************************************** -** -** Trace Levels -** -** The following values may be used for different levels: -** BT_TRACE_LEVEL_NONE 0 * No trace messages to be generated -** BT_TRACE_LEVEL_ERROR 1 * Error condition trace messages -** BT_TRACE_LEVEL_WARNING 2 * Warning condition trace messages -** BT_TRACE_LEVEL_API 3 * API traces -** BT_TRACE_LEVEL_EVENT 4 * Debug messages for events -** BT_TRACE_LEVEL_DEBUG 5 * Debug messages (general) -******************************************************************************/ - -// btla-specific ++ -/* Core Stack default trace levels */ -#ifdef CONFIG_HCI_INITIAL_TRACE_LEVEL -#define HCI_INITIAL_TRACE_LEVEL CONFIG_HCI_INITIAL_TRACE_LEVEL -#else -#define HCI_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_BTM_INITIAL_TRACE_LEVEL -#define BTM_INITIAL_TRACE_LEVEL CONFIG_BTM_INITIAL_TRACE_LEVEL -#else -#define BTM_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_L2CAP_INITIAL_TRACE_LEVEL -#define L2CAP_INITIAL_TRACE_LEVEL CONFIG_L2CAP_INITIAL_TRACE_LEVEL -#else -#define L2CAP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_RFCOMM_INITIAL_TRACE_LEVEL -#define RFCOMM_INITIAL_TRACE_LEVEL CONFIG_RFCOMM_INITIAL_TRACE_LEVEL -#else -#define RFCOMM_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_SDP_INITIAL_TRACE_LEVEL -#define SDP_INITIAL_TRACE_LEVEL CONFIG_SDP_INITIAL_TRACE_LEVEL -#else -#define SDP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_GAP_INITIAL_TRACE_LEVEL -#define GAP_INITIAL_TRACE_LEVEL CONFIG_GAP_INITIAL_TRACE_LEVEL -#else -#define GAP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_BNEP_INITIAL_TRACE_LEVEL -#define BNEP_INITIAL_TRACE_LEVEL CONFIG_BNEP_INITIAL_TRACE_LEVEL -#else -#define BNEP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_PAN_INITIAL_TRACE_LEVEL -#define PAN_INITIAL_TRACE_LEVEL CONFIG_PAN_INITIAL_TRACE_LEVEL -#else -#define PAN_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_A2D_INITIAL_TRACE_LEVEL -#define A2D_INITIAL_TRACE_LEVEL CONFIG_A2D_INITIAL_TRACE_LEVEL -#else -#define A2D_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_AVDT_INITIAL_TRACE_LEVEL -#define AVDT_INITIAL_TRACE_LEVEL CONFIG_AVDT_INITIAL_TRACE_LEVEL -#else -#define AVDT_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_AVCT_INITIAL_TRACE_LEVEL -#define AVCT_INITIAL_TRACE_LEVEL CONFIG_AVCT_INITIAL_TRACE_LEVEL -#else -#define AVCT_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_AVRC_INITIAL_TRACE_LEVEL -#define AVRC_INITIAL_TRACE_LEVEL CONFIG_AVRC_INITIAL_TRACE_LEVEL -#else -#define AVRC_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_MCA_INITIAL_TRACE_LEVEL -#define MCA_INITIAL_TRACE_LEVEL CONFIG_MCA_INITIAL_TRACE_LEVEL -#else -#define MCA_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_HID_INITIAL_TRACE_LEVEL -#define HID_INITIAL_TRACE_LEVEL CONFIG_HID_INITIAL_TRACE_LEVEL -#else -#define HID_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_APPL_INITIAL_TRACE_LEVEL -#define APPL_INITIAL_TRACE_LEVEL CONFIG_APPL_INITIAL_TRACE_LEVEL -#else -#define APPL_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_GATT_INITIAL_TRACE_LEVEL -#define GATT_INITIAL_TRACE_LEVEL CONFIG_GATT_INITIAL_TRACE_LEVEL -#else -#define GATT_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_SMP_INITIAL_TRACE_LEVEL -#define SMP_INITIAL_TRACE_LEVEL CONFIG_SMP_INITIAL_TRACE_LEVEL -#else -#define SMP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_BTIF_INITIAL_TRACE_LEVEL -#define BTIF_INITIAL_TRACE_LEVEL CONFIG_BTIF_INITIAL_TRACE_LEVEL -#else -#define BTIF_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_BTC_INITIAL_TRACE_LEVEL -#define BTC_INITIAL_TRACE_LEVEL CONFIG_BTC_INITIAL_TRACE_LEVEL -#else -#define BTC_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_OSI_INITIAL_TRACE_LEVEL -#define OSI_INITIAL_TRACE_LEVEL CONFIG_OSI_INITIAL_TRACE_LEVEL -#else -#define OSI_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -#ifdef CONFIG_BLUFI_INITIAL_TRACE_LEVEL -#define BLUFI_INITIAL_TRACE_LEVEL CONFIG_BLUFI_INITIAL_TRACE_LEVEL -#else -#define BLUFI_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_WARNING -#endif - -// btla-specific -- - -#if !CONFIG_BT_STACK_NO_LOG -#define LOG_ERROR(format, ... ) {if (LOG_LOCAL_LEVEL >= ESP_LOG_ERROR) esp_log_write(ESP_LOG_ERROR, "BT_LOG", LOG_FORMAT(E, format), esp_log_timestamp(), "BT_LOG", ##__VA_ARGS__); } -#define LOG_WARN(format, ... ) {if (LOG_LOCAL_LEVEL >= ESP_LOG_WARN) esp_log_write(ESP_LOG_WARN, "BT_LOG", LOG_FORMAT(W, format), esp_log_timestamp(), "BT_LOG", ##__VA_ARGS__); } -#define LOG_INFO(format, ... ) {if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) esp_log_write(ESP_LOG_INFO, "BT_LOG", LOG_FORMAT(I, format), esp_log_timestamp(), "BT_LOG", ##__VA_ARGS__); } -#define LOG_DEBUG(format, ... ) {if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) esp_log_write(ESP_LOG_DEBUG, "BT_LOG", LOG_FORMAT(D, format), esp_log_timestamp(), "BT_LOG", ##__VA_ARGS__); } -#define LOG_VERBOSE(format, ... ) {if (LOG_LOCAL_LEVEL >= ESP_LOG_VERBOSE) esp_log_write(ESP_LOG_VERBOSE, "BT_LOG", LOG_FORMAT(V, format), esp_log_timestamp(), "BT_LOG", ##__VA_ARGS__); } - -/* Define tracing for BTM -*/ -#define BTM_TRACE_ERROR(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BTM, ERROR)) BT_PRINT_E("BT_BTM", fmt, ## args);} -#define BTM_TRACE_WARNING(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BTM, WARNING)) BT_PRINT_W("BT_BTM", fmt, ## args);} -#define BTM_TRACE_API(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BTM,API)) BT_PRINT_I("BT_BTM", fmt, ## args);} -#define BTM_TRACE_EVENT(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BTM,EVENT)) BT_PRINT_D("BT_BTM", fmt, ## args);} -#define BTM_TRACE_DEBUG(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BTM,DEBUG)) BT_PRINT_D("BT_BTM", fmt, ## args);} - -/* Define tracing for the L2CAP unit -*/ -#define L2CAP_TRACE_ERROR(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(L2CAP, ERROR)) BT_PRINT_E("BT_L2CAP", fmt, ## args);} -#define L2CAP_TRACE_WARNING(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(L2CAP, WARNING)) BT_PRINT_W("BT_L2CAP", fmt, ## args);} -#define L2CAP_TRACE_API(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(L2CAP,API)) BT_PRINT_I("BT_L2CAP", fmt, ## args);} -#define L2CAP_TRACE_EVENT(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(L2CAP,EVENT)) BT_PRINT_D("BT_L2CAP", fmt, ## args);} -#define L2CAP_TRACE_DEBUG(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(L2CAP,DEBUG)) BT_PRINT_D("BT_L2CAP", fmt, ## args);} - -/* Define tracing for the SDP unit -*/ -#define SDP_TRACE_ERROR(fmt, args...) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(SDP, ERROR)) BT_PRINT_E("BT_SDP", fmt, ## args);} -#define SDP_TRACE_WARNING(fmt, args...) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(SDP, WARNING)) BT_PRINT_W("BT_SDP", fmt, ## args);} -#define SDP_TRACE_API(fmt, args...) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(SDP,API)) BT_PRINT_I("BT_SDP", fmt, ## args);} -#define SDP_TRACE_EVENT(fmt, args...) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(SDP,EVENT)) BT_PRINT_D("BT_SDP", fmt, ## args);} -#define SDP_TRACE_DEBUG(fmt, args...) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(SDP,DEBUG)) BT_PRINT_D("BT_SDP", fmt, ## args);} - -/* Define tracing for the RFCOMM unit -*/ -#define RFCOMM_TRACE_ERROR(fmt, args...) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(RFCOMM, ERROR)) BT_PRINT_E("BT_RFCOMM", fmt, ## args);} -#define RFCOMM_TRACE_WARNING(fmt, args...) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(RFCOMM, WARNING)) BT_PRINT_W("BT_RFCOMM", fmt, ## args);} -#define RFCOMM_TRACE_API(fmt, args...) {if (rfc_cb.trace_level >=BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(RFCOMM,API)) BT_PRINT_I("BT_RFCOMM", fmt, ## args);} -#define RFCOMM_TRACE_EVENT(fmt, args...) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(RFCOMM,EVENT)) BT_PRINT_D("BT_RFCOMM", fmt, ## args);} -#define RFCOMM_TRACE_DEBUG(fmt, args...) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(RFCOMM,DEBUG)) BT_PRINT_D("BT_RFCOMM", fmt, ## args);} - -/* Generic Access Profile traces */ -#define GAP_TRACE_ERROR(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GAP, ERROR)) BT_PRINT_E("BT_GAP", fmt, ## args);} -#define GAP_TRACE_API(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GAP,API)) BT_PRINT_I("BT_GAP", fmt, ## args);} -#define GAP_TRACE_EVENT(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GAP,EVENT)) BT_PRINT_D("BT_GAP", fmt, ## args);} -#define GAP_TRACE_WARNING(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GAP, WARNING)) BT_PRINT_W("BT_GAP", fmt, ## args);} - -/* define traces for HID Host */ -#define HIDH_TRACE_ERROR(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(HIDH, ERROR)) BT_PRINT_E("BT_HIDH", fmt, ## args);} -#define HIDH_TRACE_WARNING(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(HIDH, WARNING)) BT_PRINT_W("BT_HIDH", fmt, ## args);} -#define HIDH_TRACE_API(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(HIDH,API)) BT_PRINT_I("BT_HIDH", fmt, ## args);} -#define HIDH_TRACE_EVENT(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(HIDH,EVENT)) BT_PRINT_D("BT_HIDH", fmt, ## args);} -#define HIDH_TRACE_DEBUG(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(HIDH,DEBUG)) BT_PRINT_D("BT_HIDH", fmt, ## args);} - -/* define traces for BNEP */ - -#define BNEP_TRACE_ERROR(fmt, args...) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BNEP, ERROR)) BT_PRINT_E("BT_BNEP", fmt, ## args);} -#define BNEP_TRACE_WARNING(fmt, args...) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BNEP, WARNING)) BT_PRINT_W("BT_BNEP", fmt, ## args);} -#define BNEP_TRACE_API(fmt, args...) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BNEP,API)) BT_PRINT_I("BT_BNEP", fmt, ## args);} -#define BNEP_TRACE_EVENT(fmt, args...) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BNEP,EVENT)) BT_PRINT_D("BT_BNEP", fmt, ## args);} -#define BNEP_TRACE_DEBUG(fmt, args...) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BNEP,DEBUG)) BT_PRINT_D("BT_BNEP", fmt, ## args);} - -/* define traces for PAN */ - -#define PAN_TRACE_ERROR(fmt, args...) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(PAN, ERROR)) BT_PRINT_E("BT_PAN", fmt, ## args);} -#define PAN_TRACE_WARNING(fmt, args...) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(PAN, WARNING)) BT_PRINT_W("BT_PAN", fmt, ## args);} -#define PAN_TRACE_API(fmt, args...) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(PAN,API)) BT_PRINT_I("BT_PAN", fmt, ## args);} -#define PAN_TRACE_EVENT(fmt, args...) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(PAN,EVENT)) BT_PRINT_D("BT_PAN", fmt, ## args);} -#define PAN_TRACE_DEBUG(fmt, args...) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(PAN,DEBUG)) BT_PRINT_D("BT_PAN", fmt, ## args);} - -/* Define tracing for the A2DP profile -*/ -#define A2D_TRACE_ERROR(fmt, args...) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(A2D, ERROR)) BT_PRINT_E("BT_A2D", fmt, ## args);} -#define A2D_TRACE_WARNING(fmt, args...) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(A2D, WARNING)) BT_PRINT_W("BT_A2D", fmt, ## args);} -#define A2D_TRACE_API(fmt, args...) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(A2D,API)) BT_PRINT_I("BT_A2D", fmt, ## args);} -#define A2D_TRACE_EVENT(fmt, args...) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(A2D,EVENT)) BT_PRINT_D("BT_A2D", fmt, ## args);} -#define A2D_TRACE_DEBUG(fmt, args...) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(A2D,DEBUG)) BT_PRINT_D("BT_A2D", fmt, ## args);} - -/* AVDTP -*/ -#define AVDT_TRACE_ERROR(fmt, args...) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(AVDT, ERROR)) BT_PRINT_E("BT_AVDT", fmt, ## args);} -#define AVDT_TRACE_WARNING(fmt, args...) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(AVDT, WARNING)) BT_PRINT_W("BT_AVDT", fmt, ## args);} -#define AVDT_TRACE_API(fmt, args...) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(AVDT,API)) BT_PRINT_I("BT_AVDT", fmt, ## args);} -#define AVDT_TRACE_EVENT(fmt, args...) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(AVDT,EVENT)) BT_PRINT_D("BT_AVDT", fmt, ## args);} -#define AVDT_TRACE_DEBUG(fmt, args...) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(AVDT,DEBUG)) BT_PRINT_D("BT_AVDT", fmt, ## args);} - -/* Define tracing for the AVCTP protocol -*/ -#define AVCT_TRACE_ERROR(fmt, args...) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(AVCT, ERROR)) BT_PRINT_E("BT_AVCT", fmt, ## args);} -#define AVCT_TRACE_WARNING(fmt, args...) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(AVCT, WARNING)) BT_PRINT_W("BT_AVCT", fmt, ## args);} -#define AVCT_TRACE_API(fmt, args...) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(AVCT,API)) BT_PRINT_I("BT_AVCT", fmt, ## args);} -#define AVCT_TRACE_EVENT(fmt, args...) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(AVCT,EVENT)) BT_PRINT_D("BT_AVCT", fmt, ## args);} -#define AVCT_TRACE_DEBUG(fmt, args...) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(AVCT,DEBUG)) BT_PRINT_D("BT_AVCT", fmt, ## args);} - -/* Define tracing for the AVRCP profile -*/ -#define AVRC_TRACE_ERROR(fmt, args...) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(AVRC, ERROR)) BT_PRINT_E("BT_AVRC", fmt, ## args);} -#define AVRC_TRACE_WARNING(fmt, args...) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(AVRC, WARNING)) BT_PRINT_W("BT_AVRC", fmt, ## args);} -#define AVRC_TRACE_API(fmt, args...) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(AVRC,API)) BT_PRINT_I("BT_AVRC", fmt, ## args);} -#define AVRC_TRACE_EVENT(fmt, args...) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(AVRC,EVENT)) BT_PRINT_D("BT_AVRC", fmt, ## args);} -#define AVRC_TRACE_DEBUG(fmt, args...) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(AVRC,DEBUG)) BT_PRINT_D("BT_AVRC", fmt, ## args);} - -/* MCAP -*/ -#define MCA_TRACE_ERROR(fmt, args...) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(MCA, ERROR)) BT_PRINT_E("BT_MCA", fmt, ## args);} -#define MCA_TRACE_WARNING(fmt, args...) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(MCA, WARNING)) BT_PRINT_W("BT_MCA", fmt, ## args);} -#define MCA_TRACE_API(fmt, args...) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(MCA,API)) BT_PRINT_I("BT_MCA", fmt, ## args);} -#define MCA_TRACE_EVENT(fmt, args...) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(MCA,EVENT)) BT_PRINT_D("BT_MCA", fmt, ## args);} -#define MCA_TRACE_DEBUG(fmt, args...) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(MCA,DEBUG)) BT_PRINT_D("BT_MCA", fmt, ## args);} - -/* Define tracing for the ATT/GATT unit -*/ -#define GATT_TRACE_ERROR(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GATT, ERROR)) BT_PRINT_E("BT_GATT", fmt, ## args);} -#define GATT_TRACE_WARNING(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GATT, WARNING)) BT_PRINT_W("BT_GATT", fmt, ## args);} -#define GATT_TRACE_API(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GATT,API)) BT_PRINT_I("BT_GATT", fmt, ## args);} -#define GATT_TRACE_EVENT(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GATT,EVENT)) BT_PRINT_D("BT_GATT", fmt, ## args);} -#define GATT_TRACE_DEBUG(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(GATT,DEBUG)) BT_PRINT_D("BT_GATT", fmt, ## args);} - -/* Define tracing for the SMP unit -*/ -#define SMP_TRACE_ERROR(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(SMP, ERROR)) BT_PRINT_E("BT_SMP", fmt, ## args);} -#define SMP_TRACE_WARNING(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(SMP, WARNING)) BT_PRINT_W("BT_SMP", fmt, ## args);} -#define SMP_TRACE_API(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(SMP,API)) BT_PRINT_I("BT_SMP", fmt, ## args);} -#define SMP_TRACE_EVENT(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(SMP,EVENT)) BT_PRINT_D("BT_SMP", fmt, ## args);} -#define SMP_TRACE_DEBUG(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(SMP,DEBUG)) BT_PRINT_D("BT_SMP", fmt, ## args);} - - -extern UINT8 btif_trace_level; - -// define traces for application -#define BTIF_TRACE_ERROR(fmt, args...) {if (btif_trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BTIF, ERROR)) BT_PRINT_E("BT_BTIF", fmt, ## args);} -#define BTIF_TRACE_WARNING(fmt, args...) {if (btif_trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BTIF, WARNING)) BT_PRINT_W("BT_BTIF", fmt, ## args);} -#define BTIF_TRACE_API(fmt, args...) {if (btif_trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BTIF,API)) BT_PRINT_I("BT_BTIF", fmt, ## args);} -#define BTIF_TRACE_EVENT(fmt, args...) {if (btif_trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BTIF,EVENT)) BT_PRINT_D("BT_BTIF", fmt, ## args);} -#define BTIF_TRACE_DEBUG(fmt, args...) {if (btif_trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BTIF,DEBUG)) BT_PRINT_D("BT_BTIF", fmt, ## args);} -#define BTIF_TRACE_VERBOSE(fmt, args...) {if (btif_trace_level >= BT_TRACE_LEVEL_VERBOSE && BT_LOG_LEVEL_CHECK(BTIF,VERBOSE)) BT_PRINT_V("BT_BTIF", fmt, ## args);} - -/* define traces for application */ - -#define APPL_TRACE_ERROR(fmt, args...) {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(APPL, ERROR)) BT_PRINT_E("BT_APPL", fmt, ## args);} -#define APPL_TRACE_WARNING(fmt, args...) {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(APPL, WARNING)) BT_PRINT_W("BT_APPL", fmt, ## args);} -#define APPL_TRACE_API(fmt, args...) {if (appl_trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(APPL,API)) BT_PRINT_I("BT_APPL", fmt, ## args);} -#define APPL_TRACE_EVENT(fmt, args...) {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(APPL,EVENT)) BT_PRINT_D("BT_APPL", fmt, ## args);} -#define APPL_TRACE_DEBUG(fmt, args...) {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(APPL,DEBUG)) BT_PRINT_D("BT_APPL", fmt, ## args);} -#define APPL_TRACE_VERBOSE(fmt, args...) {if (appl_trace_level >= BT_TRACE_LEVEL_VERBOSE && BT_LOG_LEVEL_CHECK(APPL,VERBOSE)) BT_PRINT_V("BT_APPL", fmt, ## args);} - -/* Define tracing for the HCI unit - * Modified from `btu_cb.trace_level` to `HCI_INITIAL_TRACE_LEVEL`, - * to use HCI_TRACE_XXXX in hci_layer.c without including `btu.h` -*/ -#define HCI_TRACE_ERROR(fmt, args...) {if (HCI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(HCI, ERROR)) BT_PRINT_E("BT_HCI", fmt,## args);} -#define HCI_TRACE_WARNING(fmt, args...) {if (HCI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(HCI, WARNING)) BT_PRINT_W("BT_HCI", fmt,## args);} -#define HCI_TRACE_EVENT(fmt, args...) {if (HCI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(HCI,EVENT)) BT_PRINT_D("BT_HCI", fmt,## args);} -#define HCI_TRACE_DEBUG(fmt, args...) {if (HCI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(HCI,DEBUG)) BT_PRINT_D("BT_HCI", fmt,## args);} - -/* define traces for BTC */ -#define BTC_TRACE_ERROR(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BTC, ERROR)) BT_PRINT_E("BT_BTC", fmt, ## args);} -#define BTC_TRACE_WARNING(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BTC, WARNING)) BT_PRINT_W("BT_BTC", fmt, ## args);} -#define BTC_TRACE_API(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BTC,API)) BT_PRINT_I("BT_BTC", fmt, ## args);} -#define BTC_TRACE_EVENT(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BTC,EVENT)) BT_PRINT_D("BT_BTC", fmt, ## args);} -#define BTC_TRACE_DEBUG(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BTC,DEBUG)) BT_PRINT_D("BT_BTC", fmt, ## args);} -#define BTC_TRACE_VERBOSE(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_VERBOSE && BT_LOG_LEVEL_CHECK(BTC,VERBOSE)) BT_PRINT_V("BT_BTC", fmt, ## args);} - -/* define traces for OSI */ -#define OSI_TRACE_ERROR(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(OSI, ERROR)) BT_PRINT_E("BT_OSI", fmt, ## args);} -#define OSI_TRACE_WARNING(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(OSI, WARNING)) BT_PRINT_W("BT_OSI", fmt, ## args);} -#define OSI_TRACE_API(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(OSI,API)) BT_PRINT_I("BT_OSI", fmt, ## args);} -#define OSI_TRACE_EVENT(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(OSI,EVENT)) BT_PRINT_D("BT_OSI", fmt, ## args);} -#define OSI_TRACE_DEBUG(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(OSI,DEBUG)) BT_PRINT_D("BT_OSI", fmt, ## args);} -#define OSI_TRACE_VERBOSE(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_VERBOSE && BT_LOG_LEVEL_CHECK(OSI,VERBOSE)) BT_PRINT_V("BT_OSI", fmt, ## args);} - -/* define traces for BLUFI */ -#define BLUFI_TRACE_ERROR(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BLUFI, ERROR)) BT_PRINT_E("BT_BLUFI", fmt, ## args);} -#define BLUFI_TRACE_WARNING(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BLUFI, WARNING)) BT_PRINT_W("BT_BLUFI", fmt, ## args);} -#define BLUFI_TRACE_API(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BLUFI,API)) BT_PRINT_I("BT_BLUFI", fmt, ## args);} -#define BLUFI_TRACE_EVENT(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BLUFI,EVENT)) BT_PRINT_D("BT_BLUFI", fmt, ## args);} -#define BLUFI_TRACE_DEBUG(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BLUFI,DEBUG)) BT_PRINT_D("BT_BLUFI", fmt, ## args);} -#define BLUFI_TRACE_VERBOSE(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_VERBOSE && BT_LOG_LEVEL_CHECK(BLUFI,VERBOSE)) BT_PRINT_V("BT_BLUFI", fmt, ## args);} - -#else -#define LOG_ERROR(fmt, args...) -#define LOG_WARN(fmt, args...) -#define LOG_INFO(fmt, args...) -#define LOG_DEBUG(fmt, args...) -#define LOG_VERBOSE(fmt, args...) - -/* Define tracing for the HCI unit -*/ -#define HCI_TRACE_ERROR(fmt, args...) -#define HCI_TRACE_WARNING(fmt, args...) -#define HCI_TRACE_EVENT(fmt, args...) -#define HCI_TRACE_DEBUG(fmt, args...) - -/* Define tracing for BTM -*/ -#define BTM_TRACE_ERROR(fmt, args...) -#define BTM_TRACE_WARNING(fmt, args...) -#define BTM_TRACE_API(fmt, args...) -#define BTM_TRACE_EVENT(fmt, args...) -#define BTM_TRACE_DEBUG(fmt, args...) - -/* Define tracing for the L2CAP unit -*/ -#define L2CAP_TRACE_ERROR(fmt, args...) -#define L2CAP_TRACE_WARNING(fmt, args...) -#define L2CAP_TRACE_API(fmt, args...) -#define L2CAP_TRACE_EVENT(fmt, args...) -#define L2CAP_TRACE_DEBUG(fmt, args...) - -/* Define tracing for the SDP unit -*/ -#define SDP_TRACE_ERROR(fmt, args...) -#define SDP_TRACE_WARNING(fmt, args...) -#define SDP_TRACE_API(fmt, args...) -#define SDP_TRACE_EVENT(fmt, args...) -#define SDP_TRACE_DEBUG(fmt, args...) - -/* Define tracing for the RFCOMM unit -*/ -#define RFCOMM_TRACE_ERROR(fmt, args...) -#define RFCOMM_TRACE_WARNING(fmt, args...) -#define RFCOMM_TRACE_API(fmt, args...) -#define RFCOMM_TRACE_EVENT(fmt, args...) -#define RFCOMM_TRACE_DEBUG(fmt, args...) - -/* Generic Access Profile traces */ -#define GAP_TRACE_ERROR(fmt, args...) -#define GAP_TRACE_EVENT(fmt, args...) -#define GAP_TRACE_API(fmt, args...) -#define GAP_TRACE_WARNING(fmt, args...) - -/* define traces for HID Host */ -#define HIDH_TRACE_ERROR(fmt, args...) -#define HIDH_TRACE_WARNING(fmt, args...) -#define HIDH_TRACE_API(fmt, args...) -#define HIDH_TRACE_EVENT(fmt, args...) -#define HIDH_TRACE_DEBUG(fmt, args...) - -/* define traces for BNEP */ - -#define BNEP_TRACE_ERROR(fmt, args...) -#define BNEP_TRACE_WARNING(fmt, args...) -#define BNEP_TRACE_API(fmt, args...) -#define BNEP_TRACE_EVENT(fmt, args...) -#define BNEP_TRACE_DEBUG(fmt, args...) - -/* define traces for PAN */ - -#define PAN_TRACE_ERROR(fmt, args...) -#define PAN_TRACE_WARNING(fmt, args...) -#define PAN_TRACE_API(fmt, args...) -#define PAN_TRACE_EVENT(fmt, args...) -#define PAN_TRACE_DEBUG(fmt, args...) - -/* Define tracing for the A2DP profile -*/ -#define A2D_TRACE_ERROR(fmt, args...) -#define A2D_TRACE_WARNING(fmt, args...) -#define A2D_TRACE_EVENT(fmt, args...) -#define A2D_TRACE_DEBUG(fmt, args...) -#define A2D_TRACE_API(fmt, args...) - -/* AVDTP -*/ -#define AVDT_TRACE_ERROR(fmt, args...) -#define AVDT_TRACE_WARNING(fmt, args...) -#define AVDT_TRACE_EVENT(fmt, args...) -#define AVDT_TRACE_DEBUG(fmt, args...) -#define AVDT_TRACE_API(fmt, args...) - -/* Define tracing for the AVCTP protocol -*/ -#define AVCT_TRACE_ERROR(fmt, args...) -#define AVCT_TRACE_WARNING(fmt, args...) -#define AVCT_TRACE_EVENT(fmt, args...) -#define AVCT_TRACE_DEBUG(fmt, args...) -#define AVCT_TRACE_API(fmt, args...) - -/* Define tracing for the AVRCP profile -*/ -#define AVRC_TRACE_ERROR(fmt, args...) -#define AVRC_TRACE_WARNING(fmt, args...) -#define AVRC_TRACE_EVENT(fmt, args...) -#define AVRC_TRACE_DEBUG(fmt, args...) -#define AVRC_TRACE_API(fmt, args...) - -/* MCAP -*/ -#define MCA_TRACE_ERROR(fmt, args...) -#define MCA_TRACE_WARNING(fmt, args...) -#define MCA_TRACE_EVENT(fmt, args...) -#define MCA_TRACE_DEBUG(fmt, args...) -#define MCA_TRACE_API(fmt, args...) - -/* Define tracing for the ATT/GATT unit -*/ -#define GATT_TRACE_ERROR(fmt, args...) -#define GATT_TRACE_WARNING(fmt, args...) -#define GATT_TRACE_API(fmt, args...) -#define GATT_TRACE_EVENT(fmt, args...) -#define GATT_TRACE_DEBUG(fmt, args...) - -/* Define tracing for the SMP unit -*/ -#define SMP_TRACE_ERROR(fmt, args...) -#define SMP_TRACE_WARNING(fmt, args...) -#define SMP_TRACE_API(fmt, args...) -#define SMP_TRACE_EVENT(fmt, args...) -#define SMP_TRACE_DEBUG(fmt, args...) - -extern UINT8 btif_trace_level; - -// define traces for application -#define BTIF_TRACE_ERROR(fmt, args...) -#define BTIF_TRACE_WARNING(fmt, args...) -#define BTIF_TRACE_API(fmt, args...) -#define BTIF_TRACE_EVENT(fmt, args...) -#define BTIF_TRACE_DEBUG(fmt, args...) -#define BTIF_TRACE_VERBOSE(fmt, args...) - -/* define traces for application */ - -#define APPL_TRACE_ERROR(fmt, args...) -#define APPL_TRACE_WARNING(fmt, args...) -#define APPL_TRACE_API(fmt, args...) -#define APPL_TRACE_EVENT(fmt, args...) -#define APPL_TRACE_DEBUG(fmt, args...) -#define APPL_TRACE_VERBOSE(fmt, args...) - -/* define traces for BTC */ -#define BTC_TRACE_ERROR(fmt, args...) -#define BTC_TRACE_WARNING(fmt, args...) -#define BTC_TRACE_API(fmt, args...) -#define BTC_TRACE_EVENT(fmt, args...) -#define BTC_TRACE_DEBUG(fmt, args...) -#define BTC_TRACE_VERBOSE(fmt, args...) - -/* define traces for OSI */ -#define OSI_TRACE_ERROR(fmt, args...) -#define OSI_TRACE_WARNING(fmt, args...) -#define OSI_TRACE_API(fmt, args...) -#define OSI_TRACE_EVENT(fmt, args...) -#define OSI_TRACE_DEBUG(fmt, args...) -#define OSI_TRACE_VERBOSE(fmt, args...) - -/* define traces for BLUFI */ -#define BLUFI_TRACE_ERROR(fmt, args...) -#define BLUFI_TRACE_WARNING(fmt, args...) -#define BLUFI_TRACE_API(fmt, args...) -#define BLUFI_TRACE_EVENT(fmt, args...) -#define BLUFI_TRACE_DEBUG(fmt, args...) -#define BLUFI_TRACE_VERBOSE(fmt, args...) -#endif ///CONFIG_BT_STACK_NO_LOG - - -/* Simplified Trace Helper Macro -*/ -#define bdld(fmt, args...) \ - do{\ - if((MY_LOG_LEVEL) >= BT_TRACE_LEVEL_DEBUG) \ - BT_PRINT_D(fmt, ## args); \ - }while(0) - -#define bdlw(fmt, args...) \ - do{\ - if((MY_LOG_LEVEL) >= BT_TRACE_LEVEL_WARNING) \ - BT_PRINT_W(fmt, ## args); \ - }while(0) - -#define bdle(fmt, args...) \ - do{\ - if((MY_LOG_LEVEL) >= BT_TRACE_LEVEL_ERROR) \ - BT_PRINT_E(fmt, ## args); \ - }while(0) - -#define bdla(assert_if) \ - do{\ - if(((MY_LOG_LEVEL) >= BT_TRACE_LEVEL_ERROR) && !(assert_if)) \ - BT_PRINT_E("%s: assert failed\n", #assert_if); \ - }while(0) - -typedef UINT8 tBTTRC_PARAM_TYPE; -typedef UINT8 tBTTRC_LAYER_ID; -typedef UINT8 tBTTRC_TYPE; - -typedef struct { - tBTTRC_LAYER_ID layer_id; - tBTTRC_TYPE type; /* TODO: use tBTTRC_TYPE instead of "classical level 0-5" */ -} tBTTRC_LEVEL; - -typedef UINT8 (tBTTRC_SET_TRACE_LEVEL)( UINT8 ); - -typedef struct { - const tBTTRC_LAYER_ID layer_id_start; - const tBTTRC_LAYER_ID layer_id_end; - tBTTRC_SET_TRACE_LEVEL *p_f; - const char *trc_name; - UINT8 trace_level; -} tBTTRC_FUNC_MAP; - -/* External declaration for appl_trace_level here to avoid to add the declaration in all the files using APPL_TRACExxx macros */ -extern UINT8 appl_trace_level; - -#endif /*_BT_TRACE_H_*/ diff --git a/tools/sdk/include/bluedroid/common/bt_vendor_lib.h b/tools/sdk/include/bluedroid/common/bt_vendor_lib.h deleted file mode 100644 index e3a8ec8d..00000000 --- a/tools/sdk/include/bluedroid/common/bt_vendor_lib.h +++ /dev/null @@ -1,362 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2009-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef BT_VENDOR_LIB_H -#define BT_VENDOR_LIB_H - -#include -//#include -//#include - -/** Struct types */ - - -/** Typedefs and defines */ - -/** Vendor specific operations OPCODE */ -typedef enum { - /* [operation] - * Power on or off the BT Controller. - * [input param] - * A pointer to int type with content of bt_vendor_power_state_t. - * Typecasting conversion: (int *) param. - * [return] - * 0 - default, don't care. - * [callback] - * None. - */ - BT_VND_OP_POWER_CTRL, - - /* [operation] - * Perform any vendor specific initialization or configuration - * on the BT Controller. This is called before stack initialization. - * [input param] - * None. - * [return] - * 0 - default, don't care. - * [callback] - * Must call fwcfg_cb to notify the stack of the completion of vendor - * specific initialization once it has been done. - */ - BT_VND_OP_FW_CFG, - - /* [operation] - * Perform any vendor specific SCO/PCM configuration on the BT Controller. - * This is called after stack initialization. - * [input param] - * None. - * [return] - * 0 - default, don't care. - * [callback] - * Must call scocfg_cb to notify the stack of the completion of vendor - * specific SCO configuration once it has been done. - */ - BT_VND_OP_SCO_CFG, - - /* [operation] - * Open UART port on where the BT Controller is attached. - * This is called before stack initialization. - * [input param] - * A pointer to int array type for open file descriptors. - * The mapping of HCI channel to fd slot in the int array is given in - * bt_vendor_hci_channels_t. - * And, it requires the vendor lib to fill up the content before returning - * the call. - * Typecasting conversion: (int (*)[]) param. - * [return] - * Numbers of opened file descriptors. - * Valid number: - * 1 - CMD/EVT/ACL-In/ACL-Out via the same fd (e.g. UART) - * 2 - CMD/EVT on one fd, and ACL-In/ACL-Out on the other fd - * 4 - CMD, EVT, ACL-In, ACL-Out are on their individual fd - * [callback] - * None. - */ - BT_VND_OP_USERIAL_OPEN, - - /* [operation] - * Close the previously opened UART port. - * [input param] - * None. - * [return] - * 0 - default, don't care. - * [callback] - * None. - */ - BT_VND_OP_USERIAL_CLOSE, - - /* [operation] - * Get the LPM idle timeout in milliseconds. - * The stack uses this information to launch a timer delay before it - * attempts to de-assert LPM WAKE signal once downstream HCI packet - * has been delivered. - * [input param] - * A pointer to uint32_t type which is passed in by the stack. And, it - * requires the vendor lib to fill up the content before returning - * the call. - * Typecasting conversion: (uint32_t *) param. - * [return] - * 0 - default, don't care. - * [callback] - * None. - */ - BT_VND_OP_GET_LPM_IDLE_TIMEOUT, - - /* [operation] - * Enable or disable LPM mode on BT Controller. - * [input param] - * A pointer to uint8_t type with content of bt_vendor_lpm_mode_t. - * Typecasting conversion: (uint8_t *) param. - * [return] - * 0 - default, don't care. - * [callback] - * Must call lpm_cb to notify the stack of the completion of LPM - * disable/enable process once it has been done. - */ - BT_VND_OP_LPM_SET_MODE, - - /* [operation] - * Assert or Deassert LPM WAKE on BT Controller. - * [input param] - * A pointer to uint8_t type with content of bt_vendor_lpm_wake_state_t. - * Typecasting conversion: (uint8_t *) param. - * [return] - * 0 - default, don't care. - * [callback] - * None. - */ - BT_VND_OP_LPM_WAKE_SET_STATE, - - /* [operation] - * Perform any vendor specific commands related to audio state changes. - * [input param] - * a pointer to bt_vendor_op_audio_state_t indicating what audio state is - * set. - * [return] - * 0 - default, don't care. - * [callback] - * None. - */ - BT_VND_OP_SET_AUDIO_STATE, - - /* [operation] - * The epilog call to the vendor module so that it can perform any - * vendor-specific processes (e.g. send a HCI_RESET to BT Controller) - * before the caller calls for cleanup(). - * [input param] - * None. - * [return] - * 0 - default, don't care. - * [callback] - * Must call epilog_cb to notify the stack of the completion of vendor - * specific epilog process once it has been done. - */ - BT_VND_OP_EPILOG, -} bt_vendor_opcode_t; - -/** Power on/off control states */ -typedef enum { - BT_VND_PWR_OFF, - BT_VND_PWR_ON, -} bt_vendor_power_state_t; - -/** Define HCI channel identifier in the file descriptors array - used in BT_VND_OP_USERIAL_OPEN operation. - */ -typedef enum { - CH_CMD, // HCI Command channel - CH_EVT, // HCI Event channel - CH_ACL_OUT, // HCI ACL downstream channel - CH_ACL_IN, // HCI ACL upstream channel - - CH_MAX // Total channels -} bt_vendor_hci_channels_t; - -/** LPM disable/enable request */ -typedef enum { - BT_VND_LPM_DISABLE, - BT_VND_LPM_ENABLE, -} bt_vendor_lpm_mode_t; - -/** LPM WAKE set state request */ -typedef enum { - BT_VND_LPM_WAKE_ASSERT, - BT_VND_LPM_WAKE_DEASSERT, -} bt_vendor_lpm_wake_state_t; - -/** Callback result values */ -typedef enum { - BT_VND_OP_RESULT_SUCCESS, - BT_VND_OP_RESULT_FAIL, -} bt_vendor_op_result_t; - -/** audio (SCO) state changes triggering VS commands for configuration */ -typedef struct { - uint16_t handle; - uint16_t peer_codec; - uint16_t state; -} bt_vendor_op_audio_state_t; - -/* - * Bluetooth Host/Controller Vendor callback structure. - */ - -/* vendor initialization/configuration callback */ -typedef void (*cfg_result_cb)(bt_vendor_op_result_t result); - -/* datapath buffer allocation callback (callout) - * - * Vendor lib needs to request a buffer through the alloc callout function - * from HCI lib if the buffer is for constructing a HCI Command packet which - * will be sent through xmit_cb to BT Controller. - * - * For each buffer allocation, the requested size needs to be big enough to - * accommodate the below header plus a complete HCI packet -- - * typedef struct - * { - * uint16_t event; - * uint16_t len; - * uint16_t offset; - * uint16_t layer_specific; - * } HC_BT_HDR; - * - * HCI lib returns a pointer to the buffer where Vendor lib should use to - * construct a HCI command packet as below format: - * - * -------------------------------------------- - * | HC_BT_HDR | HCI command | - * -------------------------------------------- - * where - * HC_BT_HDR.event = 0x2000; - * HC_BT_HDR.len = Length of HCI command; - * HC_BT_HDR.offset = 0; - * HC_BT_HDR.layer_specific = 0; - * - * For example, a HCI_RESET Command will be formed as - * ------------------------ - * | HC_BT_HDR |03|0c|00| - * ------------------------ - * with - * HC_BT_HDR.event = 0x2000; - * HC_BT_HDR.len = 3; - * HC_BT_HDR.offset = 0; - * HC_BT_HDR.layer_specific = 0; - */ -typedef void *(*malloc_cb)(int size); - -/* datapath buffer deallocation callback (callout) */ -typedef void (*mdealloc_cb)(void *p_buf); - -/* define callback of the cmd_xmit_cb - * - * The callback function which HCI lib will call with the return of command - * complete packet. Vendor lib is responsible for releasing the buffer passed - * in at the p_mem parameter by calling dealloc callout function. - */ -typedef void (*tINT_CMD_CBACK)(void *p_mem); - -/* hci command packet transmit callback (callout) - * - * Vendor lib calls xmit_cb callout function in order to send a HCI Command - * packet to BT Controller. The buffer carrying HCI Command packet content - * needs to be first allocated through the alloc callout function. - * HCI lib will release the buffer for Vendor lib once it has delivered the - * packet content to BT Controller. - * - * Vendor lib needs also provide a callback function (p_cback) which HCI lib - * will call with the return of command complete packet. - * - * The opcode parameter gives the HCI OpCode (combination of OGF and OCF) of - * HCI Command packet. For example, opcode = 0x0c03 for the HCI_RESET command - * packet. - */ -typedef uint8_t (*cmd_xmit_cb)(uint16_t opcode, void *p_buf, tINT_CMD_CBACK p_cback); - -typedef struct { - /** set to sizeof(bt_vendor_callbacks_t) */ - size_t size; - - /* - * Callback and callout functions have implemented in HCI libray - * (libbt-hci.so). - */ - - /* notifies caller result of firmware configuration request */ - cfg_result_cb fwcfg_cb; - - /* notifies caller result of sco configuration request */ - cfg_result_cb scocfg_cb; - - /* notifies caller result of lpm enable/disable */ - cfg_result_cb lpm_cb; - - /* notifies the result of codec setting */ - cfg_result_cb audio_state_cb; - - /* buffer allocation request */ - malloc_cb alloc; - - /* buffer deallocation request */ - mdealloc_cb dealloc; - - /* hci command packet transmit request */ - cmd_xmit_cb xmit_cb; - - /* notifies caller completion of epilog process */ - cfg_result_cb epilog_cb; -} bt_vendor_callbacks_t; - -/* - * Bluetooth Host/Controller VENDOR Interface - */ -typedef struct { - /** Set to sizeof(bt_vndor_interface_t) */ - size_t size; - - /* - * Functions need to be implemented in Vendor libray (libbt-vendor.so). - */ - - /** - * Caller will open the interface and pass in the callback routines - * to the implemenation of this interface. - */ - int (*init)(const bt_vendor_callbacks_t *p_cb, unsigned char *local_bdaddr); - - /** Vendor specific operations */ - int (*op)(bt_vendor_opcode_t opcode, void *param); - - /** Closes the interface */ - void (*cleanup)(void); -} bt_vendor_interface_t; - - -/* - * External shared lib functions/data - */ - -/* Entry point of DLib -- - * Vendor library needs to implement the body of bt_vendor_interface_t - * structure and uses the below name as the variable name. HCI library - * will use this symbol name to get address of the object through the - * dlsym call. - */ -//extern const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE; - -#endif /* BT_VENDOR_LIB_H */ - diff --git a/tools/sdk/include/bluedroid/common/bte.h b/tools/sdk/include/bluedroid/common/bte.h deleted file mode 100644 index 4bef635a..00000000 --- a/tools/sdk/include/bluedroid/common/bte.h +++ /dev/null @@ -1,116 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2001-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * this file contains constants and definitions for the bte project - * - ******************************************************************************/ -#ifndef BTE_H -#define BTE_H - -//#include -//#include -//#include -#include "common/bt_target.h" - -/* by default on shutdown, baudrate is reset 115kbits. this should NOT be need for platforms - * that kill BTE driver and remove/reset BT chip - */ -#ifndef BTE_RESET_BAUD_ON_BT_DISABLE -#define BTE_RESET_BAUD_ON_BT_DISABLE TRUE -#endif - -/* Target Modes (based on jumper settings on hardware [see user manual]) */ -enum { - /* BTE BBY */ - /* J3 J4 SW3-3 SW3-2 SW3-1 */ - /* -------------------------------------------- */ - BTE_MODE_SERIAL_APP, /* OUT OUT OFF OFF OFF Sample serial port application */ - BTE_MODE_APPL, /* IN OUT OFF OFF ON Target used with Tester through RPC */ - BTE_MODE_RESERVED, /* OUT IN OFF ON OFF Reserved */ - BTE_MODE_SAMPLE_APPS, /* IN IN OFF ON ON Sample applications (ICP/HSP) */ - BTE_MODE_DONGLE, /* not yet supported ON OFF OFF Dongle mode */ - BTE_MODE_APPL_PROTOCOL_TRACE, /* this is a fake mode do allow protocol tracing in application without rpc */ - BTE_MODE_INVALID -}; - -extern volatile UINT8 bte_target_mode; /* indicates the mode that the board is running in */ - -/* Startup options */ -extern UINT32 bte_startup_options; /* Switch and jumper settings at startup */ -void bte_get_startup_options(UINT32 *p_options); /* Platform specific function for getting startup options */ - -#define BTE_OPTIONS_TARGET_MODE_MASK 0x00000007 /* bits 2-0 indicate target mode (QuickConnect: jp3 & jp4, BBY: SW3-1 & SW3-2)*/ - - -/**************************************************************************** - * Definitions to define which type of application gets built - ****************************************************************************/ -#define BUILD_HCITOOL FALSE -#define BUILD_L2PING FALSE - - -#define LINUX_FM_DRIVER_INCLUDED FALSE - - -/* hcisu userial operations. should probably go into bt_types to avoid collisions! */ -#define BT_EVT_TO_HCISU_USERIAL_OP (0x0080 | BT_EVT_HCISU) -/* operation for above hcisu event */ -#define BT_HCISU_USERIAL_OPEN (0) /* open serial port calling USERIAL_Open() */ -#define BT_HCISU_USERIAL_CLOSE (1) /* close userial port */ -/* options associated with close op */ -#define BT_HCISU_USERIAL_CL_NO_DIS_BT 0 /* do not touch bt_wake and power gpio */ -#define BT_HCISU_USERIAL_CL_DIS_BT 1 /* put power and bt_wake into defined off state to preserve - power */ -/* status codes for callback */ -/* -#define BTE_HCISU_USERIAL_FAIL 0 -#define BTE_HCISU_USERIAL_OK 1 -typedef void (tUSERIAL_MSG_CBACK) (int status); -typedef struct tHCISU_USERIAL_MSG_tag { - BT_HDR hdr; - tUSERIAL_MSG_CBACK *p_cback; - UINT8 port; // port number - UINT8 op; - UINT8 option; // option for operation. depends on operation -} tHCISU_USERIAL_MSG; - -extern void bte_hcisu_userial_oper( tUSERIAL_MSG_CBACK *p_cback, UINT8 port, UINT8 op, UINT8 option ); -*/ - -/* Pointer to function for sending HCI commands and data to the HCI tranport */ -extern int (*p_bte_hci_send)(UINT16 port, BT_HDR *p_msg); - - -/* Protocol trace mask */ -extern UINT32 bte_proto_trace_mask; - -typedef struct tBAUD_REG_tag { - UINT8 DHBR; - UINT8 DLBR; - UINT8 ExplicitBaudRate0; - UINT8 ExplicitBaudRate1; - UINT8 ExplicitBaudRate2; - UINT8 ExplicitBaudRate3; -} tBAUD_REG; - - -extern const tBAUD_REG baud_rate_regs[]; - -#endif /* BTE_H */ diff --git a/tools/sdk/include/bluedroid/common/bte_appl.h b/tools/sdk/include/bluedroid/common/bte_appl.h deleted file mode 100644 index 47a0184b..00000000 --- a/tools/sdk/include/bluedroid/common/bte_appl.h +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2002-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the interface file for the bte application task - * - ******************************************************************************/ - -#pragma once - -typedef struct { -#if ((BLE_INCLUDED == TRUE) && (SMP_INCLUDED == TRUE)) - UINT8 ble_auth_req; - UINT8 ble_io_cap; - UINT8 ble_init_key; - UINT8 ble_resp_key; - UINT8 ble_max_key_size; -#endif - -} tBTE_APPL_CFG; - -extern tBTE_APPL_CFG bte_appl_cfg; - - -typedef struct { -#if ((CLASSIC_BT_INCLUDED == TRUE) && (BT_SSP_INCLUDED == TRUE)) - UINT8 bt_auth_req; - UINT8 bt_io_cap; - UINT8 *bt_oob_auth_data; -#endif -} tBTE_BT_APPL_CFG; - -extern tBTE_BT_APPL_CFG bte_bt_appl_cfg; \ No newline at end of file diff --git a/tools/sdk/include/bluedroid/device/bdaddr.h b/tools/sdk/include/bluedroid/device/bdaddr.h deleted file mode 100644 index 611fcf0e..00000000 --- a/tools/sdk/include/bluedroid/device/bdaddr.h +++ /dev/null @@ -1,63 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _BDADDR_H_ -#define _BDADDR_H_ - -#include -#include - -#include "common/bt_defs.h" -#include "osi/hash_map.h" - -// Note: the string representation of a bdaddr is expected to have the format -// xx:xx:xx:xx:xx:xx -// where each 'x' is a hex digit. The API presented in this header will accept -// both uppercase and lowercase digits but will only ever produce lowercase -// digits. - -// Returns true if |addr| is the empty address (00:00:00:00:00:00). -// |addr| may not be NULL. -bool bdaddr_is_empty(const bt_bdaddr_t *addr); - -// Returns true if |first| and |second| refer to the same address. Neither -// may be NULL. -bool bdaddr_equals(const bt_bdaddr_t *first, const bt_bdaddr_t *second); - -// Returns destination bdaddr |dest| after copying |src| to |dest|. -// |dest| and |src| must not be NULL. -bt_bdaddr_t *bdaddr_copy(bt_bdaddr_t *dest, const bt_bdaddr_t *src); - -// Makes a string representation of |addr| and places it into |string|. |size| -// refers to the size of |string|'s buffer and must be >= 18. On success, this -// function returns |string|, otherwise it returns NULL. Neither |addr| nor |string| -// may be NULL. -const char *bdaddr_to_string(const bt_bdaddr_t *addr, char *string, size_t size); - -// Returns true if |string| represents a Bluetooth address. |string| may not be NULL. -bool string_is_bdaddr(const char *string); - -// Converts |string| to bt_bdaddr_t and places it in |addr|. If |string| does not -// represent a Bluetooth address, |addr| is not modified and this function returns -// false. Otherwise, it returns true. Neither |string| nor |addr| may be NULL. -bool string_to_bdaddr(const char *string, bt_bdaddr_t *addr); - -// A hash function tailored for bdaddrs. -hash_index_t hash_function_bdaddr(const void *key); - -#endif diff --git a/tools/sdk/include/bluedroid/device/controller.h b/tools/sdk/include/bluedroid/device/controller.h deleted file mode 100644 index 704b456d..00000000 --- a/tools/sdk/include/bluedroid/device/controller.h +++ /dev/null @@ -1,91 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _CONTROLLER_H_ -#define _CONTROLLER_H_ - -#include -#include - -#include "common/bt_target.h" -#include "device/bdaddr.h" -#include "device/device_features.h" -#include "hci/hci_layer.h" -#include "hci/hci_packet_factory.h" -#include "hci/hci_packet_parser.h" - -typedef struct controller_t { - void (*start_up)(void); - void (*shut_down)(void); - bool (*get_is_ready)(void); - - const bt_bdaddr_t *(*get_address)(void); - const bt_version_t *(*get_bt_version)(void); - - const bt_device_features_t *(*get_features_classic)(int index); - - uint8_t (*get_last_features_classic_index)(void); - - const bt_device_features_t *(*get_features_ble)(void); - const uint8_t *(*get_ble_supported_states)(void); - - bool (*supports_simple_pairing)(void); - bool (*supports_secure_connections)(void); - bool (*supports_simultaneous_le_bredr)(void); - bool (*supports_reading_remote_extended_features)(void); - bool (*supports_interlaced_inquiry_scan)(void); - bool (*supports_rssi_with_inquiry_results)(void); - bool (*supports_extended_inquiry_response)(void); - bool (*supports_master_slave_role_switch)(void); - - bool (*supports_ble)(void); - bool (*supports_ble_packet_extension)(void); - bool (*supports_ble_connection_parameters_request)(void); - bool (*supports_ble_privacy)(void); - - // Get the cached acl data sizes for the controller. - uint16_t (*get_acl_data_size_classic)(void); - uint16_t (*get_acl_data_size_ble)(void); - - // Get the cached acl packet sizes for the controller. - // This is a convenience function for the respective - // acl data size + size of the acl header. - uint16_t (*get_acl_packet_size_classic)(void); - uint16_t (*get_acl_packet_size_ble)(void); - - uint16_t (*get_ble_default_data_packet_length)(void); - uint16_t (*get_ble_default_data_packet_txtime)(void); - - // Get the number of acl packets the controller can buffer. - uint16_t (*get_acl_buffer_count_classic)(void); - uint8_t (*get_acl_buffer_count_ble)(void); - - uint8_t (*get_ble_white_list_size)(void); - - uint8_t (*get_ble_resolving_list_max_size)(void); - void (*set_ble_resolving_list_max_size)(int resolving_list_max_size); -#if (BTM_SCO_HCI_INCLUDED == TRUE) - // Get the number of sco packets the controller can buffer - uint8_t (*get_sco_data_size)(void); - uint8_t (*get_sco_buffer_count)(void); -#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */ -} controller_t; - -const controller_t *controller_get_interface(); - -#endif /*_CONTROLLER_H_*/ diff --git a/tools/sdk/include/bluedroid/device/device_features.h b/tools/sdk/include/bluedroid/device/device_features.h deleted file mode 100644 index 360d3768..00000000 --- a/tools/sdk/include/bluedroid/device/device_features.h +++ /dev/null @@ -1,29 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef _DEVICE_FEATURES_H_ -#define _DEVICE_FEATURES_H_ - -#include - -// Represents a page of device feature enabled/disabled bits returned -// by the local controller. See the bluetooth spec for bit indexes. -typedef struct { - uint8_t as_array[8]; -} bt_device_features_t; - -#endif /*_DEVICE_FEATURES_H_*/ diff --git a/tools/sdk/include/bluedroid/device/event_mask.h b/tools/sdk/include/bluedroid/device/event_mask.h deleted file mode 100644 index d4d036d5..00000000 --- a/tools/sdk/include/bluedroid/device/event_mask.h +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef _EVENT_MASK_H_ -#define _EVENT_MASK_H_ - -#include - -// Represents a mask which can be used to tell the controller which -// HCI events the stack wishes to be informed about. See the bluetooth -// spec for more information on what each bit means. -typedef struct { - uint8_t as_array[8]; -} bt_event_mask_t; - -#endif /*_EVENT_MASK_H_*/ diff --git a/tools/sdk/include/bluedroid/device/interop.h b/tools/sdk/include/bluedroid/device/interop.h deleted file mode 100644 index 64f27adb..00000000 --- a/tools/sdk/include/bluedroid/device/interop.h +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2015 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _INTEROP_H_ -#define _INTEROP_H_ - -#include -#include "common/bt_defs.h" -#include "common/bt_target.h" - -typedef enum { - // Disable secure connections - // This is for pre BT 4.1/2 devices that do not handle secure mode - // very well. - INTEROP_DISABLE_LE_SECURE_CONNECTIONS, - - // Some devices have proven problematic during the pairing process, often - // requiring multiple retries to complete pairing. To avoid degrading the user - // experience for those devices, automatically re-try pairing if page - // timeouts are received during pairing. - INTEROP_AUTO_RETRY_PAIRING -} interop_feature_t; - -// Check if a given |addr| matches a known interoperability workaround as identified -// by the |interop_feature_t| enum. This API is used for simple address based lookups -// where more information is not available. No look-ups or random address resolution -// is performed on |addr|. -bool interop_match(const interop_feature_t feature, const bt_bdaddr_t *addr); - -#endif /*_INTEROP_H_*/ diff --git a/tools/sdk/include/bluedroid/device/interop_database.h b/tools/sdk/include/bluedroid/device/interop_database.h deleted file mode 100644 index 71224905..00000000 --- a/tools/sdk/include/bluedroid/device/interop_database.h +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2015 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _INTEROP_DATABASE_H_ -#define _INTEROP_DATABASE_H_ - -#include "device/interop.h" - -typedef struct { - bt_bdaddr_t addr; - uint8_t len; - interop_feature_t feature; -} interop_entry_t; - -static const interop_entry_t interop_database[] = { - // Nexus Remote (Spike) - // Note: May affect other Asus brand devices - {{{0x08, 0x62, 0x66, 0, 0, 0}}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, - {{{0x38, 0x2c, 0x4a, 0xc9, 0, 0}}, 4, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, - {{{0x38, 0x2c, 0x4a, 0xe6, 0, 0}}, 4, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, - {{{0x54, 0xa0, 0x50, 0xd9, 0, 0}}, 4, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, - {{{0xac, 0x9e, 0x17, 0, 0, 0}}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, - {{{0xf0, 0x79, 0x59, 0, 0, 0}}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, - - // Motorola Key Link - {{{0x1c, 0x96, 0x5a, 0, 0, 0}}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, - - // Flic smart button - {{{0x80, 0xe4, 0xda, 0x70, 0, 0}}, 4, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, - - // BMW car kits (Harman/Becker) - {{{0x9c, 0xdf, 0x03, 0, 0, 0}}, 3, INTEROP_AUTO_RETRY_PAIRING} -}; - -#endif /*_INTEROP_DATABASE_H_*/ diff --git a/tools/sdk/include/bluedroid/device/version.h b/tools/sdk/include/bluedroid/device/version.h deleted file mode 100644 index c63b03bd..00000000 --- a/tools/sdk/include/bluedroid/device/version.h +++ /dev/null @@ -1,31 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef _VERSION_H_ -#define _VERSION_H_ - -#include - -typedef struct { - uint8_t hci_version; - uint16_t hci_revision; - uint8_t lmp_version; - uint16_t manufacturer; - uint16_t lmp_subversion; -} bt_version_t; - -#endif /*_VERSION_H_*/ diff --git a/tools/sdk/include/bluedroid/dis_api.h b/tools/sdk/include/bluedroid/dis_api.h deleted file mode 100644 index 7edbd67d..00000000 --- a/tools/sdk/include/bluedroid/dis_api.h +++ /dev/null @@ -1,338 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2013 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/******************************************************************************* -** -** Header file for profile folder. -** -********************************************************************************/ - -#ifndef SRVC_DIS_API_H -#define SRVC_DIS_API_H - -#include "common/bt_target.h" -#include "stack/gatt_api.h" -#include "stack/gattdefs.h" -#include "esp_gatts_api.h" - -#define DIS_SUCCESS GATT_SUCCESS -#define DIS_ILLEGAL_PARAM GATT_ILLEGAL_PARAMETER -#define DIS_NO_RESOURCES GATT_NO_RESOURCES -typedef UINT8 tDIS_STATUS; - - -/***************************************************************************** -** Data structure for DIS -*****************************************************************************/ - -#define DIS_ATTR_SYS_ID_BIT 0x0001 -#define DIS_ATTR_MODEL_NUM_BIT 0x0002 -#define DIS_ATTR_SERIAL_NUM_BIT 0x0004 -#define DIS_ATTR_FW_NUM_BIT 0x0008 -#define DIS_ATTR_HW_NUM_BIT 0x0010 -#define DIS_ATTR_SW_NUM_BIT 0x0020 -#define DIS_ATTR_MANU_NAME_BIT 0x0040 -#define DIS_ATTR_IEEE_DATA_BIT 0x0080 -#define DIS_ATTR_PNP_ID_BIT 0x0100 -typedef UINT16 tDIS_ATTR_MASK; - -#define DIS_ATTR_ALL_MASK 0xffff - -typedef tDIS_ATTR_MASK tDIS_ATTR_BIT ; - -#define DIS_MAX_NUM_INC_SVR 0 -#define DIS_MAX_CHAR_NUM 9 -#define DIS_MAX_ATTR_NUM (DIS_MAX_CHAR_NUM * 2 + DIS_MAX_NUM_INC_SVR + 1) - -#ifndef DIS_ATTR_DB_SIZE -#define DIS_ATTR_DB_SIZE GATT_DB_MEM_SIZE(DIS_MAX_NUM_INC_SVR, DIS_MAX_CHAR_NUM, 0) -#endif - -#define DIS_SYSTEM_ID_SIZE 8 -#define DIS_PNP_ID_SIZE 7 - - -typedef struct { - UINT16 uuid; - UINT16 handle; -} tDIS_DB_ENTRY; - -typedef struct { - UINT16 len; - UINT8 *p_data; -} tDIS_STRING; - -typedef struct { - UINT16 vendor_id; - UINT16 product_id; - UINT16 product_version; - UINT8 vendor_id_src; - -} tDIS_PNP_ID; - -typedef union { - UINT64 system_id; - tDIS_PNP_ID pnp_id; - tDIS_STRING data_str; -} tDIS_ATTR; - -#define DIS_MAX_STRING_DATA 7 - -typedef struct { - UINT16 attr_mask; - UINT64 system_id; - tDIS_PNP_ID pnp_id; - UINT8 *data_string[DIS_MAX_STRING_DATA]; -} tDIS_VALUE; - -//typedef void (tDIS_READ_CBACK)(BD_ADDR addr, tDIS_VALUE *p_dis_value); - -typedef struct { - tDIS_DB_ENTRY dis_attr[DIS_MAX_CHAR_NUM]; - tDIS_VALUE dis_value; - -// tDIS_READ_CBACK *p_read_dis_cback; - - UINT16 service_handle; - UINT16 max_handle; - - bool enabled; - - // UINT8 dis_read_uuid_idx; - // tDIS_ATTR_MASK request_mask; -} tDIS_CB; - -/***************************************************************************** -** Data structure used by Battery Service -*****************************************************************************/ - -#ifndef BA_MAX_INT_NUM -#define BA_MAX_INT_NUM 4 -#endif - -#define BATTERY_LEVEL_SIZE 1 - -typedef struct { - BD_ADDR remote_bda; - BOOLEAN need_rsp; - UINT16 clt_cfg; -} tBA_WRITE_DATA; - -#define BA_READ_CLT_CFG_REQ 1 -#define BA_READ_PRE_FMT_REQ 2 -#define BA_READ_RPT_REF_REQ 3 -#define BA_READ_LEVEL_REQ 4 -#define BA_WRITE_CLT_CFG_REQ 5 - -typedef void (tBA_CBACK)(UINT32 trans_id, UINT16 conn_id, UINT8 app_id, UINT8 event, tBA_WRITE_DATA *p_data); - -#define BA_LEVEL_NOTIFY 0x01 -#define BA_LEVEL_PRE_FMT 0x02 -#define BA_LEVEL_RPT_REF 0x04 -typedef UINT8 tBA_LEVEL_DESCR; - -typedef struct { - BOOLEAN is_pri; - tBA_LEVEL_DESCR ba_level_descr; - tGATT_TRANSPORT transport; - tBA_CBACK *p_cback; - -} tBA_REG_INFO; - -typedef union { - UINT8 ba_level; - UINT16 clt_cfg; - tGATT_CHAR_RPT_REF rpt_ref; - tGATT_CHAR_PRES pres_fmt; -} tBA_RSP_DATA; - -typedef struct { - UINT8 app_id; - UINT16 ba_level_hdl; - UINT16 clt_cfg_hdl; - UINT16 rpt_ref_hdl; - UINT16 pres_fmt_hdl; - - tBA_CBACK *p_cback; - - UINT16 pending_handle; - //UINT8 pending_clcb_idx; - UINT8 pending_evt; -} tBA_INST; - -typedef struct { - tBA_INST battery_inst[BA_MAX_INT_NUM]; - UINT8 inst_id; - bool enabled; -} tBATTERY_CB; -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif -/***************************************************************************** -** Service Engine API -*****************************************************************************/ -/******************************************************************************* -** -** Function srvc_eng_init -** -** Description Initializa the GATT Service engine, register a GATT application -** as for a central service management. -** -*******************************************************************************/ -//extern tGATT_STATUS srvc_eng_init (void); - - -/***************************************************************************** -** DIS Server Function -*****************************************************************************/ - -extern bool dis_valid_handle_range(UINT16 handle); -/******************************************************************************* -** -** Function DIS_Init -** -** Description Initializa the Device Information Service Server. -** -*******************************************************************************/ -extern void DIS_Init (tBTA_GATTS_IF gatt_if, tDIS_ATTR_MASK dis_attr_mask); -/******************************************************************************* -** -** Function DIS_SrUpdate -** -** Description Update the DIS server attribute values -** -*******************************************************************************/ -extern tDIS_STATUS DIS_SrUpdate(tDIS_ATTR_BIT dis_attr_bit, tDIS_ATTR *p_info); -/******************************************************************************* -** -** Function dis_AddChar -** -** Description add characteristic for dis -** -*******************************************************************************/ -extern void dis_AddChar(UINT16 service_id); -/******************************************************************************* -** dis_s_read_attr_value -** -** Process read DIS attribute request. -*******************************************************************************/ - -extern void dis_s_read_attr_value (tGATTS_DATA *p_data, tGATT_VALUE *p_value, - UINT32 trans_id, UINT16 conn_id); -/***************************************************************************** -** DIS Client Function -*****************************************************************************/ -/******************************************************************************* -** -** Function DIS_ReadDISInfo -** -** Description Read remote device DIS information. -** -** Returns void -** -*******************************************************************************/ -//extern BOOLEAN DIS_ReadDISInfo(BD_ADDR peer_bda, tDIS_READ_CBACK *p_cback, -// tDIS_ATTR_MASK mask); - -/******************************************************************************* -** BATTERY SERVICE API -*******************************************************************************/ -/*************************************************************** -** -** Function bas_register -** -** Description register app for battery service -** -****************************************************************/ -extern void bas_register(void); -/*************************************************************** -** -** Function bas_init -** -** Description register battery service -** -****************************************************************/ -extern void bas_init(tBTA_GATTS_IF gatt_if, UINT16 app_id); - -/*************************************************************** -** -** Function bas_AddChar -** -** Description add characteristic for battery service -** -****************************************************************/ -extern void bas_AddChar(UINT16 service_id, tBT_UUID *char_uuid); -/*************************************************************** -** -** Function bas_AddCharDescr -** -** Description add descriptor for battery service if needed -** -****************************************************************/ -extern void bas_AddCharDescr(UINT16 service_id, UINT16 attr_id); -/*************************************************************** -** -** Function bas_service_cmpl -** -** Description create battery service complete -** -****************************************************************/ -extern void bas_service_cmpl(UINT16 service_id, tBTA_GATT_STATUS status); -/******************************************************************************* -** -** Function Battery_Rsp -** -** Description Respond to a battery service request -** -*******************************************************************************/ -extern void Battery_Rsp (UINT32 trans_id, UINT16 conn_id, UINT8 app_id, - tGATT_STATUS st, UINT8 event, tBA_RSP_DATA *p_rsp); -/******************************************************************************* -** -** Function Battery_Notify -** -** Description Send battery level notification -** -*******************************************************************************/ -extern void Battery_Notify (UINT16 conn_id, UINT8 app_id, BD_ADDR remote_bda, UINT8 battery_level); - -/***************************************************************************** -** Function bas_s_read_attr_value -** -** Description it will be called when client send a read request -******************************************************************************/ -extern void bas_s_read_attr_value(tGATTS_DATA *p_data, UINT32 trans_id, UINT16 conn_id); -/***************************************************************************** -** Function bas_s_write_attr_value -** -** Description it will be called when client send a write request -******************************************************************************/ -extern void bas_s_write_attr_value(tGATTS_DATA *p_data, UINT32 trans_id, - UINT16 conn_id, BD_ADDR bd_addr); - -extern void gatts_server_test(void); -#ifdef __cplusplus - -} -#endif - -#endif diff --git a/tools/sdk/include/bluedroid/esp_bt.h b/tools/sdk/include/bluedroid/esp_bt.h deleted file mode 100644 index 3115cacd..00000000 --- a/tools/sdk/include/bluedroid/esp_bt.h +++ /dev/null @@ -1,472 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __ESP_BT_H__ -#define __ESP_BT_H__ - -#include -#include -#include "esp_err.h" -#include "sdkconfig.h" -#include "esp_task.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL 0x5A5AA5A5 - -/** - * @brief Bluetooth mode for controller enable/disable - */ -typedef enum { - ESP_BT_MODE_IDLE = 0x00, /*!< Bluetooth is not running */ - ESP_BT_MODE_BLE = 0x01, /*!< Run BLE mode */ - ESP_BT_MODE_CLASSIC_BT = 0x02, /*!< Run Classic BT mode */ - ESP_BT_MODE_BTDM = 0x03, /*!< Run dual mode */ -} esp_bt_mode_t; - -#ifdef CONFIG_BT_ENABLED -/* While scanning, if the free memory value in controller is less than SCAN_SEND_ADV_RESERVED_SIZE, -the adv packet will be discarded until the memory is restored. */ -#define SCAN_SEND_ADV_RESERVED_SIZE 1000 -/* enable controller log debug when adv lost */ -#define CONTROLLER_ADV_LOST_DEBUG_BIT (0<<0) - -#ifdef CONFIG_BT_HCI_UART_NO -#define BT_HCI_UART_NO_DEFAULT CONFIG_BT_HCI_UART_NO -#else -#define BT_HCI_UART_NO_DEFAULT 1 -#endif /* BT_HCI_UART_NO_DEFAULT */ - -#ifdef CONFIG_BT_HCI_UART_BAUDRATE -#define BT_HCI_UART_BAUDRATE_DEFAULT CONFIG_BT_HCI_UART_BAUDRATE -#else -#define BT_HCI_UART_BAUDRATE_DEFAULT 921600 -#endif /* BT_HCI_UART_BAUDRATE_DEFAULT */ - -#ifdef CONFIG_SCAN_DUPLICATE_TYPE -#define SCAN_DUPLICATE_TYPE_VALUE CONFIG_SCAN_DUPLICATE_TYPE -#else -#define SCAN_DUPLICATE_TYPE_VALUE 0 -#endif - -/* normal adv cache size */ -#ifdef CONFIG_DUPLICATE_SCAN_CACHE_SIZE -#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE CONFIG_DUPLICATE_SCAN_CACHE_SIZE -#else -#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE 20 -#endif - -#ifndef CONFIG_BLE_MESH_SCAN_DUPLICATE_EN -#define CONFIG_BLE_MESH_SCAN_DUPLICATE_EN FALSE -#endif - -#define SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY 0 -#define SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV 1 - -#if CONFIG_BLE_MESH_SCAN_DUPLICATE_EN - #define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV - #ifdef CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE - #define MESH_DUPLICATE_SCAN_CACHE_SIZE CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE - #else - #define MESH_DUPLICATE_SCAN_CACHE_SIZE 50 - #endif -#else - #define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY - #define MESH_DUPLICATE_SCAN_CACHE_SIZE 0 -#endif - -#if defined(CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY) -#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_BLE -#elif defined(CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY) -#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_CLASSIC_BT -#else -#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_BTDM -#endif - -#define BTDM_CONTROLLER_BLE_MAX_CONN_LIMIT 9 //Maximum BLE connection limitation -#define BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_LIMIT 7 //Maximum ACL connection limitation -#define BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_LIMIT 3 //Maximum SCO/eSCO connection limitation - -#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \ - .controller_task_stack_size = ESP_TASK_BT_CONTROLLER_STACK, \ - .controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \ - .hci_uart_no = BT_HCI_UART_NO_DEFAULT, \ - .hci_uart_baudrate = BT_HCI_UART_BAUDRATE_DEFAULT, \ - .scan_duplicate_mode = SCAN_DUPLICATE_MODE, \ - .scan_duplicate_type = SCAN_DUPLICATE_TYPE_VALUE, \ - .normal_adv_size = NORMAL_SCAN_DUPLICATE_CACHE_SIZE, \ - .mesh_adv_size = MESH_DUPLICATE_SCAN_CACHE_SIZE, \ - .send_adv_reserved_size = SCAN_SEND_ADV_RESERVED_SIZE, \ - .controller_debug_flag = CONTROLLER_ADV_LOST_DEBUG_BIT, \ - .mode = BTDM_CONTROLLER_MODE_EFF, \ - .ble_max_conn = CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF, \ - .bt_max_acl_conn = CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF, \ - .bt_max_sync_conn = CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF, \ - .magic = ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL, \ -}; - -#else -#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() {0}; _Static_assert(0, "please enable bluetooth in menuconfig to use bt.h"); -#endif - -/** - * @brief Controller config options, depend on config mask. - * Config mask indicate which functions enabled, this means - * some options or parameters of some functions enabled by config mask. - */ -typedef struct { - /* - * Following parameters can be configured runtime, when call esp_bt_controller_init() - */ - uint16_t controller_task_stack_size; /*!< Bluetooth controller task stack size */ - uint8_t controller_task_prio; /*!< Bluetooth controller task priority */ - uint8_t hci_uart_no; /*!< If use UART1/2 as HCI IO interface, indicate UART number */ - uint32_t hci_uart_baudrate; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */ - uint8_t scan_duplicate_mode; /*!< scan duplicate mode */ - uint8_t scan_duplicate_type; /*!< scan duplicate type */ - uint16_t normal_adv_size; /*!< Normal adv size for scan duplicate */ - uint16_t mesh_adv_size; /*!< Mesh adv size for scan duplicate */ - uint16_t send_adv_reserved_size; /*!< Controller minimum memory value */ - uint32_t controller_debug_flag; /*!< Controller debug log flag */ - uint8_t mode; /*!< Controller mode: BR/EDR, BLE or Dual Mode */ - uint8_t ble_max_conn; /*!< BLE maximum connection numbers */ - uint8_t bt_max_acl_conn; /*!< BR/EDR maximum ACL connection numbers */ - /* - * Following parameters can not be configured runtime when call esp_bt_controller_init() - * It will be overwrite with a constant value which in menuconfig or from a macro. - * So, do not modify the value when esp_bt_controller_init() - */ - uint8_t bt_max_sync_conn; /*!< BR/EDR maximum ACL connection numbers. Effective in menuconfig */ - uint32_t magic; /*!< Magic number */ -} esp_bt_controller_config_t; - -/** - * @brief Bluetooth controller enable/disable/initialised/de-initialised status - */ -typedef enum { - ESP_BT_CONTROLLER_STATUS_IDLE = 0, - ESP_BT_CONTROLLER_STATUS_INITED, - ESP_BT_CONTROLLER_STATUS_ENABLED, - ESP_BT_CONTROLLER_STATUS_NUM, -} esp_bt_controller_status_t; - -/** - * @brief BLE tx power type - * ESP_BLE_PWR_TYPE_CONN_HDL0-8: for each connection, and only be set after connection completed. - * when disconnect, the correspond TX power is not effected. - * ESP_BLE_PWR_TYPE_ADV : for advertising/scan response. - * ESP_BLE_PWR_TYPE_SCAN : for scan. - * ESP_BLE_PWR_TYPE_DEFAULT : if each connection's TX power is not set, it will use this default value. - * if neither in scan mode nor in adv mode, it will use this default value. - * If none of power type is set, system will use ESP_PWR_LVL_P3 as default for ADV/SCAN/CONN0-9. - */ -typedef enum { - ESP_BLE_PWR_TYPE_CONN_HDL0 = 0, /*!< For connection handle 0 */ - ESP_BLE_PWR_TYPE_CONN_HDL1 = 1, /*!< For connection handle 1 */ - ESP_BLE_PWR_TYPE_CONN_HDL2 = 2, /*!< For connection handle 2 */ - ESP_BLE_PWR_TYPE_CONN_HDL3 = 3, /*!< For connection handle 3 */ - ESP_BLE_PWR_TYPE_CONN_HDL4 = 4, /*!< For connection handle 4 */ - ESP_BLE_PWR_TYPE_CONN_HDL5 = 5, /*!< For connection handle 5 */ - ESP_BLE_PWR_TYPE_CONN_HDL6 = 6, /*!< For connection handle 6 */ - ESP_BLE_PWR_TYPE_CONN_HDL7 = 7, /*!< For connection handle 7 */ - ESP_BLE_PWR_TYPE_CONN_HDL8 = 8, /*!< For connection handle 8 */ - ESP_BLE_PWR_TYPE_ADV = 9, /*!< For advertising */ - ESP_BLE_PWR_TYPE_SCAN = 10, /*!< For scan */ - ESP_BLE_PWR_TYPE_DEFAULT = 11, /*!< For default, if not set other, it will use default value */ - ESP_BLE_PWR_TYPE_NUM = 12, /*!< TYPE numbers */ -} esp_ble_power_type_t; - -/** - * @brief Bluetooth TX power level(index), it's just a index corresponding to power(dbm). - */ -typedef enum { - ESP_PWR_LVL_N12 = 0, /*!< Corresponding to -12dbm */ - ESP_PWR_LVL_N9 = 1, /*!< Corresponding to -9dbm */ - ESP_PWR_LVL_N6 = 2, /*!< Corresponding to -6dbm */ - ESP_PWR_LVL_N3 = 3, /*!< Corresponding to -3dbm */ - ESP_PWR_LVL_N0 = 4, /*!< Corresponding to 0dbm */ - ESP_PWR_LVL_P3 = 5, /*!< Corresponding to +3dbm */ - ESP_PWR_LVL_P6 = 6, /*!< Corresponding to +6dbm */ - ESP_PWR_LVL_P9 = 7, /*!< Corresponding to +9dbm */ - ESP_PWR_LVL_N14 = ESP_PWR_LVL_N12, /*!< Backward compatibility! Setting to -14dbm will actually result to -12dbm */ - ESP_PWR_LVL_N11 = ESP_PWR_LVL_N9, /*!< Backward compatibility! Setting to -11dbm will actually result to -9dbm */ - ESP_PWR_LVL_N8 = ESP_PWR_LVL_N6, /*!< Backward compatibility! Setting to -8dbm will actually result to -6dbm */ - ESP_PWR_LVL_N5 = ESP_PWR_LVL_N3, /*!< Backward compatibility! Setting to -5dbm will actually result to -3dbm */ - ESP_PWR_LVL_N2 = ESP_PWR_LVL_N0, /*!< Backward compatibility! Setting to -2dbm will actually result to 0dbm */ - ESP_PWR_LVL_P1 = ESP_PWR_LVL_P3, /*!< Backward compatibility! Setting to +1dbm will actually result to +3dbm */ - ESP_PWR_LVL_P4 = ESP_PWR_LVL_P6, /*!< Backward compatibility! Setting to +4dbm will actually result to +6dbm */ - ESP_PWR_LVL_P7 = ESP_PWR_LVL_P9, /*!< Backward compatibility! Setting to +7dbm will actually result to +9dbm */ -} esp_power_level_t; - -/** - * @brief Bluetooth audio data transport path - */ -typedef enum { - ESP_SCO_DATA_PATH_HCI = 0, /*!< data over HCI transport */ - ESP_SCO_DATA_PATH_PCM = 1, /*!< data over PCM interface */ -} esp_sco_data_path_t; - -/** - * @brief Set BLE TX power - * Connection Tx power should only be set after connection created. - * @param power_type : The type of which tx power, could set Advertising/Connection/Default and etc - * @param power_level: Power level(index) corresponding to absolute value(dbm) - * @return ESP_OK - success, other - failed - */ -esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_t power_level); - -/** - * @brief Get BLE TX power - * Connection Tx power should only be get after connection created. - * @param power_type : The type of which tx power, could set Advertising/Connection/Default and etc - * @return >= 0 - Power level, < 0 - Invalid - */ -esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type); - -/** - * @brief Set BR/EDR TX power - * BR/EDR power control will use the power in range of minimum value and maximum value. - * The power level will effect the global BR/EDR TX power, such inquire, page, connection and so on. - * Please call the function after esp_bt_controller_enable and before any function which cause RF do TX. - * So you can call the function before doing discovery, profile init and so on. - * For example, if you want BR/EDR use the new TX power to do inquire, you should call - * this function before inquire. Another word, If call this function when BR/EDR is in inquire(ING), - * please do inquire again after call this function. - * Default minimum power level is ESP_PWR_LVL_N0, and maximum power level is ESP_PWR_LVL_P3. - * @param min_power_level: The minimum power level - * @param max_power_level: The maximum power level - * @return ESP_OK - success, other - failed - */ -esp_err_t esp_bredr_tx_power_set(esp_power_level_t min_power_level, esp_power_level_t max_power_level); - -/** - * @brief Get BR/EDR TX power - * If the argument is not NULL, then store the corresponding value. - * @param min_power_level: The minimum power level - * @param max_power_level: The maximum power level - * @return ESP_OK - success, other - failed - */ -esp_err_t esp_bredr_tx_power_get(esp_power_level_t *min_power_level, esp_power_level_t *max_power_level); - -/** - * @brief set default SCO data path - * Should be called after controller is enabled, and before (e)SCO link is established - * @param data_path: SCO data path - * @return ESP_OK - success, other - failed - */ -esp_err_t esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path); - -/** - * @brief Initialize BT controller to allocate task and other resource. - * This function should be called only once, before any other BT functions are called. - * @param cfg: Initial configuration of BT controller. Different from previous version, there's a mode and some - * connection configuration in "cfg" to configure controller work mode and allocate the resource which is needed. - * @return ESP_OK - success, other - failed - */ -esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg); - -/** - * @brief De-initialize BT controller to free resource and delete task. - * - * This function should be called only once, after any other BT functions are called. - * This function is not whole completed, esp_bt_controller_init cannot called after this function. - * @return ESP_OK - success, other - failed - */ -esp_err_t esp_bt_controller_deinit(void); - -/** - * @brief Enable BT controller. - * Due to a known issue, you cannot call esp_bt_controller_enable() a second time - * to change the controller mode dynamically. To change controller mode, call - * esp_bt_controller_disable() and then call esp_bt_controller_enable() with the new mode. - * @param mode : the mode(BLE/BT/BTDM) to enable. For compatible of API, retain this argument. This mode must be - * equal as the mode in "cfg" of esp_bt_controller_init(). - * @return ESP_OK - success, other - failed - */ -esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode); - -/** - * @brief Disable BT controller - * @return ESP_OK - success, other - failed - */ -esp_err_t esp_bt_controller_disable(void); - -/** - * @brief Get BT controller is initialised/de-initialised/enabled/disabled - * @return status value - */ -esp_bt_controller_status_t esp_bt_controller_get_status(void); - -/** @brief esp_vhci_host_callback - * used for vhci call host function to notify what host need to do - */ -typedef struct esp_vhci_host_callback { - void (*notify_host_send_available)(void); /*!< callback used to notify that the host can send packet to controller */ - int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< callback used to notify that the controller has a packet to send to the host*/ -} esp_vhci_host_callback_t; - -/** @brief esp_vhci_host_check_send_available - * used for check actively if the host can send packet to controller or not. - * @return true for ready to send, false means cannot send packet - */ -bool esp_vhci_host_check_send_available(void); - -/** @brief esp_vhci_host_send_packet - * host send packet to controller - * @param data the packet point - *,@param len the packet length - */ -void esp_vhci_host_send_packet(uint8_t *data, uint16_t len); - -/** @brief esp_vhci_host_register_callback - * register the vhci reference callback - * struct defined by vhci_host_callback structure. - * @param callback esp_vhci_host_callback type variable - * @return ESP_OK - success, ESP_FAIL - failed - */ -esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback); - -/** @brief esp_bt_controller_mem_release - * release the controller memory as per the mode - * - * This function releases the BSS, data and other sections of the controller to heap. The total size is about 70k bytes. - * - * esp_bt_controller_mem_release(mode) should be called only before esp_bt_controller_init() - * or after esp_bt_controller_deinit(). - * - * Note that once BT controller memory is released, the process cannot be reversed. It means you cannot use the bluetooth - * mode which you have released by this function. - * - * If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled) - * then do not call this function. - * - * If the app calls esp_bt_controller_enable(ESP_BT_MODE_BLE) to use BLE only then it is safe to call - * esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT) at initialization time to free unused BT Classic memory. - * - * If the mode is ESP_BT_MODE_BTDM, then it may be useful to call API esp_bt_mem_release(ESP_BT_MODE_BTDM) instead, - * which internally calls esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) and additionally releases the BSS and data - * consumed by the BT/BLE host stack to heap. For more details about usage please refer to the documentation of - * esp_bt_mem_release() function - * - * @param mode : the mode want to release memory - * @return ESP_OK - success, other - failed - */ -esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode); - -/** @brief esp_bt_mem_release - * release controller memory and BSS and data section of the BT/BLE host stack as per the mode - * - * This function first releases controller memory by internally calling esp_bt_controller_mem_release(). - * Additionally, if the mode is set to ESP_BT_MODE_BTDM, it also releases the BSS and data consumed by the BT/BLE host stack to heap - * - * Note that once BT memory is released, the process cannot be reversed. It means you cannot use the bluetooth - * mode which you have released by this function. - * - * If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled) - * then do not call this function. - * - * If you never intend to use bluetooth in a current boot-up cycle, you can call esp_bt_mem_release(ESP_BT_MODE_BTDM) - * before esp_bt_controller_init or after esp_bt_controller_deinit. - * - * For example, if a user only uses bluetooth for setting the WiFi configuration, and does not use bluetooth in the rest of the product operation". - * In such cases, after receiving the WiFi configuration, you can disable/deinit bluetooth and release its memory. - * Below is the sequence of APIs to be called for such scenarios: - * - * esp_bluedroid_disable(); - * esp_bluedroid_deinit(); - * esp_bt_controller_disable(); - * esp_bt_controller_deinit(); - * esp_bt_mem_release(ESP_BT_MODE_BTDM); - * - * @param mode : the mode whose memory is to be released - * @return ESP_OK - success, other - failed - */ -esp_err_t esp_bt_mem_release(esp_bt_mode_t mode); - -/** - * @brief enable bluetooth to enter modem sleep - * - * Note that this function shall not be invoked before esp_bt_controller_enable() - * - * There are currently two options for bluetooth modem sleep, one is ORIG mode, and another is EVED Mode. EVED Mode is intended for BLE only. - * - * For ORIG mode: - * Bluetooth modem sleep is enabled in controller start up by default if CONFIG_BTDM_CONTROLLER_MODEM_SLEEP is set and "ORIG mode" is selected. In ORIG modem sleep mode, bluetooth controller will switch off some components and pause to work every now and then, if there is no event to process; and wakeup according to the scheduled interval and resume the work. It can also wakeup earlier upon external request using function "esp_bt_controller_wakeup_request". - * Note that currently there is problem in the combination use of bluetooth modem sleep and Dynamic Frequency Scaling(DFS). So do not enable DFS if bluetooth modem sleep is in use. - * - * @return - * - ESP_OK : success - * - other : failed - */ -esp_err_t esp_bt_sleep_enable(void); - - -/** - * @brief disable bluetooth modem sleep - * - * Note that this function shall not be invoked before esp_bt_controller_enable() - * - * If esp_bt_sleep_disable() is called, bluetooth controller will not be allowed to enter modem sleep; - * - * If ORIG modem sleep mode is in use, if this function is called, bluetooth controller may not immediately wake up if it is dormant then. - * In this case, esp_bt_controller_wakeup_request() can be used to shorten the time for wakeup. - * - * @return - * - ESP_OK : success - * - other : failed - */ -esp_err_t esp_bt_sleep_disable(void); - -/** - * @brief to check whether bluetooth controller is sleeping at the instant, if modem sleep is enabled - * - * Note that this function shall not be invoked before esp_bt_controller_enable() - * This function is supposed to be used ORIG mode of modem sleep - * - * @return true if in modem sleep state, false otherwise - */ -bool esp_bt_controller_is_sleeping(void); - -/** - * @brief request controller to wakeup from sleeping state during sleep mode - * - * Note that this function shall not be invoked before esp_bt_controller_enable() - * Note that this function is supposed to be used ORIG mode of modem sleep - * Note that after this request, bluetooth controller may again enter sleep as long as the modem sleep is enabled - * - * Profiling shows that it takes several milliseconds to wakeup from modem sleep after this request. - * Generally it takes longer if 32kHz XTAL is used than the main XTAL, due to the lower frequency of the former as the bluetooth low power clock source. - */ -void esp_bt_controller_wakeup_request(void); - -/** - * @brief Manually clear scan duplicate list - * - * Note that scan duplicate list will be automatically cleared when the maximum amount of device in the filter is reached - * the amount of device in the filter can be configured in menuconfig. - * - * - * @return - * - ESP_OK : success - * - other : failed - */ -esp_err_t esp_ble_scan_dupilcate_list_flush(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __ESP_BT_H__ */ diff --git a/tools/sdk/include/bluedroid/esp_sec_api.h b/tools/sdk/include/bluedroid/esp_sec_api.h deleted file mode 100644 index d576a6cd..00000000 --- a/tools/sdk/include/bluedroid/esp_sec_api.h +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __ESP_SEC_API_H__ -#define __ESP_SEC_API_H__ - -#include "stack/bt_types.h" - -#define APP_SEC_IRK_FLAG (0) -#define RAND_NB_LEN 0x08 -#define SEC_KEY_LEN 0x10 - -/* - * STRUCTURES DEFINITIONS - **************************************************************************************** - */ - - -/// Generic Security key structure -typedef struct { - /// Key value MSB -> LSB - UINT8 key[SEC_KEY_LEN]; -} smp_sec_key; - -///Random number structure -typedef struct { - ///8-byte array for random number - UINT8 nb[RAND_NB_LEN]; -} rand_nb; - -typedef struct { - // LTK - smp_sec_key ltk; - // Random Number - rand_nb rand_nb; - // EDIV - UINT16 ediv; - // LTK key size - UINT8 key_size; - - // Last paired peer address type - UINT8 peer_addr_type; - // Last paired peer address - BD_ADDR peer_addr; - - // authentication level - UINT8 auth; - -} tAPP_SEC_ENV; - -extern tAPP_SEC_ENV app_sec_env; - -/* -* GLOBAL FUNCTIONS DECLARATIONS -**************************************************************************************** -*/ - -void app_ble_sec_init(void); - -void app_ble_sec_pairing_cmp_evt_send(UINT8); - -UINT32 app_ble_sec_gen_tk(void); - -void app_ble_sec_gen_ltk(UINT8 key_size); - -void app_ble_security_start(void); - -#endif /* __ESP_SEC_API_H__ */ diff --git a/tools/sdk/include/bluedroid/gap_int.h b/tools/sdk/include/bluedroid/gap_int.h deleted file mode 100644 index a328986f..00000000 --- a/tools/sdk/include/bluedroid/gap_int.h +++ /dev/null @@ -1,154 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2009-2013 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - - -#ifndef GAP_INT_H -#define GAP_INT_H - -#include "common/bt_target.h" -#include "osi/fixed_queue.h" -#include "stack/gap_api.h" -#include "stack/gatt_api.h" -#define GAP_MAX_BLOCKS 2 /* Concurrent GAP commands pending at a time*/ -/* Define the Generic Access Profile control structure */ -typedef struct { - void *p_data; /* Pointer to any data returned in callback */ - tGAP_CALLBACK *gap_cback; /* Pointer to users callback function */ - tGAP_CALLBACK *gap_inq_rslt_cback; /* Used for inquiry results */ - UINT16 event; /* Passed back in the callback */ - UINT8 index; /* Index of this control block and callback */ - BOOLEAN in_use; /* True when structure is allocated */ -} tGAP_INFO; - -/* Define the control block for the FindAddrByName operation (Only 1 active at a time) */ -typedef struct { - tGAP_CALLBACK *p_cback; - tBTM_INQ_INFO *p_cur_inq; /* Pointer to the current inquiry database entry */ - tGAP_FINDADDR_RESULTS results; - BOOLEAN in_use; -} tGAP_FINDADDR_CB; - -/* Define the GAP Connection Control Block. -*/ -typedef struct { -#define GAP_CCB_STATE_IDLE 0 -#define GAP_CCB_STATE_LISTENING 1 -#define GAP_CCB_STATE_CONN_SETUP 2 -#define GAP_CCB_STATE_CFG_SETUP 3 -#define GAP_CCB_STATE_WAIT_SEC 4 -#define GAP_CCB_STATE_CONNECTED 5 - UINT8 con_state; - -#define GAP_CCB_FLAGS_IS_ORIG 0x01 -#define GAP_CCB_FLAGS_HIS_CFG_DONE 0x02 -#define GAP_CCB_FLAGS_MY_CFG_DONE 0x04 -#define GAP_CCB_FLAGS_SEC_DONE 0x08 -#define GAP_CCB_FLAGS_CONN_DONE 0x0E - UINT8 con_flags; - - UINT8 service_id; /* Used by BTM */ - UINT16 gap_handle; /* GAP handle */ - UINT16 connection_id; /* L2CAP CID */ - BOOLEAN rem_addr_specified; - UINT8 chan_mode_mask; /* Supported channel modes (FCR) */ - BD_ADDR rem_dev_address; - UINT16 psm; - UINT16 rem_mtu_size; - - BOOLEAN is_congested; - fixed_queue_t *tx_queue; /* Queue of buffers waiting to be sent */ - fixed_queue_t *rx_queue; /* Queue of buffers waiting to be read */ - - UINT32 rx_queue_size; /* Total data count in rx_queue */ - - tGAP_CONN_CALLBACK *p_callback; /* Users callback function */ - - tL2CAP_CFG_INFO cfg; /* Configuration */ - tL2CAP_ERTM_INFO ertm_info; /* Pools and modes for ertm */ -} tGAP_CCB; - -typedef struct { -#if ((defined AMP_INCLUDED) && (AMP_INCLUDED == TRUE)) - tAMP_APPL_INFO reg_info; -#else - tL2CAP_APPL_INFO reg_info; /* L2CAP Registration info */ -#endif - tGAP_CCB ccb_pool[GAP_MAX_CONNECTIONS]; -} tGAP_CONN; - - -#if BLE_INCLUDED == TRUE -#define GAP_MAX_CHAR_NUM 4 - -typedef struct { - UINT16 handle; - UINT16 uuid; - tGAP_BLE_ATTR_VALUE attr_value; -} tGAP_ATTR; -#endif -/********************************************************************** -** M A I N C O N T R O L B L O C K -***********************************************************************/ - -#define GAP_MAX_CL GATT_CL_MAX_LCB - -typedef struct { - UINT16 uuid; - tGAP_BLE_CMPL_CBACK *p_cback; -} tGAP_BLE_REQ; - -typedef struct { - BD_ADDR bda; - tGAP_BLE_CMPL_CBACK *p_cback; - UINT16 conn_id; - UINT16 cl_op_uuid; - BOOLEAN in_use; - BOOLEAN connected; - fixed_queue_t *pending_req_q; - -} tGAP_CLCB; - -typedef struct { - tGAP_INFO blk[GAP_MAX_BLOCKS]; - tBTM_CMPL_CB *btm_cback[GAP_MAX_BLOCKS]; - UINT8 trace_level; - //tGAP_FINDADDR_CB findaddr_cb; /* Contains the control block for finding a device addr */ - //tBTM_INQ_INFO *cur_inqptr; - -#if GAP_CONN_INCLUDED == TRUE - tGAP_CONN conn; -#endif - - /* LE GAP attribute database */ -#if BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE - tGAP_ATTR gatt_attr[GAP_MAX_CHAR_NUM]; - tGAP_CLCB clcb[GAP_MAX_CL]; /* connection link*/ - tGATT_IF gatt_if; -#endif -} tGAP_CB; - - -extern tGAP_CB gap_cb; -#if (GAP_CONN_INCLUDED == TRUE) -extern void gap_conn_init(void); -#endif -#if (BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE) -extern void gap_attr_db_init(void); -#endif - -#endif diff --git a/tools/sdk/include/bluedroid/gatt_int.h b/tools/sdk/include/bluedroid/gatt_int.h deleted file mode 100644 index ffbf8540..00000000 --- a/tools/sdk/include/bluedroid/gatt_int.h +++ /dev/null @@ -1,753 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef GATT_INT_H -#define GATT_INT_H - -#include "common/bt_target.h" -#include "common/bt_trace.h" -#include "stack/gatt_api.h" -#include "stack/btm_ble_api.h" -#include "stack/btu.h" -#include "osi/fixed_queue.h" - -#include - - -#define GATT_CREATE_CONN_ID(tcb_idx, gatt_if) ((UINT16) ((((UINT8)(tcb_idx) ) << 8) | ((UINT8) (gatt_if)))) -#define GATT_GET_TCB_IDX(conn_id) ((UINT8) (((UINT16) (conn_id)) >> 8)) -#define GATT_GET_GATT_IF(conn_id) ((tGATT_IF)((UINT8) (conn_id))) - -#define GATT_GET_SR_REG_PTR(index) (&gatt_cb.sr_reg[(UINT8) (index)]); -#define GATT_TRANS_ID_MAX 0x0fffffff /* 4 MSB is reserved */ -#define GATT_RSP_BY_APP 0x00 -#define GATT_RSP_BY_STACK 0x01 -#define GATT_RSP_DEFAULT GATT_RSP_BY_APP //need to rsp by the app. - -/* security action for GATT write and read request */ -#define GATT_SEC_NONE 0 -#define GATT_SEC_OK 1 -#define GATT_SEC_SIGN_DATA 2 /* compute the signature for the write cmd */ -#define GATT_SEC_ENCRYPT 3 /* encrypt the link with current key */ -#define GATT_SEC_ENCRYPT_NO_MITM 4 /* unauthenticated encryption or better */ -#define GATT_SEC_ENCRYPT_MITM 5 /* authenticated encryption */ -#define GATT_SEC_ENC_PENDING 6 /* wait for link encryption pending */ -typedef UINT8 tGATT_SEC_ACTION; - - -#define GATT_ATTR_OP_SPT_MTU (0x00000001 << 0) -#define GATT_ATTR_OP_SPT_FIND_INFO (0x00000001 << 1) -#define GATT_ATTR_OP_SPT_FIND_BY_TYPE (0x00000001 << 2) -#define GATT_ATTR_OP_SPT_READ_BY_TYPE (0x00000001 << 3) -#define GATT_ATTR_OP_SPT_READ (0x00000001 << 4) -#define GATT_ATTR_OP_SPT_MULT_READ (0x00000001 << 5) -#define GATT_ATTR_OP_SPT_READ_BLOB (0x00000001 << 6) -#define GATT_ATTR_OP_SPT_READ_BY_GRP_TYPE (0x00000001 << 7) -#define GATT_ATTR_OP_SPT_WRITE (0x00000001 << 8) -#define GATT_ATTR_OP_SPT_WRITE_CMD (0x00000001 << 9) -#define GATT_ATTR_OP_SPT_PREP_WRITE (0x00000001 << 10) -#define GATT_ATTR_OP_SPT_EXE_WRITE (0x00000001 << 11) -#define GATT_ATTR_OP_SPT_HDL_VALUE_CONF (0x00000001 << 12) -#define GATT_ATTR_OP_SP_SIGN_WRITE (0x00000001 << 13) - -#define GATT_INDEX_INVALID 0xff - -#define GATT_PENDING_REQ_NONE 0 - - -#define GATT_WRITE_CMD_MASK 0xc0 /*0x1100-0000*/ -#define GATT_AUTH_SIGN_MASK 0x80 /*0x1000-0000*/ -#define GATT_AUTH_SIGN_LEN 12 - -#define GATT_HDR_SIZE 3 /* 1B opcode + 2B handle */ - -/* wait for ATT cmd response timeout value */ -#define GATT_WAIT_FOR_RSP_TOUT 30 -#define GATT_WAIT_FOR_DISC_RSP_TOUT 5 -#define GATT_REQ_RETRY_LIMIT 2 -#define GATT_WAIT_FOR_IND_ACK_TOUT 5 - -/* characteristic descriptor type */ -#define GATT_DESCR_EXT_DSCPTOR 1 /* Characteristic Extended Properties */ -#define GATT_DESCR_USER_DSCPTOR 2 /* Characteristic User Description */ -#define GATT_DESCR_CLT_CONFIG 3 /* Client Characteristic Configuration */ -#define GATT_DESCR_SVR_CONFIG 4 /* Server Characteristic Configuration */ -#define GATT_DESCR_PRES_FORMAT 5 /* Characteristic Presentation Format */ -#define GATT_DESCR_AGGR_FORMAT 6 /* Characteristic Aggregate Format */ -#define GATT_DESCR_VALID_RANGE 7 /* Characteristic Valid Range */ -#define GATT_DESCR_UNKNOWN 0xff - -#define GATT_SEC_FLAG_LKEY_UNAUTHED BTM_SEC_FLAG_LKEY_KNOWN -#define GATT_SEC_FLAG_LKEY_AUTHED BTM_SEC_FLAG_LKEY_AUTHED -#define GATT_SEC_FLAG_ENCRYPTED BTM_SEC_FLAG_ENCRYPTED -typedef UINT8 tGATT_SEC_FLAG; - -/* Find Information Response Type -*/ -#define GATT_INFO_TYPE_PAIR_16 0x01 -#define GATT_INFO_TYPE_PAIR_128 0x02 - -/* GATT client FIND_TYPE_VALUE_Request data */ -typedef struct { - tBT_UUID uuid; /* type of attribute to be found */ - UINT16 s_handle; /* starting handle */ - UINT16 e_handle; /* ending handle */ - UINT16 value_len; /* length of the attribute value */ - UINT8 value[GATT_MAX_MTU_SIZE]; /* pointer to the attribute value to be found */ -} tGATT_FIND_TYPE_VALUE; - -/* client request message to ATT protocol -*/ -typedef union { - tGATT_READ_BY_TYPE browse; /* read by type request */ - tGATT_FIND_TYPE_VALUE find_type_value;/* find by type value */ - tGATT_READ_MULTI read_multi; /* read multiple request */ - tGATT_READ_PARTIAL read_blob; /* read blob */ - tGATT_VALUE attr_value; /* write request */ - /* prepare write */ - /* write blob */ - UINT16 handle; /* read, handle value confirmation */ - UINT16 mtu; - tGATT_EXEC_FLAG exec_write; /* execute write */ -} tGATT_CL_MSG; - -/* error response strucutre */ -typedef struct { - UINT16 handle; - UINT8 cmd_code; - UINT8 reason; -} tGATT_ERROR; - -/* Execute write response structure */ -typedef struct { - UINT8 op_code; -}__attribute__((packed)) tGATT_EXEC_WRITE_RSP; - -/* Write request response structure */ -typedef struct { - UINT8 op_code; -}__attribute__((packed)) tGATT_WRITE_REQ_RSP; - -/* server response message to ATT protocol -*/ -typedef union { - /* data type member event */ - tGATT_VALUE attr_value; /* READ, HANDLE_VALUE_IND, PREPARE_WRITE */ - /* READ_BLOB, READ_BY_TYPE */ - tGATT_ERROR error; /* ERROR_RSP */ - UINT16 handle; /* WRITE, WRITE_BLOB */ - UINT16 mtu; /* exchange MTU request */ -} tGATT_SR_MSG; - -/* Characteristic declaration attribute value -*/ -typedef struct { - tGATT_CHAR_PROP property; - UINT16 char_val_handle; -} tGATT_CHAR_DECL; - -/* attribute value maintained in the server database -*/ -typedef union { - tBT_UUID uuid; /* service declaration */ - tGATT_CHAR_DECL char_decl; /* characteristic declaration */ - tGATT_INCL_SRVC incl_handle; /* included service */ - tGATT_ATTR_VAL attr_val; -} tGATT_ATTR_VALUE; - -/* Attribute UUID type -*/ -#define GATT_ATTR_UUID_TYPE_16 0 -#define GATT_ATTR_UUID_TYPE_128 1 -#define GATT_ATTR_UUID_TYPE_32 2 -typedef UINT8 tGATT_ATTR_UUID_TYPE; - -/* 16 bits UUID Attribute in server database -*/ -typedef struct { - void *p_next; /* pointer to the next attribute, either tGATT_ATTR16 or tGATT_ATTR128 */ - tGATT_ATTR_VALUE *p_value; - tGATT_ATTR_UUID_TYPE uuid_type; - tGATT_PERM permission; - tGATTS_ATTR_CONTROL control; - tGATT_ATTR_MASK mask; - UINT16 handle; - UINT16 uuid; -} tGATT_ATTR16; - -/* 32 bits UUID Attribute in server database -*/ -typedef struct { - void *p_next; /* pointer to the next attribute, either tGATT_ATTR16, tGATT_ATTR32 or tGATT_ATTR128 */ - tGATT_ATTR_VALUE *p_value; - tGATT_ATTR_UUID_TYPE uuid_type; - tGATT_PERM permission; - tGATTS_ATTR_CONTROL control; - tGATT_ATTR_MASK mask; - UINT16 handle; - UINT32 uuid; -} tGATT_ATTR32; - - -/* 128 bits UUID Attribute in server database -*/ -typedef struct { - void *p_next; /* pointer to the next attribute, either tGATT_ATTR16 or tGATT_ATTR128 */ - tGATT_ATTR_VALUE *p_value; - tGATT_ATTR_UUID_TYPE uuid_type; - tGATT_PERM permission; - tGATTS_ATTR_CONTROL control; - tGATT_ATTR_MASK mask; - UINT16 handle; - UINT8 uuid[LEN_UUID_128]; -} tGATT_ATTR128; - -/* Service Database definition -*/ -typedef struct { - void *p_attr_list; /* pointer to the first attribute, either tGATT_ATTR16 or tGATT_ATTR128 */ - UINT8 *p_free_mem; /* Pointer to free memory */ - fixed_queue_t *svc_buffer; /* buffer queue used for service database */ - UINT32 mem_free; /* Memory still available */ - UINT16 end_handle; /* Last handle number */ - UINT16 next_handle; /* Next usable handle value */ -} tGATT_SVC_DB; - -/* Data Structure used for GATT server */ -/* A GATT registration record consists of a handle, and 1 or more attributes */ -/* A service registration information record consists of beginning and ending */ -/* attribute handle, service UUID and a set of GATT server callback. */ -typedef struct { - tGATT_SVC_DB *p_db; /* pointer to the service database */ - tBT_UUID app_uuid; /* applicatino UUID */ - UINT32 sdp_handle; /* primamry service SDP handle */ - UINT16 service_instance; /* service instance number */ - UINT16 type; /* service type UUID, primary or secondary */ - UINT16 s_hdl; /* service starting handle */ - UINT16 e_hdl; /* service ending handle */ - tGATT_IF gatt_if; /* this service is belong to which application */ - BOOLEAN in_use; -} tGATT_SR_REG; - -#define GATT_LISTEN_TO_ALL 0xff -#define GATT_LISTEN_TO_NONE 0 - -/* Data Structure used for GATT server */ -/* An GATT registration record consists of a handle, and 1 or more attributes */ -/* A service registration information record consists of beginning and ending */ -/* attribute handle, service UUID and a set of GATT server callback. */ - -typedef struct { - tBT_UUID app_uuid128; - tGATT_CBACK app_cb; - tGATT_IF gatt_if; /* one based */ - BOOLEAN in_use; - UINT8 listening; /* if adv for all has been enabled */ -} tGATT_REG; - - - - -/* command queue for each connection */ -typedef struct { - BT_HDR *p_cmd; - UINT16 clcb_idx; - UINT8 op_code; - BOOLEAN to_send; -} tGATT_CMD_Q; - - -#if GATT_MAX_SR_PROFILES <= 8 -typedef UINT8 tGATT_APP_MASK; -#elif GATT_MAX_SR_PROFILES <= 16 -typedef UINT16 tGATT_APP_MASK; -#elif GATT_MAX_SR_PROFILES <= 32 -typedef UINT32 tGATT_APP_MASK; -#endif - -/* command details for each connection */ -typedef struct { - BT_HDR *p_rsp_msg; - UINT32 trans_id; - tGATT_READ_MULTI multi_req; - fixed_queue_t *multi_rsp_q; - UINT16 handle; - UINT8 op_code; - UINT8 status; - UINT8 cback_cnt[GATT_MAX_APPS]; -} tGATT_SR_CMD; - -#define GATT_CH_CLOSE 0 -#define GATT_CH_CLOSING 1 -#define GATT_CH_CONN 2 -#define GATT_CH_CFG 3 -#define GATT_CH_OPEN 4 - -typedef UINT8 tGATT_CH_STATE; - -#define GATT_GATT_START_HANDLE 1 -#define GATT_GAP_START_HANDLE 20 -#define GATT_APP_START_HANDLE 40 - -typedef struct hdl_cfg { - UINT16 gatt_start_hdl; - UINT16 gap_start_hdl; - UINT16 app_start_hdl; -} tGATT_HDL_CFG; - -typedef struct hdl_list_elem { - struct hdl_list_elem *p_next; - struct hdl_list_elem *p_prev; - tGATTS_HNDL_RANGE asgn_range; /* assigned handle range */ - tGATT_SVC_DB svc_db; - BOOLEAN in_use; -} tGATT_HDL_LIST_ELEM; - -typedef struct { - tGATT_HDL_LIST_ELEM *p_first; - tGATT_HDL_LIST_ELEM *p_last; - UINT16 count; -} tGATT_HDL_LIST_INFO; - - -typedef struct srv_list_elem { - struct srv_list_elem *p_next; - struct srv_list_elem *p_prev; - UINT16 s_hdl; - UINT8 i_sreg; - BOOLEAN in_use; - BOOLEAN is_primary; -} tGATT_SRV_LIST_ELEM; - - -typedef struct { - tGATT_SRV_LIST_ELEM *p_last_primary; - tGATT_SRV_LIST_ELEM *p_first; - tGATT_SRV_LIST_ELEM *p_last; - UINT16 count; -} tGATT_SRV_LIST_INFO; - -/* prepare write queue data */ -typedef struct{ - //len: length of value - tGATT_ATTR16 *p_attr; - UINT16 len; - UINT8 op_code; - UINT16 handle; - UINT16 offset; - UINT8 value[2]; -}__attribute__((packed)) tGATT_PREPARE_WRITE_QUEUE_DATA; - -/* structure to store prepare write packts information */ -typedef struct{ - //only store prepare write packets which need - //to be responded by stack (not by application) - fixed_queue_t *queue; - - //store the total number of prepare write packets - //including that should be responded by stack or by application - UINT16 total_num; - - //store application error code for prepare write, - //invalid offset && invalid length - UINT8 error_code_app; -}tGATT_PREPARE_WRITE_RECORD; - -typedef struct { - fixed_queue_t *pending_enc_clcb; /* pending encryption channel q */ - tGATT_SEC_ACTION sec_act; - BD_ADDR peer_bda; - tBT_TRANSPORT transport; - UINT32 trans_id; - - UINT16 att_lcid; /* L2CAP channel ID for ATT */ - UINT16 payload_size; - - tGATT_CH_STATE ch_state; - UINT8 ch_flags; - - tGATT_IF app_hold_link[GATT_MAX_APPS]; - - /* server needs */ - /* server response data */ -#if (GATTS_INCLUDED == TRUE) - tGATT_SR_CMD sr_cmd; -#endif ///GATTS_INCLUDED == TRUE - UINT16 indicate_handle; - fixed_queue_t *pending_ind_q; - - TIMER_LIST_ENT conf_timer_ent; /* peer confirm to indication timer */ - - UINT8 prep_cnt[GATT_MAX_APPS]; - UINT8 ind_count; - - tGATT_CMD_Q cl_cmd_q[GATT_CL_MAX_LCB]; - TIMER_LIST_ENT ind_ack_timer_ent; /* local app confirm to indication timer */ - UINT8 pending_cl_req; - UINT8 next_slot_inq; /* index of next available slot in queue */ - - BOOLEAN in_use; - UINT8 tcb_idx; - tGATT_PREPARE_WRITE_RECORD prepare_write_record; /* prepare write packets record */ -} tGATT_TCB; - - -/* logic channel */ -typedef struct { - UINT16 next_disc_start_hdl; /* starting handle for the next inc srvv discovery */ - tGATT_DISC_RES result; - BOOLEAN wait_for_read_rsp; -} tGATT_READ_INC_UUID128; -typedef struct { - tGATT_TCB *p_tcb; /* associated TCB of this CLCB */ - tGATT_REG *p_reg; /* owner of this CLCB */ - UINT8 sccb_idx; - UINT8 *p_attr_buf; /* attribute buffer for read multiple, prepare write */ - tBT_UUID uuid; - UINT16 conn_id; /* connection handle */ - UINT16 clcb_idx; - UINT16 s_handle; /* starting handle of the active request */ - UINT16 e_handle; /* ending handle of the active request */ - UINT16 counter; /* used as offset, attribute length, num of prepare write */ - UINT16 start_offset; - tGATT_AUTH_REQ auth_req; /* authentication requirement */ - UINT8 operation; /* one logic channel can have one operation active */ - UINT8 op_subtype; /* operation subtype */ - UINT8 status; /* operation status */ - BOOLEAN first_read_blob_after_read; - tGATT_READ_INC_UUID128 read_uuid128; - BOOLEAN in_use; - TIMER_LIST_ENT rsp_timer_ent; /* peer response timer */ - UINT8 retry_count; - -} tGATT_CLCB; - -typedef struct { - tGATT_CLCB *p_clcb; -} tGATT_PENDING_ENC_CLCB; - - -#define GATT_SIGN_WRITE 1 -#define GATT_VERIFY_SIGN_DATA 2 - -typedef struct { - BT_HDR hdr; - tGATT_CLCB *p_clcb; -} tGATT_SIGN_WRITE_OP; - -typedef struct { - BT_HDR hdr; - tGATT_TCB *p_tcb; - BT_HDR *p_data; - -} tGATT_VERIFY_SIGN_OP; - - -typedef struct { - UINT16 clcb_idx; - BOOLEAN in_use; -} tGATT_SCCB; - -typedef struct { - UINT16 handle; - UINT16 uuid; - UINT32 service_change; -} tGATT_SVC_CHG; - -typedef struct { - tGATT_IF gatt_if[GATT_MAX_APPS]; - tGATT_IF listen_gif[GATT_MAX_APPS]; - BD_ADDR remote_bda; - BOOLEAN in_use; -} tGATT_BG_CONN_DEV; - -#define GATT_SVC_CHANGED_CONNECTING 1 /* wait for connection */ -#define GATT_SVC_CHANGED_SERVICE 2 /* GATT service discovery */ -#define GATT_SVC_CHANGED_CHARACTERISTIC 3 /* service change char discovery */ -#define GATT_SVC_CHANGED_DESCRIPTOR 4 /* service change CCC discoery */ -#define GATT_SVC_CHANGED_CONFIGURE_CCCD 5 /* config CCC */ - -typedef struct { - UINT16 conn_id; - BOOLEAN in_use; - BOOLEAN connected; - BD_ADDR bda; - tBT_TRANSPORT transport; - - /* GATT service change CCC related variables */ - UINT8 ccc_stage; - UINT8 ccc_result; - UINT16 s_handle; - UINT16 e_handle; -} tGATT_PROFILE_CLCB; - -typedef struct { - tGATT_TCB tcb[GATT_MAX_PHY_CHANNEL]; - fixed_queue_t *sign_op_queue; - - tGATT_SR_REG sr_reg[GATT_MAX_SR_PROFILES]; - UINT16 next_handle; /* next available handle */ - tGATT_SVC_CHG gattp_attr; /* GATT profile attribute service change */ - tGATT_IF gatt_if; -#if (GATTS_INCLUDED == TRUE) - tGATT_HDL_LIST_INFO hdl_list_info; - tGATT_HDL_LIST_ELEM hdl_list[GATT_MAX_SR_PROFILES]; - tGATT_SRV_LIST_INFO srv_list_info; - tGATT_SRV_LIST_ELEM srv_list[GATT_MAX_SR_PROFILES]; -#endif ///GATTS_INCLUDED == TRUE - fixed_queue_t *srv_chg_clt_q; /* service change clients queue */ - fixed_queue_t *pending_new_srv_start_q; /* pending new service start queue */ - tGATT_REG cl_rcb[GATT_MAX_APPS]; - tGATT_CLCB clcb[GATT_CL_MAX_LCB]; /* connection link control block*/ - tGATT_SCCB sccb[GATT_MAX_SCCB]; /* sign complete callback function GATT_MAX_SCCB <= GATT_CL_MAX_LCB */ - UINT8 trace_level; - UINT16 def_mtu_size; - -#if GATT_CONFORMANCE_TESTING == TRUE - BOOLEAN enable_err_rsp; - UINT8 req_op_code; - UINT8 err_status; - UINT16 handle; -#endif -#if (GATTS_INCLUDED == TRUE) - tGATT_PROFILE_CLCB profile_clcb[GATT_MAX_APPS]; -#endif ///GATTS_INCLUDED == TRUE - UINT16 handle_of_h_r; /* Handle of the handles reused characteristic value */ - - tGATT_APPL_INFO cb_info; - - - - tGATT_HDL_CFG hdl_cfg; - tGATT_BG_CONN_DEV bgconn_dev[GATT_MAX_BG_CONN_DEV]; - -} tGATT_CB; - -typedef struct{ - UINT16 local_mtu; -} tGATT_DEFAULT; - -#define GATT_SIZE_OF_SRV_CHG_HNDL_RANGE 4 - -#ifdef __cplusplus -extern "C" { -#endif - -extern tGATT_DEFAULT gatt_default; - -/* Global GATT data */ -#if GATT_DYNAMIC_MEMORY == FALSE -extern tGATT_CB gatt_cb; -#else -extern tGATT_CB *gatt_cb_ptr; -#define gatt_cb (*gatt_cb_ptr) -#endif - -#if GATT_CONFORMANCE_TESTING == TRUE -extern void gatt_set_err_rsp(BOOLEAN enable, UINT8 req_op_code, UINT8 err_status); -#endif - -#ifdef __cplusplus -} -#endif - -/* internal functions */ -extern void gatt_init (void); -extern void gatt_free(void); - -/* from gatt_main.c */ -extern BOOLEAN gatt_disconnect (tGATT_TCB *p_tcb); -extern BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_type, tBT_TRANSPORT transport); -extern BOOLEAN gatt_connect (BD_ADDR rem_bda, tBLE_ADDR_TYPE bd_addr_type, tGATT_TCB *p_tcb, tBT_TRANSPORT transport); -extern void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf); -extern void gatt_update_app_use_link_flag ( tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add, BOOLEAN check_acl_link); - -extern void gatt_profile_db_init(void); -extern void gatt_set_ch_state(tGATT_TCB *p_tcb, tGATT_CH_STATE ch_state); -extern tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB *p_tcb); -extern void gatt_init_srv_chg(void); -extern void gatt_proc_srv_chg (void); -extern void gatt_send_srv_chg_ind (BD_ADDR peer_bda); -extern void gatt_chk_srv_chg(tGATTS_SRV_CHG *p_srv_chg_clt); -extern void gatt_add_a_bonded_dev_for_srv_chg (BD_ADDR bda); - -/* from gatt_attr.c */ -extern UINT16 gatt_profile_find_conn_id_by_bd_addr(BD_ADDR bda); - - -/* Functions provided by att_protocol.c */ -extern tGATT_STATUS attp_send_cl_msg (tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code, tGATT_CL_MSG *p_msg); -extern BT_HDR *attp_build_sr_msg(tGATT_TCB *p_tcb, UINT8 op_code, tGATT_SR_MSG *p_msg); -extern tGATT_STATUS attp_send_sr_msg (tGATT_TCB *p_tcb, BT_HDR *p_msg); -extern tGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB *p_tcb, BT_HDR *p_toL2CAP); - -/* utility functions */ -extern UINT8 *gatt_dbg_op_name(UINT8 op_code); -#if (SDP_INCLUDED == TRUE) -extern UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl); -#endif ///SDP_INCLUDED == TRUE -extern BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid, UINT16 len, UINT8 **p_data); -extern UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid); -extern BOOLEAN gatt_uuid_compare(tBT_UUID src, tBT_UUID tar); -extern void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32); -extern void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size); -extern void gatt_start_rsp_timer(UINT16 clcb_idx); -extern void gatt_start_conf_timer(tGATT_TCB *p_tcb); -extern void gatt_rsp_timeout(TIMER_LIST_ENT *p_tle); -extern void gatt_ind_ack_timeout(TIMER_LIST_ENT *p_tle); -extern void gatt_start_ind_ack_timer(tGATT_TCB *p_tcb); -extern tGATT_STATUS gatt_send_error_rsp(tGATT_TCB *p_tcb, UINT8 err_code, UINT8 op_code, UINT16 handle, BOOLEAN deq); -extern void gatt_dbg_display_uuid(tBT_UUID bt_uuid); -extern tGATT_PENDING_ENC_CLCB *gatt_add_pending_enc_channel_clcb(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb ); - -extern tGATTS_PENDING_NEW_SRV_START *gatt_sr_is_new_srv_chg(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst); - -extern BOOLEAN gatt_is_srv_chg_ind_pending (tGATT_TCB *p_tcb); -extern tGATTS_SRV_CHG *gatt_is_bda_in_the_srv_chg_clt_list (BD_ADDR bda); - -extern BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx, tBT_TRANSPORT *p_transport); -extern void gatt_set_srv_chg(void); -extern void gatt_delete_dev_from_srv_chg_clt_list(BD_ADDR bd_addr); -extern tGATT_VALUE *gatt_add_pending_ind(tGATT_TCB *p_tcb, tGATT_VALUE *p_ind); -extern tGATTS_PENDING_NEW_SRV_START *gatt_add_pending_new_srv_start( tGATTS_HNDL_RANGE *p_new_srv_start); -extern void gatt_free_srvc_db_buffer_app_id(tBT_UUID *p_app_id); -extern BOOLEAN gatt_update_listen_mode(void); -extern BOOLEAN gatt_cl_send_next_cmd_inq(tGATT_TCB *p_tcb); - -/* reserved handle list */ -extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_app_id (tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst); -extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_handle(UINT16 handle); -extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_attr_handle(UINT16 attr_handle); -extern tGATT_HDL_LIST_ELEM *gatt_alloc_hdl_buffer(void); -extern void gatt_free_hdl_buffer(tGATT_HDL_LIST_ELEM *p); -extern void gatt_free_attr_value_buffer(tGATT_HDL_LIST_ELEM *p); -extern BOOLEAN gatt_is_last_attribute(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_start, tBT_UUID value); -extern void gatt_update_last_pri_srv_info(tGATT_SRV_LIST_INFO *p_list); -extern BOOLEAN gatt_add_a_srv_to_list(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_new); -extern BOOLEAN gatt_remove_a_srv_from_list(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_remove); -extern BOOLEAN gatt_add_an_item_to_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIST_ELEM *p_new); -extern BOOLEAN gatt_remove_an_item_from_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIST_ELEM *p_remove); -extern tGATTS_SRV_CHG *gatt_add_srv_chg_clt(tGATTS_SRV_CHG *p_srv_chg); - -/* for background connection */ -extern BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_addr, BOOLEAN is_initiator); -extern BOOLEAN gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV *p_dev, tGATT_IF gatt_if); -extern BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr); -extern UINT8 gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr); -extern BOOLEAN gatt_find_app_for_bg_dev(BD_ADDR bd_addr, tGATT_IF *p_gatt_if); -extern tGATT_BG_CONN_DEV *gatt_find_bg_dev(BD_ADDR remote_bda); -extern void gatt_deregister_bgdev_list(tGATT_IF gatt_if); -extern void gatt_reset_bgdev_list(void); - -/* server function */ -extern UINT8 gatt_sr_find_i_rcb_by_handle(UINT16 handle); -extern UINT8 gatt_sr_find_i_rcb_by_app_id(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst); -extern UINT8 gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM *p_list); -extern tGATT_STATUS gatt_sr_process_app_rsp (tGATT_TCB *p_tcb, tGATT_IF gatt_if, UINT32 trans_id, UINT8 op_code, tGATT_STATUS status, tGATTS_RSP *p_msg); -extern void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code, - UINT16 len, UINT8 *p_data); -extern void gatt_sr_send_req_callback(UINT16 conn_id, UINT32 trans_id, - UINT8 op_code, tGATTS_DATA *p_req_data); -extern UINT32 gatt_sr_enqueue_cmd (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 handle); -extern BOOLEAN gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda); - -/* */ - -extern tGATT_REG *gatt_get_regcb (tGATT_IF gatt_if); -extern BOOLEAN gatt_is_clcb_allocated (UINT16 conn_id); -extern tGATT_CLCB *gatt_clcb_alloc (UINT16 conn_id); -extern void gatt_clcb_dealloc (tGATT_CLCB *p_clcb); - -extern void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB *p_tcb ); -extern BOOLEAN gatt_sr_is_cback_cnt_zero(tGATT_TCB *p_tcb ); -extern BOOLEAN gatt_sr_is_prep_cnt_zero(tGATT_TCB *p_tcb ); -extern void gatt_sr_reset_cback_cnt(tGATT_TCB *p_tcb ); -extern void gatt_sr_reset_prep_cnt(tGATT_TCB *p_tcb ); -extern void gatt_sr_update_cback_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first); -extern void gatt_sr_update_prep_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first); - -extern BOOLEAN gatt_find_app_hold_link(tGATT_TCB *p_tcb, UINT8 start_idx, UINT8 *p_found_idx, tGATT_IF *p_gatt_if); -extern BOOLEAN gatt_find_specific_app_in_hold_link(tGATT_TCB *p_tcb, tGATT_IF p_gatt_if); -extern UINT8 gatt_num_apps_hold_link(tGATT_TCB *p_tcb); -extern UINT8 gatt_num_clcb_by_bd_addr(BD_ADDR bda); -extern tGATT_TCB *gatt_find_tcb_by_cid(UINT16 lcid); -extern tGATT_TCB *gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport); -extern tGATT_TCB *gatt_get_tcb_by_idx(UINT8 tcb_idx); -extern tGATT_TCB *gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport); -extern BOOLEAN gatt_send_ble_burst_data (BD_ADDR remote_bda, BT_HDR *p_buf); - -/* GATT client functions */ -extern void gatt_dequeue_sr_cmd (tGATT_TCB *p_tcb); -extern UINT8 gatt_send_write_msg(tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code, UINT16 handle, - UINT16 len, UINT16 offset, UINT8 *p_data); -extern void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport); -extern void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data); - -extern void gatt_act_discovery(tGATT_CLCB *p_clcb); -extern void gatt_act_read(tGATT_CLCB *p_clcb, UINT16 offset); -extern void gatt_act_write(tGATT_CLCB *p_clcb, UINT8 sec_act); -extern UINT8 gatt_act_send_browse(tGATT_TCB *p_tcb, UINT16 index, UINT8 op, UINT16 s_handle, UINT16 e_handle, - tBT_UUID uuid); -extern tGATT_CLCB *gatt_cmd_dequeue(tGATT_TCB *p_tcb, UINT8 *p_opcode); -extern BOOLEAN gatt_cmd_enq(tGATT_TCB *p_tcb, UINT16 clcb_idx, BOOLEAN to_send, UINT8 op_code, BT_HDR *p_buf); -extern void gatt_client_handle_server_rsp (tGATT_TCB *p_tcb, UINT8 op_code, - UINT16 len, UINT8 *p_data); -extern void gatt_send_queue_write_cancel (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, tGATT_EXEC_FLAG flag); - -/* gatt_auth.c */ -extern BOOLEAN gatt_security_check_start(tGATT_CLCB *p_clcb); -extern void gatt_verify_signature(tGATT_TCB *p_tcb, BT_HDR *p_buf); -extern tGATT_SEC_ACTION gatt_determine_sec_act(tGATT_CLCB *p_clcb ); -extern tGATT_STATUS gatt_get_link_encrypt_status(tGATT_TCB *p_tcb); -extern tGATT_SEC_ACTION gatt_get_sec_act(tGATT_TCB *p_tcb); -extern void gatt_set_sec_act(tGATT_TCB *p_tcb, tGATT_SEC_ACTION sec_act); - -/* gatt_db.c */ -extern BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri, UINT16 s_hdl, UINT16 num_handle); -extern UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e_handle, tBT_UUID service); -extern UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, - tGATT_CHAR_PROP property, - tBT_UUID *p_char_uuid, tGATT_ATTR_VAL *attr_val, - tGATTS_ATTR_CONTROL *control); -extern UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, - tBT_UUID *p_dscp_uuid, tGATT_ATTR_VAL *attr_val, - tGATTS_ATTR_CONTROL *control); - -extern tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, - UINT16 length, UINT8 *value); - -extern tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, - UINT16 *length, UINT8 **value); -extern BOOLEAN gatts_is_auto_response(UINT16 attr_handle); -extern tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB *p_tcb, tGATT_SVC_DB *p_db, UINT8 op_code, BT_HDR *p_rsp, UINT16 s_handle, - UINT16 e_handle, tBT_UUID type, UINT16 *p_len, tGATT_SEC_FLAG sec_flag, UINT8 key_size, UINT32 trans_id, UINT16 *p_cur_handle); -extern tGATT_STATUS gatts_read_attr_value_by_handle(tGATT_TCB *p_tcb, tGATT_SVC_DB *p_db, UINT8 op_code, UINT16 handle, UINT16 offset, - UINT8 *p_value, UINT16 *p_len, UINT16 mtu, tGATT_SEC_FLAG sec_flag, UINT8 key_size, UINT32 trans_id); -extern tGATT_STATUS gatts_write_attr_value_by_handle(tGATT_SVC_DB *p_db, - UINT16 handle, UINT16 offset, - UINT8 *p_value, UINT16 len); -extern tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, UINT16 handle, UINT16 offset, UINT8 *p_data, - UINT16 len, tGATT_SEC_FLAG sec_flag, UINT8 key_size); -extern tGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB *p_db, BOOLEAN is_long, UINT16 handle, tGATT_SEC_FLAG sec_flag, UINT8 key_size); -extern void gatts_update_srv_list_elem(UINT8 i_sreg, UINT16 handle, BOOLEAN is_primary); -extern tBT_UUID *gatts_get_service_uuid (tGATT_SVC_DB *p_db); - -extern void gatt_reset_bgdev_list(void); -extern uint16_t gatt_get_local_mtu(void); -extern void gatt_set_local_mtu(uint16_t mtu); -#endif diff --git a/tools/sdk/include/bluedroid/hci/bt_vendor_lib.h b/tools/sdk/include/bluedroid/hci/bt_vendor_lib.h deleted file mode 100644 index e3a8ec8d..00000000 --- a/tools/sdk/include/bluedroid/hci/bt_vendor_lib.h +++ /dev/null @@ -1,362 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2009-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef BT_VENDOR_LIB_H -#define BT_VENDOR_LIB_H - -#include -//#include -//#include - -/** Struct types */ - - -/** Typedefs and defines */ - -/** Vendor specific operations OPCODE */ -typedef enum { - /* [operation] - * Power on or off the BT Controller. - * [input param] - * A pointer to int type with content of bt_vendor_power_state_t. - * Typecasting conversion: (int *) param. - * [return] - * 0 - default, don't care. - * [callback] - * None. - */ - BT_VND_OP_POWER_CTRL, - - /* [operation] - * Perform any vendor specific initialization or configuration - * on the BT Controller. This is called before stack initialization. - * [input param] - * None. - * [return] - * 0 - default, don't care. - * [callback] - * Must call fwcfg_cb to notify the stack of the completion of vendor - * specific initialization once it has been done. - */ - BT_VND_OP_FW_CFG, - - /* [operation] - * Perform any vendor specific SCO/PCM configuration on the BT Controller. - * This is called after stack initialization. - * [input param] - * None. - * [return] - * 0 - default, don't care. - * [callback] - * Must call scocfg_cb to notify the stack of the completion of vendor - * specific SCO configuration once it has been done. - */ - BT_VND_OP_SCO_CFG, - - /* [operation] - * Open UART port on where the BT Controller is attached. - * This is called before stack initialization. - * [input param] - * A pointer to int array type for open file descriptors. - * The mapping of HCI channel to fd slot in the int array is given in - * bt_vendor_hci_channels_t. - * And, it requires the vendor lib to fill up the content before returning - * the call. - * Typecasting conversion: (int (*)[]) param. - * [return] - * Numbers of opened file descriptors. - * Valid number: - * 1 - CMD/EVT/ACL-In/ACL-Out via the same fd (e.g. UART) - * 2 - CMD/EVT on one fd, and ACL-In/ACL-Out on the other fd - * 4 - CMD, EVT, ACL-In, ACL-Out are on their individual fd - * [callback] - * None. - */ - BT_VND_OP_USERIAL_OPEN, - - /* [operation] - * Close the previously opened UART port. - * [input param] - * None. - * [return] - * 0 - default, don't care. - * [callback] - * None. - */ - BT_VND_OP_USERIAL_CLOSE, - - /* [operation] - * Get the LPM idle timeout in milliseconds. - * The stack uses this information to launch a timer delay before it - * attempts to de-assert LPM WAKE signal once downstream HCI packet - * has been delivered. - * [input param] - * A pointer to uint32_t type which is passed in by the stack. And, it - * requires the vendor lib to fill up the content before returning - * the call. - * Typecasting conversion: (uint32_t *) param. - * [return] - * 0 - default, don't care. - * [callback] - * None. - */ - BT_VND_OP_GET_LPM_IDLE_TIMEOUT, - - /* [operation] - * Enable or disable LPM mode on BT Controller. - * [input param] - * A pointer to uint8_t type with content of bt_vendor_lpm_mode_t. - * Typecasting conversion: (uint8_t *) param. - * [return] - * 0 - default, don't care. - * [callback] - * Must call lpm_cb to notify the stack of the completion of LPM - * disable/enable process once it has been done. - */ - BT_VND_OP_LPM_SET_MODE, - - /* [operation] - * Assert or Deassert LPM WAKE on BT Controller. - * [input param] - * A pointer to uint8_t type with content of bt_vendor_lpm_wake_state_t. - * Typecasting conversion: (uint8_t *) param. - * [return] - * 0 - default, don't care. - * [callback] - * None. - */ - BT_VND_OP_LPM_WAKE_SET_STATE, - - /* [operation] - * Perform any vendor specific commands related to audio state changes. - * [input param] - * a pointer to bt_vendor_op_audio_state_t indicating what audio state is - * set. - * [return] - * 0 - default, don't care. - * [callback] - * None. - */ - BT_VND_OP_SET_AUDIO_STATE, - - /* [operation] - * The epilog call to the vendor module so that it can perform any - * vendor-specific processes (e.g. send a HCI_RESET to BT Controller) - * before the caller calls for cleanup(). - * [input param] - * None. - * [return] - * 0 - default, don't care. - * [callback] - * Must call epilog_cb to notify the stack of the completion of vendor - * specific epilog process once it has been done. - */ - BT_VND_OP_EPILOG, -} bt_vendor_opcode_t; - -/** Power on/off control states */ -typedef enum { - BT_VND_PWR_OFF, - BT_VND_PWR_ON, -} bt_vendor_power_state_t; - -/** Define HCI channel identifier in the file descriptors array - used in BT_VND_OP_USERIAL_OPEN operation. - */ -typedef enum { - CH_CMD, // HCI Command channel - CH_EVT, // HCI Event channel - CH_ACL_OUT, // HCI ACL downstream channel - CH_ACL_IN, // HCI ACL upstream channel - - CH_MAX // Total channels -} bt_vendor_hci_channels_t; - -/** LPM disable/enable request */ -typedef enum { - BT_VND_LPM_DISABLE, - BT_VND_LPM_ENABLE, -} bt_vendor_lpm_mode_t; - -/** LPM WAKE set state request */ -typedef enum { - BT_VND_LPM_WAKE_ASSERT, - BT_VND_LPM_WAKE_DEASSERT, -} bt_vendor_lpm_wake_state_t; - -/** Callback result values */ -typedef enum { - BT_VND_OP_RESULT_SUCCESS, - BT_VND_OP_RESULT_FAIL, -} bt_vendor_op_result_t; - -/** audio (SCO) state changes triggering VS commands for configuration */ -typedef struct { - uint16_t handle; - uint16_t peer_codec; - uint16_t state; -} bt_vendor_op_audio_state_t; - -/* - * Bluetooth Host/Controller Vendor callback structure. - */ - -/* vendor initialization/configuration callback */ -typedef void (*cfg_result_cb)(bt_vendor_op_result_t result); - -/* datapath buffer allocation callback (callout) - * - * Vendor lib needs to request a buffer through the alloc callout function - * from HCI lib if the buffer is for constructing a HCI Command packet which - * will be sent through xmit_cb to BT Controller. - * - * For each buffer allocation, the requested size needs to be big enough to - * accommodate the below header plus a complete HCI packet -- - * typedef struct - * { - * uint16_t event; - * uint16_t len; - * uint16_t offset; - * uint16_t layer_specific; - * } HC_BT_HDR; - * - * HCI lib returns a pointer to the buffer where Vendor lib should use to - * construct a HCI command packet as below format: - * - * -------------------------------------------- - * | HC_BT_HDR | HCI command | - * -------------------------------------------- - * where - * HC_BT_HDR.event = 0x2000; - * HC_BT_HDR.len = Length of HCI command; - * HC_BT_HDR.offset = 0; - * HC_BT_HDR.layer_specific = 0; - * - * For example, a HCI_RESET Command will be formed as - * ------------------------ - * | HC_BT_HDR |03|0c|00| - * ------------------------ - * with - * HC_BT_HDR.event = 0x2000; - * HC_BT_HDR.len = 3; - * HC_BT_HDR.offset = 0; - * HC_BT_HDR.layer_specific = 0; - */ -typedef void *(*malloc_cb)(int size); - -/* datapath buffer deallocation callback (callout) */ -typedef void (*mdealloc_cb)(void *p_buf); - -/* define callback of the cmd_xmit_cb - * - * The callback function which HCI lib will call with the return of command - * complete packet. Vendor lib is responsible for releasing the buffer passed - * in at the p_mem parameter by calling dealloc callout function. - */ -typedef void (*tINT_CMD_CBACK)(void *p_mem); - -/* hci command packet transmit callback (callout) - * - * Vendor lib calls xmit_cb callout function in order to send a HCI Command - * packet to BT Controller. The buffer carrying HCI Command packet content - * needs to be first allocated through the alloc callout function. - * HCI lib will release the buffer for Vendor lib once it has delivered the - * packet content to BT Controller. - * - * Vendor lib needs also provide a callback function (p_cback) which HCI lib - * will call with the return of command complete packet. - * - * The opcode parameter gives the HCI OpCode (combination of OGF and OCF) of - * HCI Command packet. For example, opcode = 0x0c03 for the HCI_RESET command - * packet. - */ -typedef uint8_t (*cmd_xmit_cb)(uint16_t opcode, void *p_buf, tINT_CMD_CBACK p_cback); - -typedef struct { - /** set to sizeof(bt_vendor_callbacks_t) */ - size_t size; - - /* - * Callback and callout functions have implemented in HCI libray - * (libbt-hci.so). - */ - - /* notifies caller result of firmware configuration request */ - cfg_result_cb fwcfg_cb; - - /* notifies caller result of sco configuration request */ - cfg_result_cb scocfg_cb; - - /* notifies caller result of lpm enable/disable */ - cfg_result_cb lpm_cb; - - /* notifies the result of codec setting */ - cfg_result_cb audio_state_cb; - - /* buffer allocation request */ - malloc_cb alloc; - - /* buffer deallocation request */ - mdealloc_cb dealloc; - - /* hci command packet transmit request */ - cmd_xmit_cb xmit_cb; - - /* notifies caller completion of epilog process */ - cfg_result_cb epilog_cb; -} bt_vendor_callbacks_t; - -/* - * Bluetooth Host/Controller VENDOR Interface - */ -typedef struct { - /** Set to sizeof(bt_vndor_interface_t) */ - size_t size; - - /* - * Functions need to be implemented in Vendor libray (libbt-vendor.so). - */ - - /** - * Caller will open the interface and pass in the callback routines - * to the implemenation of this interface. - */ - int (*init)(const bt_vendor_callbacks_t *p_cb, unsigned char *local_bdaddr); - - /** Vendor specific operations */ - int (*op)(bt_vendor_opcode_t opcode, void *param); - - /** Closes the interface */ - void (*cleanup)(void); -} bt_vendor_interface_t; - - -/* - * External shared lib functions/data - */ - -/* Entry point of DLib -- - * Vendor library needs to implement the body of bt_vendor_interface_t - * structure and uses the below name as the variable name. HCI library - * will use this symbol name to get address of the object through the - * dlsym call. - */ -//extern const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE; - -#endif /* BT_VENDOR_LIB_H */ - diff --git a/tools/sdk/include/bluedroid/hci/hci_audio.h b/tools/sdk/include/bluedroid/hci/hci_audio.h deleted file mode 100644 index a9234c3a..00000000 --- a/tools/sdk/include/bluedroid/hci/hci_audio.h +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2015 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _HCI_AUDIO_H_ -#define _HCI_AUDIO_H_ -#include - -// Audio state definitions. -typedef enum { - SCO_STATE_OFF = 0, // Audio is off. - SCO_STATE_OFF_TRANSFER, // Closed pending final transfer of audio. - SCO_STATE_ON, // Audio is on. - SCO_STATE_SETUP, // Open pending completion of audio setup. -} sco_state_t; - -// Codec type definitions. -typedef enum { - SCO_CODEC_NONE = 0x0000, - SCO_CODEC_CVSD = 0x0001, - SCO_CODEC_MSBC = 0x0002, -} sco_codec_t; - -// Set the audio state on the controller for SCO (PCM, WBS, ...) using the -// vendor library. -void set_audio_state(uint16_t handle, sco_codec_t codec, sco_state_t state); - -#endif /* _HCI_AUDIO_H_ */ diff --git a/tools/sdk/include/bluedroid/hci/hci_hal.h b/tools/sdk/include/bluedroid/hci/hci_hal.h deleted file mode 100644 index 2928f29a..00000000 --- a/tools/sdk/include/bluedroid/hci/hci_hal.h +++ /dev/null @@ -1,85 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _HCI_HAL_H_ -#define _HCI_HAL_H_ - -#include -#include - -#include "stack/bt_types.h" - -typedef enum { - DATA_TYPE_COMMAND = 1, - DATA_TYPE_ACL = 2, - DATA_TYPE_SCO = 3, - DATA_TYPE_EVENT = 4 -} serial_data_type_t; - -typedef void (*packet_ready_cb)(BT_HDR *packet); - -typedef struct { - // Called when the HAL detects inbound data. - // Data |type| may be ACL, SCO, or EVENT. - // Executes in the context of the thread supplied to |init|. - packet_ready_cb packet_ready; - - /* - // Called when the HAL detects inbound astronauts named Dave. - // HAL will deny all requests to open the pod bay doors after this. - dave_ready_cb dave_ready; - */ -} hci_hal_callbacks_t; - -typedef struct hci_hal_t { - // Initialize the HAL, with |upper_callbacks| and |upper_thread| to run in the context of. - //bool (*init)(const hci_hal_callbacks_t *upper_callbacks); - - // Connect to the underlying hardware, and let data start flowing. - bool (*open)(const hci_hal_callbacks_t *upper_callbacks); - // Disconnect from the underlying hardware, and close the HAL. - // "Daisy, Daisy..." - void (*close)(void); - - // Retrieve up to |max_size| bytes for ACL, SCO, or EVENT data packets into - // |buffer|, blocking until max_size bytes read if |block| is true. - // Only guaranteed to be correct in the context of a data_ready callback - // of the corresponding type. - //size_t (*read_data)(serial_data_type_t type, uint8_t *buffer, size_t max_size); - // The upper layer must call this to notify the HAL that it has finished - // reading a packet of the specified |type|. Underlying implementations that - // use shared channels for multiple data types depend on this to know when - // to reinterpret the data stream. - //void (*packet_finished)(serial_data_type_t type); - // Transmit COMMAND, ACL, or SCO data packets. - // |data| may not be NULL. |length| must be greater than zero. - // - // IMPORTANT NOTE: - // Depending on the underlying implementation, the byte right - // before the beginning of |data| may be borrowed during this call - // and then restored to its original value. - // This is safe in the bluetooth context, because there is always a buffer - // header that prefixes data you're sending. - uint16_t (*transmit_data)(serial_data_type_t type, uint8_t *data, uint16_t length); -} hci_hal_t; - - -// Gets the correct hal implementation, as compiled for. -const hci_hal_t *hci_hal_h4_get_interface(void); - -#endif /* _HCI_HAL_H */ diff --git a/tools/sdk/include/bluedroid/hci/hci_internals.h b/tools/sdk/include/bluedroid/hci/hci_internals.h deleted file mode 100644 index 41c792cf..00000000 --- a/tools/sdk/include/bluedroid/hci/hci_internals.h +++ /dev/null @@ -1,31 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _HCI_INTERNALS_H_ -#define _HCI_INTERNALS_H_ - -// 2 bytes for opcode, 1 byte for parameter length (Volume 2, Part E, 5.4.1) -#define HCI_COMMAND_PREAMBLE_SIZE 3 -// 2 bytes for handle, 2 bytes for data length (Volume 2, Part E, 5.4.2) -#define HCI_ACL_PREAMBLE_SIZE 4 -// 2 bytes for handle, 1 byte for data length (Volume 2, Part E, 5.4.3) -#define HCI_SCO_PREAMBLE_SIZE 3 -// 1 byte for event code, 1 byte for parameter length (Volume 2, Part E, 5.4.4) -#define HCI_EVENT_PREAMBLE_SIZE 2 - -#endif /* _HCI_INTERNALS_H_ */ diff --git a/tools/sdk/include/bluedroid/hci/hci_layer.h b/tools/sdk/include/bluedroid/hci/hci_layer.h deleted file mode 100644 index 4b101809..00000000 --- a/tools/sdk/include/bluedroid/hci/hci_layer.h +++ /dev/null @@ -1,99 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _HCI_LAYER_H_ -#define _HCI_LAYER_H_ - -#include "stack/bt_types.h" -#include "osi/allocator.h" -#include "osi/osi.h" -#include "osi/future.h" -///// LEGACY DEFINITIONS ///// - -/* Message event mask across Host/Controller lib and stack */ -#define MSG_EVT_MASK 0xFF00 /* eq. BT_EVT_MASK */ -#define MSG_SUB_EVT_MASK 0x00FF /* eq. BT_SUB_EVT_MASK */ - -/* Message event ID passed from Host/Controller lib to stack */ -#define MSG_HC_TO_STACK_HCI_ERR 0x1300 /* eq. BT_EVT_TO_BTU_HCIT_ERR */ -#define MSG_HC_TO_STACK_HCI_ACL 0x1100 /* eq. BT_EVT_TO_BTU_HCI_ACL */ -#define MSG_HC_TO_STACK_HCI_SCO 0x1200 /* eq. BT_EVT_TO_BTU_HCI_SCO */ -#define MSG_HC_TO_STACK_HCI_EVT 0x1000 /* eq. BT_EVT_TO_BTU_HCI_EVT */ -#define MSG_HC_TO_STACK_L2C_SEG_XMIT 0x1900 /* eq. BT_EVT_TO_BTU_L2C_SEG_XMIT */ - -/* Message event ID passed from stack to vendor lib */ -#define MSG_STACK_TO_HC_HCI_ACL 0x2100 /* eq. BT_EVT_TO_LM_HCI_ACL */ -#define MSG_STACK_TO_HC_HCI_SCO 0x2200 /* eq. BT_EVT_TO_LM_HCI_SCO */ -#define MSG_STACK_TO_HC_HCI_CMD 0x2000 /* eq. BT_EVT_TO_LM_HCI_CMD */ - -/* Local Bluetooth Controller ID for BR/EDR */ -#define LOCAL_BR_EDR_CONTROLLER_ID 0 - -///// END LEGACY DEFINITIONS ///// - -typedef struct hci_hal_t hci_hal_t; -//typedef struct btsnoop_t btsnoop_t; -typedef struct controller_t controller_t; -//typedef struct hci_inject_t hci_inject_t; -typedef struct packet_fragmenter_t packet_fragmenter_t; -//typedef struct vendor_t vendor_t; -//typedef struct low_power_manager_t low_power_manager_t; - -//typedef unsigned char * bdaddr_t; -typedef uint16_t command_opcode_t; - -/* -typedef enum { - LPM_DISABLE, - LPM_ENABLE, - LPM_WAKE_ASSERT, - LPM_WAKE_DEASSERT -} low_power_command_t; -*/ - -typedef void (*command_complete_cb)(BT_HDR *response, void *context); -typedef void (*command_status_cb)(uint8_t status, BT_HDR *command, void *context); - -typedef struct hci_t { - // Send a low power command, if supported and the low power manager is enabled. - //void (*send_low_power_command)(low_power_command_t command); - - // Do the postload sequence (call after the rest of the BT stack initializes). - void (*do_postload)(void); - - // Send a command through the HCI layer - void (*transmit_command)( - BT_HDR *command, - command_complete_cb complete_callback, - command_status_cb status_cb, - void *context - ); - - future_t *(*transmit_command_futured)(BT_HDR *command); - - // Send some data downward through the HCI layer - void (*transmit_downward)(uint16_t type, void *data); -} hci_t; - -const hci_t *hci_layer_get_interface(); - -int hci_start_up(void); -void hci_shut_down(void); - - -#endif /* _HCI_LAYER_H_ */ diff --git a/tools/sdk/include/bluedroid/hci/hci_packet_factory.h b/tools/sdk/include/bluedroid/hci/hci_packet_factory.h deleted file mode 100644 index 21bd2c9a..00000000 --- a/tools/sdk/include/bluedroid/hci/hci_packet_factory.h +++ /dev/null @@ -1,52 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _HCI_PACKET_FACTORY_H_ -#define _HCI_PACKET_FACTORY_H_ - -#include "stack/bt_types.h" -#include "device/event_mask.h" - -typedef struct { - BT_HDR *(*make_reset)(void); - BT_HDR *(*make_read_buffer_size)(void); - BT_HDR *(*make_set_c2h_flow_control)(uint8_t enable); - BT_HDR *(*make_host_buffer_size)(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count); - BT_HDR *(*make_read_local_version_info)(void); - BT_HDR *(*make_read_bd_addr)(void); - BT_HDR *(*make_read_local_supported_commands)(void); - BT_HDR *(*make_read_local_extended_features)(uint8_t page_number); - BT_HDR *(*make_write_simple_pairing_mode)(uint8_t mode); - BT_HDR *(*make_write_secure_connections_host_support)(uint8_t mode); - BT_HDR *(*make_set_event_mask)(const bt_event_mask_t *event_mask); - BT_HDR *(*make_ble_write_host_support)(uint8_t supported_host, uint8_t simultaneous_host); - BT_HDR *(*make_ble_read_white_list_size)(void); - BT_HDR *(*make_ble_read_buffer_size)(void); - BT_HDR *(*make_ble_read_supported_states)(void); - BT_HDR *(*make_ble_read_local_supported_features)(void); - BT_HDR *(*make_ble_read_resolving_list_size)(void); - BT_HDR *(*make_ble_read_suggested_default_data_length)(void); - BT_HDR *(*make_ble_write_suggested_default_data_length)(uint16_t SuggestedMaxTxOctets, uint16_t SuggestedMaxTxTime); - BT_HDR *(*make_ble_set_event_mask)(const bt_event_mask_t *event_mask); - BT_HDR *(*make_write_sync_flow_control_enable)(uint8_t enable); - BT_HDR *(*make_write_default_erroneous_data_report)(uint8_t enable); -} hci_packet_factory_t; - -const hci_packet_factory_t *hci_packet_factory_get_interface(); - -#endif /*_HCI_PACKET_FACTORY_H_*/ diff --git a/tools/sdk/include/bluedroid/hci/hci_packet_parser.h b/tools/sdk/include/bluedroid/hci/hci_packet_parser.h deleted file mode 100644 index b0cc4b3b..00000000 --- a/tools/sdk/include/bluedroid/hci/hci_packet_parser.h +++ /dev/null @@ -1,102 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _HCI_PACKET_PARSER_H_ -#define _HCI_PACKET_PARSER_H_ - -#include - -#include "osi/allocator.h" -#include "device/bdaddr.h" -#include "stack/bt_types.h" -#include "device/device_features.h" -//#include "features.h" -#include "device/version.h" - -typedef struct { - void (*parse_generic_command_complete)(BT_HDR *response); - - void (*parse_read_buffer_size_response)( - BT_HDR *response, - uint16_t *acl_data_size_ptr, - uint16_t *acl_buffer_count_ptr, - uint8_t *sco_data_size_ptr, - uint16_t *sco_buffer_count_ptr - ); - - void (*parse_read_local_version_info_response)( - BT_HDR *response, - bt_version_t *bt_version_ptr - ); - - void (*parse_read_bd_addr_response)( - BT_HDR *response, - bt_bdaddr_t *address_ptr - ); - - void (*parse_read_local_supported_commands_response)( - BT_HDR *response, - uint8_t *supported_commands_ptr, - size_t supported_commands_length - ); - - void (*parse_read_local_extended_features_response)( - BT_HDR *response, - uint8_t *page_number_ptr, - uint8_t *max_page_number_ptr, - bt_device_features_t *feature_pages, - size_t feature_pages_count - ); - - void (*parse_ble_read_white_list_size_response)( - BT_HDR *response, - uint8_t *white_list_size_ptr - ); - - void (*parse_ble_read_buffer_size_response)( - BT_HDR *response, - uint16_t *data_size_ptr, - uint8_t *acl_buffer_count_ptr - ); - - void (*parse_ble_read_supported_states_response)( - BT_HDR *response, - uint8_t *supported_states, - size_t supported_states_size - ); - - void (*parse_ble_read_local_supported_features_response)( - BT_HDR *response, - bt_device_features_t *supported_features - ); - - void (*parse_ble_read_resolving_list_size_response) ( - BT_HDR *response, - uint8_t *resolving_list_size_ptr - ); - - void (*parse_ble_read_suggested_default_data_length_response)( - BT_HDR *response, - uint16_t *ble_default_packet_length_ptr, - uint16_t *ble_default_packet_txtime_ptr - ); -} hci_packet_parser_t; - -const hci_packet_parser_t *hci_packet_parser_get_interface(); - -#endif /*_HCI_PACKET_PARSER_H_*/ diff --git a/tools/sdk/include/bluedroid/hci/packet_fragmenter.h b/tools/sdk/include/bluedroid/hci/packet_fragmenter.h deleted file mode 100644 index 80b442f2..00000000 --- a/tools/sdk/include/bluedroid/hci/packet_fragmenter.h +++ /dev/null @@ -1,62 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _PACKET_FRAGMENTER_H_ -#define _PACKET_FRAGMENTER_H_ - -#include "osi/allocator.h" -#include "stack/bt_types.h" -#include "hci/hci_layer.h" - -typedef void (*transmit_finished_cb)(BT_HDR *packet, bool all_fragments_sent); -typedef void (*packet_reassembled_cb)(BT_HDR *packet); -typedef void (*packet_fragmented_cb)(BT_HDR *packet, bool send_transmit_finished); - -typedef struct { - // Called for every packet fragment. - packet_fragmented_cb fragmented; - - // Called for every completely reassembled packet. - packet_reassembled_cb reassembled; - - // Called when the fragmenter finishes sending all requested fragments, - // but the packet has not been entirely sent. - transmit_finished_cb transmit_finished; -} packet_fragmenter_callbacks_t; - -typedef struct packet_fragmenter_t { - // Initialize the fragmenter, specifying the |result_callbacks|. - void (*init)(const packet_fragmenter_callbacks_t *result_callbacks); - - // Release all resources associated with the fragmenter. - void (*cleanup)(void); - - // CHeck if Current fragmenter is ongoing - BT_HDR *(*fragment_current_packet)(void); - - // Fragments |packet| if necessary and hands off everything to the fragmented callback. - void (*fragment_and_dispatch)(BT_HDR *packet); - // If |packet| is a complete packet, forwards to the reassembled callback. Otherwise - // holds onto it until all fragments arrive, at which point the reassembled callback is called - // with the reassembled data. - void (*reassemble_and_dispatch)(BT_HDR *packet); -} packet_fragmenter_t; - -const packet_fragmenter_t *packet_fragmenter_get_interface(); - -#endif /* _PACKET_FRAGMENTER_H_ */ diff --git a/tools/sdk/include/bluedroid/hid_conn.h b/tools/sdk/include/bluedroid/hid_conn.h deleted file mode 100644 index 320b78fa..00000000 --- a/tools/sdk/include/bluedroid/hid_conn.h +++ /dev/null @@ -1,69 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2002-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains HID connection internal definitions - * - ******************************************************************************/ - -#ifndef HID_CONN_H -#define HID_CONN_H - -#if (HID_HOST_INCLUDED == TRUE) -/* Define the HID Connection Block -*/ -typedef struct hid_conn { -#define HID_CONN_STATE_UNUSED (0) -#define HID_CONN_STATE_CONNECTING_CTRL (1) -#define HID_CONN_STATE_CONNECTING_INTR (2) -#define HID_CONN_STATE_CONFIG (3) -#define HID_CONN_STATE_CONNECTED (4) -#define HID_CONN_STATE_DISCONNECTING (5) -#define HID_CONN_STATE_SECURITY (6) - - UINT8 conn_state; - -#define HID_CONN_FLAGS_IS_ORIG (0x01) -#define HID_CONN_FLAGS_HIS_CTRL_CFG_DONE (0x02) -#define HID_CONN_FLAGS_MY_CTRL_CFG_DONE (0x04) -#define HID_CONN_FLAGS_HIS_INTR_CFG_DONE (0x08) -#define HID_CONN_FLAGS_MY_INTR_CFG_DONE (0x10) -#define HID_CONN_FLAGS_ALL_CONFIGURED (0x1E) /* All the config done */ -#define HID_CONN_FLAGS_CONGESTED (0x20) -#define HID_CONN_FLAGS_INACTIVE (0x40) - - UINT8 conn_flags; - - UINT8 ctrl_id; - UINT16 ctrl_cid; - UINT16 intr_cid; - UINT16 rem_mtu_size; - UINT16 disc_reason; /* Reason for disconnecting (for HID_HDEV_EVT_CLOSE) */ - TIMER_LIST_ENT timer_entry; - -} tHID_CONN; - -#define HID_SEC_CHN 1 -#define HID_NOSEC_CHN 2 - -#define HIDD_SEC_CHN 3 -#define HIDD_NOSEC_CHN 4 - -#endif ///HID_HOST_INCLUDED == TRUE -#endif diff --git a/tools/sdk/include/bluedroid/hidh_int.h b/tools/sdk/include/bluedroid/hidh_int.h deleted file mode 100644 index 20eda6e3..00000000 --- a/tools/sdk/include/bluedroid/hidh_int.h +++ /dev/null @@ -1,95 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2002-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains HID HOST internal definitions - * - ******************************************************************************/ - -#ifndef HIDH_INT_H -#define HIDH_INT_H - -#include "stack/hidh_api.h" -#include "hid_conn.h" -#include "stack/l2c_api.h" - -#if (HID_HOST_INCLUDED == TRUE) - -enum { - HID_DEV_NO_CONN, - HID_DEV_CONNECTED -}; - -typedef struct per_device_ctb { - BOOLEAN in_use; - BD_ADDR addr; /* BD-Addr of the host device */ - UINT16 attr_mask; /* 0x01- virtual_cable; 0x02- normally_connectable; 0x03- reconn_initiate; - 0x04- sdp_disable; */ - UINT8 state; /* Device state if in HOST-KNOWN mode */ - UINT8 conn_substate; - UINT8 conn_tries; /* Remembers to the number of connection attempts while CONNECTING */ - - tHID_CONN conn; /* L2CAP channel info */ -} tHID_HOST_DEV_CTB; - -typedef struct host_ctb { - tHID_HOST_DEV_CTB devices[HID_HOST_MAX_DEVICES]; - tHID_HOST_DEV_CALLBACK *callback; /* Application callbacks */ - tL2CAP_CFG_INFO l2cap_cfg; - -#define MAX_SERVICE_DB_SIZE 4000 - - BOOLEAN sdp_busy; - tHID_HOST_SDP_CALLBACK *sdp_cback; - tSDP_DISCOVERY_DB *p_sdp_db; - tHID_DEV_SDP_INFO sdp_rec; - BOOLEAN reg_flag; - UINT8 trace_level; -} tHID_HOST_CTB; - -extern tHID_STATUS hidh_conn_snd_data(UINT8 dhandle, UINT8 trans_type, UINT8 param, \ - UINT16 data, UINT8 rpt_id, BT_HDR *buf); -extern tHID_STATUS hidh_conn_reg (void); -extern void hidh_conn_dereg( void ); -extern tHID_STATUS hidh_conn_disconnect (UINT8 dhandle); -extern tHID_STATUS hidh_conn_initiate (UINT8 dhandle); -extern void hidh_proc_repage_timeout (TIMER_LIST_ENT *p_tle); - -#ifdef __cplusplus -extern "C" -{ -#endif - -/****************************************************************************** -** Main Control Block -*******************************************************************************/ -#if HID_DYNAMIC_MEMORY == FALSE -extern tHID_HOST_CTB hh_cb; -#else -extern tHID_HOST_CTB *hidh_cb_ptr; -#define hh_cb (*hidh_cb_ptr) -#endif - -#ifdef __cplusplus -} -#endif - -#endif ///HID_HOST_INCLUDED == TRUE - -#endif diff --git a/tools/sdk/include/bluedroid/l2c_int.h b/tools/sdk/include/bluedroid/l2c_int.h deleted file mode 100644 index e2c0ef6a..00000000 --- a/tools/sdk/include/bluedroid/l2c_int.h +++ /dev/null @@ -1,819 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains L2CAP internal definitions - * - ******************************************************************************/ -#ifndef L2C_INT_H -#define L2C_INT_H - -#include - -#include "stack/btm_api.h" -#include "stack/l2c_api.h" -#include "stack/l2cdefs.h" -#include "osi/list.h" -#include "osi/fixed_queue.h" - -#define L2CAP_MIN_MTU 48 /* Minimum acceptable MTU is 48 bytes */ - -/* LE credit based L2CAP connection parameters */ -#define L2CAP_LE_MIN_MTU 23 -#define L2CAP_LE_MIN_MPS 23 -#define L2CAP_LE_MAX_MPS 65533 -#define L2CAP_LE_MIN_CREDIT 0 -#define L2CAP_LE_MAX_CREDIT 65535 -#define L2CAP_LE_DEFAULT_MTU 512 -#define L2CAP_LE_DEFAULT_MPS 23 -#define L2CAP_LE_DEFAULT_CREDIT 1 - - -/* Timeouts. Since L2CAP works off a 1-second list, all are in seconds. -*/ -#define L2CAP_LINK_ROLE_SWITCH_TOUT 10 /* 10 seconds */ -#define L2CAP_LINK_CONNECT_TOUT 60 /* 30 seconds */ -#define L2CAP_LINK_CONNECT_TOUT_EXT 120 /* 120 seconds */ -#define L2CAP_ECHO_RSP_TOUT 30 /* 30 seconds */ -#define L2CAP_LINK_FLOW_CONTROL_TOUT 2 /* 2 seconds */ -#define L2CAP_LINK_DISCONNECT_TOUT 30 /* 30 seconds */ - -#ifndef L2CAP_CHNL_CONNECT_TOUT /* BTIF needs to override for internal project needs */ -#define L2CAP_CHNL_CONNECT_TOUT 60 /* 60 seconds */ -#endif - -#define L2CAP_CHNL_CONNECT_TOUT_EXT 120 /* 120 seconds */ -#define L2CAP_CHNL_CFG_TIMEOUT 30 /* 30 seconds */ -#define L2CAP_CHNL_DISCONNECT_TOUT 10 /* 10 seconds */ -#define L2CAP_DELAY_CHECK_SM4 2 /* 2 seconds */ -#define L2CAP_WAIT_INFO_RSP_TOUT 3 /* 3 seconds */ -#define L2CAP_WAIT_UNPARK_TOUT 2 /* 2 seconds */ -#define L2CAP_LINK_INFO_RESP_TOUT 2 /* 2 seconds */ -#define L2CAP_UPDATE_CONN_PARAM_TOUT 6 /* 6 seconds */ -#define L2CAP_BLE_LINK_CONNECT_TOUT 30 /* 30 seconds */ -#define L2CAP_BLE_CONN_PARAM_UPD_TOUT 30 /* 30 seconds */ - -/* quick timer uses millisecond unit */ -#define L2CAP_DEFAULT_RETRANS_TOUT 2000 /* 2000 milliseconds */ -#define L2CAP_DEFAULT_MONITOR_TOUT 12000 /* 12000 milliseconds */ -#define L2CAP_FCR_ACK_TOUT 200 /* 200 milliseconds */ - -/* Define the possible L2CAP channel states. The names of -** the states may seem a bit strange, but they are taken from -** the Bluetooth specification. -*/ -typedef enum { - CST_CLOSED, /* Channel is in clodes state */ - CST_ORIG_W4_SEC_COMP, /* Originator waits security clearence */ - CST_TERM_W4_SEC_COMP, /* Acceptor waits security clearence */ - CST_W4_L2CAP_CONNECT_RSP, /* Waiting for peer conenct response */ - CST_W4_L2CA_CONNECT_RSP, /* Waiting for upper layer connect rsp */ - CST_CONFIG, /* Negotiating configuration */ - CST_OPEN, /* Data transfer state */ - CST_W4_L2CAP_DISCONNECT_RSP, /* Waiting for peer disconnect rsp */ - CST_W4_L2CA_DISCONNECT_RSP /* Waiting for upper layer disc rsp */ -} tL2C_CHNL_STATE; - -/* Define the possible L2CAP link states -*/ -typedef enum { - LST_DISCONNECTED, - LST_CONNECT_HOLDING, - LST_CONNECTING_WAIT_SWITCH, - LST_CONNECTING, - LST_CONNECTED, - LST_DISCONNECTING -} tL2C_LINK_STATE; - - - -/* Define input events to the L2CAP link and channel state machines. The names -** of the events may seem a bit strange, but they are taken from -** the Bluetooth specification. -*/ -#define L2CEVT_LP_CONNECT_CFM 0 /* Lower layer connect confirm */ -#define L2CEVT_LP_CONNECT_CFM_NEG 1 /* Lower layer connect confirm (failed) */ -#define L2CEVT_LP_CONNECT_IND 2 /* Lower layer connect indication */ -#define L2CEVT_LP_DISCONNECT_IND 3 /* Lower layer disconnect indication */ -#define L2CEVT_LP_QOS_CFM 4 /* Lower layer QOS confirmation */ -#define L2CEVT_LP_QOS_CFM_NEG 5 /* Lower layer QOS confirmation (failed)*/ -#define L2CEVT_LP_QOS_VIOLATION_IND 6 /* Lower layer QOS violation indication */ - -#define L2CEVT_SEC_COMP 7 /* Security cleared successfully */ -#define L2CEVT_SEC_COMP_NEG 8 /* Security procedure failed */ - -#define L2CEVT_L2CAP_CONNECT_REQ 10 /* Peer connection request */ -#define L2CEVT_L2CAP_CONNECT_RSP 11 /* Peer connection response */ -#define L2CEVT_L2CAP_CONNECT_RSP_PND 12 /* Peer connection response pending */ -#define L2CEVT_L2CAP_CONNECT_RSP_NEG 13 /* Peer connection response (failed) */ -#define L2CEVT_L2CAP_CONFIG_REQ 14 /* Peer configuration request */ -#define L2CEVT_L2CAP_CONFIG_RSP 15 /* Peer configuration response */ -#define L2CEVT_L2CAP_CONFIG_RSP_NEG 16 /* Peer configuration response (failed) */ -#define L2CEVT_L2CAP_DISCONNECT_REQ 17 /* Peer disconnect request */ -#define L2CEVT_L2CAP_DISCONNECT_RSP 18 /* Peer disconnect response */ -#define L2CEVT_L2CAP_INFO_RSP 19 /* Peer information response */ -#define L2CEVT_L2CAP_DATA 20 /* Peer data */ - -#define L2CEVT_L2CA_CONNECT_REQ 21 /* Upper layer connect request */ -#define L2CEVT_L2CA_CONNECT_RSP 22 /* Upper layer connect response */ -#define L2CEVT_L2CA_CONNECT_RSP_NEG 23 /* Upper layer connect response (failed)*/ -#define L2CEVT_L2CA_CONFIG_REQ 24 /* Upper layer config request */ -#define L2CEVT_L2CA_CONFIG_RSP 25 /* Upper layer config response */ -#define L2CEVT_L2CA_CONFIG_RSP_NEG 26 /* Upper layer config response (failed) */ -#define L2CEVT_L2CA_DISCONNECT_REQ 27 /* Upper layer disconnect request */ -#define L2CEVT_L2CA_DISCONNECT_RSP 28 /* Upper layer disconnect response */ -#define L2CEVT_L2CA_DATA_READ 29 /* Upper layer data read */ -#define L2CEVT_L2CA_DATA_WRITE 30 /* Upper layer data write */ -#define L2CEVT_L2CA_FLUSH_REQ 31 /* Upper layer flush */ - -#define L2CEVT_TIMEOUT 32 /* Timeout */ -#define L2CEVT_SEC_RE_SEND_CMD 33 /* btm_sec has enough info to proceed */ - -#define L2CEVT_ACK_TIMEOUT 34 /* RR delay timeout */ - - -/* Bitmask to skip over Broadcom feature reserved (ID) to avoid sending two - successive ID values, '0' id only or both */ -#define L2CAP_ADJ_BRCM_ID 0x1 -#define L2CAP_ADJ_ZERO_ID 0x2 -#define L2CAP_ADJ_ID 0x3 - -/* Return values for l2cu_process_peer_cfg_req() */ -#define L2CAP_PEER_CFG_UNACCEPTABLE 0 -#define L2CAP_PEER_CFG_OK 1 -#define L2CAP_PEER_CFG_DISCONNECT 2 - -/* eL2CAP option constants */ -#define L2CAP_MIN_RETRANS_TOUT 2000 /* Min retransmission timeout if no flush timeout or PBF */ -#define L2CAP_MIN_MONITOR_TOUT 12000 /* Min monitor timeout if no flush timeout or PBF */ - -#define L2CAP_MAX_FCR_CFG_TRIES 2 /* Config attempts before disconnecting */ - -typedef uint8_t tL2C_BLE_FIXED_CHNLS_MASK; - -typedef struct { - UINT8 next_tx_seq; /* Next sequence number to be Tx'ed */ - UINT8 last_rx_ack; /* Last sequence number ack'ed by the peer */ - UINT8 next_seq_expected; /* Next peer sequence number expected */ - UINT8 last_ack_sent; /* Last peer sequence number ack'ed */ - UINT8 num_tries; /* Number of retries to send a packet */ - UINT8 max_held_acks; /* Max acks we can hold before sending */ - - BOOLEAN remote_busy; /* TRUE if peer has flowed us off */ - BOOLEAN local_busy; /* TRUE if we have flowed off the peer */ - - BOOLEAN rej_sent; /* Reject was sent */ - BOOLEAN srej_sent; /* Selective Reject was sent */ - BOOLEAN wait_ack; /* Transmitter is waiting ack (poll sent) */ - BOOLEAN rej_after_srej; /* Send a REJ when SREJ clears */ - - BOOLEAN send_f_rsp; /* We need to send an F-bit response */ - - UINT16 rx_sdu_len; /* Length of the SDU being received */ - BT_HDR *p_rx_sdu; /* Buffer holding the SDU being received */ - fixed_queue_t *waiting_for_ack_q; /* Buffers sent and waiting for peer to ack */ - fixed_queue_t *srej_rcv_hold_q; /* Buffers rcvd but held pending SREJ rsp */ - fixed_queue_t *retrans_q; /* Buffers being retransmitted */ - - TIMER_LIST_ENT ack_timer; /* Timer delaying RR */ - TIMER_LIST_ENT mon_retrans_timer; /* Timer Monitor or Retransmission */ - -#if (L2CAP_ERTM_STATS == TRUE) - UINT32 connect_tick_count; /* Time channel was established */ - UINT32 ertm_pkt_counts[2]; /* Packets sent and received */ - UINT32 ertm_byte_counts[2]; /* Bytes sent and received */ - UINT32 s_frames_sent[4]; /* S-frames sent (RR, REJ, RNR, SREJ) */ - UINT32 s_frames_rcvd[4]; /* S-frames rcvd (RR, REJ, RNR, SREJ) */ - UINT32 xmit_window_closed; /* # of times the xmit window was closed */ - UINT32 controller_idle; /* # of times less than 2 packets in controller */ - /* when the xmit window was closed */ - UINT32 pkts_retransmitted; /* # of packets that were retransmitted */ - UINT32 retrans_touts; /* # of retransmission timouts */ - UINT32 xmit_ack_touts; /* # of xmit ack timouts */ - -#define L2CAP_ERTM_STATS_NUM_AVG 10 -#define L2CAP_ERTM_STATS_AVG_NUM_SAMPLES 100 - UINT32 ack_delay_avg_count; - UINT32 ack_delay_avg_index; - UINT32 throughput_start; - UINT32 throughput[L2CAP_ERTM_STATS_NUM_AVG]; - UINT32 ack_delay_avg[L2CAP_ERTM_STATS_NUM_AVG]; - UINT32 ack_delay_min[L2CAP_ERTM_STATS_NUM_AVG]; - UINT32 ack_delay_max[L2CAP_ERTM_STATS_NUM_AVG]; - UINT32 ack_q_count_avg[L2CAP_ERTM_STATS_NUM_AVG]; - UINT32 ack_q_count_min[L2CAP_ERTM_STATS_NUM_AVG]; - UINT32 ack_q_count_max[L2CAP_ERTM_STATS_NUM_AVG]; -#endif -} tL2C_FCRB; - - -/* Define a registration control block. Every application (e.g. RFCOMM, SDP, -** TCS etc) that registers with L2CAP is assigned one of these. -*/ -#if (L2CAP_UCD_INCLUDED == TRUE) -#define L2C_UCD_RCB_ID 0x00 -#define L2C_UCD_STATE_UNUSED 0x00 -#define L2C_UCD_STATE_W4_DATA 0x01 -#define L2C_UCD_STATE_W4_RECEPTION 0x02 -#define L2C_UCD_STATE_W4_MTU 0x04 - -typedef struct { - UINT8 state; - tL2CAP_UCD_CB_INFO cb_info; -} tL2C_UCD_REG; -#endif - -typedef struct { - BOOLEAN in_use; - UINT16 psm; - UINT16 real_psm; /* This may be a dummy RCB for an o/b connection but */ - /* this is the real PSM that we need to connect to */ -#if (L2CAP_UCD_INCLUDED == TRUE) - tL2C_UCD_REG ucd; -#endif - - tL2CAP_APPL_INFO api; -} tL2C_RCB; - -typedef void (tL2CAP_SEC_CBACK) (BD_ADDR bd_addr, tBT_TRANSPORT trasnport, - void *p_ref_data, tBTM_STATUS result); - -typedef struct -{ - UINT16 psm; - tBT_TRANSPORT transport; - BOOLEAN is_originator; - tL2CAP_SEC_CBACK *p_callback; - void *p_ref_data; -}tL2CAP_SEC_DATA; - -#ifndef L2CAP_CBB_DEFAULT_DATA_RATE_BUFF_QUOTA -#define L2CAP_CBB_DEFAULT_DATA_RATE_BUFF_QUOTA 100 -#endif -/* Define a channel control block (CCB). There may be many channel control blocks -** between the same two Bluetooth devices (i.e. on the same link). -** Each CCB has unique local and remote CIDs. All channel control blocks on -** the same physical link and are chained together. -*/ -typedef struct t_l2c_ccb { - BOOLEAN in_use; /* TRUE when in use, FALSE when not */ - tL2C_CHNL_STATE chnl_state; /* Channel state */ - tL2CAP_LE_CFG_INFO local_conn_cfg; /* Our config for ble conn oriented channel */ - tL2CAP_LE_CFG_INFO peer_conn_cfg; /* Peer device config ble conn oriented channel */ - - struct t_l2c_ccb *p_next_ccb; /* Next CCB in the chain */ - struct t_l2c_ccb *p_prev_ccb; /* Previous CCB in the chain */ - struct t_l2c_linkcb *p_lcb; /* Link this CCB is assigned to */ - - UINT16 local_cid; /* Local CID */ - UINT16 remote_cid; /* Remote CID */ - - TIMER_LIST_ENT timer_entry; /* CCB Timer List Entry */ - - tL2C_RCB *p_rcb; /* Registration CB for this Channel */ - bool should_free_rcb; /* True if RCB was allocated on the heap */ - -#define IB_CFG_DONE 0x01 -#define OB_CFG_DONE 0x02 -#define RECONFIG_FLAG 0x04 /* True after initial configuration */ -#define CFG_DONE_MASK (IB_CFG_DONE | OB_CFG_DONE) - - UINT8 config_done; /* Configuration flag word */ - UINT8 local_id; /* Transaction ID for local trans */ - UINT8 remote_id; /* Transaction ID for local */ - -#define CCB_FLAG_NO_RETRY 0x01 /* no more retry */ -#define CCB_FLAG_SENT_PENDING 0x02 /* already sent pending response */ - UINT8 flags; - - tL2CAP_CFG_INFO our_cfg; /* Our saved configuration options */ - tL2CAP_CH_CFG_BITS peer_cfg_bits; /* Store what peer wants to configure */ - tL2CAP_CFG_INFO peer_cfg; /* Peer's saved configuration options */ - - fixed_queue_t *xmit_hold_q; /* Transmit data hold queue */ - BOOLEAN cong_sent; /* Set when congested status sent */ - UINT16 buff_quota; /* Buffer quota before sending congestion */ - - tL2CAP_CHNL_PRIORITY ccb_priority; /* Channel priority */ - tL2CAP_CHNL_DATA_RATE tx_data_rate; /* Channel Tx data rate */ - tL2CAP_CHNL_DATA_RATE rx_data_rate; /* Channel Rx data rate */ - - /* Fields used for eL2CAP */ - tL2CAP_ERTM_INFO ertm_info; - tL2C_FCRB fcrb; - UINT16 tx_mps; /* TX MPS adjusted based on current controller */ - UINT16 max_rx_mtu; - UINT8 fcr_cfg_tries; /* Max number of negotiation attempts */ - BOOLEAN peer_cfg_already_rejected; /* If mode rejected once, set to TRUE */ - BOOLEAN out_cfg_fcr_present; /* TRUE if cfg response shoulkd include fcr options */ - -#define L2CAP_CFG_FCS_OUR 0x01 /* Our desired config FCS option */ -#define L2CAP_CFG_FCS_PEER 0x02 /* Peer's desired config FCS option */ -#define L2CAP_BYPASS_FCS (L2CAP_CFG_FCS_OUR | L2CAP_CFG_FCS_PEER) - UINT8 bypass_fcs; - -#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) - BOOLEAN is_flushable; /* TRUE if channel is flushable */ -#endif - -#if (L2CAP_NUM_FIXED_CHNLS > 0) || (L2CAP_UCD_INCLUDED == TRUE) - UINT16 fixed_chnl_idle_tout; /* Idle timeout to use for the fixed channel */ -#endif - UINT16 tx_data_len; -} tL2C_CCB; - -/*********************************************************************** -** Define a queue of linked CCBs. -*/ -typedef struct { - tL2C_CCB *p_first_ccb; /* The first channel in this queue */ - tL2C_CCB *p_last_ccb; /* The last channel in this queue */ -} tL2C_CCB_Q; - -#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) - -/* Round-Robin service for the same priority channels */ -#define L2CAP_NUM_CHNL_PRIORITY 3 /* Total number of priority group (high, medium, low)*/ -#define L2CAP_CHNL_PRIORITY_WEIGHT 5 /* weight per priority for burst transmission quota */ -#define L2CAP_GET_PRIORITY_QUOTA(pri) ((L2CAP_NUM_CHNL_PRIORITY - (pri)) * L2CAP_CHNL_PRIORITY_WEIGHT) - -/* CCBs within the same LCB are served in round robin with priority */ -/* It will make sure that low priority channel (for example, HF signaling on RFCOMM) */ -/* can be sent to headset even if higher priority channel (for example, AV media channel) */ -/* is congested. */ - -typedef struct { - tL2C_CCB *p_serve_ccb; /* current serving ccb within priority group */ - tL2C_CCB *p_first_ccb; /* first ccb of priority group */ - UINT8 num_ccb; /* number of channels in priority group */ - UINT8 quota; /* burst transmission quota */ -} tL2C_RR_SERV; - -#endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */ - -/* Define a link control block. There is one link control block between -** this device and any other device (i.e. BD ADDR). -*/ -typedef struct t_l2c_linkcb { - BOOLEAN in_use; /* TRUE when in use, FALSE when not */ - tL2C_LINK_STATE link_state; - - TIMER_LIST_ENT timer_entry; /* Timer list entry for timeout evt */ - UINT16 handle; /* The handle used with LM */ - UINT16 completed_packets; /* The number of conpleted packets */ - - tL2C_CCB_Q ccb_queue; /* Queue of CCBs on this LCB */ - - tL2C_CCB *p_pending_ccb; /* ccb of waiting channel during link disconnect */ - TIMER_LIST_ENT info_timer_entry; /* Timer entry for info resp timeout evt */ - TIMER_LIST_ENT upda_con_timer; /* Timer entry for update connection parametr */ - BD_ADDR remote_bd_addr; /* The BD address of the remote */ - - UINT8 link_role; /* Master or slave */ - UINT8 id; - UINT8 cur_echo_id; /* Current id value for echo request */ - tL2CA_ECHO_RSP_CB *p_echo_rsp_cb; /* Echo response callback */ - UINT16 idle_timeout; /* Idle timeout */ - BOOLEAN is_bonding; /* True - link active only for bonding */ - - UINT16 link_flush_tout; /* Flush timeout used */ - - UINT16 link_xmit_quota; /* Num outstanding pkts allowed */ - UINT16 sent_not_acked; /* Num packets sent but not acked */ - - BOOLEAN partial_segment_being_sent; /* Set TRUE when a partial segment */ - /* is being sent. */ - BOOLEAN w4_info_rsp; /* TRUE when info request is active */ - UINT8 info_rx_bits; /* set 1 if received info type */ - UINT32 peer_ext_fea; /* Peer's extended features mask */ - list_t *link_xmit_data_q; /* Link transmit data buffer queue */ - - UINT8 peer_chnl_mask[L2CAP_FIXED_CHNL_ARRAY_SIZE]; -#if (L2CAP_UCD_INCLUDED == TRUE) - UINT16 ucd_mtu; /* peer MTU on UCD */ - fixed_queue_t *ucd_out_sec_pending_q; /* Security pending outgoing UCD packet */ - fixed_queue_t *ucd_in_sec_pending_q; /* Security pending incoming UCD packet */ -#endif - - BT_HDR *p_hcit_rcv_acl; /* Current HCIT ACL buf being rcvd */ - UINT16 idle_timeout_sv; /* Save current Idle timeout */ - UINT8 acl_priority; /* L2C_PRIORITY_NORMAL or L2C_PRIORITY_HIGH */ - tL2CA_NOCP_CB *p_nocp_cb; /* Num Cmpl pkts callback */ - -#if (L2CAP_NUM_FIXED_CHNLS > 0) - tL2C_CCB *p_fixed_ccbs[L2CAP_NUM_FIXED_CHNLS]; - UINT16 disc_reason; -#endif - - tBT_TRANSPORT transport; -#if (BLE_INCLUDED == TRUE) - tBLE_ADDR_TYPE open_addr_type; /* be set by open API */ - tBLE_ADDR_TYPE ble_addr_type; - UINT16 tx_data_len; /* tx data length used in data length extension */ - fixed_queue_t *le_sec_pending_q; /* LE coc channels waiting for security check completion */ - UINT8 sec_act; -#define L2C_BLE_CONN_UPDATE_DISABLE 0x1 /* disable update connection parameters */ -#define L2C_BLE_NEW_CONN_PARAM 0x2 /* new connection parameter to be set */ -#define L2C_BLE_UPDATE_PENDING 0x4 /* waiting for connection update finished */ -#define L2C_BLE_NOT_DEFAULT_PARAM 0x8 /* not using default connection parameters */ -#define L2C_BLE_UPDATE_PARAM_FULL 0x10 /* update connection parameters full, can not update */ - UINT8 conn_update_mask; - /* cache connection parameters that wait to update */ - UINT16 waiting_update_conn_min_interval; - UINT16 waiting_update_conn_max_interval; - UINT16 waiting_update_conn_latency; - UINT16 waiting_update_conn_timeout; - /* cache parameters that is being updated */ - UINT16 updating_conn_min_interval; - UINT16 updating_conn_max_interval; - bool updating_param_flag; - /* current connection parameters that current connection is using */ - UINT16 current_used_conn_interval; - UINT16 current_used_conn_latency; - UINT16 current_used_conn_timeout; - /* connection parameters update order: - waiting_update_conn_xx -> updating_conn_xx -> current_used_conn_xx - */ -#endif - -#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) - /* each priority group is limited burst transmission */ - /* round robin service for the same priority channels */ - tL2C_RR_SERV rr_serv[L2CAP_NUM_CHNL_PRIORITY]; - UINT8 rr_pri; /* current serving priority group */ -#endif - -} tL2C_LCB; - -/* Define the L2CAP control structure -*/ -typedef struct { - UINT8 l2cap_trace_level; - UINT16 controller_xmit_window; /* Total ACL window for all links */ - - UINT16 round_robin_quota; /* Round-robin link quota */ - UINT16 round_robin_unacked; /* Round-robin unacked */ - BOOLEAN check_round_robin; /* Do a round robin check */ - - BOOLEAN is_cong_cback_context; - - tL2C_LCB lcb_pool[MAX_L2CAP_LINKS]; /* Link Control Block pool */ - tL2C_CCB ccb_pool[MAX_L2CAP_CHANNELS]; /* Channel Control Block pool */ - tL2C_RCB rcb_pool[MAX_L2CAP_CLIENTS]; /* Registration info pool */ - - tL2C_CCB *p_free_ccb_first; /* Pointer to first free CCB */ - tL2C_CCB *p_free_ccb_last; /* Pointer to last free CCB */ - - UINT8 desire_role; /* desire to be master/slave when accepting a connection */ - BOOLEAN disallow_switch; /* FALSE, to allow switch at create conn */ - UINT16 num_lm_acl_bufs; /* # of ACL buffers on controller */ - UINT16 idle_timeout; /* Idle timeout */ - - list_t *rcv_pending_q; /* Recv pending queue */ - TIMER_LIST_ENT rcv_hold_tle; /* Timer list entry for rcv hold */ - - tL2C_LCB *p_cur_hcit_lcb; /* Current HCI Transport buffer */ - UINT16 num_links_active; /* Number of links active */ - -#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) - UINT16 non_flushable_pbf; /* L2CAP_PKT_START_NON_FLUSHABLE if controller supports */ - /* Otherwise, L2CAP_PKT_START */ - BOOLEAN is_flush_active; /* TRUE if an HCI_Enhanced_Flush has been sent */ -#endif - -#if L2CAP_CONFORMANCE_TESTING == TRUE - UINT32 test_info_resp; /* Conformance testing needs a dynamic response */ -#endif - -#if (L2CAP_NUM_FIXED_CHNLS > 0) - tL2CAP_FIXED_CHNL_REG fixed_reg[L2CAP_NUM_FIXED_CHNLS]; /* Reg info for fixed channels */ -#endif - -#if (BLE_INCLUDED == TRUE) - UINT16 num_ble_links_active; /* Number of LE links active */ - BOOLEAN is_ble_connecting; - BD_ADDR ble_connecting_bda; - UINT16 controller_le_xmit_window; /* Total ACL window for all links */ - tL2C_BLE_FIXED_CHNLS_MASK l2c_ble_fixed_chnls_mask; // LE fixed channels mask - UINT16 num_lm_ble_bufs; /* # of ACL buffers on controller */ - UINT16 ble_round_robin_quota; /* Round-robin link quota */ - UINT16 ble_round_robin_unacked; /* Round-robin unacked */ - BOOLEAN ble_check_round_robin; /* Do a round robin check */ - tL2C_RCB ble_rcb_pool[BLE_MAX_L2CAP_CLIENTS]; /* Registration info pool */ -#endif - - tL2CA_ECHO_DATA_CB *p_echo_data_cb; /* Echo data callback */ - -#if (defined(L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE) && (L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE == TRUE)) - UINT16 high_pri_min_xmit_quota; /* Minimum number of ACL credit for high priority link */ -#endif /* (L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE == TRUE) */ - - UINT16 dyn_psm; -} tL2C_CB; - - - -/* Define a structure that contains the information about a connection. -** This structure is used to pass between functions, and not all the -** fields will always be filled in. -*/ -typedef struct { - BD_ADDR bd_addr; /* Remote BD address */ - UINT8 status; /* Connection status */ - UINT16 psm; /* PSM of the connection */ - UINT16 l2cap_result; /* L2CAP result */ - UINT16 l2cap_status; /* L2CAP status */ - UINT16 remote_cid; /* Remote CID */ -} tL2C_CONN_INFO; - - -typedef void (tL2C_FCR_MGMT_EVT_HDLR) (UINT8, tL2C_CCB *); - -/* The offset in a buffer that L2CAP will use when building commands. -*/ -#define L2CAP_SEND_CMD_OFFSET 0 - - -/* Number of ACL buffers to use for high priority channel -*/ -#if (!defined(L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE) || (L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE == FALSE)) -#define L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A (L2CAP_HIGH_PRI_MIN_XMIT_QUOTA) -#else -#define L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A (l2cb.high_pri_min_xmit_quota) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -/* L2CAP global data -************************************ -*/ -#if (!defined L2C_DYNAMIC_MEMORY) || (L2C_DYNAMIC_MEMORY == FALSE) -extern tL2C_CB l2cb; -#else -extern tL2C_CB *l2c_cb_ptr; -#define l2cb (*l2c_cb_ptr) -#endif - - -/* Functions provided by l2c_main.c -************************************ -*/ -void l2c_init(void); -void l2c_free(void); - -extern void l2c_process_timeout (TIMER_LIST_ENT *p_tle); -extern UINT8 l2c_data_write (UINT16 cid, BT_HDR *p_data, UINT16 flag); -extern void l2c_rcv_acl_data (BT_HDR *p_msg); -extern void l2c_process_held_packets (BOOLEAN timed_out); - -/* Functions provided by l2c_utils.c -************************************ -*/ -extern tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPORT transport); -extern BOOLEAN l2cu_start_post_bond_timer (UINT16 handle); -extern void l2cu_release_lcb (tL2C_LCB *p_lcb); -extern tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport); -extern tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle); -extern void l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding); - -extern UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb); -extern BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_after_rs); - -extern void l2cu_enqueue_ccb (tL2C_CCB *p_ccb); -extern void l2cu_dequeue_ccb (tL2C_CCB *p_ccb); -extern void l2cu_change_pri_ccb (tL2C_CCB *p_ccb, tL2CAP_CHNL_PRIORITY priority); - -extern tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid); -extern void l2cu_release_ccb (tL2C_CCB *p_ccb); -extern tL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, UINT16 local_cid); -extern tL2C_CCB *l2cu_find_ccb_by_remote_cid (tL2C_LCB *p_lcb, UINT16 remote_cid); -extern void l2cu_adj_id (tL2C_LCB *p_lcb, UINT8 adj_mask); -extern BOOLEAN l2c_is_cmd_rejected (UINT8 cmd_code, UINT8 id, tL2C_LCB *p_lcb); - -extern void l2cu_send_peer_cmd_reject (tL2C_LCB *p_lcb, UINT16 reason, - UINT8 rem_id, UINT16 p1, UINT16 p2); -extern void l2cu_send_peer_connect_req (tL2C_CCB *p_ccb); -extern void l2cu_send_peer_connect_rsp (tL2C_CCB *p_ccb, UINT16 result, UINT16 status); -extern void l2cu_send_peer_config_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern void l2cu_send_peer_config_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern void l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, UINT16 rej_len); -extern void l2cu_send_peer_disc_req (tL2C_CCB *p_ccb); -extern void l2cu_send_peer_disc_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 local_cid, UINT16 remote_cid); -extern void l2cu_send_peer_echo_req (tL2C_LCB *p_lcb, UINT8 *p_data, UINT16 data_len); -extern void l2cu_send_peer_echo_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 data_len); -extern void l2cu_send_peer_info_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT16 info_type); -extern void l2cu_reject_connection (tL2C_LCB *p_lcb, UINT16 remote_cid, UINT8 rem_id, UINT16 result); -extern void l2cu_send_peer_info_req (tL2C_LCB *p_lcb, UINT16 info_type); -extern void l2cu_set_acl_hci_header (BT_HDR *p_buf, tL2C_CCB *p_ccb); -extern void l2cu_check_channel_congestion (tL2C_CCB *p_ccb); -extern void l2cu_disconnect_chnl (tL2C_CCB *p_ccb); - -#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) -extern void l2cu_set_non_flushable_pbf(BOOLEAN); -#endif - -#if (BLE_INCLUDED == TRUE) -extern void l2cu_send_peer_ble_par_req (tL2C_LCB *p_lcb, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout); -extern void l2cu_send_peer_ble_par_rsp (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id); -#endif - -extern BOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR_OPTS *p_fcr); -extern void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb); -extern void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb); - -/* Functions provided by l2c_ucd.c -************************************ -*/ -#if (L2CAP_UCD_INCLUDED == TRUE) -void l2c_ucd_delete_sec_pending_q(tL2C_LCB *p_lcb); -void l2c_ucd_enqueue_pending_out_sec_q(tL2C_CCB *p_ccb, void *p_data); -BOOLEAN l2c_ucd_check_pending_info_req(tL2C_CCB *p_ccb); -BOOLEAN l2c_ucd_check_pending_out_sec_q(tL2C_CCB *p_ccb); -void l2c_ucd_send_pending_out_sec_q(tL2C_CCB *p_ccb); -void l2c_ucd_discard_pending_out_sec_q(tL2C_CCB *p_ccb); -BOOLEAN l2c_ucd_check_pending_in_sec_q(tL2C_CCB *p_ccb); -void l2c_ucd_send_pending_in_sec_q(tL2C_CCB *p_ccb); -void l2c_ucd_discard_pending_in_sec_q(tL2C_CCB *p_ccb); -BOOLEAN l2c_ucd_check_rx_pkts(tL2C_LCB *p_lcb, BT_HDR *p_msg); -BOOLEAN l2c_ucd_process_event(tL2C_CCB *p_ccb, UINT16 event, void *p_data); -#endif - -#if (BLE_INCLUDED == TRUE) -extern void l2cu_send_peer_ble_par_req (tL2C_LCB *p_lcb, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout); -extern void l2cu_send_peer_ble_par_rsp (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id); -extern void l2cu_reject_ble_connection (tL2C_LCB *p_lcb, UINT8 rem_id, UINT16 result); -extern void l2cu_send_peer_ble_credit_based_conn_res (tL2C_CCB *p_ccb, UINT16 result); -extern void l2cu_send_peer_ble_credit_based_conn_req (tL2C_CCB *p_ccb); -extern void l2cu_send_peer_ble_flow_control_credit(tL2C_CCB *p_ccb, UINT16 credit_value); -extern void l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB *p_ccb); - -#endif - -#if (C2H_FLOW_CONTROL_INCLUDED == TRUE) -extern UINT8 l2cu_find_completed_packets(UINT16 *handles, UINT16 *num_packets); -#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE - -extern BOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR_OPTS *p_fcr); -extern void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb); -extern void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb); - - -/* Functions provided for Broadcom Aware -**************************************** -*/ -extern BOOLEAN l2cu_check_feature_req (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 data_len); -extern void l2cu_check_feature_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 data_len); -extern void l2cu_send_feature_req (tL2C_CCB *p_ccb); - -extern tL2C_RCB *l2cu_allocate_rcb (UINT16 psm); -extern tL2C_RCB *l2cu_find_rcb_by_psm (UINT16 psm); -extern void l2cu_release_rcb (tL2C_RCB *p_rcb); -extern tL2C_RCB *l2cu_allocate_ble_rcb (UINT16 psm); -extern tL2C_RCB *l2cu_find_ble_rcb_by_psm (UINT16 psm); - - -extern UINT8 l2cu_process_peer_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern void l2cu_process_peer_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern void l2cu_process_our_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern void l2cu_process_our_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); - -extern void l2cu_device_reset (void); -extern tL2C_LCB *l2cu_find_lcb_by_state (tL2C_LINK_STATE state); -extern BOOLEAN l2cu_lcb_disconnecting (void); - -extern BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport); -extern BOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb); -extern BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb); -extern void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda); -extern void l2cu_initialize_amp_ccb (tL2C_LCB *p_lcb); -extern void l2cu_adjust_out_mps (tL2C_CCB *p_ccb); - -/* Functions provided by l2c_link.c -************************************ -*/ -extern BOOLEAN l2c_link_hci_conn_req (BD_ADDR bd_addr); -extern BOOLEAN l2c_link_hci_conn_comp (UINT8 status, UINT16 handle, BD_ADDR p_bda); -extern BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason); -extern BOOLEAN l2c_link_hci_qos_violation (UINT16 handle); -extern void l2c_link_timeout (tL2C_LCB *p_lcb); -extern void l2c_info_timeout (tL2C_LCB *p_lcb); -extern void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf); -extern void l2c_link_adjust_allocation (void); -extern void l2c_link_process_num_completed_pkts (UINT8 *p); -extern void l2c_link_process_num_completed_blocks (UINT8 controller_id, UINT8 *p, UINT16 evt_len); -extern void l2c_link_processs_num_bufs (UINT16 num_lm_acl_bufs); -extern UINT8 l2c_link_pkts_rcvd (UINT16 *num_pkts, UINT16 *handles); -extern void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status); -extern void l2c_link_sec_comp (BD_ADDR p_bda, tBT_TRANSPORT trasnport, void *p_ref_data, UINT8 status); -extern void l2c_link_segments_xmitted (BT_HDR *p_msg); -extern void l2c_pin_code_request (BD_ADDR bd_addr); -extern void l2c_link_adjust_chnl_allocation (void); - -#if (BLE_INCLUDED == TRUE) -extern void l2c_link_processs_ble_num_bufs (UINT16 num_lm_acl_bufs); -#endif - -#if L2CAP_WAKE_PARKED_LINK == TRUE -extern BOOLEAN l2c_link_check_power_mode ( tL2C_LCB *p_lcb ); -#define L2C_LINK_CHECK_POWER_MODE(x) l2c_link_check_power_mode ((x)) -#else // L2CAP_WAKE_PARKED_LINK -#define L2C_LINK_CHECK_POWER_MODE(x) (FALSE) -#endif // L2CAP_WAKE_PARKED_LINK - -#if L2CAP_CONFORMANCE_TESTING == TRUE -/* Used only for conformance testing */ -extern void l2cu_set_info_rsp_mask (UINT32 mask); -#endif - -/* Functions provided by l2c_csm.c -************************************ -*/ -extern void l2c_csm_execute (tL2C_CCB *p_ccb, UINT16 event, void *p_data); - -extern void l2c_enqueue_peer_data (tL2C_CCB *p_ccb, BT_HDR *p_buf); - - -/* Functions provided by l2c_fcr.c -************************************ -*/ -extern void l2c_fcr_cleanup (tL2C_CCB *p_ccb); -extern void l2c_fcr_proc_pdu (tL2C_CCB *p_ccb, BT_HDR *p_buf); -extern void l2c_fcr_proc_tout (tL2C_CCB *p_ccb); -extern void l2c_fcr_proc_ack_tout (tL2C_CCB *p_ccb); -extern void l2c_fcr_send_S_frame (tL2C_CCB *p_ccb, UINT16 function_code, UINT16 pf_bit); -extern BT_HDR *l2c_fcr_clone_buf (BT_HDR *p_buf, UINT16 new_offset, UINT16 no_of_bytes); -extern BOOLEAN l2c_fcr_is_flow_controlled (tL2C_CCB *p_ccb); -extern BT_HDR *l2c_fcr_get_next_xmit_sdu_seg (tL2C_CCB *p_ccb, UINT16 max_packet_length); -extern void l2c_fcr_start_timer (tL2C_CCB *p_ccb); - -/* Configuration negotiation */ -extern UINT8 l2c_fcr_chk_chan_modes (tL2C_CCB *p_ccb); -extern BOOLEAN l2c_fcr_adj_our_req_options (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern void l2c_fcr_adj_our_rsp_options (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_peer_cfg); -extern BOOLEAN l2c_fcr_renegotiate_chan(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern UINT8 l2c_fcr_process_peer_cfg_req(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern void l2c_fcr_adj_monitor_retran_timeout (tL2C_CCB *p_ccb); -extern void l2c_fcr_stop_timer (tL2C_CCB *p_ccb); -extern void l2c_fcr_free_timer (tL2C_CCB *p_ccb); -/* Functions provided by l2c_ble.c -************************************ -*/ -#if (BLE_INCLUDED == TRUE) -extern BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb); -extern void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len); -extern void l2cble_conn_comp (UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type, - UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout); -extern BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb); -extern void l2cble_notify_le_connection (BD_ADDR bda); -extern void l2c_ble_link_adjust_allocation (void); -extern void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status, UINT16 conn_interval, - UINT16 conn_latency, UINT16 conn_timeout); -extern void l2cble_get_conn_param_format_err_from_contoller(UINT8 status, UINT16 handle); - -extern void l2cble_credit_based_conn_req (tL2C_CCB *p_ccb); -extern void l2cble_credit_based_conn_res (tL2C_CCB *p_ccb, UINT16 result); -extern void l2cble_send_peer_disc_req(tL2C_CCB *p_ccb); -extern void l2cble_send_flow_control_credit(tL2C_CCB *p_ccb, UINT16 credit_value); -extern BOOLEAN l2ble_sec_access_req(BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_originator, tL2CAP_SEC_CBACK *p_callback, void *p_ref_data); - - -#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) -extern void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max, - UINT16 latency, UINT16 timeout); -#endif - -extern void l2cble_update_data_length(tL2C_LCB *p_lcb); -extern void l2cble_set_fixed_channel_tx_data_length(BD_ADDR remote_bda, UINT16 fix_cid, - UINT16 tx_mtu); -extern void l2c_send_update_conn_params_cb(tL2C_LCB *p_lcb, UINT8 status); -extern void l2cble_process_data_length_change_event(UINT16 handle, UINT16 tx_data_len, - UINT16 rx_data_len); -extern UINT32 CalConnectParamTimeout(tL2C_LCB *p_lcb); - -#endif -extern void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/tools/sdk/include/bluedroid/oi_assert.h b/tools/sdk/include/bluedroid/oi_assert.h deleted file mode 100644 index 9649f660..00000000 --- a/tools/sdk/include/bluedroid/oi_assert.h +++ /dev/null @@ -1,86 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 The Android Open Source Project - * Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef _OI_ASSERT_H -#define _OI_ASSERT_H -/** @file - This file provides macros and functions for compile-time and run-time assertions. - - When the OI_DEBUG preprocessor value is defined, the macro OI_ASSERT is compiled into - the program, providing for a runtime assertion failure check. - C_ASSERT is a macro that can be used to perform compile time checks. -*/ -/********************************************************************************** - $Revision: #1 $ -***********************************************************************************/ - - -/** \addtogroup Debugging Debugging APIs */ -/**@{*/ - -#ifdef __cplusplus -extern "C" { -#endif - - -#ifdef OI_DEBUG - -/** The macro OI_ASSERT takes a condition argument. If the asserted condition - does not evaluate to true, the OI_ASSERT macro calls the host-dependent function, - OI_AssertFail(), which reports the failure and generates a runtime error. -*/ -void OI_AssertFail(char *file, int line, char *reason); - - -#define OI_ASSERT(condition) \ - { if (!(condition)) OI_AssertFail(__FILE__, __LINE__, #condition); } - -#define OI_ASSERT_FAIL(msg) \ - { OI_AssertFail(__FILE__, __LINE__, msg); } - -#else - - -#define OI_ASSERT(condition) -#define OI_ASSERT_FAIL(msg) - -#endif - - -/** - C_ASSERT() can be used to perform many compile-time assertions: type sizes, field offsets, etc. - An assertion failure results in compile time error C2118: negative subscript. - Unfortunately, this elegant macro doesn't work with GCC, so it's all commented out - for now. Perhaps later..... -*/ - -#ifndef C_ASSERT -// #define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1] -// #define C_ASSERT(e) -#endif - - -/*****************************************************************************/ -#ifdef __cplusplus -} -#endif - -/**@}*/ - -#endif /* _OI_ASSERT_H */ - diff --git a/tools/sdk/include/bluedroid/oi_bitstream.h b/tools/sdk/include/bluedroid/oi_bitstream.h deleted file mode 100644 index c6ce59b4..00000000 --- a/tools/sdk/include/bluedroid/oi_bitstream.h +++ /dev/null @@ -1,123 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 The Android Open Source Project - * Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef _OI_BITSTREAM_H -#define _OI_BITSTREAM_H - -/********************************************************************************** - $Revision: #1 $ -***********************************************************************************/ - - -/** -@file -Function prototypes and macro definitions for manipulating input and output -bitstreams. - -@ingroup codec_internal -*/ - -/** -@addtogroup codec_internal -@{ -*/ - -#include "oi_codec_sbc_private.h" -#include "oi_stddefs.h" - -INLINE void OI_BITSTREAM_ReadInit(OI_BITSTREAM *bs, const OI_BYTE *buffer); - -INLINE void OI_BITSTREAM_WriteInit(OI_BITSTREAM *bs, OI_BYTE *buffer); - -INLINE OI_UINT32 OI_BITSTREAM_ReadUINT(OI_BITSTREAM *bs, OI_UINT bits); - -INLINE OI_UINT8 OI_BITSTREAM_ReadUINT4Aligned(OI_BITSTREAM *bs); - -INLINE OI_UINT8 OI_BITSTREAM_ReadUINT8Aligned(OI_BITSTREAM *bs); - -INLINE void OI_BITSTREAM_WriteUINT(OI_BITSTREAM *bs, - OI_UINT16 value, - OI_UINT bits); - -/* - * Use knowledge that the bitstream is aligned to optimize the write of a byte - */ -PRIVATE void OI_BITSTREAM_WriteUINT8Aligned(OI_BITSTREAM *bs, - OI_UINT8 datum); - -/* - * Use knowledge that the bitstream is aligned to optimize the write pair of nibbles - */ -PRIVATE void OI_BITSTREAM_Write2xUINT4Aligned(OI_BITSTREAM *bs, - OI_UINT8 datum1, - OI_UINT8 datum2); - -/** Internally the bitstream looks ahead in the stream. When - * OI_SBC_ReadScalefactors() goes to temporarily break the abstraction, it will - * need to know where the "logical" pointer is in the stream. - */ -#define OI_BITSTREAM_GetWritePtr(bs) ((bs)->ptr.w - 3) -#define OI_BITSTREAM_GetReadPtr(bs) ((bs)->ptr.r - 3) - -/** This is declared here as a macro because decoder.c breaks the bitsream - * encapsulation for efficiency reasons. - */ -#define OI_BITSTREAM_READUINT(result, bits, ptr, value, bitPtr) \ -do { \ - OI_ASSERT((bits) <= 16); \ - OI_ASSERT((bitPtr) < 16); \ - OI_ASSERT((bitPtr) >= 8); \ - \ - result = (value) << (bitPtr); \ - result >>= 32 - (bits); \ - \ - bitPtr += (bits); \ - while (bitPtr >= 16) { \ - value = ((value) << 8) | *ptr++; \ - bitPtr -= 8; \ - } \ - OI_ASSERT((bits == 0) || (result < (1u << (bits)))); \ -} while (0) - - -#define OI_BITSTREAM_WRITEUINT(ptr, value, bitPtr, datum, bits) \ -do {\ - bitPtr -= bits;\ - value |= datum << bitPtr;\ - \ - while (bitPtr <= 16) {\ - bitPtr += 8;\ - *ptr++ = (OI_UINT8)(value >> 24);\ - value <<= 8;\ - }\ -} while (0) - -#define OI_BITSTREAM_WRITEFLUSH(ptr, value, bitPtr) \ -do {\ - while (bitPtr < 32) {\ - bitPtr += 8;\ - *ptr++ = (OI_UINT8)(value >> 24);\ - value <<= 8;\ - }\ -} while (0) - -/** -@} -*/ - -#endif /* _OI_BITSTREAM_H */ diff --git a/tools/sdk/include/bluedroid/oi_bt_spec.h b/tools/sdk/include/bluedroid/oi_bt_spec.h deleted file mode 100644 index b98a5821..00000000 --- a/tools/sdk/include/bluedroid/oi_bt_spec.h +++ /dev/null @@ -1,229 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 The Android Open Source Project - * Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef _OI_BT_SPEC_H -#define _OI_BT_SPEC_H -/** - * @file - * - * This file contains common definitions from the Bluetooth specification. - * - */ - -/********************************************************************************** - $Revision: #1 $ -***********************************************************************************/ - -#include "oi_stddefs.h" - -/** \addtogroup Misc Miscellaneous APIs */ -/**@{*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/** The maximum number of active slaves in a piconet. */ -#define OI_BT_MAX_ACTIVE_SLAVES 7 - -/** the number of bytes in a Bluetooth device address (BD_ADDR) */ -#define OI_BD_ADDR_BYTE_SIZE 6 - -/** - * 48-bit Bluetooth device address - * - * Because 48-bit integers may not be supported on all platforms, the - * address is defined as an array of bytes. This array is big-endian, - * meaning that - * - array[0] contains bits 47-40, - * - array[1] contains bits 39-32, - * - array[2] contains bits 31-24, - * - array[3] contains bits 23-16, - * - array[4] contains bits 15-8, and - * - array[5] contains bits 7-0. - */ -typedef struct { - OI_UINT8 addr[OI_BD_ADDR_BYTE_SIZE] ; /**< Bluetooth device address represented as an array of 8-bit values */ -} OI_BD_ADDR ; - -/** - * @name Data types for working with UUIDs - * UUIDs are 16 bytes (128 bits). - * - * To avoid having to pass around 128-bit values all the time, 32-bit and 16-bit - * UUIDs are defined, along with a mapping from the shorter versions to the full - * version. - * - * @{ - */ - -/** - * 16-bit representation of a 128-bit UUID - */ -typedef OI_UINT16 OI_UUID16; - -/** - * 32-bit representation of a 128-bit UUID - */ -typedef OI_UINT32 OI_UUID32; - -/** - * number of bytes in a 128 bit UUID - */ -#define OI_BT_UUID128_SIZE 16 - -/** - * number of bytes in IPv6 style addresses - */ -#define OI_BT_IPV6ADDR_SIZE 16 - -/** - * type definition for a 128-bit UUID - * - * To simplify conversion between 128-bit UUIDs and 16-bit and 32-bit UUIDs, - * the most significant 32 bits are stored with the same endian-ness as is - * native on the target (local) device. The remainder of the 128-bit UUID is - * stored as bytes in big-endian order. - */ -typedef struct { - OI_UINT32 ms32bits; /**< most significant 32 bits of 128-bit UUID */ - OI_UINT8 base[OI_BT_UUID128_SIZE - sizeof(OI_UINT32)]; /**< remainder of 128-bit UUID, array of 8-bit values */ -} OI_UUID128; - -/** @} */ - -/** number of bytes in a link key */ -#define OI_BT_LINK_KEY_SIZE 16 - -/** - * type definition for a baseband link key - * - * Because 128-bit integers may not be supported on all platforms, we define - * link keys as an array of bytes. Unlike the Bluetooth device address, - * the link key is stored in little-endian order, meaning that - * - array[0] contains bits 0 - 7, - * - array[1] contains bits 8 - 15, - * - array[2] contains bits 16 - 23, - * - array[3] contains bits 24 - 31, - * - array[4] contains bits 32 - 39, - * - array[5] contains bits 40 - 47, - * - array[6] contains bits 48 - 55, - * - array[7] contains bits 56 - 63, - * - array[8] contains bits 64 - 71, - * - array[9] contains bits 72 - 79, - * - array[10] contains bits 80 - 87, - * - array[11] contains bits 88 - 95, - * - array[12] contains bits 96 - 103, - * - array[13] contains bits 104- 111, - * - array[14] contains bits 112- 119, and - * - array[15] contains bits 120- 127. - */ -typedef struct { - OI_UINT8 key[OI_BT_LINK_KEY_SIZE] ; /**< link key represented as an array of 8-bit values */ -} OI_LINK_KEY ; - - -/** Out-of-band data size - C and R values are 16-bytes each */ -#define OI_BT_OOB_NUM_BYTES 16 - -typedef struct { - OI_UINT8 value[OI_BT_OOB_NUM_BYTES] ; /**< same struct used for C and R values */ -} OI_OOB_DATA ; - - -/** - * link key types - */ -typedef enum { - OI_LINK_KEY_TYPE_COMBO = 0, /**< combination key */ - OI_LINK_KEY_TYPE_LOCAL_UNIT = 1, /**< local unit key */ - OI_LINK_KEY_TYPE_REMOTE_UNIT = 2, /**< remote unit key */ - OI_LINK_KEY_TYPE_DEBUG_COMBO = 3, /**< debug combination key */ - OI_LINK_KEY_TYPE_UNAUTHENTICATED = 4, /**< Unauthenticated */ - OI_LINK_KEY_TYPE_AUTHENTICATED = 5, /**< Authenticated */ - OI_LINK_KEY_TYPE_CHANGED_COMBO = 6 /**< Changed */ - -} OI_BT_LINK_KEY_TYPE ; - - -/** amount of space allocated for a PIN (personal indentification number) in bytes */ -#define OI_BT_PIN_CODE_SIZE 16 - -/** data type for a PIN (PINs are treated as strings, so endianness does not apply.) */ -typedef struct { - OI_UINT8 pin[OI_BT_PIN_CODE_SIZE] ; /**< PIN represented as an array of 8-bit values */ -} OI_PIN_CODE ; - -/** maximum number of SCO connections per device, which is 3 as of version 2.0+EDR - of the Bluetooth specification (see sec 4.3 of vol 2 part B) */ -#define OI_BT_MAX_SCO_CONNECTIONS 3 - -/** data type for clock offset */ -typedef OI_UINT16 OI_BT_CLOCK_OFFSET ; - -/** data type for a LM handle */ -typedef OI_UINT16 OI_HCI_LM_HANDLE; - -/** opaque data type for a SCO or ACL connection handle */ -typedef struct _OI_HCI_CONNECTION *OI_HCI_CONNECTION_HANDLE; - -/** data type for HCI Error Code, as defined in oi_hcispec.h */ -typedef OI_UINT8 OI_HCI_ERROR_CODE ; - -/** - * The Bluetooth device type is indicated by a 24-bit bitfield, represented as a - * 32-bit number in the stack. The bit layout and values for device class are specified - * in the file oi_bt_assigned_nos.h and in the Bluetooth "Assigned Numbers" specification - * at http://www.bluetooth.org/assigned-numbers/. - */ -typedef OI_UINT32 OI_BT_DEVICE_CLASS ; - -#define OI_BT_DEV_CLASS_FORMAT_MASK 0x000003 /**< Bits 0-1 contain format type. */ -#define OI_BT_DEV_CLASS_MINOR_DEVICE_MASK 0x0000FC /**< Bits 2-7 contain minor device class value. */ -#define OI_BT_DEV_CLASS_MAJOR_DEVICE_MASK 0x001F00 /**< Bits 8-12 contain major device class value. */ -#define OI_BT_DEV_CLASS_MAJOR_SERVICE_MASK 0xFFE000 /**< Bits 13-23 contain major service class value. */ - -/** There is currently only one device class format defined, type 00. */ -#define OI_BT_DEV_CLASS_FORMAT_TYPE 00 - -/** Bit 13 in device class indicates limited discoverability mode (GAP v2.0+EDR, section 4.1.2.2) */ -#define OI_BT_DEV_CLASS_LIMITED_DISCO_BIT BIT13 - -/** macro to test validity of the Device Class Format */ -#define OI_BT_VALID_DEVICE_CLASS_FORMAT(class) (OI_BT_DEV_CLASS_FORMAT_TYPE == ((class) & OI_BT_DEV_CLASS_FORMAT_MASK)) - -/** the time between baseband clock ticks, currently 625 microseconds (one slot) */ -#define OI_BT_TICK 625 -/** some macros to convert to/from baseband clock ticks - use no floating point! */ -#define OI_SECONDS_TO_BT_TICKS(secs) ((secs)*1600) -#define OI_BT_TICKS_TO_SECONDS(ticks) ((ticks)/1600) -#define OI_MSECS_TO_BT_TICKS(msecs) (((msecs)*8)/5) -#define OI_BT_TICKS_TO_MSECS(ticks) (((ticks)*5)/8) - -/** EIR byte order */ -#define OI_EIR_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER - - -#ifdef __cplusplus -} -#endif - -/**@}*/ - -/*****************************************************************************/ -#endif /* _OI_BT_SPEC_H */ diff --git a/tools/sdk/include/bluedroid/oi_codec_sbc.h b/tools/sdk/include/bluedroid/oi_codec_sbc.h deleted file mode 100644 index a3f7d875..00000000 --- a/tools/sdk/include/bluedroid/oi_codec_sbc.h +++ /dev/null @@ -1,484 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 The Android Open Source Project - * Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/********************************************************************************** - $Revision: #1 $ -***********************************************************************************/ - -#ifndef _OI_CODEC_SBC_CORE_H -#define _OI_CODEC_SBC_CORE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** -@file -Declarations of codec functions, data types, and macros. - -@ingroup codec_lib -*/ - -/** -@addtogroup codec_lib -@{ -*/ - -/* Non-BM3 users of of the codec must include oi_codec_sbc_bm3defs.h prior to - * including this file, or else these includes will fail because the BM3 SDK is - * not in the include path */ -#ifndef _OI_CODEC_SBC_BM3DEFS_H -#include "oi_stddefs.h" -#include "oi_status.h" -#endif - -#include - -#define SBC_MAX_CHANNELS 2 -#define SBC_MAX_BANDS 8 -#define SBC_MAX_BLOCKS 16 -#define SBC_MIN_BITPOOL 2 /**< Minimum size of the bit allocation pool used to encode the stream */ -#define SBC_MAX_BITPOOL 250 /**< Maximum size of the bit allocation pool used to encode the stream */ -#define SBC_MAX_ONE_CHANNEL_BPS 320000 -#define SBC_MAX_TWO_CHANNEL_BPS 512000 - - -#define SBC_WBS_BITRATE 62000 -#define SBC_WBS_BITPOOL 27 -#define SBC_WBS_NROF_BLOCKS 16 -#define SBC_WBS_FRAME_LEN 62 -#define SBC_WBS_SAMPLES_PER_FRAME 128 - - -#define SBC_HEADER_LEN 4 -#define SBC_MAX_FRAME_LEN (SBC_HEADER_LEN + \ - ((SBC_MAX_BANDS * SBC_MAX_CHANNELS / 2) + \ - (SBC_MAX_BANDS + SBC_MAX_BLOCKS * SBC_MAX_BITPOOL + 7)/8)) -#define SBC_MAX_SAMPLES_PER_FRAME (SBC_MAX_BANDS * SBC_MAX_BLOCKS) - -#define SBC_MAX_SCALEFACTOR_BYTES ((4*(SBC_MAX_CHANNELS * SBC_MAX_BANDS) + 7)/8) - -#define OI_SBC_SYNCWORD 0x9c -#define OI_SBC_ENHANCED_SYNCWORD 0x9d - -/**@name Sampling frequencies */ -/**@{*/ -#define SBC_FREQ_16000 0 /**< The sampling frequency is 16 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */ -#define SBC_FREQ_32000 1 /**< The sampling frequency is 32 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */ -#define SBC_FREQ_44100 2 /**< The sampling frequency is 44.1 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */ -#define SBC_FREQ_48000 3 /**< The sampling frequency is 48 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */ -/**@}*/ - -/**@name Channel modes */ -/**@{*/ -#define SBC_MONO 0 /**< The mode of the encoded channel is mono. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */ -#define SBC_DUAL_CHANNEL 1 /**< The mode of the encoded channel is dual-channel. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */ -#define SBC_STEREO 2 /**< The mode of the encoded channel is stereo. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */ -#define SBC_JOINT_STEREO 3 /**< The mode of the encoded channel is joint stereo. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */ -/**@}*/ - -/**@name Subbands */ -/**@{*/ -#define SBC_SUBBANDS_4 0 /**< The encoded stream has 4 subbands. One possible value for the @a subbands parameter of OI_CODEC_SBC_EncoderConfigure()*/ -#define SBC_SUBBANDS_8 1 /**< The encoded stream has 8 subbands. One possible value for the @a subbands parameter of OI_CODEC_SBC_EncoderConfigure() */ -/**@}*/ - -/**@name Block lengths */ -/**@{*/ -#define SBC_BLOCKS_4 0 /**< A block size of 4 blocks was used to encode the stream. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */ -#define SBC_BLOCKS_8 1 /**< A block size of 8 blocks was used to encode the stream is. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */ -#define SBC_BLOCKS_12 2 /**< A block size of 12 blocks was used to encode the stream. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */ -#define SBC_BLOCKS_16 3 /**< A block size of 16 blocks was used to encode the stream. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */ -/**@}*/ - -/**@name Bit allocation methods */ -/**@{*/ -#define SBC_LOUDNESS 0 /**< The bit allocation method. One possible value for the @a loudness parameter of OI_CODEC_SBC_EncoderConfigure() */ -#define SBC_SNR 1 /**< The bit allocation method. One possible value for the @a loudness parameter of OI_CODEC_SBC_EncoderConfigure() */ -/**@}*/ - -/** -@} - -@addtogroup codec_internal -@{ -*/ - -typedef OI_INT16 SBC_BUFFER_T; - - -/** Used internally. */ -typedef struct { - OI_UINT16 frequency; /**< The sampling frequency. Input parameter. */ - OI_UINT8 freqIndex; - - OI_UINT8 nrof_blocks; /**< The block size used to encode the stream. Input parameter. */ - OI_UINT8 blocks; - - - OI_UINT8 nrof_subbands; /**< The number of subbands of the encoded stream. Input parameter. */ - OI_UINT8 subbands; - - OI_UINT8 mode; /**< The mode of the encoded channel. Input parameter. */ - OI_UINT8 nrof_channels; /**< The number of channels of the encoded stream. */ - - OI_UINT8 alloc; /**< The bit allocation method. Input parameter. */ - OI_UINT8 bitpool; /**< Size of the bit allocation pool used to encode the stream. Input parameter. */ - OI_UINT8 crc; /**< Parity check byte used for error detection. */ - OI_UINT8 join; /**< Whether joint stereo has been used. */ - OI_UINT8 enhanced; - OI_UINT8 min_bitpool; /**< This value is only used when encoding. SBC_MAX_BITPOOL if variable - bitpools are disallowed, otherwise the minimum bitpool size that will - be used by the bit allocator. */ - - OI_UINT8 cachedInfo; /**< Information about the previous frame */ -} OI_CODEC_SBC_FRAME_INFO; - -/** Used internally. */ -typedef struct { - const OI_CHAR *codecInfo; - OI_CODEC_SBC_FRAME_INFO frameInfo; - OI_INT8 scale_factor[SBC_MAX_CHANNELS * SBC_MAX_BANDS]; - OI_UINT32 frameCount; - OI_INT32 *subdata; - - SBC_BUFFER_T *filterBuffer[SBC_MAX_CHANNELS]; - OI_INT32 filterBufferLen; - OI_UINT filterBufferOffset; - - union { - OI_UINT8 uint8[SBC_MAX_CHANNELS * SBC_MAX_BANDS]; - OI_UINT32 uint32[SBC_MAX_CHANNELS * SBC_MAX_BANDS / 4]; - } bits; - OI_UINT8 maxBitneed; /**< Running maximum bitneed */ - OI_BYTE formatByte; - OI_UINT8 pcmStride; - OI_UINT8 maxChannels; -} OI_CODEC_SBC_COMMON_CONTEXT; - - -/* - * A smaller value reduces RAM usage at the expense of increased CPU usage. Values in the range - * 27..50 are recommended, beyond 50 there is a diminishing return on reduced CPU usage. - */ -#define SBC_CODEC_MIN_FILTER_BUFFERS 16 -#define SBC_CODEC_FAST_FILTER_BUFFERS 27 - -/* Expands to the number of OI_UINT32s needed to ensure enough memory to encode - * or decode streams of numChannels channels, using numBuffers buffers. - * Example: - * OI_UINT32 decoderData[CODEC_DATA_WORDS(SBC_MAX_CHANNELS, SBC_DECODER_FAST_SYNTHESIS_BUFFERS)]; - * */ -#define CODEC_DATA_WORDS(numChannels, numBuffers) \ - ((\ - (sizeof(OI_INT32) * SBC_MAX_BLOCKS * numChannels * SBC_MAX_BANDS) \ - + (sizeof(SBC_BUFFER_T) * SBC_MAX_CHANNELS * SBC_MAX_BANDS * numBuffers) \ - + (sizeof (OI_UINT32) - 1) \ - ) / sizeof(OI_UINT32)) - -/** Opaque parameter to decoding functions; maintains decoder context. */ -typedef struct { - OI_CODEC_SBC_COMMON_CONTEXT common; - OI_UINT8 limitFrameFormat; /* Boolean, set by OI_CODEC_SBC_DecoderLimit() */ - OI_UINT8 restrictSubbands; - OI_UINT8 enhancedEnabled; - OI_UINT8 bufferedBlocks; -} OI_CODEC_SBC_DECODER_CONTEXT; - -typedef struct { - OI_UINT32 data[CODEC_DATA_WORDS(1, SBC_CODEC_FAST_FILTER_BUFFERS)]; -} OI_CODEC_SBC_CODEC_DATA_MONO; - -typedef struct { - OI_UINT32 data[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)]; -} OI_CODEC_SBC_CODEC_DATA_STEREO; - -/** -@} - -@addtogroup codec_lib -@{ -*/ - -/** - * This function resets the decoder. The context must be reset when - * changing streams, or if the following stream parameters change: - * number of subbands, stereo mode, or frequency. - * - * @param context Pointer to the decoder context structure to be reset. - * - * @param enhanced If true, enhanced SBC operation is enabled. If enabled, - * the codec will recognize the alternative syncword for - * decoding an enhanced SBC stream. Enhancements should not - * be enabled unless the stream is known to be generated - * by an enhanced encoder, or there is a small possibility - * for decoding glitches if synchronization were to be lost. - */ -OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context, - OI_UINT32 *decoderData, - OI_UINT32 decoderDataBytes, - OI_UINT8 maxChannels, - OI_UINT8 pcmStride, - OI_BOOL enhanced); - -/** - * This function restricts the kind of SBC frames that the Decoder will - * process. Its use is optional. If used, it must be called after - * calling OI_CODEC_SBC_DecoderReset(). After it is called, any calls - * to OI_CODEC_SBC_DecodeFrame() with SBC frames that do not conform - * to the Subband and Enhanced SBC setting will be rejected with an - * OI_STATUS_INVALID_PARAMETERS return. - * - * @param context Pointer to the decoder context structure to be limited. - * - * @param enhanced If true, all frames passed to the decoder must be - * Enhanced SBC frames. If false, all frames must be - * standard SBC frames. - * - * @param subbands May be set to SBC_SUBBANDS_4 or SBC_SUBBANDS_8. All - * frames passed to the decoder must be encoded with - * the requested number of subbands. - * - */ -OI_STATUS OI_CODEC_SBC_DecoderLimit(OI_CODEC_SBC_DECODER_CONTEXT *context, - OI_BOOL enhanced, - OI_UINT8 subbands); - -/** - * This function sets the decoder parameters for a raw decode where the decoder parameters are not - * available in the sbc data stream. OI_CODEC_SBC_DecoderReset must be called - * prior to calling this function. - * - * @param context Decoder context structure. This must be the context must be - * used each time a frame is decoded. - * - * @param enhanced Set to TRUE to enable Qualcomm proprietary - * quality enhancements. - * - * @param frequency One of SBC_FREQ_16000, SBC_FREQ_32000, SBC_FREQ_44100, - * SBC_FREQ_48000 - * - * @param mode One of SBC_MONO, SBC_DUAL_CHANNEL, SBC_STEREO, - * SBC_JOINT_STEREO - * - * @param subbands One of SBC_SUBBANDS_4, SBC_SUBBANDS_8 - * - * @param blocks One of SBC_BLOCKS_4, SBC_BLOCKS_8, SBC_BLOCKS_12, - * SBC_BLOCKS_16 - * - * @param alloc One of SBC_LOUDNESS, SBC_SNR - * - * @param maxBitpool The maximum bitpool size for this context - */ -OI_STATUS OI_CODEC_SBC_DecoderConfigureRaw(OI_CODEC_SBC_DECODER_CONTEXT *context, - OI_BOOL enhanced, - OI_UINT8 frequency, - OI_UINT8 mode, - OI_UINT8 subbands, - OI_UINT8 blocks, - OI_UINT8 alloc, - OI_UINT8 maxBitpool); - -/** - * Decode one SBC frame. The frame has no header bytes. The context must have been previously - * initialized by calling OI_CODEC_SBC_DecoderConfigureRaw(). - * - * @param context Pointer to a decoder context structure. The same context - * must be used each time when decoding from the same stream. - * - * @param bitpool The actual bitpool size for this frame. Must be <= the maxbitpool specified - * in the call to OI_CODEC_SBC_DecoderConfigureRaw(), - * - * @param frameData Address of a pointer to the SBC data to decode. This - * value will be updated to point to the next frame after - * successful decoding. - * - * @param frameBytes Pointer to a UINT32 containing the number of available - * bytes of frame data. This value will be updated to reflect - * the number of bytes remaining after a decoding operation. - * - * @param pcmData Address of an array of OI_INT16 pairs, which will be - * populated with the decoded audio data. This address - * is not updated. - * - * @param pcmBytes Pointer to a UINT32 in/out parameter. On input, it - * should contain the number of bytes available for pcm - * data. On output, it will contain the number of bytes - * written. Note that this differs from the semantics of - * frameBytes. - */ -OI_STATUS OI_CODEC_SBC_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context, - OI_UINT8 bitpool, - const OI_BYTE **frameData, - OI_UINT32 *frameBytes, - OI_INT16 *pcmData, - OI_UINT32 *pcmBytes); - -/** - * Decode one SBC frame. - * - * @param context Pointer to a decoder context structure. The same context - * must be used each time when decoding from the same stream. - * - * @param frameData Address of a pointer to the SBC data to decode. This - * value will be updated to point to the next frame after - * successful decoding. - * - * @param frameBytes Pointer to a UINT32 containing the number of available - * bytes of frame data. This value will be updated to reflect - * the number of bytes remaining after a decoding operation. - * - * @param pcmData Address of an array of OI_INT16 pairs, which will be - * populated with the decoded audio data. This address - * is not updated. - * - * @param pcmBytes Pointer to a UINT32 in/out parameter. On input, it - * should contain the number of bytes available for pcm - * data. On output, it will contain the number of bytes - * written. Note that this differs from the semantics of - * frameBytes. - */ -OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context, - const OI_BYTE **frameData, - OI_UINT32 *frameBytes, - OI_INT16 *pcmData, - OI_UINT32 *pcmBytes); - -/** - * Calculate the number of SBC frames but don't decode. CRC's are not checked, - * but the Sync word is found prior to count calculation. - * - * @param frameData Pointer to the SBC data. - * - * @param frameBytes Number of bytes avaiable in the frameData buffer - * - */ -OI_UINT8 OI_CODEC_SBC_FrameCount(OI_BYTE *frameData, - OI_UINT32 frameBytes); - -/** - * Analyze an SBC frame but don't do the decode. - * - * @param context Pointer to a decoder context structure. The same context - * must be used each time when decoding from the same stream. - * - * @param frameData Address of a pointer to the SBC data to decode. This - * value will be updated to point to the next frame after - * successful decoding. - * - * @param frameBytes Pointer to a UINT32 containing the number of available - * bytes of frame data. This value will be updated to reflect - * the number of bytes remaining after a decoding operation. - * - */ -OI_STATUS OI_CODEC_SBC_SkipFrame(OI_CODEC_SBC_DECODER_CONTEXT *context, - const OI_BYTE **frameData, - OI_UINT32 *frameBytes); - -/* Common functions */ - -/** - Calculate the frame length. - - @param frame The frame whose length to calculate - - @return the length of an individual encoded frame in - bytes - */ -OI_UINT16 OI_CODEC_SBC_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame); - - -/** - * Calculate the maximum bitpool size that fits within a given frame length. - * - * @param frame The frame to calculate the bitpool size for - * @param frameLen The frame length to fit the bitpool to - * - * @return the maximum bitpool that will fit in the specified frame length - */ -OI_UINT16 OI_CODEC_SBC_CalculateBitpool(OI_CODEC_SBC_FRAME_INFO *frame, - OI_UINT16 frameLen); - -/** - Calculate the bit rate. - - @param frame The frame whose bit rate to calculate - - @return the approximate bit rate in bits per second, - assuming that stream parameters are constant - */ -OI_UINT32 OI_CODEC_SBC_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame); - -/** - Calculate decoded audio data length for one frame. - - @param frame The frame whose audio data length to calculate - - @return length of decoded audio data for a - single frame, in bytes - */ -OI_UINT16 OI_CODEC_SBC_CalculatePcmBytes(OI_CODEC_SBC_COMMON_CONTEXT *common); - -/** - * Get the codec version text. - * - * @return pointer to text string containing codec version text - * - */ -OI_CHAR *OI_CODEC_Version(void); - - -/** -@} - -@addtogroup codec_internal -@{ -*/ - -extern const OI_CHAR *const OI_CODEC_SBC_FreqText[]; -extern const OI_CHAR *const OI_CODEC_SBC_ModeText[]; -extern const OI_CHAR *const OI_CODEC_SBC_SubbandsText[]; -extern const OI_CHAR *const OI_CODEC_SBC_BlocksText[]; -extern const OI_CHAR *const OI_CODEC_SBC_AllocText[]; - -/** -@} - -@addtogroup codec_lib -@{ -*/ - -#ifdef OI_DEBUG -void OI_CODEC_SBC_DumpConfig(OI_CODEC_SBC_FRAME_INFO *frameInfo); -#else -#define OI_CODEC_SBC_DumpConfig(f) -#endif - -/** -@} -*/ - -#ifdef __cplusplus -} -#endif - - -#endif /* _OI_CODEC_SBC_CORE_H */ - - diff --git a/tools/sdk/include/bluedroid/oi_codec_sbc_private.h b/tools/sdk/include/bluedroid/oi_codec_sbc_private.h deleted file mode 100644 index 4e389761..00000000 --- a/tools/sdk/include/bluedroid/oi_codec_sbc_private.h +++ /dev/null @@ -1,229 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 The Android Open Source Project - * Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef _OI_CODEC_SBC_PRIVATE_H -#define _OI_CODEC_SBC_PRIVATE_H - -/********************************************************************************** - $Revision: #1 $ -***********************************************************************************/ - -/** -@file -Function prototypes and macro definitions used internally by the codec. - -@ingroup codec_internal -*/ - -/** -@addtogroup codec_internal -@{ -*/ - -#ifdef USE_RESTRICT_KEYWORD -#define RESTRICT restrict -#else -#define RESTRICT -#endif - -#ifdef CODEC_DEBUG -#include -#define ERROR(x) do { printf x; printf("\n"); } while (0) -#else -#define ERROR(x) -#endif - -#ifdef TRACE_EXECUTION -#define TRACE(x) do { printf x; printf("\n"); } while (0) -#else -#define TRACE(x) -#endif - -#ifndef PRIVATE -#define PRIVATE -#endif - -#ifndef INLINE -#define INLINE -#endif - -#include "oi_assert.h" -#include "oi_codec_sbc.h" - -#ifndef OI_SBC_SYNCWORD -#define OI_SBC_SYNCWORD 0x9c -#endif - -#ifndef DIVIDE -#define DIVIDE(a, b) ((a) / (b)) -#endif - -typedef union { - OI_UINT8 uint8[SBC_MAX_BANDS]; - OI_UINT32 uint32[SBC_MAX_BANDS / 4]; -} BITNEED_UNION1; - -typedef union { - OI_UINT8 uint8[2 * SBC_MAX_BANDS]; - OI_UINT32 uint32[2 * SBC_MAX_BANDS / 4]; -} BITNEED_UNION2; - -static const OI_UINT16 freq_values[] = { 16000, 32000, 44100, 48000 }; -static const OI_UINT8 block_values[] = { 4, 8, 12, 16 }; -static const OI_UINT8 channel_values[] = { 1, 2, 2, 2 }; -static const OI_UINT8 band_values[] = { 4, 8 }; - - -#define TEST_MODE_SENTINEL "OINA" -#define TEST_MODE_SENTINEL_LENGTH 4 - -/** Used internally. */ -typedef struct { - union { - const OI_UINT8 *r; - OI_UINT8 *w; - } ptr; - OI_UINT32 value; - OI_UINT bitPtr; -} OI_BITSTREAM; - - -#define VALID_INT16(x) (((x) >= OI_INT16_MIN) && ((x) <= OI_INT16_MAX)) -#define VALID_INT32(x) (((x) >= OI_INT32_MIN) && ((x) <= OI_INT32_MAX)) - -#define DCTII_8_SHIFT_IN 0 -#define DCTII_8_SHIFT_OUT 16-DCTII_8_SHIFT_IN - -#define DCTII_8_SHIFT_0 (DCTII_8_SHIFT_OUT) -#define DCTII_8_SHIFT_1 (DCTII_8_SHIFT_OUT) -#define DCTII_8_SHIFT_2 (DCTII_8_SHIFT_OUT) -#define DCTII_8_SHIFT_3 (DCTII_8_SHIFT_OUT) -#define DCTII_8_SHIFT_4 (DCTII_8_SHIFT_OUT) -#define DCTII_8_SHIFT_5 (DCTII_8_SHIFT_OUT) -#define DCTII_8_SHIFT_6 (DCTII_8_SHIFT_OUT-1) -#define DCTII_8_SHIFT_7 (DCTII_8_SHIFT_OUT-2) - -#define DCT_SHIFT 15 - -#define DCTIII_4_SHIFT_IN 2 -#define DCTIII_4_SHIFT_OUT 15 - -#define DCTIII_8_SHIFT_IN 3 -#define DCTIII_8_SHIFT_OUT 14 - -OI_UINT computeBitneed(OI_CODEC_SBC_COMMON_CONTEXT *common, - OI_UINT8 *bitneeds, - OI_UINT ch, - OI_UINT *preferredBitpool); - -void oneChannelBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common, - BITNEED_UNION1 *bitneeds, - OI_UINT ch, - OI_UINT bitcount); - - -OI_INT adjustToFitBitpool(const OI_UINT bitpool, - OI_UINT32 *bitneeds, - const OI_UINT subbands, - OI_UINT bitcount, - OI_UINT *excess); - -INLINE OI_INT allocAdjustedBits(OI_UINT8 *dest, - OI_INT bits, - OI_INT excess); - -INLINE OI_INT allocExcessBits(OI_UINT8 *dest, - OI_INT excess); - -PRIVATE OI_UINT32 internal_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame); - -PRIVATE OI_UINT16 internal_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame); - -void monoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common); - -typedef void (*BIT_ALLOC)(OI_CODEC_SBC_COMMON_CONTEXT *common); - -PRIVATE OI_STATUS internal_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context, - OI_UINT8 bitpool, - const OI_BYTE **frameData, - OI_UINT32 *frameBytes, - OI_INT16 *pcmData, - OI_UINT32 *pcmBytes); - -INLINE OI_STATUS internal_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context, - OI_UINT32 *decoderData, - OI_UINT32 decoderDataBytes, - OI_BYTE maxChannels, - OI_BYTE pcmStride, - OI_BOOL enhanced); - -INLINE OI_UINT16 OI_SBC_CalculateFrameAndHeaderlen(OI_CODEC_SBC_FRAME_INFO *frame, OI_UINT *headerLen_); - -PRIVATE OI_UINT32 OI_SBC_MaxBitpool(OI_CODEC_SBC_FRAME_INFO *frame); - -PRIVATE void OI_SBC_ComputeBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *frame); -PRIVATE OI_UINT8 OI_SBC_CalculateChecksum(OI_CODEC_SBC_FRAME_INFO *frame, OI_BYTE const *data); - -/* Transform functions */ -PRIVATE void shift_buffer(SBC_BUFFER_T *dest, SBC_BUFFER_T *src, OI_UINT wordCount); -PRIVATE void cosineModulateSynth4(SBC_BUFFER_T *RESTRICT out, OI_INT32 const *RESTRICT in); -PRIVATE void SynthWindow40_int32_int32_symmetry_with_sum(OI_INT16 *pcm, SBC_BUFFER_T buffer[80], OI_UINT strideShift); - -INLINE void dct3_4(OI_INT32 *RESTRICT out, OI_INT32 const *RESTRICT in); -PRIVATE void analyze4_generated(SBC_BUFFER_T analysisBuffer[RESTRICT 40], - OI_INT16 *pcm, - OI_UINT strideShift, - OI_INT32 subband[4]); - -INLINE void dct3_8(OI_INT32 *RESTRICT out, OI_INT32 const *RESTRICT in); - -PRIVATE void analyze8_generated(SBC_BUFFER_T analysisBuffer[RESTRICT 80], - OI_INT16 *pcm, - OI_UINT strideShift, - OI_INT32 subband[8]); - -#ifdef SBC_ENHANCED -PRIVATE void analyze8_enhanced_generated(SBC_BUFFER_T analysisBuffer[RESTRICT 112], - OI_INT16 *pcm, - OI_UINT strideShift, - OI_INT32 subband[8]); -#endif - -/* Decoder functions */ - -INLINE void OI_SBC_ReadHeader(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *data); -PRIVATE void OI_SBC_ReadScalefactors(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *b, OI_BITSTREAM *bs); -PRIVATE void OI_SBC_ReadSamples(OI_CODEC_SBC_DECODER_CONTEXT *common, OI_BITSTREAM *ob); -PRIVATE void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_DECODER_CONTEXT *common, OI_BITSTREAM *global_bs); -PRIVATE void OI_SBC_SynthFrame(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT start_block, OI_UINT nrof_blocks); -INLINE OI_INT32 OI_SBC_Dequant(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits); -PRIVATE OI_BOOL OI_SBC_ExamineCommandPacket(OI_CODEC_SBC_DECODER_CONTEXT *context, const OI_BYTE *data, OI_UINT32 len); -PRIVATE void OI_SBC_GenerateTestSignal(OI_INT16 pcmData[][2], OI_UINT32 sampleCount); - -PRIVATE void OI_SBC_ExpandFrameFields(OI_CODEC_SBC_FRAME_INFO *frame); -PRIVATE OI_STATUS OI_CODEC_SBC_Alloc(OI_CODEC_SBC_COMMON_CONTEXT *common, - OI_UINT32 *codecDataAligned, - OI_UINT32 codecDataBytes, - OI_UINT8 maxChannels, - OI_UINT8 pcmStride); -/** -@} -*/ - -#endif /* _OI_CODEC_SBC_PRIVATE_H */ - diff --git a/tools/sdk/include/bluedroid/oi_common.h b/tools/sdk/include/bluedroid/oi_common.h deleted file mode 100644 index c4169f93..00000000 --- a/tools/sdk/include/bluedroid/oi_common.h +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 The Android Open Source Project - * Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef _OI_COMMON_H -#define _OI_COMMON_H -/** - * @file - * - * This file is used to group commonly used BLUEmagic 3.0 software - * header files. - * - * This file should be included in application source code along with the header - * files for the specific modules of the protocol stack being used. - */ - -/********************************************************************************** - $Revision: #1 $ -***********************************************************************************/ - -#include "oi_bt_spec.h" -#include "oi_stddefs.h" -#include "oi_status.h" -#include "oi_time.h" -#include "oi_osinterface.h" - - -/*****************************************************************************/ -#endif /* _OI_COMMON_H */ diff --git a/tools/sdk/include/bluedroid/oi_cpu_dep.h b/tools/sdk/include/bluedroid/oi_cpu_dep.h deleted file mode 100644 index dfa52c16..00000000 --- a/tools/sdk/include/bluedroid/oi_cpu_dep.h +++ /dev/null @@ -1,505 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 The Android Open Source Project - * Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef _OI_CPU_DEP_H -#define _OI_CPU_DEP_H -/** - * @file - * This file contains definitions for characteristics of the target CPU and - * compiler, including primitive data types and endianness. - * - * This file defines the byte order and primitive data types for various - * CPU families. The preprocessor symbol 'CPU' must be defined to be an - * appropriate value or this header will generate a compile-time error. - * - * @note The documentation for this header file uses the x86 family of processors - * as an illustrative example for CPU/compiler-dependent data type definitions. - * Go to the source code of this header file to see the details of primitive type - * definitions for each platform. - * - * Additional information is available in the @ref data_types_docpage section. - */ - -/********************************************************************************** - $Revision: #1 $ -***********************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -/** \addtogroup Misc Miscellaneous APIs */ -/**@{*/ - -/** @name Definitions indicating family of target OI_CPU_TYPE - * @{ - */ - -#define OI_CPU_X86 1 /**< x86 processor family */ -#define OI_CPU_ARM 2 /**< ARM processor family. - @deprecated Use #OI_CPU_ARM7_LEND or - #OI_CPU_ARM7_BEND. */ -#define OI_CPU_ARC 3 /**< ARC processor family. - @deprecated Use #OI_CPU_ARC_LEND or - #OI_CPU_ARC_BEND. */ -#define OI_CPU_SH3 4 /**< Hitachi SH-3 processor family */ -#define OI_CPU_H8 5 /**< Hitachi H8 processor family */ -#define OI_CPU_MIPS 6 /**< MIPS processor family */ -#define OI_CPU_SPARC 7 /**< SPARC processor family */ -#define OI_CPU_M68000 8 /**< Motorola M68000 processor family */ -#define OI_CPU_PPC 9 /**< PowerPC (PPC) processor family */ -#define OI_CPU_SH4_7750 10 /**< Hitachi SH7750 series in SH-4 processor family */ -#define OI_CPU_SH2 11 /**< Hitachi SH-2 processor family */ -#define OI_CPU_ARM7_LEND 12 /**< ARM7, little-endian */ -#define OI_CPU_ARM7_BEND 13 /**< ARM7, big-endian */ -#define OI_CPU_GDM1202 14 /**< GCT GDM1202 */ -#define OI_CPU_ARC_LEND 15 /**< ARC processor family, little-endian */ -#define OI_CPU_ARC_BEND 16 /**< ARC processor family, big-endian */ -#define OI_CPU_M30833F 17 /**< Mitsubishi M308 processor family */ -#define OI_CPU_CR16C 18 /**< National Semiconductor 16 bit processor family */ -#define OI_CPU_M64111 19 /**< Renesas M64111 processor (M32R family) */ -#define OI_CPU_ARMV5_LEND 20 //*< ARM5, little-endian */ - -#define OI_CPU_TYPE 12 - -#ifndef OI_CPU_TYPE -#error "OI_CPU_TYPE type not defined" -#endif - -/**@}*/ - - -/** @name Definitions indicating byte-wise endianness of target CPU - * @{ - */ - -#define OI_BIG_ENDIAN_BYTE_ORDER 0 /**< Multiple-byte values are stored in memory beginning with the most significant byte at the lowest address. */ -#define OI_LITTLE_ENDIAN_BYTE_ORDER 1 /**< Multiple-byte values are stored in memory beginning with the least significant byte at the lowest address. */ - -/**@}*/ - - -/** @name CPU/compiler-independent primitive data type definitions - * @{ - */ - -typedef int OI_BOOL; /**< Boolean values use native integer data type for target CPU. */ -typedef int OI_INT; /**< Integer values use native integer data type for target CPU. */ -typedef unsigned int OI_UINT; /**< Unsigned integer values use native unsigned integer data type for target CPU. */ -typedef unsigned char OI_BYTE; /**< Raw bytes type uses native character data type for target CPU. */ - -/**@}*/ - - - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_X86 - -#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER /**< x86 platform byte ordering is little-endian */ - -/** @name CPU/compiler-dependent primitive data type definitions for x86 processor family - * @{ - */ -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for x86 processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for x86 processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for x86 processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for x86 processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for x86 processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for x86 processor. */ - -typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ - -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_ARM -/* This CPU type is deprecated (removed from use). Instead, use OI_CPU_ARM7_LEND or OI_CPU_ARM7_BEND for - little-endian or big-endian configurations of the ARM7, respectively. */ -#error OI_CPU_ARM is deprecated -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_ARC -/* This CPU type is deprecated (removed from use). Instead, use OI_CPU_ARC_LEND or OI_CPU_ARC_BEND for - little-endian or big-endian configurations of the ARC, respectively. */ -#error OI_CPU_ARC is deprecated -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_SH3 -/* The Hitachi SH C compiler defines _LIT or _BIG, depending on the endianness - specified to the compiler on the command line. */ -#if defined(_LIT) -#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER /**< If _LIT is defined, SH-3 platform byte ordering is little-endian. */ -#elif defined(_BIG) -#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER /**< If _BIG is defined, SH-3 platform byte ordering is big-endian. */ -#else -#error SH compiler endianness undefined -#endif - -/** @name CPU/compiler-dependent primitive data type definitions for SH-3 processor family - * @{ - */ - -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for SH-3 processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for SH-3 processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for SH-3 processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for SH-3 processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for SH-3 processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for SH-3 processor. */ - -typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ - -#endif -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_SH2 - -#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER /**< SH-2 platform byte ordering is big-endian. */ - -/** @name CPU/compiler-dependent primitive data type definitions for SH-2 processor family - * @{ - */ - -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for SH-2 processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for SH-2 processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for SH-2 processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for SH-2 processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for SH-2 processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for SH-2 processor. */ - -typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ - -#endif -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_H8 -#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER -#error basic types not defined -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_MIPS -#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER -/** @name CPU/compiler-dependent primitive data type definitions for MIPS processor family - * @{ - */ -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */ - -typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ - -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_SPARC -#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER -#error basic types not defined -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_M68000 -#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER /**< M68000 platform byte ordering is big-endian. */ - -/** @name CPU/compiler-dependent primitive data type definitions for M68000 processor family - * @{ - */ - -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for M68000 processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for M68000 processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for M68000 processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for M68000 processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for M68000 processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for M68000 processor. */ - -typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ - -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_PPC -#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER - - -/** @name CPU/compiler-dependent primitive data type definitions for PPC 8XX processor family - * @{ - */ - -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for PPC8XX processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for PPC8XX processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for PPC8XX processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for PPC8XX processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for PPC8XX processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for PPC8XX processor. */ - -typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ - -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_SH4_7750 -#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER /**< SH7750 platform byte ordering is big-endian. */ - -/** @name CPU/compiler-dependent primitive data type definitions for SH7750 processor series of the SH-4 processor family - * @{ - */ - -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for SH7750 SH-4 processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for SH7750 SH-4 processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for SH7750 SH-4 processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for SH7750 SH-4 processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for SH7750 SH-4 processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for SH7750 SH-4 processor. */ - -typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ - -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_ARM7_LEND -#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER - -/** @name little-endian CPU/compiler-dependent primitive data type definitions for the ARM7 processor family - * @{ - */ - -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */ - -typedef void *OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ - -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_ARM7_BEND -#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER -/** @name big-endian CPU/compiler-dependent primitive data type definitions for the ARM7 processor family - * @{ - */ -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */ - -typedef void *OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ - -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_GDM1202 -#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER - -typedef signed char OI_INT8; /**< 8-bit signed integer. */ -typedef signed short OI_INT16; /**< 16-bit signed integer. */ -typedef signed long OI_INT32; /**< 32-bit signed integer. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer. */ - -typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_ARC_LEND - -#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER - -/** @name CPU/compiler-dependent primitive data type definitions for ARC processor family - * @{ - */ - -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARC processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARC processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARC processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARC processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARC processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARC processor. */ - -typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_ARC_BEND - -#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER - -/** @name CPU/compiler-dependent primitive data type definitions for ARC processor family - * @{ - */ - -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARC processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARC processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARC processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARC processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARC processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARC processor. */ - -typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_M30833F - -#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER - -/** @name CPU/compiler-dependent primitive data type definitions for Mitsubishi M308 processor family - * @{ - */ - -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for M308 processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for M308 processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for M308 processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for M308 processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for M308 processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for M308 processor. */ - -typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_CR16C - -#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER - -/** @name CPU/compiler-dependent primitive data type definitions for National Semicnductor processor family - * @{ - */ - -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for CR16C processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for CR16C processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for CR16C processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for CR16C processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for CR16C processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for CR16C processor. */ - -typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_M64111 - -#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER - -/** @name CPU/compiler-dependent primitive data type definitions for Renesas M32R processor family - * @{ - */ - -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for M64111 processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for M64111 processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for M64111 processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for M64111 processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for M64111 processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for M64111 processor. */ - -typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ -#endif - -/*********************************************************************************/ - -#if OI_CPU_TYPE==OI_CPU_ARMV5_LEND -#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER - -/** @name little-endian CPU/compiler-dependent primitive data type definitions for the ARM7 processor family - * @{ - */ - -typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */ -typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */ -typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */ -typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */ -typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */ -typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */ - -typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */ - -/**@}*/ - -#endif - -/*********************************************************************************/ - - -#ifndef OI_CPU_BYTE_ORDER -#error "Byte order (endian-ness) not defined" -#endif - - -/**@}*/ - -#ifdef __cplusplus -} -#endif - -/*********************************************************************************/ -#endif /* _OI_CPU_DEP_H */ diff --git a/tools/sdk/include/bluedroid/oi_modules.h b/tools/sdk/include/bluedroid/oi_modules.h deleted file mode 100644 index 7784212a..00000000 --- a/tools/sdk/include/bluedroid/oi_modules.h +++ /dev/null @@ -1,171 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 The Android Open Source Project - * Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef _OI_MODULES_H -#define _OI_MODULES_H -/** - * @file - * - * Enumeration type defining the inidivual stack components. - * - */ - -/********************************************************************************** - $Revision: #1 $ -***********************************************************************************/ - - -/** \addtogroup Misc Miscellaneous APIs */ -/**@{*/ - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * This enumeration lists constants for referencing the components of - * the BLUEmagic 3.0 protocol stack, profiles, and other functionalities. - * - * In order to distinguish types of modules, items are grouped with markers to - * delineate start and end of the groups - * - * The module type is used for various purposes: - * identification in debug print statements - * access to initialization flags - * access to the configuration table - */ - -typedef enum { - /* profiles and protocols --> Updates to oi_debug.c and oi_config_table.c */ - - /* XX --> Keep Enum values up-to-date! */ - OI_MODULE_AT, /**< 00 AT command processing */ - OI_MODULE_A2DP, /**< 01 Advanced Audio Distribution Profile */ - OI_MODULE_AVCTP, /**< 02 Audio-Visual Control Transport Profile */ - OI_MODULE_AVDTP, /**< 03 Audio-Visual Distribution Protocol */ - OI_MODULE_AVRCP, /**< 04 Audio-Visual Remote Control Profile */ - OI_MODULE_BIP_CLI, /**< 05 Basic Imaging Profile protocol client */ - OI_MODULE_BIP_SRV, /**< 06 Basic Imaging Profile protocol server */ - OI_MODULE_BNEP, /**< 07 Bluetooth Network Encapsulation Protocol */ - OI_MODULE_BPP_SENDER, /**< 08 Basic Printing Profile */ - OI_MODULE_BPP_PRINTER, /**< 09 Basic Printing Profile */ - OI_MODULE_CTP, /**< 10 Cordless Telephony Profile */ - OI_MODULE_DUN, /**< 11 Dial-Up Networking Profile */ - OI_MODULE_FAX, /**< 12 Fax Profile */ - OI_MODULE_FTP_CLI, /**< 13 File Transfer Profile protocol client */ - OI_MODULE_FTP_SRV, /**< 14 File Transfer Profile protocol server */ - OI_MODULE_HANDSFREE, /**< 15 Hands-Free Profile */ - OI_MODULE_HANDSFREE_AG, /**< 16 Hands-Free Profile */ - OI_MODULE_HCRP_CLI, /**< 17 Hardcopy Cable Replacement Profile */ - OI_MODULE_HCRP_SRV, /**< 18 Hardcopy Cable Replacement Profile */ - OI_MODULE_HEADSET, /**< 19 Headset Profile */ - OI_MODULE_HEADSET_AG, /**< 20 Headset Profile */ - OI_MODULE_HID, /**< 21 Human Interface Device profile */ - OI_MODULE_INTERCOM, /**< 22 Intercom Profile */ - OI_MODULE_OBEX_CLI, /**< 23 OBEX protocol client, Generic Object Exchange Profile */ - OI_MODULE_OBEX_SRV, /**< 24 OBEX protocol server, Generic Object Exchange Profile */ - OI_MODULE_OPP_CLI, /**< 25 Object Push Profile protocol client */ - OI_MODULE_OPP_SRV, /**< 26 Object Push Profile protocol server */ - OI_MODULE_PAN, /**< 27 PAN profile */ - OI_MODULE_PBAP_CLI, /**< 28 Phonebook Access Profile client */ - OI_MODULE_PBAP_SRV, /**< 29 Phonebook Access Profile server */ - OI_MODULE_SAP_CLI, /**< 30 SIM Access Profile */ - OI_MODULE_SAP_SRV, /**< 31 SIM Access Profile */ - OI_MODULE_SPP, /**< 32 Serial Port Profile */ - OI_MODULE_SYNC_CLI, /**< 33 Synchronization Profile */ - OI_MODULE_SYNC_SRV, /**< 34 Synchronization Profile */ - OI_MODULE_SYNC_CMD_CLI, /**< 35 Synchronization Profile */ - OI_MODULE_SYNC_CMD_SRV, /**< 36 Synchronization Profile */ - OI_MODULE_SYNCML, /**< 37 SyncML Profile */ - OI_MODULE_TCS, /**< 38 TCS Binary */ - OI_MODULE_VDP, /**< 39 Video Distribution Profile */ - - /* corestack components --> Updates to oi_debug.c and oi_config_table.c */ - - OI_MODULE_COMMON_CONFIG, /**< 40 Common configuration, module has no meaning other than for config struct */ - OI_MODULE_CMDCHAIN, /**< 41 Command chaining utility */ - OI_MODULE_DISPATCH, /**< 42 Dispatcher */ - OI_MODULE_DATAELEM, /**< 43 Data Elements, marshaller */ - OI_MODULE_DEVMGR, /**< 44 Device Manager */ - OI_MODULE_DEVMGR_MODES, /**< 45 Device Manager connectability/discoverability modes */ - OI_MODULE_HCI, /**< 46 Host Controller Interface command layer */ - OI_MODULE_L2CAP, /**< 47 L2CAP */ - OI_MODULE_MEMMGR, /**< 48 modules that do memory management */ - OI_MODULE_POLICYMGR, /**< 49 Policy Manager */ - OI_MODULE_RFCOMM, /**< 50 RFCOMM */ - OI_MODULE_RFCOMM_SD, /**< 51 RFCOMM Service discovery */ - OI_MODULE_SDP_CLI, /**< 52 Service Discovery Protocol client */ - OI_MODULE_SDP_SRV, /**< 53 Service Discovery Protocol server */ - OI_MODULE_SDPDB, /**< 54 Service Discovery Protocol database */ - OI_MODULE_SECMGR, /**< 55 Security Manager */ - OI_MODULE_SNIFFLOG, /**< 56 sniff log */ - OI_MODULE_SUPPORT, /**< 57 support functions, including CThru Dispatcher, time functions, and stack initialization */ - OI_MODULE_TRANSPORT, /**< 58 transport layer between HCI command layer and driver */ - OI_MODULE_TEST, /**< 59 used to debug output from internal test programs */ - OI_MODULE_XML, /**< 60 XML/CSS parser */ - - OI_MODULE_DI, /**< 61 Device Identification Profile */ - - // bhapi components --> Updates to oi_debug.c - - OI_MODULE_BHAPI, /**< 62 BLUEmagic Host API generic */ - OI_MODULE_BHCLI, /**< 63 BLUEmagic Host API client side */ - OI_MODULE_BHSRV, /**< 64 BLUEmagic Host API server side */ - OI_MODULE_MSGQ, /**< 65 module that handles message queuing */ - OI_MODULE_BHAPI_TRANSPORT, /**< 66 module that handles message queuing */ - OI_MODULE_BLST_SRV, /**< 67 module that provides server side BHAPI Lightweight Serial Transport */ - OI_MODULE_BLST_CLI, /**< 68 module that provides client side BHAPI Lightweight Serial Transport */ - - // OEM files --> Updates to oi_debug.c - OI_MODULE_OEM, /**< 69 Application Memory allocation */ - - // Application glue --> Updates to oi_debug.c - OI_MODULE_APP, /**< 70 Application Memory allocation */ - - /* various pieces of code depend on these last 2 elements occuring in a specific order: - OI_MODULE_ALL must be the 2nd to last element - OI_MODULE_UNKNOWN must be the last element - */ - OI_MODULE_ALL, /**< 71 special value identifying all modules - used for control of debug print statements */ - OI_MODULE_UNKNOWN /**< 72 special value - used for debug print statements */ -} OI_MODULE; - -/** - * This constant is the number of actual modules in the list. ALL and UNKNOWN are - * special values that are not actually modules. - * Used for debug print and memmgr profiling - */ -#define OI_NUM_MODULES OI_MODULE_ALL - - -/** - * This constant is the number of profile and core components. It is used to size - * the initialization and configuration tables. - */ -#define OI_NUM_STACK_MODULES OI_MODULE_BHAPI - - -#ifdef __cplusplus -} -#endif - -/**@}*/ - -#endif /* _OI_MODULES_H */ - diff --git a/tools/sdk/include/bluedroid/oi_osinterface.h b/tools/sdk/include/bluedroid/oi_osinterface.h deleted file mode 100644 index 78680419..00000000 --- a/tools/sdk/include/bluedroid/oi_osinterface.h +++ /dev/null @@ -1,197 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 The Android Open Source Project - * Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef _OI_OSINTERFACE_H -#define _OI_OSINTERFACE_H -/** - @file - * This file provides the platform-independent interface for functions for which - * implementation is platform-specific. - * - * The functions in this header file define the operating system or hardware - * services needed by the BLUEmagic 3.0 protocol stack. The - * actual implementation of these services is platform-dependent. - * - */ - -/********************************************************************************** - $Revision: #1 $ -***********************************************************************************/ - -#include "oi_stddefs.h" -#include "oi_time.h" -#include "oi_status.h" -#include "oi_modules.h" - -/** \addtogroup Misc Miscellaneous APIs */ -/**@{*/ - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * Terminates execution. - * - * @param reason Reason for termination - */ -void OI_FatalError(OI_STATUS reason); - -/** - * This function logs an error. - * - * When built for release mode, BLUEmagic 3 errors are logged to - * this function. (in debug mode, errors are logged via - * OI_Print()). - * - * @param module Module in which the error was detected (see - * oi_modules.h) - * @param lineno Line number of the C file OI_SLOG_ERROR called - * @param status Status code associated with the error event - */ -void OI_LogError(OI_MODULE module, OI_INT lineno, OI_STATUS status); - -/** - * This function initializes the debug code handling. - * - * When built for debug mode, this function performs platform - * dependent initialization to handle message codes passed in - * via OI_SetMsgCode(). - */ -void OI_InitDebugCodeHandler(void); - - -/** - * This function reads the time from the real time clock. - * - * All timing in BM3 is relative, typically a granularity - * of 5 or 10 msecs is adequate. - * - * @param[out] now Pointer to the buffer to which the current - * time will be returned - */ -void OI_Time_Now(OI_TIME *now); - -/** - * This function causes the current thread to sleep for the - * specified amount of time. This function must be called - * without the stack access token. - * - * @note BM3 corestack and profiles never suspend and never call - * OI_Sleep. The use of OI_Sleep is limited to applications and - * platform-specific code. - * - * If your port and applications never use OI_Sleep, this function can be left unimplemented. - * - * @param milliseconds Number of milliseconds to sleep - */ -void OI_Sleep(OI_UINT32 milliseconds); - - -/** - * Defines for message type codes. - */ -#define OI_MSG_CODE_APPLICATION 0 /**< Application output */ -#define OI_MSG_CODE_ERROR 1 /**< Error message output */ -#define OI_MSG_CODE_WARNING 2 /**< Warning message output */ -#define OI_MSG_CODE_TRACE 3 /**< User API function trace output */ -#define OI_MSG_CODE_PRINT1 4 /**< Catagory 1 debug print output */ -#define OI_MSG_CODE_PRINT2 5 /**< Catagory 2 debug print output */ -#define OI_MSG_CODE_HEADER 6 /**< Error/Debug output header */ - -/** - * This function is used to indicate the type of text being output with - * OI_Print(). For the Linux and Win32 platforms, it will set - * the color of the text. Other possible uses could be to insert - * HTML style tags, add some other message type indication, or - * be completely ignored altogether. - * - * @param code OI_MSG_CODE_* indicating setting the message type. - */ -void OI_SetMsgCode(OI_UINT8 code); - -/** - * All output from OI_Printf() and all debug output is sent to OI_Print. - * Typically, if the platform has a console, OI_Print() is sent to stdout. - * Embedded platforms typically send OI_Print() output to a serial port. - * - * @param str String to print - */ -void OI_Print(OI_CHAR const *str); - -/** - * In cases where OI_Print() is sending output to a logfile in addition to console, - * it is desirable to also put console input into the logfile. - * This function can be called by the console input process. - * - * @note This is an optional API which is strictly - * between the platform-specific stack_console and osinterface - * modules. This API need only be implemented on those - * platforms where is serves a useful purpose, e.g., win32. - * - * @param str Console input string - */ - -void OI_Print_ConsoleInput(OI_CHAR const *str); - -/** - * This function computes the CRC16 of the program image. - */ -OI_UINT16 OI_ProgramImageCRC16(void); - -/** - * Writes an integer to stdout in hex. This macro is intended - * for selective use when debugging in small memory - * configurations or other times when it is not possible to use - * OI_DBGPRINT. - * - * @param n the integer to print - */ - -#define OI_Print_Int(n) \ -{ \ - static const OI_CHAR _digits[] = "0123456789ABCDEF"; \ - OI_CHAR _buf[9]; \ - OI_CHAR *_str = &_buf[8]; \ - OI_UINT32 _i = n; \ - *_str = 0; \ - do { *(--_str) = _digits[(_i & 0xF)]; _i >>= 4; } while (_i); \ - OI_Print(_str); \ -} - -/** - * Application Dynamic Memory allocation. - * - * These APIs are provided for application use on those - * platforms which have no dynamic memory support. Memory is - * allocated from the pool-based heap managed by the stack's - * internal memory manager. - */ -void *OI_APP_Malloc(OI_INT32 size); -void OI_APP_Free(void *ptr); - -/*****************************************************************************/ -#ifdef __cplusplus -} -#endif - -/**@}*/ - -#endif /* _OI_OSINTERFACE_H */ - diff --git a/tools/sdk/include/bluedroid/oi_status.h b/tools/sdk/include/bluedroid/oi_status.h deleted file mode 100644 index 8c392a29..00000000 --- a/tools/sdk/include/bluedroid/oi_status.h +++ /dev/null @@ -1,579 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 The Android Open Source Project - * Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef _OI_STATUS_H -#define _OI_STATUS_H -/** - * @file - * This file contains status codes for BLUEmagic 3.0 software. - */ - -#include "oi_stddefs.h" - -/** \addtogroup Misc Miscellaneous APIs */ -/**@{*/ - -#ifdef __cplusplus -extern "C" { -#endif - - -/** test it **/ - -/** - * OI_STATUS must fit in 16 bits, so status codes can range from 0 to 66535, inclusive. - */ - -typedef enum { - OI_STATUS_SUCCESS = 0, /**< function call succeeded alias for #OI_OK */ - OI_OK = 0, /**< function call succeeded alias for #OI_STATUS_SUCCESS */ - OI_STATUS_INVALID_PARAMETERS = 101, /**< invalid function input parameters */ - OI_STATUS_NOT_IMPLEMENTED = 102, /**< attempt to use an unimplemented function */ - OI_STATUS_NOT_INITIALIZED = 103, /**< data not initialized */ - OI_STATUS_NO_RESOURCES = 104, /**< generic resource allocation failure status */ - OI_STATUS_INTERNAL_ERROR = 105, /**< internal inconsistency */ - OI_STATUS_OUT_OF_MEMORY = 106, /**< generally, OI_Malloc failed */ - OI_ILLEGAL_REENTRANT_CALL = 107, /**< violation of non-reentrant module policy */ - OI_STATUS_INITIALIZATION_FAILED = 108, /**< module initialization failed */ - OI_STATUS_INITIALIZATION_PENDING = 109, /**< inititialization not yet complete */ - OI_STATUS_NO_SCO_SUPPORT = 110, /**< SCO operation rejected; system not configured for SCO */ - OI_STATUS_OUT_OF_STATIC_MEMORY = 111, /**< static malloc failed */ - OI_TIMEOUT = 112, /**< generic timeout */ - OI_OS_ERROR = 113, /**< some operating system error */ - OI_FAIL = 114, /**< generic failure */ - OI_STRING_FORMAT_ERROR = 115, /**< error in VarString formatting string */ - OI_STATUS_PENDING = 116, /**< The operation is pending. */ - OI_STATUS_INVALID_COMMAND = 117, /**< The command was invalid. */ - OI_BUSY_FAIL = 118, /**< command rejected due to busy */ - OI_STATUS_ALREADY_REGISTERED = 119, /**< The registration has already been performed. */ - OI_STATUS_NOT_FOUND = 120, /**< The referenced resource was not found. */ - OI_STATUS_NOT_REGISTERED = 121, /**< not registered */ - OI_STATUS_NOT_CONNECTED = 122, /**< not connected */ - OI_CALLBACK_FUNCTION_REQUIRED = 123, /**< A callback function parameter was required. */ - OI_STATUS_MBUF_OVERFLOW = 124, /**< There is no room to add another buffer to an mbuf. */ - OI_STATUS_MBUF_UNDERFLOW = 125, /**< There was an attempt to pull too many bytes from an mbuf. */ - OI_STATUS_CONNECTION_EXISTS = 126, /**< connection exists */ - OI_STATUS_NOT_CONFIGURED = 127, /**< module not configured */ - OI_LOWER_STACK_ERROR = 128, /**< An error was reported by lower stack API. This is used for embedded platforms. */ - OI_STATUS_RESET_IN_PROGRESS = 129, /**< Request failed/rejected because we're busy resetting. */ - OI_STATUS_ACCESS_DENIED = 130, /**< Generic access denied error. */ - OI_STATUS_DATA_ERROR = 131, /**< Generic data error. */ - OI_STATUS_INVALID_ROLE = 132, /**< The requested role was invalid. */ - OI_STATUS_ALREADY_CONNECTED = 133, /**< The requested connection is already established. */ - OI_STATUS_PARSE_ERROR = 134, /**< Parse error */ - OI_STATUS_END_OF_FILE = 135, /**< End of file */ - OI_STATUS_READ_ERROR = 136, /**< Generic read error */ - OI_STATUS_WRITE_ERROR = 137, /**< Generic write error */ - OI_STATUS_NEGOTIATION_FAILURE = 138, /**< Error in negotiation */ - OI_STATUS_READ_IN_PROGRESS = 139, /**< A read is already in progress */ - OI_STATUS_ALREADY_INITIALIZED = 140, /**< Initialization has already been done */ - OI_STATUS_STILL_CONNECTED = 141, /**< The service cannot be shutdown because there are still active connections. */ - OI_STATUS_MTU_EXCEEDED = 142, /**< The packet is too big */ - OI_STATUS_LINK_TERMINATED = 143, /**< The link was terminated */ - OI_STATUS_PIN_CODE_TOO_LONG = 144, /**< Application gave us a pin code that is too long */ - OI_STATUS_STILL_REGISTERED = 145, /**< The service cannot be shutdown because there are still active registrations. */ - OI_STATUS_SPEC_VIOLATION = 146, /**< Some application behavior contrary to BT specifications */ - - - OI_STATUS_PSM_ALREADY_REGISTERED = 402, /**< L2CAP: The specified PSM has already been registered. */ - OI_STATUS_INVALID_CID = 403, /**< L2CAP: CID is invalid or no longer valid (connection terminated) */ - OI_STATUS_CID_NOT_FOUND = 404, /**< L2CAP: CID does not represent a current connection */ - OI_STATUS_CHANNEL_NOT_FOUND = 406, /**< L2CAP: CID does not represent a current connection */ - OI_STATUS_PSM_NOT_FOUND = 407, /**< L2CAP: PSM not found */ - OI_STATUS_INVALID_STATE = 408, /**< L2CAP: invalid state */ - OI_STATUS_WRITE_IN_PROGRESS = 410, /**< L2CAP: write in progress */ - OI_STATUS_INVALID_PACKET = 411, /**< L2CAP: invalid packet */ - OI_STATUS_SEND_COMPLETE = 412, /**< L2CAP: send is complete */ - OI_STATUS_INVALID_HANDLE = 414, /**< L2CAP: handle is invalid */ - OI_STATUS_GROUP_FULL = 418, /**< L2CAP: No more members can be added to the specified group. */ - OI_STATUS_DEVICE_ALREADY_IN_GROUP = 423, /**< L2CAP: The device already exists in the group. */ - OI_STATUS_DUPLICATE_GROUP = 425, /**< L2CAP: attempt to add more than one group */ - OI_STATUS_EMPTY_GROUP = 426, /**< L2CAP: group is empty */ - OI_STATUS_PACKET_NOT_FOUND = 427, /**< L2CAP: packet not found */ - OI_STATUS_BUFFER_TOO_SMALL = 428, /**< L2CAP: The buffer size is too small. */ - OI_STATUS_IDENTIFIER_NOT_FOUND = 429, /**< L2CAP: identifier not found */ - - OI_L2CAP_DISCONNECT_LOWER_LAYER = 430, /**< L2CAP: The lower level forced a disconnect. */ - OI_L2CAP_DISCONNECT_REMOTE_REQUEST = 431, /**< L2CAP: The remote device requested a disconnect. */ - OI_L2CAP_GROUP_ADD_CONNECT_FAIL = 433, /**< L2CAP: Group add connect faiL */ - OI_L2CAP_GROUP_REMOVE_FAILURE = 434, /**< L2CAP: Group remove failure */ - OI_L2CAP_DATA_WRITE_ERROR_LINK_TERM = 435, /**< L2CAP: Data write error LINK_TERM */ - OI_L2CAP_DISCONNECT_LOCAL_REQUEST = 436, /**< L2CAP: Disconnect local request */ - - OI_L2CAP_CONNECT_TIMEOUT = 437, /**< L2CAP: Connect timeout */ - OI_L2CAP_DISCONNECT_TIMEOUT = 439, /**< L2CAP: Disconnect timeout */ - OI_L2CAP_PING_TIMEOUT = 440, /**< L2CAP: Ping timeout */ - OI_L2CAP_GET_INFO_TIMEOUT = 441, /**< L2CAP: Get info timeout */ - OI_L2CAP_INVALID_ADDRESS = 444, /**< L2CAP: Invalid address */ - OI_L2CAP_CMD_REJECT_RCVD = 445, /**< L2CAP: remote sent us 'command reject' response */ - - OI_L2CAP_CONNECT_BASE = 450, /**< L2CAP: Connect base */ - OI_L2CAP_CONNECT_PENDING = 451, /**< L2CAP: Connect pending */ - OI_L2CAP_CONNECT_REFUSED_INVALID_PSM = 452, /**< L2CAP: Connect refused invalid PSM */ - OI_L2CAP_CONNECT_REFUSED_SECURITY = 453, /**< L2CAP: Connect refused security */ - OI_L2CAP_CONNECT_REFUSED_NO_RESOURCES = 454, /**< L2CAP: Connect refused no resources */ - - OI_L2CAP_CONFIG_BASE = 460, /**< L2CAP: Config base */ - OI_L2CAP_CONFIG_FAIL_INVALID_PARAMETERS = 461, /**< L2CAP: Config fail invalid parameters */ - OI_L2CAP_CONFIG_FAIL_NO_REASON = 462, /**< L2CAP: Config fail no reason */ - OI_L2CAP_CONFIG_FAIL_UNKNOWN_OPTIONS = 463, /**< L2CAP: Config fail unknown options */ - - OI_L2CAP_GET_INFO_BASE = 470, /**< L2CAP: Get info base */ - OI_L2CAP_GET_INFO_NOT_SUPPORTED = 471, /**< L2CAP: Get info not supported */ - OI_L2CAP_MTU_EXCEEDED = 472, /**< L2CAP: The MTU of the channel was exceeded */ - OI_L2CAP_INVALID_PSM = 482, /**< L2CAP: Invalid PSM */ - OI_L2CAP_INVALID_MTU = 483, /**< L2CAP: Invalid MTU */ - OI_L2CAP_INVALID_FLUSHTO = 484, /**< L2CAP: Invalid flush timeout */ - - OI_HCI_NO_SUCH_CONNECTION = 601, /**< HCI: caller specified a non-existent connection handle */ - OI_HCI_CB_LIST_FULL = 603, /**< HCI: callback list is full, cannot attempt to send command */ - OI_HCI_EVENT_UNDERRUN = 605, /**< HCI: parsing event packet, premature end-of-parameters */ - OI_HCI_UNKNOWN_EVENT_CODE = 607, /**< HCI: event received - event code is unknown */ - OI_HCI_BAD_EVENT_PARM_LEN = 608, /**< HCI: event - parameter length is incorrect */ - OI_HCI_CMD_QUEUE_FULL = 611, /**< HCI: command queue is full */ - OI_HCI_SHORT_EVENT = 612, /**< HCI: event received, missing event code and/or parm len */ - OI_HCI_TRANSMIT_NOT_READY = 613, /**< HCI: ACL/SCO transmit request failed - busy or no buffers available */ - OI_HCI_ORPHAN_SENT_EVENT = 614, /**< HCI: got spurious 'sent' event from transport layer */ - OI_HCI_CMD_TABLE_ERROR = 615, /**< HCI: inconsistency in the internal command table */ - OI_HCI_UNKNOWN_CMD_ID = 616, /**< HCI: HciApi Command - unknown command id */ - OI_HCI_UNEXPECTED_EVENT = 619, /**< HCI: event received which only occurs in response to our cmd */ - OI_HCI_EVENT_TABLE_ERROR = 620, /**< HCI: inconsistency in the internal event table */ - OI_HCI_EXPECTED_EVENT_TIMOUT = 621, /**< HCI: timed out waiting for an expected event */ - OI_HCI_NO_CMD_DESC_FOR_OPCODE = 622, /**< HCI: event opcode is not known */ - OI_HCI_INVALID_OPCODE_ERROR = 623, /**< HCI: command opcode is invalid */ - OI_HCI_FLOW_CONTROL_DISABLED = 624, /**< HCI: can not use host flow control APIs if disabled in configuration */ - OI_HCI_TX_COMPLETE = 625, /**< HCI: packet delivery to Host Controler complete */ - OI_HCI_TX_ERROR = 626, /**< HCI: failed to deliver packet to Host Controler */ - OI_HCI_DEVICE_NOT_INITIALIZED = 627, /**< HCI: commands from upper layers disallowed until device is up and running */ - OI_HCI_UNSUPPORTED_COMMAND = 628, /**< HCI: command requested is not supported by local device */ - OI_HCI_PASSTHROUGH_ERROR = 629, /**< HCI: Error processing passthrough command */ - OI_HCI_PASSTHROUGH_ALREADY_SET = 630, /**< HCI: Passthrough mode already enabled */ - OI_HCI_RESET_FAILURE = 631, /**< HCI: failed to reset the device/baseband */ - OI_HCI_TRANSPORT_RESET = 632, /**< HCI: some operation failed because of a reset in the transport */ - OI_HCIERR_HCIIFC_INIT_FAILURE = 633, /**< HCI: failed to initialize transport layer interface */ - - OI_HCIERR_FIRST_ERROR_VALUE = 701, /**< marker for first HCI protocol error */ - OI_HCIERR_UNKNOWN_HCI_COMMAND = 701, /**< HCI: protocol error 0x01 */ - OI_HCIERR_NO_CONNECTION = 702, /**< HCI: protocol error 0x02 */ - OI_HCIERR_HARDWARE_FAILURE = 703, /**< HCI: protocol error 0x03 */ - OI_HCIERR_PAGE_TIMEOUT = 704, /**< HCI: protocol error 0x04 */ - OI_HCIERR_AUTHENTICATION_FAILURE = 705, /**< HCI: protocol error 0x05 */ - OI_HCIERR_KEY_MISSING = 706, /**< HCI: protocol error 0x06 */ - OI_HCIERR_MEMORY_FULL = 707, /**< HCI: protocol error 0x07 */ - OI_HCIERR_CONNECTION_TIMEOUT = 708, /**< HCI: protocol error 0x08 */ - OI_HCIERR_MAX_NUM_OF_CONNECTIONS = 709, /**< HCI: protocol error 0x09 */ - OI_HCIERR_MAX_NUM_OF_SCO_CONNECTIONS = 710, /**< HCI: protocol error 0x0A */ - OI_HCIERR_ACL_CONNECTION_ALREADY_EXISTS = 711, /**< HCI: protocol error 0x0B */ - OI_HCIERR_COMMAND_DISALLOWED = 712, /**< HCI: protocol error 0x0C */ - OI_HCIERR_HOST_REJECTED_RESOURCES = 713, /**< HCI: protocol error 0x0D */ - OI_HCIERR_HOST_REJECTED_SECURITY = 714, /**< HCI: protocol error 0x0E */ - OI_HCIERR_HOST_REJECTED_PERSONAL_DEVICE = 715, /**< HCI: protocol error 0x0F */ - OI_HCIERR_HOST_TIMEOUT = 716, /**< HCI: protocol error 0x10 */ - OI_HCIERR_UNSUPPORTED = 717, /**< HCI: protocol error 0x11 */ - OI_HCIERR_INVALID_PARAMETERS = 718, /**< HCI: protocol error 0x12 */ - OI_HCIERR_OTHER_END_USER_DISCONNECT = 719, /**< HCI: protocol error 0x13 */ - OI_HCIERR_OTHER_END_LOW_RESOURCES = 720, /**< HCI: protocol error 0x14 */ - OI_HCIERR_OTHER_END_POWERING_OFF = 721, /**< HCI: protocol error 0x15 */ - OI_HCIERR_CONNECTION_TERMINATED_LOCALLY = 722, /**< HCI: protocol error 0x16 */ - OI_HCIERR_REPEATED_ATTEMPTS = 723, /**< HCI: protocol error 0x17 */ - OI_HCIERR_PAIRING_NOT_ALLOWED = 724, /**< HCI: protocol error 0x18 */ - OI_HCIERR_UNKNOWN_LMP_PDU = 725, /**< HCI: protocol error 0x19 */ - OI_HCIERR_UNSUPPORTED_REMOTE_FEATURE = 726, /**< HCI: protocol error 0x1A */ - OI_HCIERR_SCO_OFFSET_REJECTED = 727, /**< HCI: protocol error 0x1B */ - OI_HCIERR_SCO_INTERVAL_REJECTED = 728, /**< HCI: protocol error 0x1C */ - OI_HCIERR_SCO_AIR_MODE_REJECTED = 729, /**< HCI: protocol error 0x1D */ - OI_HCIERR_INVALID_LMP_PARMS = 730, /**< HCI: protocol error 0x1E */ - OI_HCIERR_UNSPECIFIED_ERROR = 731, /**< HCI: protocol error 0x1F */ - OI_HCIERR_UNSUPPORTED_LMP_PARAMETERS = 732, /**< HCI: protocol error 0x20 */ - OI_HCIERR_ROLE_CHANGE_NOT_ALLOWED = 733, /**< HCI: protocol error 0x21 */ - OI_HCIERR_LMP_RESPONSE_TIMEOUT = 734, /**< HCI: protocol error 0x22 */ - OI_HCIERR_LMP_ERROR_TRANS_COLLISION = 735, /**< HCI: protocol error 0x23 */ - OI_HCIERR_LMP_PDU_NOT_ALLOWED = 736, /**< HCI: protocol error 0x24 */ - OI_HCIERR_ENCRYPTION_MODE_NOT_ACCEPTABLE = 737, /**< HCI: protocol error 0x25 */ - OI_HCIERR_UNIT_KEY_USED = 738, /**< HCI: protocol error 0x26 */ - OI_HCIERR_QOS_NOT_SUPPORTED = 739, /**< HCI: protocol error 0x27 */ - OI_HCIERR_INSTANT_PASSED = 740, /**< HCI: protocol error 0x28 */ - OI_HCIERR_UNIT_KEY_PAIRING_UNSUPPORTED = 741, /**< HCI: protocol error 0x29 */ - OI_HCIERR_DIFFERENT_TRANS_COLLISION = 742, /**< HCI: protocol error 0x2A */ - OI_HCIERR_RESERVED_2B = 743, /**< HCI: protocol error 0x2B */ - OI_HCIERR_QOS_UNACCEPTABLE_PARAMETER = 744, /**< HCI: protocol error 0x2C */ - OI_HCIERR_QOS_REJECTED = 745, /**< HCI: protocol error 0x2D */ - OI_HCIERR_CHANNEL_CLASSIFICATION_NS = 746, /**< HCI: protocol error 0x2E */ - OI_HCIERR_INSUFFICIENT_SECURITY = 747, /**< HCI: protocol error 0x2F */ - OI_HCIERR_PARM_OUT_OF_MANDATORY_RANGE = 748, /**< HCI: protocol error 0x30 */ - OI_HCIERR_RESERVED_31 = 749, /**< HCI: protocol error 0x31 */ - OI_HCIERR_ROLE_SWITCH_PENDING = 750, /**< HCI: protocol error 0x32 */ - OI_HCIERR_RESERVED_33 = 751, /**< HCI: protocol error 0x33 */ - OI_HCIERR_RESERVED_SLOT_VIOLATION = 752, /**< HCI: protocol error 0x34 */ - OI_HCIERR_ROLE_SWITCH_FAILED = 753, /**< HCI: protocol error 0x35 */ - OI_HCIERR_EIR_TOO_LARGE = 754, /**< HCI: protocol error 0x36 */ - OI_HCIERR_SSP_NOT_SUPPORTED_BY_HOST = 755, /**< HCI: protocol error 0x37 */ - OI_HCIERR_HOST_BUSY_PAIRING = 756, /**< HCI: protocol error 0x38 */ - - OI_HCIERR_UNKNOWN_ERROR = 757, /**< HCI: unknown error code */ - OI_HCIERR_LAST_ERROR_VALUE = 757, /**< marker for last HCI protocol error */ - - OI_SDP_SPEC_ERROR = 800, /**< SDP: Base error status for mapping OI_STATUS codes to SDP errors */ - OI_SDP_INVALID_SERVICE_RECORD_HANDLE = (OI_SDP_SPEC_ERROR + 2), /**< SDP: protocol error Invalid Service Record Handle */ - OI_SDP_INVALID_REQUEST_SYNTAX = (OI_SDP_SPEC_ERROR + 3), /**< SDP: protocol error Invalid Request Syntax */ - OI_SDP_INVALID_PDU_SIZE = (OI_SDP_SPEC_ERROR + 4), /**< SDP: protocol error Invalid PDU Size */ - OI_SDP_INVALID_CONTINUATION_STATE = (OI_SDP_SPEC_ERROR + 5), /**< SDP: protocol error Invalid Continuation State */ - OI_SDP_INSUFFICIENT_RESOURCES = (OI_SDP_SPEC_ERROR + 6), /**< SDP: protocol error Insufficient Resources */ - OI_SDP_ERROR = 807, /**< SDP: server returned an error code */ - OI_SDP_CORRUPT_DATA_ELEMENT = 808, /**< SDP: Invalid or corrupt data element representation */ - OI_SDP_SERVER_NOT_CONNECTED = 810, /**< SDP: Attempt to disconnect from an unconnected server */ - OI_SDP_ACCESS_DENIED = 811, /**< SDP: Server denied access to server */ - OI_SDP_ATTRIBUTES_OUT_OF_ORDER = 812, /**< SDP: Attributes in attribute list not in ascending order */ - OI_SDP_DEVICE_DOES_NOT_SUPPORT_SDP = 813, /**< SDP: Tried to connect to a device that does not support SDP */ - OI_SDP_NO_MORE_DATA = 815, /**< SDP: Server does not have more continuation data */ - OI_SDP_REQUEST_PARAMS_TOO_LONG = 816, /**< SDP: Parameters for a request exceed the L2CAP buffer size */ - OI_SDP_REQUEST_PENDING = 817, /**< SDP: Cannot make a request when another request is being processed */ - OI_SDP_SERVER_CONNECT_FAILED = 819, /**< SDP: Failed attempt to connect to an SDP server */ - OI_SDP_SERVER_TOO_MANY_CONNECTIONS = 821, /**< SDP: Exceeded maximum number of simultaneous server connections */ - OI_SDP_NO_MATCHING_SERVICE_RECORD = 823, /**< SDP: No service record matched the UUID list */ - OI_SDP_PARTIAL_RESPONSE = 824, /**< SDP: Internal use only */ - OI_SDP_ILLEGAL_ARGUMENT = 825, /**< SDP: Illegal argument passed to an SDP function */ - OI_SDP_ATTRIBUTE_NOT_FOUND = 826, /**< SDP: A requested attribute was not found in a service record */ - OI_SDP_DATABASE_OUT_OF_RESOURCES = 827, /**< SDP: server database is out of memory */ - OI_SDP_SHORT_PDU = 829, /**< SDP: Not enough bytes in the packet */ - OI_SDP_TRANSACTION_ID_MISMATCH = 830, /**< SDP: Transaction Id was not as expected */ - OI_SDP_UNEXPECTED_RESPONSE_PDU_ID = 831, /**< SDP: Did not expect this response PDU */ - OI_SDP_REQUEST_TIMEOUT = 832, /**< SDP: Did not get a response within the timeout period */ - OI_SDP_INVALID_RESPONSE_SYNTAX = 833, /**< SDP: Response is not correctly formatted */ - OI_SDP_CONNECTION_TIMEOUT = 834, /**< SDP: Connection attempt timed out at a lower layer */ - OI_SDP_RESPONSE_DATA_ERROR = 835, /**< SDP: Response to a service request appears to be corrupt */ - OI_SDP_TOO_MANY_ATTRIBUTE_BYTES = 836, /**< SDP: Response contained more bytes than requested. */ - OI_SDP_TOO_MANY_SERVICE_RECORDS = 837, /**< SDP: Response contained more service records than requested. */ - OI_SDP_INVALID_CONNECTION_ID = 838, /**< SDP: Invalid connection ID in an SDP request */ - OI_SDP_CANNOT_SET_ATTRIBUTE = 839, /**< SDP: Attempt to set a dynamic attribute value failed */ - OI_SDP_BADLY_FORMED_ATTRIBUTE_VALUE = 840, /**< SDP: An attribute value has the wrong type or structure */ - OI_SDP_NO_ATTRIBUTE_LIST_TO_REMOVE = 841, /**< SDP: Attempt to remove a non-existent attribute list from a service record */ - OI_SDP_ATTRIBUTE_LIST_ALREADY_ADDED = 842, /**< SDP: An attribute list has already been added to the service record */ - OI_SDP_DATA_ELEMENT_TRUNCATED = 843, /**< SDP: Data element truncated (too few bytes) */ - - OI_RFCOMM_WRITE_IN_PROGRESS = 901, /**< RFCOMM: Write in progress */ - OI_RFCOMM_INVALID_BAUDRATE = 903, /**< RFCOMM: Invalid baudrate */ - OI_RFCOMM_INVALID_DATABIT = 904, /**< RFCOMM: Invalid databit */ - OI_RFCOMM_INVALID_STOPBIT = 905, /**< RFCOMM: Invalid stopbit */ - OI_RFCOMM_INVALID_PARITY = 906, /**< RFCOMM: Invalid parity */ - OI_RFCOMM_INVALID_PARITYTYPE = 907, /**< RFCOMM: Invalid paritytype */ - OI_RFCOMM_INVALID_FLOWCONTROL = 908, /**< RFCOMM: Invalid flowcontrol */ - OI_RFCOMM_SESSION_EXISTS = 909, /**< RFCOMM: Session exists */ - OI_RFCOMM_INVALID_CHANNEL = 910, /**< RFCOMM: Invalid channel */ - OI_RFCOMM_DLCI_EXISTS = 911, /**< RFCOMM: DLCI exists */ - OI_RFCOMM_LINK_NOT_FOUND = 912, /**< RFCOMM: Link not found */ - OI_RFCOMM_REMOTE_REJECT = 913, /**< RFCOMM: Remote reject */ - OI_RFCOMM_TEST_IN_PROGRESS = 915, /**< RFCOMM: Test in progress */ - OI_RFCOMM_SESSION_NOT_FOUND = 916, /**< RFCOMM: Session not found */ - OI_RFCOMM_INVALID_PACKET = 917, /**< RFCOMM: Invalid packet */ - OI_RFCOMM_FRAMESIZE_EXCEEDED = 918, /**< RFCOMM: Framesize exceeded */ - OI_RFCOMM_INVALID_DLCI = 920, /**< RFCOMM: Invalid dlci */ - OI_RFCOMM_SERVER_NOT_REGISTERED = 921, /**< RFCOMM: Server not registered */ - OI_RFCOMM_CREDIT_ERROR = 922, /**< RFCOMM: Credit error */ - OI_RFCOMM_NO_CHANNEL_NUMBER = 923, /**< RFCOMM: No channel number */ - OI_RFCOMM_QUERY_IN_PROGRESS = 924, /**< RFCOMM: Query in progress */ - OI_RFCOMM_SESSION_SHUTDOWN = 925, /**< RFCOMM: Session shutdown */ - OI_RFCOMM_LOCAL_DEVICE_DISCONNECTED = 926, /**< RFCOMM: Local device disconnected */ - OI_RFCOMM_REMOTE_DEVICE_DISCONNECTED = 927, /**< RFCOMM: Remote device disconnected */ - OI_RFCOMM_OUT_OF_SERVER_CHANNELS = 928, /**< RFCOMM: Out of server channels */ - - OI_DISPATCH_INVALID_CB_HANDLE = 1001, /**< Dispatcher was handed an invalid callback handle */ - OI_DISPATCH_TABLE_OVERFLOW = 1002, /**< Dispatcher table is full */ - - OI_TEST_UNKNOWN_TEST = 1101, /**< TEST: Unknown test */ - OI_TEST_FAIL = 1102, /**< TEST: Fail */ - - OI_HCITRANS_CANNOT_CONNECT_TO_DEVICE = 1201, /**< TRANSPORT: Cannot connect to device */ - OI_HCITRANS_BUFFER_TOO_SMALL = 1203, /**< TRANSPORT: Buffer too small */ - OI_HCITRANS_NULL_DEVICE_HANDLE = 1204, /**< TRANSPORT: Null device handle */ - OI_HCITRANS_IO_ERROR = 1205, /**< TRANSPORT: IO error */ - OI_HCITRANS_DEVICE_NOT_READY = 1206, /**< TRANSPORT: Device not ready */ - OI_HCITRANS_FUNCTION_NOT_SUPPORTED = 1207, /**< TRANSPORT: Function not supporteD */ - OI_HCITRANS_ACCESS_DENIED = 1209, /**< TRANSPORT: win32 */ - OI_HCITRANS_ACL_DATA_ERROR = 1210, /**< TRANSPORT: ACL data error */ - OI_HCITRANS_SCO_DATA_ERROR = 1211, /**< TRANSPORT: SCO data error */ - OI_HCITRANS_EVENT_DATA_ERROR = 1212, /**< TRANSPORT: HCI event data error */ - OI_HCITRANS_INTERNAL_ERROR = 1214, /**< TRANSPORT: Internal error in the transport */ - OI_HCITRANS_LINK_NOT_ACTIVE = 1215, /**< TRANSPORT: Link to the device is not currently active */ - OI_HCITRANS_INITIALIZING = 1216, /**< TRANSPORT: Transport is initializing */ - - OI_DEVMGR_NO_CONNECTION = 1301, /**< DEVMGR: No connection */ - OI_DEVMGR_HARDWARE_ERROR = 1305, /**< DEVMGR: error reported by HCI */ - OI_DEVMGR_PENDING_CONNECT_LIST_FULL = 1307, /**< DEVMGR: Pending connect list full */ - OI_DEVMGR_CONNECTION_LIST_FULL = 1309, /**< DEVMGR: Connection list full */ - OI_DEVMGR_NO_SUCH_CONNECTION = 1310, /**< DEVMGR: No such connection */ - OI_DEVMGR_INQUIRY_IN_PROGRESS = 1311, /**< DEVMGR: Inquiry in progress */ - OI_DEVMGR_PERIODIC_INQUIRY_ACTIVE = 1312, /**< DEVMGR: Periodic inquiry active */ - OI_DEVMGR_NO_INQUIRIES_ACTIVE = 1313, /**< DEVMGR: can not cancel/exit if not active */ - OI_DEVMGR_DUPLICATE_CONNECTION = 1314, /**< DEVMGR: internal error */ - OI_DEVMGR_DUPLICATE_EVENT_CALLBACK = 1316, /**< DEVMGR: attempt to register same callback twice */ - OI_DEVMGR_EVENT_CALLBACK_LIST_FULL = 1317, /**< DEVMGR: can not register event callback, list is full */ - OI_DEVMGR_EVENT_CALLBACK_NOT_FOUND = 1318, /**< DEVMGR: attempt to unregister callback failed */ - OI_DEVMGR_BUSY = 1319, /**< DEVMGR: some operations can only execute one at a time */ - OI_DEVMGR_ENUM_UNEXPECTED_INQ_COMPLETE = 1320, /**< DEVMGR: inquiry complete event in inappropriate enumeration state */ - OI_DEVMGR_ENUM_UNEXPECTED_INQ_RESULT = 1321, /**< DEVMGR: inquiry result event in inappropriate enumeration state */ - OI_DEVMGR_ENUM_DATABASE_FULL = 1322, /**< DEVMGR: device enumeration, database is full, couldn't add a new device */ - OI_DEVMGR_ENUM_INQUIRIES_OVERLAP = 1323, /**< DEVMGR: device enumeration, periodic inquiries occurring too close together */ - OI_DEVMGR_UNKNOWN_LINK_TYPE = 1324, /**< DEVMGR: HCI connect request with unkown link type */ - OI_DEVMGR_PARAM_IO_ACTIVE = 1325, /**< DEVMGR: request for parameter read/write while param read/write active */ - OI_DEVMGR_UNKNOWN_IAC_LAP = 1326, /**< DEVMGR: unrecognized IAC LAP */ - OI_DEVMGR_SCO_ALREADY_REGISTERED = 1327, /**< DEVMGR: only one application can use SCO */ - OI_DEVMGR_SCO_NOT_REGISTERED = 1328, /**< DEVMGR: SCO applications must register before using the API */ - OI_DEVMGR_SCO_WITHOUT_ACL = 1329, /**< DEVMGR: Got SCO connection but there is no underlying ACL connection */ - OI_DEVMGR_NO_SUPPORT = 1330, /**< DEVMGR: Request is not supported by the device */ - OI_DEVMGR_WRITE_POLICY_FAILED = 1331, /**< DEVMGR: connection attempt failed - unable to write link policy */ - OI_DEVMGR_NOT_IN_MASTER_MODE = 1332, /**< DEVMGR: OI_DEVMGR EndMasterMode without prior OI_DEVMGR_BeginMasterMode */ - OI_DEVMGR_POLICY_VIOLATION = 1333, /**< DEVMGR: low-power request is rejected - link policy does not allow it */ - OI_DEVMGR_BUSY_TIMEOUT = 1334, /**< DEVMGR: queued operation timed out while in the queue; \n - timeout configurable via @ref OI_CONFIG_DEVMGR::connectQueueTimeoutSecs "connectQueueTimeoutSecs" */ - OI_DEVMGR_REENCRYPT_FAILED = 1335, /**< DEVMGR: failed to re-encrypt link after role switch */ - OI_DEVMGR_ROLE_POLICY_CONFLICT = 1336, /**< DEVMGR: requested role conflicts with current policy */ - OI_DEVMGR_BAD_INTERVAL = 1337, /**< DEVMGR: current linkTO outside range of requested min/max interval */ - OI_DEVMGR_INVALID_SCO_HANDLE = 1338, /**< DEVMGR: HCI SCO event, invalid handle */ - OI_DEVMGR_CONNECTION_OVERLAP = 1339, /**< DEVMGR: Connection failed due to race condition with remote side */ - OI_DEVMGR_ORPHAN_SUBRATE_COMPLETE = 1340, /**< DEVMGR: sniff subrate complete, but no callback */ - OI_DEVMGR_EIR_RESPONSE_2_LARGE = 1341, /**< DEVMGR: eir builder, response length would exceed spec max */ - - OI_SECMGR_NO_POLICY = 1401, /**< SECMGR: no security policy has been established */ - OI_SECMGR_INTERNAL_ERROR = 1402, /**< SECMGR: internal inconsistency */ - OI_SECMGR_ORPHANED_CALLBACK = 1403, /**< SECMGR: we've been called back, but CB context is gone */ - OI_SECMGR_BUSY = 1404, /**< SECMGR: configure and access request cannot be concurrent */ - OI_SECMGR_DEVICE_NOT_TRUSTED = 1405, /**< SECMGR: l2cap access denied - device is not trusted */ - OI_SECMGR_DEVICE_ENCRYPT_FAIL = 1407, /**< SECMGR: l2cap access denied - failed to start encryption */ - OI_SECMGR_DISCONNECTED_FAIL = 1408, /**< SECMGR: l2cap access denied - disconnected */ - OI_SECMGR_ACCESS_PENDING = 1409, /**< SECMGR: l2cap access request is still pending */ - OI_SECMGR_PIN_CODE_TOO_SHORT = 1410, /**< SECMGR: Higher-layer process gave us a pin code that is too short */ - OI_SECMGR_UNKNOWN_ENCRYPT_VALUE = 1411, /**< SECMGR: got EncryptionChange event, unknown encryption enable value */ - OI_SECMGR_INVALID_POLICY = 1412, /**< SECMGR: the specified security policy is not valid for security mode */ - OI_SECMGR_AUTHORIZATION_FAILED = 1413, /**< SECMGR: device authorization failed */ - OI_SECMGR_ENCRYPTION_FAILED = 1414, /**< SECMGR: device encryption failed */ - OI_SECMGR_UNIT_KEY_UNSUPPORTED = 1415, /**< SECMGR: authentication failed due to non-support of unit keys */ - OI_SECMGR_NOT_REGISTERED = 1416, /**< SECMGR: required registrations have not yet occurred */ - OI_SECMGR_ILLEGAL_WRITE_SSP_MODE = 1417, /**< SECMGR: 2.1 HCI spec does not allow SSP mode to be disabled */ - OI_SECMGR_INVALID_SEC_LEVEL = 1418, /**< SECMGR: security level for a service is not a valid value */ - OI_SECMGR_INSUFFICIENT_LINK_KEY = 1419, /**< SECMGR: link key type is not sufficient to meet service requirements */ - OI_SECMGR_INVALID_KEY_TYPE = 1420, /**< SECMGR: link key type is not a valid value */ - OI_SECMGR_SSP_NOT_ENCRYPTED = 1421, /**< SECMGR: ssp required encryption on incoming link */ - OI_SECMGR_ORPHAN_EVENT = 1422, /**< SECMGR: some HCI security event unrelated to current processes */ - OI_SECMGR_NOT_BONDABLE = 1423, /**< SECMGR: not in bondable mode */ - - OI_TCS_INVALID_ELEMENT_TYPE = 1602, /**< TCS: element type is invalid */ - OI_TCS_INVALID_PACKET = 1603, /**< TCS: packet is invalide */ - OI_TCS_CALL_IN_PROGRESS = 1604, /**< TCS: call is in progress */ - OI_TCS_NO_CALL_IN_PROGRESS = 1605, /**< TCS: no call in progress */ - - OI_OBEX_CONTINUE = 1701, /**< OBEX: Continue processing OBEX request */ - OI_OBEX_COMMAND_ERROR = 1702, /**< OBEX: An unrecognized OBEX command opcode */ - OI_OBEX_CONNECTION_TIMEOUT = 1703, /**< OBEX: Timeout waiting for a response to a request */ - OI_OBEX_CONNECT_FAILED = 1704, /**< OBEX: An OBEX connection request did not succeed */ - OI_OBEX_DISCONNECT_FAILED = 1705, /**< OBEX: A disconnect failed probably because the connection did not exist */ - OI_OBEX_ERROR = 1706, /**< OBEX: Unspecified OBEX error */ - OI_OBEX_INCOMPLETE_PACKET = 1707, /**< OBEX: Packet too short or corrupt */ - OI_OBEX_LENGTH_REQUIRED = 1708, /**< OBEX: Length header required in OBEX command */ - OI_OBEX_NOT_CONNECTED = 1709, /**< OBEX: No connection to OBEX server */ - OI_OBEX_NO_MORE_CONNECTIONS = 1710, /**< OBEX: Reached max connections limit */ - OI_OBEX_OPERATION_IN_PROGRESS = 1711, /**< OBEX: Another operation is still in progress on a connection */ - OI_OBEX_PUT_RESPONSE_ERROR = 1712, /**< OBEX: An error in the response to a PUT command */ - OI_OBEX_GET_RESPONSE_ERROR = 1713, /**< OBEX: An error in the response to a GET command */ - OI_OBEX_REQUIRED_HEADER_NOT_FOUND = 1714, /**< OBEX: packet was missing a required header */ - OI_OBEX_SERVICE_UNAVAILABLE = 1715, /**< OBEX: Unown OBEX target or required service */ - OI_OBEX_TOO_MANY_HEADER_BYTES = 1716, /**< OBEX: Headers will not fit in single OBEX packet */ - OI_OBEX_UNKNOWN_COMMAND = 1717, /**< OBEX: Unrecognized OBEX command */ - OI_OBEX_UNSUPPORTED_VERSION = 1718, /**< OBEX: Version mismatch */ - OI_OBEX_CLIENT_ABORTED_COMMAND = 1719, /**< OBEX: server received abort command */ - OI_OBEX_BAD_PACKET = 1720, /**< OBEX: Any malformed OBEX packet */ - OI_OBEX_BAD_REQUEST = 1721, /**< OBEX: Maps to OBEX response of the same name */ - OI_OBEX_OBJECT_OVERFLOW = 1723, /**< OBEX: Too many bytes received. */ - OI_OBEX_NOT_FOUND = 1724, /**< OBEX: Maps to obex response of same name */ - OI_OBEX_ACCESS_DENIED = 1735, /**< OBEX: Object could not be read or written. */ - OI_OBEX_VALUE_NOT_ACCEPTABLE = 1736, /**< OBEX: Value in a command was not in the acceptable range. */ - OI_OBEX_PACKET_OVERFLOW = 1737, /**< OBEX: Buffer will not fit in a single OBEX packet. */ - OI_OBEX_NO_SUCH_FOLDER = 1738, /**< OBEX: Error returned by a setpath operation. */ - OI_OBEX_NAME_REQUIRED = 1739, /**< OBEX: Name must be non-null and non-empty. */ - OI_OBEX_PASSWORD_TOO_LONG = 1740, /**< OBEX: Password exceeds implementation imposed length limit. */ - OI_OBEX_PRECONDITION_FAILED = 1741, /**< OBEX: response Precondition Failed */ - OI_OBEX_UNAUTHORIZED = 1742, /**< OBEX: authentication was not successful. */ - OI_OBEX_NOT_IMPLEMENTED = 1743, /**< OBEX: Unimplemented feature. */ - OI_OBEX_INVALID_AUTH_DIGEST = 1744, /**< OBEX: An authentication digest was bad. */ - OI_OBEX_INVALID_OPERATION = 1745, /**< OBEX: Operation not allowed at this time. */ - OI_OBEX_DATABASE_FULL = 1746, /**< OBEX: Sync database full. */ - OI_OBEX_DATABASE_LOCKED = 1747, /**< OBEX: Sync database locked. */ - OI_OBEX_INTERNAL_SERVER_ERROR = 1748, /**< OBEX: response Internal Server Error */ - OI_OBEX_UNSUPPORTED_MEDIA_TYPE = 1749, /**< OBEX: response Unsupported Media Type */ - OI_OBEX_PARTIAL_CONTENT = 1750, /**< OBEX: response Partial Content */ - OI_OBEX_METHOD_NOT_ALLOWED = 1751, /**< OBEX: response Method Not Allowed */ - OI_OBEXSRV_INCOMPLETE_GET = 1752, /**< OBEX: Indicates to a GET handler that the request phase is still in progress */ - OI_OBEX_FOLDER_BROWSING_NOT_ALLOWED = 1753, /**< OBEX: Indicates that an FTP server does not allow folder browsing */ - OI_OBEX_SERVER_FORCED_DISCONNECT = 1754, /**< OBEX: connection was forcibly terminated by the server */ - OI_OBEX_OFS_ERROR = 1755, /**< OBEX: OPP object file system error occurred */ - OI_OBEX_FILEOP_ERROR = 1756, /**< OBEX: FTP/PBAP file operation system error occurred */ - OI_OBEX_USERID_TOO_LONG = 1757, /**< OBEX: User Id exceeds spec limited length limit. */ - - OI_HANDSFREE_EVENT_REPORTING_DISABLED = 1801, /**< HANDSFREE: Event reporting disabled */ - OI_HANDSFREE_NOT_CONNECTED = 1802, /**< HANDSFREE: Not connected */ - OI_HANDSFREE_SERVICE_NOT_STARTED = 1803, /**< HANDSFREE: Cannot connect to handsfree AG if handsfree service not started */ - OI_HANDSFREE_AG_SERVICE_NOT_STARTED = 1804, /**< HANDSFREE: Cannot connect to handsfree device if handsfree AG service not started */ - OI_HANDSFREE_COMMAND_IN_PROGRESS = 1805, /**< HANDSFREE: Cannot accept a command at this time */ - OI_HANDSFREE_AUDIO_ALREADY_CONNECTED = 1806, /**< HANDSFREE: Audio is already connected */ - OI_HANDSFREE_AUDIO_NOT_CONNECTED = 1807, /**< HANDSFREE: Audio is not connected */ - OI_HANDSFREE_FEATURE_NOT_SUPPORTED = 1808, /**< HANDSFREE: Local or remote feature not supported for requested command */ - - OI_HEADSET_SERVICE_NOT_STARTED = 1901, /**< HEADSET: Cannot connect to headset AG if headset service not started */ - OI_HEADSET_AG_SERVICE_NOT_STARTED = 1902, /**< HEADSET: Cannot connect to headset device if headset AG service not started */ - OI_HEADSET_COMMAND_IN_PROGRESS = 1903, /**< HEADSET: Cannot accept a command at this time */ - - OI_BNEP_INVALID_MTU = 2001, /**< BNEP: The remote device cannot support the minimum BNEP MTU */ - OI_BNEP_SETUP_TIMEOUT = 2002, /**< BNEP: The setup request timed out. */ - OI_BNEP_SERVICE_NOT_REGISTERED = 2003, /**< BNEP: The requested service was not found. */ - OI_BNEP_INVALID_HANDLE = 2004, /**< BNEP: The specified connection handle is not valid. */ - OI_BNEP_RESPONSE_TIMEOUT = 2005, /**< BNEP: The timer for receiving a response has expired. */ - OI_BNEP_INVALID_CONNECTION = 2006, /**< BNEP: Invalid connection */ - OI_BNEP_INVALID_FILTER = 2007, /**< BNEP: The supplied filter was invalid. */ - OI_BNEP_CONNECTION_EXISTS = 2008, /**< BNEP: An attempt was made to create a duplicate connection. */ - OI_BNEP_NOT_INITIALIZED = 2009, /**< BNEP: Init has not been called */ - OI_BNEP_CONNECT_BASE = 2010, /**< BNEP: connection response codes */ - OI_BNEP_CONNECT_FAILED_INVALID_DEST_UUID = 2011, /**< BNEP: connect response code Invalid Dest UUID */ - OI_BNEP_CONNECT_FAILED_INVALID_SOURCE_UUID = 2012, /**< BNEP: connect response code Invalid Source UUID */ - OI_BNEP_CONNECT_FAILED_INVALID_UUID_SIZE = 2013, /**< BNEP: connect response code Invalid UUID Size */ - OI_BNEP_CONNECT_FAILED_NOT_ALLOWED = 2014, /**< BNEP: connect response code Not Allowed */ - OI_BNEP_FILTER_NET_BASE = 2020, /**< BNEP: filter response codes */ - OI_BNEP_FILTER_NET_UNSUPPORTED_REQUEST = 2021, /**< BNEP: filter response code Unsupported Request */ - OI_BNEP_FILTER_NET_FAILED_INVALID_PROTOCOL_TYPE = 2022, /**< BNEP: filter response code Invalid Protocol Type */ - OI_BNEP_FILTER_NET_FAILED_MAX_LIMIT_REACHED = 2023, /**< BNEP: filter response code Max Limit Reached */ - OI_BNEP_FILTER_NET_FAILED_SECURITY = 2024, /**< BNEP: filter response code Security */ - OI_BNEP_FILTER_MULTI_BASE = 2030, /**< BNEP: multicast response codes */ - OI_BNEP_FILTER_MULTI_UNSUPPORTED_REQUEST = 2031, /**< BNEP: multicast response code Unsupported Request */ - OI_BNEP_FILTER_MULTI_FAILED_INVALID_ADDRESS = 2032, /**< BNEP: multicast response code Invalid Address */ - OI_BNEP_FILTER_MULTI_FAILED_MAX_LIMIT_REACHED = 2033, /**< BNEP: multicast response code Max Limit Reached */ - OI_BNEP_FILTER_MULTI_FAILED_SECURITY = 2034, /**< BNEP: multicast response code Security */ - OI_BNEP_LOCAL_DEVICE_MUST_BE_MASTER = 2040, /**< BNEP: Device must be master of the piconet for this function */ - OI_BNEP_PACKET_FILTERED_OUT = 2041, /**< BNEP: Packet did not pass current filters */ - - OI_NETIFC_UP_FAILED = 2101, /**< NETIFC: Could not bring up network interface */ - OI_NETIFC_COULD_NOT_CREATE_THREAD = 2102, /**< NETIFC: Network interface could not create a read thread */ - OI_NETIFC_INITIALIZATION_FAILED = 2103, /**< NETIFC: Error in network interface initialization */ - OI_NETIFC_INTERFACE_ALREADY_UP = 2104, /**< NETIFC: Network interface is already up */ - OI_NETIFC_INTERFACE_NOT_UP = 2105, /**< NETIFC: Network interface is not up */ - OI_NETIFC_PACKET_TOO_BIG = 2106, /**< NETIFC: The packet is too big */ - - OI_PAN_ROLE_ALREADY_REGISTERED = 2201, /**< PAN: This PAN role was already registered */ - OI_PAN_ROLE_NOT_ALLOWED = 2202, /**< PAN: The PAN role is not currently allowed */ - OI_PAN_INCOMPATIBLE_ROLES = 2203, /**< PAN: Only certain local and remote role combinations are permitted */ - OI_PAN_INVALID_ROLE = 2204, /**< PAN: Role specified is not one the defined PAN roles */ - OI_PAN_CONNECTION_IN_PROGRESS = 2205, /**< PAN: A PAN connection is currently being established */ - OI_PAN_USER_ALREADY_CONNECTED = 2206, /**< PAN: PAN user role only allows a single connection */ - OI_PAN_DEVICE_CONNECTED = 2207, /**< PAN: A PAN connection already exists to specified device */ - - OI_CODEC_SBC_NO_SYNCWORD = 2301, /**< CODEC: Couldn't find an SBC SYNCWORD */ - OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA = 2302, /**< CODEC: Not enough data provided to decode an SBC header */ - OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA = 2303, /**< CODEC: Decoded the header, but not enough data to contain the rest of the frame */ - OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA = 2304, /**< CODEC: Not enough audio data for this frame */ - OI_CODEC_SBC_CHECKSUM_MISMATCH = 2305, /**< CODEC: The frame header didn't match the checksum */ - OI_CODEC_SBC_PARTIAL_DECODE = 2306, /**< CODEC: Decoding was successful, but frame data still remains. Next call will provide audio without consuming input data. */ - - OI_FIFOQ_QUEUE_NOT_ALIGNED = 2401, /**< FIFOQ: queue must be 32-bit aligned */ - OI_FIFOQ_INVALID_Q = 2402, /**< FIFOQ: queue parameter is not a valid queue */ - OI_FIFOQ_BUF_TOO_LARGE = 2403, /**< FIFOQ: attempt to queue a buffer which is too large */ - OI_FIFOQ_FULL = 2404, /**< FIFOQ: enqueue() failed, queue is full */ - OI_FIFOQ_NOT_ALLOCATED = 2405, /**< FIFOQ: Enqueue QBuf() failed, buffer not allocated */ - OI_FIFOQ_INVALID_DATA_PTR = 2406, /**< FIFOQ: Enqueue QBuf() failed, data pointer does not match */ - - OI_HID_HOST_SERVICE_NOT_STARTED = 2601, /**< HID: Cannot connect to a HID device unless HID host is started */ - OI_HID_DEVICE_SERVICE_NOT_STARTED = 2602, /**< HID: Cannot connect to a HID host unless HID device is started */ - - OI_AT_ERROR = 2701, /**< AT: ERROR response */ - OI_AT_NO_CARRIER = 2702, /**< AT: NO CARRIER response */ - OI_AT_BUSY = 2703, /**< AT: BUSY response */ - OI_AT_NO_ANSWER = 2704, /**< AT: NO ANSWER response */ - OI_AT_DELAYED = 2705, /**< AT: DELAYED response */ - OI_AT_BLACKLISTED = 2706, /**< AT: BLACKLISTED response */ - OI_AT_CME_ERROR = 2707, /**< AT: +CME ERROR response */ - OI_AT_CMS_ERROR = 2708, /**< AT: +CMS ERROR response */ - - OI_BLST_CHARACTER_TIMEOUT = 2801, /**< BLST: Timeout expired while waiting for a character from the client. */ - OI_BLST_ACKNOWLDGE_TIMEOUT = 2802, /**< BLST: Timeout expired while waiting for event acknowledgment from the client */ - OI_BLST_TX_NOT_READY = 2803, /**< BLST: BLST is not ready to send a BHAPI message to the client. */ - OI_BLST_TX_BUSY = 2804, /**< BLST: BLST transmit buffer is in use. */ - - OI_AVDTP_CONNECTION_SEQ_ERROR = 2901, /**< AVDTP: sequencing of signalling/media channel connections broken. */ - OI_AVDTP_OUT_OF_RESOURCES = 2902, /**< AVDTP: Tried to allocate too many endpoints or signalling channels. */ - - OI_PBAP_REPOSITORY_NOT_SET = 3001, /**< PBAP: Phonebook repository must be set for operation to complete. */ - OI_PBAP_PHONEBOOK_NOT_SET = 3002, /**< PBAP: Phonebook be set for operation to complete. */ - - OI_AADP_BAD_ENDPOINT = 3101, /**< AADP: Invalid local endpoint specified */ - OI_AADP_BAD_STATE = 3102, /**< AADP: AADP State is not correct for this operation. */ - - OI_UNICODE_INVALID_SOURCE = 3200, /**< Unicode Conversion: Source string has invalid character encoding. */ - OI_UNICODE_SOURCE_EXHAUSTED = 3201, /**< Unicode Conversion: Incomplete Unicode character at end of source buffer. */ - OI_UNICODE_DESTINATION_EXHAUSTED = 3202, /**< Unicode Conversion: Destination buffer not large enough to hold resulting Unicode string. */ - - OI_AVRCP_TOO_MANY_CONNECTIONS = 3300, /**< AVRCP: Exceeded maximum number of simultaneous AVCTP connections. */ - OI_AVRCP_NOT_IMPLEMENTED = 3301, /**< AVRCP: The target does not implement the command specified by the opcode and operand. */ - OI_AVRCP_REJECTED = 3302, /**< AVRCP: The target cannot respond because of invalid operands in command packet. */ - OI_AVRCP_INVALID_RESPONSE = 3303, /**< AVRCP: The controller received the response with invalid parameters */ - OI_AVRCP_RESPONSE_PACKET_OVERFLOW = 3304, /**< AVRCP: The response message does not fir in one AVRCP packet (512 bytes), has to be fragmented. */ - OI_AVRCP_RESPONSE_INVALID_PDU = 3305, /**< AVRCP: Command rejected: target received a PDU that it did not understand. */ - OI_AVRCP_RESPONSE_INVALID_PARAMETER = 3306, /**< AVRCP: Command rejected: target received a PDU with a parameter ID that it did not understand. */ - OI_AVRCP_RESPONSE_PARAMETER_NOT_FOUND = 3307, /**< AVRCP: Command rejected: specified parameter not found, sent if the parameter ID is understood, but content is wrong or corrupted.*/ - OI_AVRCP_RESPONSE_INTERNAL_ERROR = 3308, /**< AVRCP: Command rejected: target detected other error conditions. */ - OI_MAX_BM3_STATUS_VAL, /* Maximum BM3 status code */ - - /* Status code values reserved for BM3 SDK platform-specific implementations */ - OI_STATUS_RESERVED_FOR_BCOT = 9000, - - /* Status code values reserved for BHAPI products */ - OI_STATUS_RESERVED_FOR_BHAPI = 9200, - - /* Status code values reserved for Soundabout products */ - OI_STATUS_RESERVED_FOR_SOUNDABOUT = 9400, - - /* - * Status code values greater than or equal to this value are reserved for use by applications. - * However, because of differences between compilers, and differences between 16-bit and 32-bit - * platforms custom status codes should be in the 16-bit range, so status codes can range from 0 - * to 65534, inclusive (65535 is reserved) - */ - OI_STATUS_RESERVED_FOR_APPS = 10000, - - - - OI_STATUS_NONE = 0xffff /**< Special status code to indicate that there is no status. (Only to be used for special cases involving OI_SLOG_ERROR() and OI_SLOG_WARNING().) */ - -} OI_STATUS; - - -/* Remeber to update the #define below when new reserved blocks are added to - * the list above. */ -#define OI_NUM_RESERVED_STATUS_BLOCKS 4 /**< Number of status code blocks reserved, including user apps */ - - -/** - * Test for success - */ -#define OI_SUCCESS(x) ((x) == OI_OK) - -/*****************************************************************************/ -#ifdef __cplusplus -} -#endif - -/**@}*/ - -#endif /* _OI_STATUS_H */ - diff --git a/tools/sdk/include/bluedroid/oi_stddefs.h b/tools/sdk/include/bluedroid/oi_stddefs.h deleted file mode 100644 index 9ab424db..00000000 --- a/tools/sdk/include/bluedroid/oi_stddefs.h +++ /dev/null @@ -1,232 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 The Android Open Source Project - * Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef OI_STDDEFS_H -#define OI_STDDEFS_H -/** - * @file - * This file contains BM3 standard type definitions. - * - */ - -/********************************************************************************** - $Revision: #1 $ -***********************************************************************************/ - -#include "oi_cpu_dep.h" - -/** \addtogroup Misc Miscellaneous APIs */ -/**@{*/ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef FALSE -#define FALSE 0 /**< This define statement sets FALSE as a preprocessor alias for 0. */ -#endif - -#ifndef TRUE -#define TRUE (!FALSE) /**< This define statement sets TRUE as a preprocessor alias for !FALSE. */ -#endif - -#ifdef HEW_TOOLCHAIN -#ifdef NULL -#undef NULL /**< Override HEW toolchain NULL definition */ -#endif -#define NULL 0 /**< HEW toolchain does not allow us to compare (void*) type to function pointer */ -#else -#ifndef NULL -#define NULL ((void*)0) /**< This define statement sets NULL as a preprocessor alias for (void*)0 */ -#endif -#endif - -/** - * @name Maximum and minimum values for basic types - * @{ - */ -#define OI_INT8_MIN ((OI_INT8)0x80) /**< decimal value: -128 */ -#define OI_INT8_MAX ((OI_INT8)0x7F) /**< decimal value: 127 */ -#define OI_INT16_MIN ((OI_INT16)0x8000) /**< decimal value: -32768 */ -#define OI_INT16_MAX ((OI_INT16)0x7FFF) /**< decimal value: 32767 */ -#define OI_INT32_MIN ((OI_INT32)0x80000000) /**< decimal value: -2,147,483,648 */ -#define OI_INT32_MAX ((OI_INT32)0x7FFFFFFF) /**< decimal value: 2,147,483,647 */ -#define OI_UINT8_MIN ((OI_UINT8)0) /**< decimal value: 0 */ -#define OI_UINT8_MAX ((OI_UINT8)0xFF) /**< decimal value: 255 */ -#define OI_UINT16_MIN ((OI_UINT16)0) /**< decimal value: 0 */ -#define OI_UINT16_MAX ((OI_UINT16)0xFFFF) /**< decimal value: 65535 */ -#define OI_UINT32_MIN ((OI_UINT32)0) /**< decimal value: 0 */ -#define OI_UINT32_MAX ((OI_UINT32)0xFFFFFFFF) /**< decimal value: 4,294,967,295 */ - -/** - * @} - */ - -/** - * @name Integer types required by the Service Discovery Protocol - * @{ - */ - -/** unsigned 64-bit integer as a structure of two unsigned 32-bit integers */ -typedef struct { - OI_UINT32 I1; /**< most significant 32 bits */ - OI_UINT32 I2; /**< least significant 32 bits */ -} OI_UINT64; - -#define OI_UINT64_MIN { (OI_UINT32)0x00000000, (OI_UINT32)0x00000000 } -#define OI_UINT64_MAX { (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF } - -/** signed 64-bit integer as a structure of one unsigned 32-bit integer and one signed 32-bit integer */ -typedef struct { - OI_INT32 I1; /**< most significant 32 bits as a signed integer */ - OI_UINT32 I2; /**< least significant 32 bits as an unsigned integer */ -} OI_INT64; - -#define OI_INT64_MIN { (OI_INT32)0x80000000, (OI_UINT32)0x00000000 } -#define OI_INT64_MAX { (OI_INT32)0X7FFFFFFF, (OI_UINT32)0XFFFFFFFF } - -/** unsigned 128-bit integer as a structure of four unsigned 32-bit integers */ -typedef struct { - OI_UINT32 I1; /**< most significant 32 bits */ - OI_UINT32 I2; /**< second-most significant 32 bits */ - OI_UINT32 I3; /**< third-most significant 32 bits */ - OI_UINT32 I4; /**< least significant 32 bits */ -} OI_UINT128; - -#define OI_UINT128_MIN { (OI_UINT32)0x00000000, (OI_UINT32)0x00000000, (OI_UINT32)0x00000000, (OI_UINT32)0x00000000 } -#define OI_UINT128_MAX { (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF } - -/** signed 128-bit integer as a structure of three unsigned 32-bit integers and one signed 32-bit integer */ -typedef struct { - OI_INT32 I1; /**< most significant 32 bits as a signed integer */ - OI_UINT32 I2; /**< second-most significant 32 bits as an unsigned integer */ - OI_UINT32 I3; /**< third-most significant 32 bits as an unsigned integer */ - OI_UINT32 I4; /**< least significant 32 bits as an unsigned integer */ -} OI_INT128; - -#define OI_INT128_MIN { (OI_UINT32)0x80000000, (OI_UINT32)0x00000000, (OI_UINT32)0x00000000, (OI_UINT32)0x00000000 } -#define OI_INT128_MAX { (OI_UINT32)0X7FFFFFFF, (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF } - -/** - * @} - */ - - -/** - * type for ASCII character data items - */ -typedef char OI_CHAR; - -/** - * type for double-byte character data items - */ -typedef OI_UINT16 OI_CHAR16; - -/** - * types for UTF encoded strings. - */ -typedef OI_UINT8 OI_UTF8; -typedef OI_UINT16 OI_UTF16; -typedef OI_UINT32 OI_UTF32; - - -/** - * @name Single-bit operation macros - * @{ - * In these macros, x is the data item for which a bit is to be tested or set and y specifies which bit - * is to be tested or set. - */ - -/** This macro's value is TRUE if the bit specified by y is set in data item x. */ -#define OI_BIT_TEST(x,y) ((x) & (y)) - -/** This macro's value is TRUE if the bit specified by y is not set in data item x. */ -#define OI_BIT_CLEAR_TEST(x,y) (((x) & (y)) == 0) - -/** This macro sets the bit specified by y in data item x. */ -#define OI_BIT_SET(x,y) ((x) |= (y)) - -/** This macro clears the bit specified by y in data item x. */ -#define OI_BIT_CLEAR(x,y) ((x) &= ~(y)) - -/** @} */ - -/** - * The OI_ARRAYSIZE macro is set to the number of elements in an array - * (instead of the number of bytes, which is returned by sizeof()). - */ - -#ifndef OI_ARRAYSIZE -#define OI_ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) -#endif - -/** - * @name Preprocessor aliases for individual bit positions - * Bits are defined here only if they are not already defined. - * @{ - */ - -#ifndef BIT0 - -#define BIT0 0x00000001 /**< preprocessor alias for 32-bit value with bit 0 set, used to specify this single bit */ -#define BIT1 0x00000002 /**< preprocessor alias for 32-bit value with bit 1 set, used to specify this single bit */ -#define BIT2 0x00000004 /**< preprocessor alias for 32-bit value with bit 2 set, used to specify this single bit */ -#define BIT3 0x00000008 /**< preprocessor alias for 32-bit value with bit 3 set, used to specify this single bit */ -#define BIT4 0x00000010 /**< preprocessor alias for 32-bit value with bit 4 set, used to specify this single bit */ -#define BIT5 0x00000020 /**< preprocessor alias for 32-bit value with bit 5 set, used to specify this single bit */ -#define BIT6 0x00000040 /**< preprocessor alias for 32-bit value with bit 6 set, used to specify this single bit */ -#define BIT7 0x00000080 /**< preprocessor alias for 32-bit value with bit 7 set, used to specify this single bit */ -#define BIT8 0x00000100 /**< preprocessor alias for 32-bit value with bit 8 set, used to specify this single bit */ -#define BIT9 0x00000200 /**< preprocessor alias for 32-bit value with bit 9 set, used to specify this single bit */ -#define BIT10 0x00000400 /**< preprocessor alias for 32-bit value with bit 10 set, used to specify this single bit */ -#define BIT11 0x00000800 /**< preprocessor alias for 32-bit value with bit 11 set, used to specify this single bit */ -#define BIT12 0x00001000 /**< preprocessor alias for 32-bit value with bit 12 set, used to specify this single bit */ -#define BIT13 0x00002000 /**< preprocessor alias for 32-bit value with bit 13 set, used to specify this single bit */ -#define BIT14 0x00004000 /**< preprocessor alias for 32-bit value with bit 14 set, used to specify this single bit */ -#define BIT15 0x00008000 /**< preprocessor alias for 32-bit value with bit 15 set, used to specify this single bit */ -#define BIT16 0x00010000 /**< preprocessor alias for 32-bit value with bit 16 set, used to specify this single bit */ -#define BIT17 0x00020000 /**< preprocessor alias for 32-bit value with bit 17 set, used to specify this single bit */ -#define BIT18 0x00040000 /**< preprocessor alias for 32-bit value with bit 18 set, used to specify this single bit */ -#define BIT19 0x00080000 /**< preprocessor alias for 32-bit value with bit 19 set, used to specify this single bit */ -#define BIT20 0x00100000 /**< preprocessor alias for 32-bit value with bit 20 set, used to specify this single bit */ -#define BIT21 0x00200000 /**< preprocessor alias for 32-bit value with bit 21 set, used to specify this single bit */ -#define BIT22 0x00400000 /**< preprocessor alias for 32-bit value with bit 22 set, used to specify this single bit */ -#define BIT23 0x00800000 /**< preprocessor alias for 32-bit value with bit 23 set, used to specify this single bit */ -#define BIT24 0x01000000 /**< preprocessor alias for 32-bit value with bit 24 set, used to specify this single bit */ -#define BIT25 0x02000000 /**< preprocessor alias for 32-bit value with bit 25 set, used to specify this single bit */ -#define BIT26 0x04000000 /**< preprocessor alias for 32-bit value with bit 26 set, used to specify this single bit */ -#define BIT27 0x08000000 /**< preprocessor alias for 32-bit value with bit 27 set, used to specify this single bit */ -#define BIT28 0x10000000 /**< preprocessor alias for 32-bit value with bit 28 set, used to specify this single bit */ -#define BIT29 0x20000000 /**< preprocessor alias for 32-bit value with bit 29 set, used to specify this single bit */ -#define BIT30 0x40000000 /**< preprocessor alias for 32-bit value with bit 30 set, used to specify this single bit */ -#define BIT31 0x80000000 /**< preprocessor alias for 32-bit value with bit 31 set, used to specify this single bit */ - -#endif /* BIT0 et al */ - - -/** @} */ - - -#ifdef __cplusplus -} -#endif - -/**@}*/ - -/*****************************************************************************/ -#endif /* OI_STDDEFS_H */ diff --git a/tools/sdk/include/bluedroid/oi_string.h b/tools/sdk/include/bluedroid/oi_string.h deleted file mode 100644 index 928acb07..00000000 --- a/tools/sdk/include/bluedroid/oi_string.h +++ /dev/null @@ -1,208 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 The Android Open Source Project - * Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef OI_STRING_H -#define OI_STRING_H -/** - * @file - * This file contains BM3 supplied portable string.h functions - * - */ - -/********************************************************************************** - $Revision: #1 $ -***********************************************************************************/ - -#include "oi_cpu_dep.h" -#include "oi_stddefs.h" - -#if defined(USE_NATIVE_MEMCPY) || defined(USE_NATIVE_MALLOC) -#include -#endif - -/** \addtogroup Misc Miscellaneous APIs */ -/**@{*/ - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * If we are using Native malloc(), we must also use - * native Ansi string.h functions for memory manipulation. - */ -#ifdef USE_NATIVE_MALLOC -#ifndef USE_NATIVE_MEMCPY -#define USE_NATIVE_MEMCPY -#endif -#endif - -#ifdef USE_NATIVE_MEMCPY - -#define OI_MemCopy(to, from, size) memcpy((to), (from), (size)) -#define OI_MemSet(block, val, size) memset((block), (val), (size)) -#define OI_MemZero(block, size) memset((block), 0, (size)) -#define OI_MemCmp(s1, s2, n) memcmp((s1), (s2), (n)) -#define OI_Strcpy(dest, src) strcpy((dest),(src)) -#define OI_Strcat(dest, src) strcat((dest),(src)) -#define OI_StrLen(str) strlen((str)) -#define OI_Strcmp(s1, s2) strcmp((s1), (s2)) -#define OI_Strncmp(s1, s2, n) strncmp((s1), (s2), (n)) - -#else - -/* - * OI_MemCopy - * - * Copy an arbitrary number of bytes from one memory address to another. - * The underlying implementation is the ANSI memmove() or equivalant, so - * overlapping memory copies will work correctly. - */ -void OI_MemCopy(void *To, void const *From, OI_UINT32 Size); - - -/* - * OI_MemSet - * - * Sets all bytes in a block of memory to the same value - */ -void OI_MemSet(void *Block, OI_UINT8 Val, OI_UINT32 Size); - - -/* - * OI_MemZero - * - * Sets all bytes in a block of memory to zero - */ -void OI_MemZero(void *Block, OI_UINT32 Size); - - -/* - * OI_MemCmp - * - * Compare two blocks of memory - * - * Returns: - * 0, if s1 == s2 - * < 0, if s1 < s2 - * > 0, if s2 > s2 - */ -OI_INT OI_MemCmp(void const *s1, void const *s2, OI_UINT32 n); - -/* - * OI_Strcpy - * - * Copies the Null terminated string from pStr to pDest, and - * returns pDest. - */ - -OI_CHAR *OI_Strcpy(OI_CHAR *pDest, - OI_CHAR const *pStr); - -/* - * OI_Strcat - * - * Concatonates the pStr string to the end of pDest, and - * returns pDest. - */ - -OI_CHAR *OI_Strcat(OI_CHAR *pDest, - OI_CHAR const *pStr) ; - -/* - * OI_StrLen - * - * Calculates the number of OI_CHARs in pStr (not including - * the Null terminator) and returns the value. - */ -OI_UINT OI_StrLen(OI_CHAR const *pStr) ; - -/* - * OI_Strcmp - * - * Compares two Null terminated strings - * - * Returns: - * 0, if s1 == s2 - * < 0, if s1 < s2 - * > 0, if s2 > s2 - */ -OI_INT OI_Strcmp(OI_CHAR const *s1, - OI_CHAR const *s2); - -/* - * OI_Strncmp - * - * Compares the first "len" OI_CHARs of strings s1 and s2. - * - * Returns: - * 0, if s1 == s2 - * < 0, if s1 < s2 - * > 0, if s2 > s2 - */ -OI_INT OI_Strncmp(OI_CHAR const *s1, - OI_CHAR const *s2, - OI_UINT32 len); - - -#endif /* USE_NATIVE_MEMCPY */ - -/* - * OI_StrcmpInsensitive - * - * Compares two Null terminated strings, treating - * the Upper and Lower case of 'A' through 'Z' as - * equivilent. - * - * Returns: - * 0, if s1 == s2 - * < 0, if s1 < s2 - * > 0, if s2 > s2 - */ -OI_INT OI_StrcmpInsensitive(OI_CHAR const *s1, - OI_CHAR const *s2); - -/* - * OI_StrncmpInsensitive - * - * Compares the first "len" OI_CHARs of strings s1 and s2, - * treating the Upper and Lower case of 'A' through 'Z' as - * equivilent. - * - * - * Returns: - * 0, if s1 == s2 - * < 0, if s1 < s2 - * > 0, if s2 > s2 - */ -OI_INT OI_StrncmpInsensitive(OI_CHAR const *s1, - OI_CHAR const *s2, - OI_UINT len); - - - -#ifdef __cplusplus -} -#endif - -/** @} */ - -/*****************************************************************************/ -#endif /* OI_STRING_H */ - diff --git a/tools/sdk/include/bluedroid/oi_time.h b/tools/sdk/include/bluedroid/oi_time.h deleted file mode 100644 index 40b8dfc4..00000000 --- a/tools/sdk/include/bluedroid/oi_time.h +++ /dev/null @@ -1,200 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 The Android Open Source Project - * Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef _OI_TIME_H -#define _OI_TIME_H -/** @file - * - * This file provides time type definitions and interfaces to time-related functions. - * - * The stack maintains a 64-bit real-time millisecond clock. The choice of - * milliseconds is for convenience, not accuracy. - * - * Timeouts are specified as tenths of seconds in a 32-bit value. Timeout values - * specified by the Bluetooth specification are usually muliple seconds, so - * accuracy to a tenth of a second is more than adequate. - * - * This file also contains macros to convert between seconds and the Link - * Manager's 1.28-second units. - * - */ - -/********************************************************************************** - $Revision: #1 $ -***********************************************************************************/ - -#include "oi_stddefs.h" - - -/** \addtogroup Misc Miscellaneous APIs */ -/**@{*/ - -#ifdef __cplusplus -extern "C" { -#endif - - - -/** - * Within the core stack timeouts are specified in intervals of tenths of seconds - */ - -typedef OI_UINT16 OI_INTERVAL; -#define OI_INTERVALS_PER_SECOND 10 -#define MSECS_PER_OI_INTERVAL (1000 / OI_INTERVALS_PER_SECOND) - -/** maximum interval (54 min 36.7 sec) */ -#define OI_MAX_INTERVAL 0x7fff - - -/** - * Macro to convert seconds to OI_INTERVAL time units - */ - -#define OI_SECONDS(n) ((OI_INTERVAL) ((n) * OI_INTERVALS_PER_SECOND)) - -/** - * Macro to convert milliseconds to OI_INTERVAL time units (Rounded Up) - */ - -#define OI_MSECONDS(n) ((OI_INTERVAL) ((n + MSECS_PER_OI_INTERVAL - 1) / MSECS_PER_OI_INTERVAL)) - -/** - * Macro to convert minutes to OI_INTERVAL time units - */ - -#define OI_MINUTES(n) ((OI_INTERVAL) ((n) * OI_SECONDS(60))) - -/** Convert an OI_INTERVAL to milliseconds. */ -#define OI_INTERVAL_TO_MILLISECONDS(i) ((i) * MSECS_PER_OI_INTERVAL) - -/** - * The stack depends on relative not absolute time. Any mapping between the - * stack's real-time clock and absolute time and date is implementation-dependent. - */ - -typedef struct { - OI_INT32 seconds; - OI_INT16 mseconds; -} OI_TIME; - -/** - * Convert an OI_TIME to milliseconds. - * - * @param t the time to convert - * - * @return the time in milliseconds - */ -OI_UINT32 OI_Time_ToMS(OI_TIME *t); - - -/** - * This function compares two time values. - * - * @param T1 first time to compare. - * - * @param T2 second time to compare. - * - * @return - @verbatim - -1 if t1 < t2 - 0 if t1 = t2 - +1 if t1 > t2 - @endverbatim - */ - -OI_INT16 OI_Time_Compare(OI_TIME *T1, - OI_TIME *T2); - - -/** - * This function returns the interval between two times to a granularity of 0.1 seconds. - * - * @param Sooner a time value more recent that Later - * - * @param Later a time value later than Sooner - * - * @note The result is an OI_INTERVAL value so this function only works for time intervals - * that are less than about 71 minutes. - * - * @return the time interval between the two times = (Later - Sooner) - */ - -OI_INTERVAL OI_Time_Interval(OI_TIME *Sooner, - OI_TIME *Later); - - - -/** - * This function returns the interval between two times to a granularity of milliseconds. - * - * @param Sooner a time value more recent that Later - * - * @param Later a time value later than Sooner - * - * @note The result is an OI_UINT32 value so this function only works for time intervals - * that are less than about 50 days. - * - * @return the time interval between the two times = (Later - Sooner) - */ - -OI_UINT32 OI_Time_IntervalMsecs(OI_TIME *Sooner, - OI_TIME *Later); - - - -/** - * This function answers the question, Have we reached or gone past the target time? - * - * @param pTargetTime target time - * - * @return TRUE means time now is at or past target time - * FALSE means target time is still some time in the future - */ - -OI_BOOL OI_Time_NowReachedTime(OI_TIME *pTargetTime); - -/** - * Convert seconds to the Link Manager 1.28-second units - * Approximate by using 1.25 conversion factor. - */ - -#define OI_SECONDS_TO_LM_TIME_UNITS(lmUnits) ((lmUnits)<4?(lmUnits):(lmUnits)-((lmUnits)>>2)) - - -/** - * Convert Link Manager 1.28-second units to seconds. - * Approximate by using 1.25 conversion factor. - */ - -#define OI_LM_TIME_UNITS_TO_SECONDS(lmUnits) ((lmUnits) + ((lmUnits)>>2)) - -#ifdef __cplusplus -} -#endif - -/**@}*/ - -/* Include for OI_Time_Now() prototype - * Must be included at end to obtain OI_TIME typedef - */ -#include "oi_osinterface.h" - -/*****************************************************************************/ -#endif /* _OI_TIME_H */ - diff --git a/tools/sdk/include/bluedroid/oi_utils.h b/tools/sdk/include/bluedroid/oi_utils.h deleted file mode 100644 index f12ef0d4..00000000 --- a/tools/sdk/include/bluedroid/oi_utils.h +++ /dev/null @@ -1,377 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 The Android Open Source Project - * Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef _OI_UTILS_H -#define _OI_UTILS_H -/** - * @file - * - * This file provides the interface for utility functions. - * Among the utilities are strlen (string length), strcmp (string compare), and - * other string manipulation functions. These are provided for those plaforms - * where this functionality is not available in stdlib. - */ - -/********************************************************************************** - $Revision: #1 $ -***********************************************************************************/ - -#include -#include "oi_common.h" -#include "oi_string.h" -#include "oi_bt_spec.h" - -/** \addtogroup Misc Miscellaneous APIs */ -/**@{*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Opaque type for a callback function handle. See OI_ScheduleCallbackFunction() - */ -typedef OI_UINT32 OI_CALLBACK_HANDLE; - - -/** - * Function prototype for a timed procedure callback. - * - * @param arg Value that was passed into the OI_ScheduleCallback() function - * - */ -typedef void (*OI_SCHEDULED_CALLBACK)(void *arg); - - -/** - * Registers a function to be called when a timeout expires. This API uses BLUEmagic's internal - * function dispatch mechanism, so applications that make extensive use of this facility may need to - * increase the value of DispatchTableSize in the configuration block for the dispatcher (see - * oi_bt_stack_config.h). - * - * @param callbackFunction The function that will be called when the timeout expires - * - * @param arg Value that will be returned as the parameter to the callback function. - * - * @param timeout A timeout expressed in OI_INTERVALs (tenths of seconds). This can be - * zero in which case the callback function will be called as soon as - * possible. - * - * @param handle NULL or a pointer receive the callback handle. - * - * @return OI_OK if the function was reqistered, or an error status. - */ -OI_STATUS OI_ScheduleCallbackFunction(OI_SCHEDULED_CALLBACK callbackFunction, - void *arg, - OI_INTERVAL timeout, - OI_CALLBACK_HANDLE *handle); - - -/** - * Cancels a function registered with OI_ScheduleCallbackFunction() before its timer expires. - * - * @param handle handle returned by OI_ScheduleCallbackFunction(). - * - * @return OI_OK if the function was cancelled, or an error status. - */ -OI_STATUS OI_CancelCallbackFunction(OI_CALLBACK_HANDLE handle); - - -/** - * Registers a function to be called when a timeout expires. This version does not return a handle - * so can only be canceled by calling OI_CancelCallback(). - * - * @param callbackFunction The function that will be called when the timeout expires - * - * @param arg Value that will be returned as the parameter to the callback function. - * - * @param timeout A timeout expressed in OI_INTERVALs (tenths of seconds). This can be - * zero in which case the callback function will be called as soon as - * possible. - * - * @return OI_OK if the function was reqistered, or an error status. - */ -#define OI_ScheduleCallback(f, a, t) OI_ScheduleCallbackFunction(f, a, t, NULL); - - -/** - * Cancels a function registered with OI_ScheduleCallback() before its timer expires. This - * function will cancel the first entry matches the indicated callback function pointer. - * - * @param callbackFunction The function that was originally registered - * - * @return OI_OK if the function was cancelled, or an error status. - */ -OI_STATUS OI_CancelCallback(OI_SCHEDULED_CALLBACK callbackFunction); - - -/** - * Parse a Bluetooth device address from the specified string. - * - * @param str the string to parse - * @param addr the parsed address, if successful - * - * @return TRUE if an address was successfully parsed, FALSE otherwise - */ - -OI_BOOL OI_ParseBdAddr(const OI_CHAR *str, - OI_BD_ADDR *addr) ; - -/** - * Printf function for platforms which have no stdio or printf available. - * OI_Printf supports the basic formatting types, with the exception of - * floating point types. Additionally, OI_Printf supports several formats - * specific to BLUEmagic 3.0 software: - * - * \%! prints the string for an #OI_STATUS value. - * @code OI_Printf("There was an error %!", status); @endcode - * - * \%@ prints a hex dump of a buffer. - * Requires a pointer to the buffer and a signed integer length - * (0 for default length). If the buffer is large, only an excerpt will - * be printed. - * @code OI_Printf("Contents of buffer %@", buffer, sizeof(buffer)); @endcode - * - * \%: prints a Bluetooth address in the form "HH:HH:HH:HH:HH:HH". - * Requires a pointer to an #OI_BD_ADDR. - * @code OI_Printf("Bluetooth address %:", &bdaddr); @endcode - * - * \%^ decodes and prints a data element as formatted XML. - * Requires a pointer to an #OI_DATAELEM. - * @code OI_Printf("Service attribute list is:\n%^", &attributes); @endcode - * - * \%/ prints the base file name of a path, that is, the final substring - * following a '/' or '\\' character. Requires a pointer to a null - * terminated string. - * @code OI_Printf("File %/", "c:\\dir1\\dir2\\file.txt"); @endcode - * - * \%~ prints a string, escaping characters as needed to display it in - * ASCII. Requires a pointer to an #OI_PSTR and an #OI_UNICODE_ENCODING - * parameter. - * @code OI_Printf("Identifier %~", &id, OI_UNICODE_UTF16_BE); @endcode - * - * \%[ inserts an ANSI color escape sequence. Requires a single character - * identifying the color to select. Colors are red (r/R), green (g/G), - * blue (b/B), yellow (y/Y), cyan (c/C), magenta (m/M), white (W), - * light-gray (l/L), dark-gray (d/D), and black (0). The lower case is - * dim, the upper case is bright (except in the case of light-gray and - * dark-gray, where bright and dim are identical). Any other value will - * select the default color. - * @code OI_Printf("%[red text %[black %[normal\n", 'r', '0', 0); @endcode - * - * \%a same as \%s, except '\\r' and '\\n' are output as "" and "". - * \%?a is valid, but \%la is not. - * - * \%b prints an integer in base 2. - * @code OI_Printf("Bits are %b", I); @endcode - * - * \%lb prints a long integer in base 2. - * - * \%?b prints the least significant N bits of an integer (or long integer) - * in base 2. Requires the integer and a length N. - * @code OI_Printf("Bottom 4 bits are: %?b", I, 4); @endcode - * - * \%B prints an integer as boolean text, "TRUE" or "FALSE". - * @code OI_Printf("The value 0 is %B, the value 1 is %B", 0, 1); @endcode - * - * \%?s prints a substring up to a specified maximum length. - * Requires a pointer to a string and a length parameter. - * @code OI_Printf("String prefix is %?s", str, 3); @endcode - * - * \%ls same as \%S. - * - * \%S prints a UTF16 string as UTF8 (plain ASCII, plus 8-bit char sequences - * where needed). Requires a pointer to #OI_CHAR16. \%?S is valid. The - * length parameter is in OI_CHAR16 characters. - * - * \%T prints time, formatted as "secs.msecs". - * Requires pointer to #OI_TIME struct, NULL pointer prints current time. - * @code OI_Printf("The time now is %T", NULL); @endcode - * - * @param format The format string - * - */ -void OI_Printf(const OI_CHAR *format, ...); - - -/** - * Var-args version OI_Printf - * - * @param format Same as for OI_Printf. - * - * @param argp Var-args list. - */ -void OI_VPrintf(const OI_CHAR *format, va_list argp); - - -/** - * Writes a formatted string to a buffer. This function supports the same format specifiers as - * OI_Printf(). - * - * @param buffer Destination buffer for the formatted string. - * - * @param bufLen The length of the destination buffer. - * - * @param format The format string - * - * @return Number of characters written or -1 in the case of an error. - */ -OI_INT32 OI_SNPrintf(OI_CHAR *buffer, - OI_UINT16 bufLen, - const OI_CHAR *format, ...); - - -/** - * Var-args version OI_SNPrintf - * - * @param buffer Destination buffer for the formatted string. - * - * @param bufLen The length of the destination buffer. - * - * @param format The format string - * - * @param argp Var-args list. - * - * @return Number of characters written or -1 in the case of an error. - */ -OI_INT32 OI_VSNPrintf(OI_CHAR *buffer, - OI_UINT16 bufLen, - const OI_CHAR *format, va_list argp); - - -/** - * Convert a string to an integer. - * - * @param str the string to parse - * - * @return the integer value of the string or 0 if the string could not be parsed - */ -OI_INT OI_atoi(const OI_CHAR *str); - - -/** - * Parse a signed integer in a string. - * - * Skips leading whitespace (space and tabs only) and parses a decimal or hex string. Hex string - * must be prefixed by "0x". Returns pointer to first character following the integer. Returns the - * pointer passed in if the string does not describe an integer. - * - * @param str String to parse. - * - * @param val Pointer to receive the parsed integer value. - * - * @return A pointer to the first character following the integer or the pointer passed in. - */ -const OI_CHAR *OI_ScanInt(const OI_CHAR *str, - OI_INT32 *val); - - -/** - * Parse an unsigned integer in a string. - * - * Skips leading whitespace (space and tabs only) and parses a decimal or hex string. Hex string - * must be prefixed by "0x". Returns pointer to first character following the integer. Returns the - * pointer passed in if the string does not describe an integer. - * - * @param str String to parse. - * - * @param val Pointer to receive the parsed unsigned integer value. - * - * @return A pointer to the first character following the unsigned integer or the pointer passed in. - */ -const OI_CHAR *OI_ScanUInt(const OI_CHAR *str, - OI_UINT32 *val); - -/** - * Parse a whitespace delimited substring out of a string. - * - * @param str Input string to parse. - * @param outStr Buffer to return the substring - * @param len Length of outStr - * - * - * @return A pointer to the first character following the substring or the pointer passed in. - */ -const OI_CHAR *OI_ScanStr(const OI_CHAR *str, - OI_CHAR *outStr, - OI_UINT16 len); - - -/** - * Parse a string for one of a set of alternative value. Skips leading whitespace (space and tabs - * only) and parses text matching one of the alternative strings. Returns pointer to first character - * following the matched text. - * - * @param str String to parse. - * - * @param alts Alternative matching strings separated by '|' - * - * @param index Pointer to receive the index of the matching alternative, return value is -1 if - * there is no match. - * - * @return A pointer to the first character following the matched value or the pointer passed in - * if there was no matching text. - */ -const OI_CHAR *OI_ScanAlt(const OI_CHAR *str, - const OI_CHAR *alts, - OI_INT *index); - -/** - * Parse a string for a BD Addr. Skips leading whitespace (space and tabs only) and parses a - * Bluetooth device address with nibbles optionally separated by colons. Return pointet to first - * character following the BD Addr. - * - * @param str String to parse. - * - * @param addr Pointer to receive the Bluetooth device address - * - * @return A pointer to the first character following the BD Addr or the pointer passed in. - */ -const OI_CHAR *OI_ScanBdAddr(const OI_CHAR *str, - OI_BD_ADDR *addr); - - -/** Get a character from a digit integer value (0 - 9). */ -#define OI_DigitToChar(d) ((d) + '0') - -/** - * Determine Maximum and Minimum between two arguments. - * - * @param a 1st value - * @param b 2nd value - * - * @return the max or min value between a & b - */ -#define OI_MAX(a, b) (((a) < (b)) ? (b) : (a) ) -#define OI_MIN(a, b) (((a) > (b)) ? (b) : (a) ) - -/** - * Compare two BD_ADDRs - * SAME_BD_ADDR - Boolean: TRUE if they are the same address - */ - -#define SAME_BD_ADDR(x, y) (0 == OI_MemCmp((x),(y),OI_BD_ADDR_BYTE_SIZE) ) - -#ifdef __cplusplus -} -#endif - -/**@}*/ - -#endif /* _OI_UTILS_H */ - diff --git a/tools/sdk/include/bluedroid/osi/alarm.h b/tools/sdk/include/bluedroid/osi/alarm.h deleted file mode 100644 index 3dc177c7..00000000 --- a/tools/sdk/include/bluedroid/osi/alarm.h +++ /dev/null @@ -1,80 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _ALARM_H_ -#define _ALARM_H_ - -#include -#include "esp_timer.h" - -typedef struct alarm_t osi_alarm_t; -typedef uint64_t period_ms_t; -typedef esp_timer_cb_t osi_alarm_callback_t; - -typedef enum { - OSI_ALARM_ERR_PASS = 0, - OSI_ALARM_ERR_FAIL = -1, - OSI_ALARM_ERR_INVALID_ARG = -2, - OSI_ALARM_ERR_INVALID_STATE = -3, -} osi_alarm_err_t; - -#define ALARM_CBS_NUM 30 -#define ALARM_ID_BASE 1000 - -int osi_alarm_create_mux(void); -int osi_alarm_delete_mux(void); -void osi_alarm_init(void); -void osi_alarm_deinit(void); - -// Creates a new alarm object. The returned object must be freed by calling -// |alarm_free|. Returns NULL on failure. -osi_alarm_t *osi_alarm_new(const char *alarm_name, osi_alarm_callback_t callback, void *data, period_ms_t timer_expire); - -// Frees an alarm object created by |alarm_new|. |alarm| may be NULL. If the -// alarm is pending, it will be cancelled. It is not safe to call |alarm_free| -// from inside the callback of |alarm|. -void osi_alarm_free(osi_alarm_t *alarm); - -// Sets an alarm to fire |cb| after the given |deadline|. Note that |deadline| is the -// number of milliseconds relative to the current time. |data| is a context variable -// for the callback and may be NULL. |cb| will be called back in the context of an -// unspecified thread (i.e. it will not be called back in the same thread as the caller). -// |alarm| and |cb| may not be NULL. -osi_alarm_err_t osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout); - -// Sets an periodic alarm to fire |cb| each given |period|. -osi_alarm_err_t osi_alarm_set_periodic(osi_alarm_t *alarm, period_ms_t period); - -// This function cancels the |alarm| if it was previously set. When this call -// returns, the caller has a guarantee that the callback is not in progress and -// will not be called if it hasn't already been called. This function is idempotent. -// |alarm| may not be NULL. -osi_alarm_err_t osi_alarm_cancel(osi_alarm_t *alarm); - -// Figure out how much time until next expiration. -// Returns 0 if not armed. |alarm| may not be NULL. -// only for oneshot alarm, not for periodic alarm -// TODO: Remove this function once PM timers can be re-factored -period_ms_t osi_alarm_get_remaining_ms(const osi_alarm_t *alarm); - -// Alarm-related state cleanup -//void alarm_cleanup(void); - -uint32_t osi_time_get_os_boottime_ms(void); - -#endif /*_ALARM_H_*/ diff --git a/tools/sdk/include/bluedroid/osi/allocator.h b/tools/sdk/include/bluedroid/osi/allocator.h deleted file mode 100644 index 888d8134..00000000 --- a/tools/sdk/include/bluedroid/osi/allocator.h +++ /dev/null @@ -1,141 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _ALLOCATOR_H_ -#define _ALLOCATOR_H_ - -#include -#include -#include "esp_heap_caps.h" -#include "sdkconfig.h" - -char *osi_strdup(const char *str); - -void *osi_malloc_func(size_t size); -void *osi_calloc_func(size_t size); -void osi_free_func(void *ptr); - -#ifdef CONFIG_BLUEDROID_MEM_DEBUG - -void osi_mem_dbg_init(void); -void osi_mem_dbg_record(void *p, int size, const char *func, int line); -void osi_mem_dbg_clean(void *p, const char *func, int line); -void osi_mem_dbg_show(void); - -#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST -#define osi_malloc(size) \ -({ \ - void *p; \ - p = heap_caps_malloc_prefer(size, 2, \ - MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \ - MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \ - osi_mem_dbg_record(p, size, __func__, __LINE__); \ - (void *)p; \ -}) - -#define osi_calloc(size) \ -({ \ - void *p; \ - p = heap_caps_calloc_prefer(1, size, 2, \ - MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \ - MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \ - osi_mem_dbg_record(p, size, __func__, __LINE__); \ - (void *)p; \ -}) - -#else - -#define osi_malloc(size) \ -({ \ - void *p; \ - p = malloc((size)); \ - osi_mem_dbg_record(p, size, __func__, __LINE__); \ - (void *)p; \ -}) - -#define osi_calloc(size) \ -({ \ - void *p; \ - p = calloc(1, (size)); \ - osi_mem_dbg_record(p, size, __func__, __LINE__); \ - (void *)p; \ -}) - -#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */ - - -#if 0 -#define osi_malloc(size) \ -do { \ - void *p; \ - \ -#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST \ - p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \ -#else \ - p = malloc((size)); \ -#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */ \ - osi_mem_dbg_record(p, size, __func__, __LINE__); \ - (void *)p; \ -}while(0) - -#define osi_calloc(size) \ -do { \ - void *p; \ - \ -#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST \ - p = heap_caps_calloc_prefer(1, size, 2, \ - MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \ - MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \ -#else \ - p = calloc(1, (size)); \ -#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */ \ - osi_mem_dbg_record(p, size, __func__, __LINE__); \ - (void *)p; \ -} while(0) -#endif - -#define osi_free(ptr) \ -do { \ - void *tmp_point = (void *)(ptr); \ - osi_mem_dbg_clean(tmp_point, __func__, __LINE__); \ - free(tmp_point); \ -} while (0) - -#else - -#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST -#define osi_malloc(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL) -#define osi_calloc(size) heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL) -#else -#define osi_malloc(size) malloc((size)) -#define osi_calloc(size) calloc(1, (size)) -#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */ -#define osi_free(p) free((p)) - -#endif /* CONFIG_BLUEDROID_MEM_DEBUG */ - -#define FREE_AND_RESET(a) \ -do { \ - if (a) { \ - osi_free(a); \ - a = NULL; \ - } \ -}while (0) - - -#endif /* _ALLOCATOR_H_ */ diff --git a/tools/sdk/include/bluedroid/osi/buffer.h b/tools/sdk/include/bluedroid/osi/buffer.h deleted file mode 100644 index fd1b2fa3..00000000 --- a/tools/sdk/include/bluedroid/osi/buffer.h +++ /dev/null @@ -1,59 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _BUFFER_H_ -#define _BUFFER_H_ - -#include -#include - -typedef struct buffer_t buffer_t; - -// Returns a new buffer of |size| bytes. Returns NULL if a buffer could not be -// allocated. |size| must be non-zero. The caller must release this buffer with -// |buffer_free|. -buffer_t *buffer_new(size_t size); - -// Creates a new reference to the buffer |buf|. A reference is indistinguishable -// from the original: writes to the original will be reflected in the reference -// and vice versa. In other words, this function creates an alias to |buf|. The -// caller must release the returned buffer with |buffer_free|. Note that releasing -// the returned buffer does not release |buf|. |buf| must not be NULL. -buffer_t *buffer_new_ref(const buffer_t *buf); - -// Creates a new reference to the last |slice_size| bytes of |buf|. See -// |buffer_new_ref| for a description of references. |slice_size| must be -// greater than 0 and may be at most |buffer_length| -// (0 < slice_size <= buffer_length). |buf| must not be NULL. -buffer_t *buffer_new_slice(const buffer_t *buf, size_t slice_size); - -// Frees a buffer object. |buf| may be NULL. -void buffer_free(buffer_t *buf); - -// Returns a pointer to a writeable memory region for |buf|. All references -// and slices that share overlapping bytes will also be written to when -// writing to the returned pointer. The caller may safely write up to -// |buffer_length| consecutive bytes starting at the address returned by -// this function. |buf| must not be NULL. -void *buffer_ptr(const buffer_t *buf); - -// Returns the length of the writeable memory region referred to by |buf|. -// |buf| must not be NULL. -size_t buffer_length(const buffer_t *buf); - -#endif /*_BUFFER_H_*/ diff --git a/tools/sdk/include/bluedroid/osi/config.h b/tools/sdk/include/bluedroid/osi/config.h deleted file mode 100644 index c1a2f3d5..00000000 --- a/tools/sdk/include/bluedroid/osi/config.h +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __CONFIG_H__ -#define __CONFIG_H__ - -// This module implements a configuration parser. Clients can query the -// contents of a configuration file through the interface provided here. -// The current implementation is read-only; mutations are only kept in -// memory. This parser supports the INI file format. - -// Implementation notes: -// - Key/value pairs that are not within a section are assumed to be under -// the |CONFIG_DEFAULT_SECTION| section. -// - Multiple sections with the same name will be merged as if they were in -// a single section. -// - Empty sections with no key/value pairs will be treated as if they do -// not exist. In other words, |config_has_section| will return false for -// empty sections. -// - Duplicate keys in a section will overwrite previous values. -// - All strings are case sensitive. - -#include - -// The default section name to use if a key/value pair is not defined within -// a section. -#define CONFIG_DEFAULT_SECTION "Global" - -typedef struct config_t config_t; -typedef struct config_section_node_t config_section_node_t; - -// Creates a new config object with no entries (i.e. not backed by a file). -// This function returns a config object or NULL on error. Clients must call -// |config_free| on the returned handle when it is no longer required. -config_t *config_new_empty(void); - -// Loads the specified file and returns a handle to the config file. If there -// was a problem loading the file or allocating memory, this function returns -// NULL. Clients must call |config_free| on the returned handle when it is no -// longer required. |filename| must not be NULL and must point to a readable -// file on the filesystem. -config_t *config_new(const char *filename); - -// Frees resources associated with the config file. No further operations may -// be performed on the |config| object after calling this function. |config| -// may be NULL. -void config_free(config_t *config); - -// Returns true if the config file contains a section named |section|. If -// the section has no key/value pairs in it, this function will return false. -// |config| and |section| must not be NULL. -bool config_has_section(const config_t *config, const char *section); - -// Returns true if the config file has a key named |key| under |section|. -// Returns false otherwise. |config|, |section|, and |key| must not be NULL. -bool config_has_key(const config_t *config, const char *section, const char *key); - -// Returns true if the config file has a key named |key| and the key_value. -// Returns false otherwise. |config|, |key|, and |key_value| must not be NULL. -bool config_has_key_in_section(config_t *config, const char *key, char *key_value); - -// Returns the integral value for a given |key| in |section|. If |section| -// or |key| do not exist, or the value cannot be fully converted to an integer, -// this function returns |def_value|. |config|, |section|, and |key| must not -// be NULL. -int config_get_int(const config_t *config, const char *section, const char *key, int def_value); - -// Returns the boolean value for a given |key| in |section|. If |section| -// or |key| do not exist, or the value cannot be converted to a boolean, this -// function returns |def_value|. |config|, |section|, and |key| must not be NULL. -bool config_get_bool(const config_t *config, const char *section, const char *key, bool def_value); - -// Returns the string value for a given |key| in |section|. If |section| or -// |key| do not exist, this function returns |def_value|. The returned string -// is owned by the config module and must not be freed. |config|, |section|, -// and |key| must not be NULL. |def_value| may be NULL. -const char *config_get_string(const config_t *config, const char *section, const char *key, const char *def_value); - -// Sets an integral value for the |key| in |section|. If |key| or |section| do -// not already exist, this function creates them. |config|, |section|, and |key| -// must not be NULL. -void config_set_int(config_t *config, const char *section, const char *key, int value); - -// Sets a boolean value for the |key| in |section|. If |key| or |section| do -// not already exist, this function creates them. |config|, |section|, and |key| -// must not be NULL. -void config_set_bool(config_t *config, const char *section, const char *key, bool value); - -// Sets a string value for the |key| in |section|. If |key| or |section| do -// not already exist, this function creates them. |config|, |section|, |key|, and -// |value| must not be NULL. -void config_set_string(config_t *config, const char *section, const char *key, const char *value, bool insert_back); - -// Removes |section| from the |config| (and, as a result, all keys in the section). -// Returns true if |section| was found and removed from |config|, false otherwise. -// Neither |config| nor |section| may be NULL. -bool config_remove_section(config_t *config, const char *section); - -// Removes one specific |key| residing in |section| of the |config|. Returns true -// if the section and key were found and the key was removed, false otherwise. -// None of |config|, |section|, or |key| may be NULL. -bool config_remove_key(config_t *config, const char *section, const char *key); - -// Returns an iterator to the first section in the config file. If there are no -// sections, the iterator will equal the return value of |config_section_end|. -// The returned pointer must be treated as an opaque handle and must not be freed. -// The iterator is invalidated on any config mutating operation. |config| may not -// be NULL. -const config_section_node_t *config_section_begin(const config_t *config); - -// Returns an iterator to one past the last section in the config file. It does not -// represent a valid section, but can be used to determine if all sections have been -// iterated over. The returned pointer must be treated as an opaque handle and must -// not be freed and must not be iterated on (must not call |config_section_next| on -// it). |config| may not be NULL. -const config_section_node_t *config_section_end(const config_t *config); - -// Moves |iter| to the next section. If there are no more sections, |iter| will -// equal the value of |config_section_end|. |iter| may not be NULL and must be -// a pointer returned by either |config_section_begin| or |config_section_next|. -const config_section_node_t *config_section_next(const config_section_node_t *iter); - -// Returns the name of the section referred to by |iter|. The returned pointer is -// owned by the config module and must not be freed by the caller. The pointer will -// remain valid until |config_free| is called. |iter| may not be NULL and must not -// equal the value returned by |config_section_end|. -const char *config_section_name(const config_section_node_t *iter); - -// Saves |config| to a file given by |filename|. Note that this could be a destructive -// operation: if |filename| already exists, it will be overwritten. The config -// module does not preserve comments or formatting so if a config file was opened -// with |config_new| and subsequently overwritten with |config_save|, all comments -// and special formatting in the original file will be lost. Neither |config| nor -// |filename| may be NULL. -bool config_save(const config_t *config, const char *filename); - -#endif /* #ifndef __CONFIG_H__ */ diff --git a/tools/sdk/include/bluedroid/osi/fixed_queue.h b/tools/sdk/include/bluedroid/osi/fixed_queue.h deleted file mode 100644 index 5ec0c074..00000000 --- a/tools/sdk/include/bluedroid/osi/fixed_queue.h +++ /dev/null @@ -1,135 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _FIXED_QUEUE_H_ -#define _FIXED_QUEUE_H_ - -#include -#include "osi/list.h" - -#ifndef QUEUE_SIZE_MAX -#define QUEUE_SIZE_MAX 254 -#endif - -struct fixed_queue_t; - -typedef struct fixed_queue_t fixed_queue_t; -//typedef struct reactor_t reactor_t; - -typedef void (*fixed_queue_free_cb)(void *data); -typedef void (*fixed_queue_cb)(fixed_queue_t *queue); - -// Creates a new fixed queue with the given |capacity|. If more elements than -// |capacity| are added to the queue, the caller is blocked until space is -// made available in the queue. Returns NULL on failure. The caller must free -// the returned queue with |fixed_queue_free|. -fixed_queue_t *fixed_queue_new(size_t capacity); - -// Freeing a queue that is currently in use (i.e. has waiters -// blocked on it) results in undefined behaviour. -void fixed_queue_free(fixed_queue_t *queue, fixed_queue_free_cb free_cb); - -// Returns a value indicating whether the given |queue| is empty. If |queue| -// is NULL, the return value is true. -bool fixed_queue_is_empty(fixed_queue_t *queue); - -// Returns the length of the |queue|. If |queue| is NULL, the return value -// is 0. -size_t fixed_queue_length(fixed_queue_t *queue); - -// Returns the maximum number of elements this queue may hold. |queue| may -// not be NULL. -size_t fixed_queue_capacity(fixed_queue_t *queue); - -// Enqueues the given |data| into the |queue|. The caller will be blocked -// if nore more space is available in the queue. Neither |queue| nor |data| -// may be NULL. -void fixed_queue_enqueue(fixed_queue_t *queue, void *data); - -// Dequeues the next element from |queue|. If the queue is currently empty, -// this function will block the caller until an item is enqueued. This -// function will never return NULL. |queue| may not be NULL. -void *fixed_queue_dequeue(fixed_queue_t *queue); - -// Tries to enqueue |data| into the |queue|. This function will never block -// the caller. If the queue capacity would be exceeded by adding one more -// element, this function returns false immediately. Otherwise, this function -// returns true. Neither |queue| nor |data| may be NULL. -bool fixed_queue_try_enqueue(fixed_queue_t *queue, void *data); - -// Tries to dequeue an element from |queue|. This function will never block -// the caller. If the queue is empty, this function returns NULL immediately. -// Otherwise, the next element in the queue is returned. |queue| may not be -// NULL. -void *fixed_queue_try_dequeue(fixed_queue_t *queue); - -// Returns the first element from |queue|, if present, without dequeuing it. -// This function will never block the caller. Returns NULL if there are no -// elements in the queue or |queue| is NULL. -void *fixed_queue_try_peek_first(fixed_queue_t *queue); - -// Returns the last element from |queue|, if present, without dequeuing it. -// This function will never block the caller. Returns NULL if there are no -// elements in the queue or |queue| is NULL. -void *fixed_queue_try_peek_last(fixed_queue_t *queue); - -// Tries to remove a |data| element from the middle of the |queue|. This -// function will never block the caller. If the queue is empty or NULL, this -// function returns NULL immediately. |data| may not be NULL. If the |data| -// element is found in the queue, a pointer to the removed data is returned, -// otherwise NULL. -void *fixed_queue_try_remove_from_queue(fixed_queue_t *queue, void *data); - -// Returns the iterateable list with all entries in the |queue|. This function -// will never block the caller. |queue| may not be NULL. -// -// NOTE: The return result of this function is not thread safe: the list could -// be modified by another thread, and the result would be unpredictable. -// TODO: The usage of this function should be refactored, and the function -// itself should be removed. -list_t *fixed_queue_get_list(fixed_queue_t *queue); - -// This function returns a valid file descriptor. Callers may perform one -// operation on the fd: select(2). If |select| indicates that the file -// descriptor is readable, the caller may call |fixed_queue_enqueue| without -// blocking. The caller must not close the returned file descriptor. |queue| -// may not be NULL. -//int fixed_queue_get_enqueue_fd(const fixed_queue_t *queue); - -// This function returns a valid file descriptor. Callers may perform one -// operation on the fd: select(2). If |select| indicates that the file -// descriptor is readable, the caller may call |fixed_queue_dequeue| without -// blocking. The caller must not close the returned file descriptor. |queue| -// may not be NULL. -//int fixed_queue_get_dequeue_fd(const fixed_queue_t *queue); - -// Registers |queue| with |reactor| for dequeue operations. When there is an element -// in the queue, ready_cb will be called. The |context| parameter is passed, untouched, -// to the callback routine. Neither |queue|, nor |reactor|, nor |read_cb| may be NULL. -// |context| may be NULL. -void fixed_queue_register_dequeue(fixed_queue_t *queue, fixed_queue_cb ready_cb); - -// Unregisters the dequeue ready callback for |queue| from whichever reactor -// it is registered with, if any. This function is idempotent. -void fixed_queue_unregister_dequeue(fixed_queue_t *queue); - -void fixed_queue_process(fixed_queue_t *queue); - -list_t *fixed_queue_get_list(fixed_queue_t *queue); - -#endif diff --git a/tools/sdk/include/bluedroid/osi/future.h b/tools/sdk/include/bluedroid/osi/future.h deleted file mode 100644 index 9d1cb521..00000000 --- a/tools/sdk/include/bluedroid/osi/future.h +++ /dev/null @@ -1,53 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef __FUTURE_H__ -#define __FUTURE_H__ - -#include "osi/semaphore.h" - -struct future { - bool ready_can_be_called; - osi_sem_t semaphore; // NULL semaphore means immediate future - void *result; -}; -typedef struct future future_t; - -#define FUTURE_SUCCESS ((void *)1) -#define FUTURE_FAIL ((void *)0) - -// Constructs a new future_t object. Returns NULL on failure. -future_t *future_new(void); - -// Constructs a new future_t object with an immediate |value|. No waiting will -// occur in the call to |future_await| because the value is already present. -// Returns NULL on failure. -future_t *future_new_immediate(void *value); - -// Signals that the |future| is ready, passing |value| back to the context -// waiting for the result. Must only be called once for every future. -// |future| may not be NULL. -void future_ready(future_t *future, void *value); - -// Waits for the |future| to be ready. Returns the value set in |future_ready|. -// Frees the future before return. |future| may not be NULL. -void *future_await(future_t *async_result); - -//Free the future if this "future" is not used -void future_free(future_t *future); -#endif /* __FUTURE_H__ */ diff --git a/tools/sdk/include/bluedroid/osi/hash_functions.h b/tools/sdk/include/bluedroid/osi/hash_functions.h deleted file mode 100644 index 8102a0c1..00000000 --- a/tools/sdk/include/bluedroid/osi/hash_functions.h +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _HASH_FUNCTIONS_H_ -#define _HASH_FUNCTIONS_H_ - -#include "osi/hash_map.h" - -typedef unsigned char hash_key_t[4]; - -hash_index_t hash_function_naive(const void *key); - -hash_index_t hash_function_integer(const void *key); - -// Hashes a pointer based only on its address value -hash_index_t hash_function_pointer(const void *key); - -hash_index_t hash_function_string(const void *key); - -void hash_function_blob(const unsigned char *s, unsigned int len, hash_key_t h); - -#endif /* _HASH_FUNCTIONS_H_ */ diff --git a/tools/sdk/include/bluedroid/osi/hash_map.h b/tools/sdk/include/bluedroid/osi/hash_map.h deleted file mode 100644 index fea1e021..00000000 --- a/tools/sdk/include/bluedroid/osi/hash_map.h +++ /dev/null @@ -1,110 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _HASH_MAP_H_ -#define _HASH_MAP_H_ - -#include -#include - -struct hash_map_t; -typedef struct hash_map_t hash_map_t; - -typedef struct hash_map_entry_t { - const void *key; - void *data; - const hash_map_t *hash_map; -} hash_map_entry_t; - -typedef size_t hash_index_t; - -// Takes a key structure and returns a hash value. -typedef hash_index_t (*hash_index_fn)(const void *key); -typedef bool (*hash_map_iter_cb)(hash_map_entry_t *hash_entry, void *context); - -typedef bool (*key_equality_fn)(const void *x, const void *y); - -typedef void (*key_free_fn)(void *data); -typedef void (*data_free_fn)(void *data); - -// Returns a new, empty hash_map. Returns NULL if not enough memory could be allocated -// for the hash_map structure. The returned hash_map must be freed with |hash_map_free|. -// The |num_bucket| specifies the number of hashable buckets for the map and must not -// be zero. The |hash_fn| specifies a hash function to be used and must not be NULL. -// The |key_fn| and |data_fn| are called whenever a hash_map element is removed from -// the hash_map. They can be used to release resources held by the hash_map element, -// e.g. memory or file descriptor. |key_fn| and |data_fn| may be NULL if no cleanup -// is necessary on element removal. |equality_fn| is used to check for key equality. -// If |equality_fn| is NULL, default pointer equality is used. -hash_map_t *hash_map_new( - size_t size, - hash_index_fn hash_fn, - key_free_fn key_fn, - data_free_fn data_fn, - key_equality_fn equality_fn); - -// Frees the hash_map. This function accepts NULL as an argument, in which case it -// behaves like a no-op. -void hash_map_free(hash_map_t *hash_map); - -// Returns true if the hash_map is empty (has no elements), false otherwise. -// Note that a NULL |hash_map| is not the same as an empty |hash_map|. This function -// does not accept a NULL |hash_map|. -//bool hash_map_is_empty(const hash_map_t *hash_map); - -// Returns the number of elements in the hash map. This function does not accept a -// NULL |hash_map|. -//size_t hash_map_size(const hash_map_t *hash_map); - -// Returns the number of buckets in the hash map. This function does not accept a -// NULL |hash_map|. -//size_t hash_map_num_buckets(const hash_map_t *hash_map); - -// Returns true if the hash_map has a valid entry for the presented key. -// This function does not accept a NULL |hash_map|. -bool hash_map_has_key(const hash_map_t *hash_map, const void *key); - -// Returns the element indexed by |key| in the hash_map without removing it. |hash_map| -// may not be NULL. Returns NULL if no entry indexed by |key|. -void *hash_map_get(const hash_map_t *hash_map, const void *key); - -// Sets the value |data| indexed by |key| into the |hash_map|. Neither |data| nor -// |hash_map| may be NULL. This function does not make copies of |data| nor |key| -// so the pointers must remain valid at least until the element is removed from the -// hash_map or the hash_map is freed. Returns true if |data| could be set, false -// otherwise (e.g. out of memory). -bool hash_map_set(hash_map_t *hash_map, const void *key, void *data); - -// Removes data indexed by |key| from the hash_map. |hash_map| may not be NULL. -// If |key_fn| or |data_fn| functions were specified in |hash_map_new|, they -// will be called back with |key| or |data| respectively. This function returns true -// if |key| was found in the hash_map and removed, false otherwise. -bool hash_map_erase(hash_map_t *hash_map, const void *key); - -// Removes all elements in the hash_map. Calling this function will return the hash_map -// to the same state it was in after |hash_map_new|. |hash_map| may not be NULL. -void hash_map_clear(hash_map_t *hash_map); - -// Iterates through the entire |hash_map| and calls |callback| for each data -// element and passes through the |context| argument. If the hash_map is -// empty, |callback| will never be called. It is not safe to mutate the -// hash_map inside the callback. Neither |hash_map| nor |callback| may be NULL. -// If |callback| returns false, the iteration loop will immediately exit. -void hash_map_foreach(hash_map_t *hash_map, hash_map_iter_cb callback, void *context); - -#endif /* _HASH_MAP_H_ */ diff --git a/tools/sdk/include/bluedroid/osi/list.h b/tools/sdk/include/bluedroid/osi/list.h deleted file mode 100644 index c0abd106..00000000 --- a/tools/sdk/include/bluedroid/osi/list.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef _LIST_H_ -#define _LIST_H_ - -#include -#include -struct list_node_t; -typedef struct list_node_t list_node_t; - -struct list_t; -typedef struct list_t list_t; - -typedef void (*list_free_cb)(void *data); -typedef bool (*list_iter_cb)(void *data, void *context); - -// Returns a new, empty list. Returns NULL if not enough memory could be allocated -// for the list structure. The returned list must be freed with |list_free|. The -// |callback| specifies a function to be called whenever a list element is removed -// from the list. It can be used to release resources held by the list element, e.g. -// memory or file descriptor. |callback| may be NULL if no cleanup is necessary on -// element removal. -list_t *list_new(list_free_cb callback); - - -list_node_t *list_free_node(list_t *list, list_node_t *node); -// Frees the list. This function accepts NULL as an argument, in which case it -// behaves like a no-op. -void list_free(list_t *list); - -// Returns true if |list| is empty (has no elements), false otherwise. -// |list| may not be NULL. -bool list_is_empty(const list_t *list); - -// Returns true if the list contains |data|, false otherwise. -// |list| may not be NULL. -bool list_contains(const list_t *list, const void *data); - -// Returns the length of the |list|. |list| may not be NULL. -size_t list_length(const list_t *list); - -// Returns the first element in the list without removing it. |list| may not -// be NULL or empty. -void *list_front(const list_t *list); - -// Returns the last element in the list without removing it. |list| may not -// be NULL or empty. -void *list_back(const list_t *list); -list_node_t *list_back_node(const list_t *list); - -// Inserts |data| after |prev_node| in |list|. |data|, |list|, and |prev_node| -// may not be NULL. This function does not make a copy of |data| so the pointer -// must remain valid at least until the element is removed from the list or the -// list is freed. Returns true if |data| could be inserted, false otherwise -// (e.g. out of memory). -bool list_insert_after(list_t *list, list_node_t *prev_node, void *data); - -// Inserts |data| at the beginning of |list|. Neither |data| nor |list| may be NULL. -// This function does not make a copy of |data| so the pointer must remain valid -// at least until the element is removed from the list or the list is freed. -// Returns true if |data| could be inserted, false otherwise (e.g. out of memory). -bool list_prepend(list_t *list, void *data); - -// Inserts |data| at the end of |list|. Neither |data| nor |list| may be NULL. -// This function does not make a copy of |data| so the pointer must remain valid -// at least until the element is removed from the list or the list is freed. -// Returns true if |data| could be inserted, false otherwise (e.g. out of memory). -bool list_append(list_t *list, void *data); - -// Removes |data| from the list. Neither |list| nor |data| may be NULL. If |data| -// is inserted multiple times in the list, this function will only remove the first -// instance. If a free function was specified in |list_new|, it will be called back -// with |data|. This function returns true if |data| was found in the list and removed, -// false otherwise. -//list_node_t list_remove_node(list_t *list, list_node_t *prev_node, list_node_t *node); -//list_node_t list_insert_node(list_t *list, list_node_t *prev_node, list_node_t *node); - -bool list_remove(list_t *list, void *data); - -// Removes all elements in the list. Calling this function will return the list to the -// same state it was in after |list_new|. |list| may not be NULL. -void list_clear(list_t *list); - -// Iterates through the entire |list| and calls |callback| for each data element. -// If the list is empty, |callback| will never be called. It is safe to mutate the -// list inside the callback. If an element is added before the node being visited, -// there will be no callback for the newly-inserted node. Neither |list| nor -// |callback| may be NULL. -list_node_t *list_foreach(const list_t *list, list_iter_cb callback, void *context); - -// Returns an iterator to the first element in |list|. |list| may not be NULL. -// The returned iterator is valid as long as it does not equal the value returned -// by |list_end|. -list_node_t *list_begin(const list_t *list); - -// Returns an iterator that points past the end of the list. In other words, -// this function returns the value of an invalid iterator for the given list. -// When an iterator has the same value as what's returned by this function, you -// may no longer call |list_next| with the iterator. |list| may not be NULL. -list_node_t *list_end(const list_t *list); - -// Given a valid iterator |node|, this function returns the next value for the -// iterator. If the returned value equals the value returned by |list_end|, the -// iterator has reached the end of the list and may no longer be used for any -// purpose. -list_node_t *list_next(const list_node_t *node); - -// Returns the value stored at the location pointed to by the iterator |node|. -// |node| must not equal the value returned by |list_end|. -void *list_node(const list_node_t *node); - -#endif /* _LIST_H_ */ diff --git a/tools/sdk/include/bluedroid/osi/mutex.h b/tools/sdk/include/bluedroid/osi/mutex.h deleted file mode 100644 index 65180a78..00000000 --- a/tools/sdk/include/bluedroid/osi/mutex.h +++ /dev/null @@ -1,53 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2015 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef __MUTEX_H__ -#define __MUTEX_H__ - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/semphr.h" - - -#define OSI_MUTEX_MAX_TIMEOUT 0xffffffffUL - -#define osi_mutex_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE ) -#define osi_mutex_set_invalid( x ) ( ( *x ) = NULL ) - -typedef xSemaphoreHandle osi_mutex_t; - -int osi_mutex_new(osi_mutex_t *mutex); - -int osi_mutex_lock(osi_mutex_t *mutex, uint32_t timeout); - -void osi_mutex_unlock(osi_mutex_t *mutex); - -void osi_mutex_free(osi_mutex_t *mutex); - -/* Just for a global mutex */ -int osi_mutex_global_init(void); - -void osi_mutex_global_deinit(void); - -void osi_mutex_global_lock(void); - -void osi_mutex_global_unlock(void); - -#endif /* __MUTEX_H__ */ - diff --git a/tools/sdk/include/bluedroid/osi/osi.h b/tools/sdk/include/bluedroid/osi/osi.h deleted file mode 100644 index 3bd217af..00000000 --- a/tools/sdk/include/bluedroid/osi/osi.h +++ /dev/null @@ -1,16 +0,0 @@ - -#ifndef _OSI_H_ -#define _OSI_H_ - -#include -#include - -#define UNUSED_ATTR __attribute__((unused)) - -#define CONCAT(a, b) a##b -#define COMPILE_ASSERT(x) - -int osi_init(void); -void osi_deinit(void); - -#endif /*_OSI_H_*/ diff --git a/tools/sdk/include/bluedroid/osi/semaphore.h b/tools/sdk/include/bluedroid/osi/semaphore.h deleted file mode 100644 index 621d5a2c..00000000 --- a/tools/sdk/include/bluedroid/osi/semaphore.h +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2015 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef __SEMAPHORE_H__ -#define __SEMAPHORE_H__ - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/semphr.h" - -#define OSI_SEM_MAX_TIMEOUT 0xffffffffUL - -typedef xSemaphoreHandle osi_sem_t; - -#define osi_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE ) -#define osi_sem_set_invalid( x ) ( ( *x ) = NULL ) - -int osi_sem_new(osi_sem_t *sem, uint32_t max_count, uint32_t init_count); - -void osi_sem_free(osi_sem_t *sem); - -int osi_sem_take(osi_sem_t *sem, uint32_t timeout); - -void osi_sem_give(osi_sem_t *sem); - - -#endif /* __SEMAPHORE_H__ */ diff --git a/tools/sdk/include/bluedroid/osi/thread.h b/tools/sdk/include/bluedroid/osi/thread.h deleted file mode 100644 index 1aa773c0..00000000 --- a/tools/sdk/include/bluedroid/osi/thread.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __THREAD_H__ -#define __THREAD_H__ - -#include "freertos/xtensa_api.h" -#include "freertos/FreeRTOSConfig.h" -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" -#include "freertos/task.h" -#include "esp_task.h" -#include "common/bt_defs.h" - -#define portBASE_TYPE int - -struct bt_task_evt { - uint32_t sig; //task sig - void *par; //point to task param - void *cb; //point to function cb - void *arg; //point to function arg -}; -typedef struct bt_task_evt BtTaskEvt_t; - -typedef bt_status_t (* BtTaskCb_t)(void *arg); - -typedef enum { - SIG_HCI_HAL_RECV_PACKET = 0, - SIG_HCI_HAL_NUM, -} SIG_HCI_HAL_t; - - -typedef enum { - SIG_HCI_HOST_SEND_AVAILABLE = 0, - SIG_HCI_HOST_NUM, -} SIG_HCI_HOST_t; - -typedef enum { - SIG_BTU_START_UP = 0, - SIG_BTU_HCI_MSG, - SIG_BTU_BTA_MSG, - SIG_BTU_BTA_ALARM, - SIG_BTU_GENERAL_ALARM, - SIG_BTU_ONESHOT_ALARM, - SIG_BTU_L2CAP_ALARM, - SIG_BTU_NUM, -} SIG_BTU_t; - -#define TASK_PINNED_TO_CORE (CONFIG_BLUEDROID_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BLUEDROID_PINNED_TO_CORE : tskNO_AFFINITY) - -#define HCI_HOST_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE) -#define HCI_HOST_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE) -#define HCI_HOST_TASK_PRIO (configMAX_PRIORITIES - 3) -#define HCI_HOST_TASK_NAME "hciHostT" -#define HCI_HOST_QUEUE_LEN 40 - -#define HCI_H4_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE) -#define HCI_H4_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE) -#define HCI_H4_TASK_PRIO (configMAX_PRIORITIES - 4) -#define HCI_H4_TASK_NAME "hciH4T" -#define HCI_H4_QUEUE_LEN 1 - -#define BTU_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE) -#define BTU_TASK_STACK_SIZE (4096 + BT_TASK_EXTRA_STACK_SIZE) -#define BTU_TASK_PRIO (configMAX_PRIORITIES - 5) -#define BTU_TASK_NAME "btuT" -#define BTU_QUEUE_LEN 50 - -#define BTC_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE) -#define BTC_TASK_STACK_SIZE (CONFIG_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) //by menuconfig -#define BTC_TASK_NAME "btcT" -#define BTC_TASK_PRIO (configMAX_PRIORITIES - 6) -#define BTC_TASK_QUEUE_LEN 60 - -#define BTC_A2DP_SINK_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE) -#define BTC_A2DP_SINK_TASK_STACK_SIZE (CONFIG_A2DP_SINK_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig -#define BTC_A2DP_SINK_TASK_NAME "BtA2dSinkT" -#define BTC_A2DP_SINK_TASK_PRIO (configMAX_PRIORITIES - 3) -#define BTC_A2DP_SINK_DATA_QUEUE_LEN (3) -#define BTC_A2DP_SINK_CTRL_QUEUE_LEN (5) -#define BTC_A2DP_SINK_TASK_QUEUE_SET_LEN (BTC_A2DP_SINK_DATA_QUEUE_LEN + BTC_A2DP_SINK_CTRL_QUEUE_LEN) - -#define BTC_A2DP_SOURCE_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE) -#define BTC_A2DP_SOURCE_TASK_STACK_SIZE (CONFIG_A2DP_SOURCE_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig -#define BTC_A2DP_SOURCE_TASK_NAME "BtA2dSourceT" -#define BTC_A2DP_SOURCE_TASK_PRIO (configMAX_PRIORITIES - 3) -#define BTC_A2DP_SOURCE_DATA_QUEUE_LEN (3) -#define BTC_A2DP_SOURCE_CTRL_QUEUE_LEN (5) -#define BTC_A2DP_SOURCE_TASK_QUEUE_SET_LEN (BTC_A2DP_SOURCE_DATA_QUEUE_LEN + BTC_A2DP_SOURCE_CTRL_QUEUE_LEN) - -#define TASK_POST_NON_BLOCKING (0) -#define TASK_POST_BLOCKING (portMAX_DELAY) -typedef uint32_t task_post_t; /* Timeout of task post return, unit TICK */ - -typedef enum { - TASK_POST_SUCCESS = 0, - TASK_POST_FAIL, -} task_post_status_t; - -task_post_status_t btu_task_post(uint32_t sig, void *param, task_post_t timeout); -task_post_status_t hci_host_task_post(task_post_t timeout); -task_post_status_t hci_hal_h4_task_post(task_post_t timeout); - -#endif /* __THREAD_H__ */ diff --git a/tools/sdk/include/bluedroid/p_256_ecc_pp.h b/tools/sdk/include/bluedroid/p_256_ecc_pp.h deleted file mode 100644 index f91d6056..00000000 --- a/tools/sdk/include/bluedroid/p_256_ecc_pp.h +++ /dev/null @@ -1,67 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2006-2015 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains simple pairing algorithms using Elliptic Curve Cryptography for private public key - * - ******************************************************************************/ - -#pragma once - -#include "p_256_multprecision.h" - -typedef unsigned long DWORD; - -typedef struct { - DWORD x[KEY_LENGTH_DWORDS_P256]; - DWORD y[KEY_LENGTH_DWORDS_P256]; - DWORD z[KEY_LENGTH_DWORDS_P256]; -} Point; - -typedef struct { - // curve's coefficients - DWORD a[KEY_LENGTH_DWORDS_P256]; - DWORD b[KEY_LENGTH_DWORDS_P256]; - - //whether a is -3 - int a_minus3; - - // prime modulus - DWORD p[KEY_LENGTH_DWORDS_P256]; - - // Omega, p = 2^m -omega - DWORD omega[KEY_LENGTH_DWORDS_P256]; - - // base point, a point on E of order r - Point G; - -} elliptic_curve_t; - -extern elliptic_curve_t curve; -extern elliptic_curve_t curve_p256; - -void ECC_PointMult_Bin_NAF(Point *q, Point *p, DWORD *n, uint32_t keyLength); - -bool ECC_CheckPointIsInElliCur_P256(Point *p); - -#define ECC_PointMult(q, p, n, keyLength) ECC_PointMult_Bin_NAF(q, p, n, keyLength) - -void p_256_init_curve(UINT32 keyLength); - - diff --git a/tools/sdk/include/bluedroid/p_256_multprecision.h b/tools/sdk/include/bluedroid/p_256_multprecision.h deleted file mode 100644 index c9a1a4ea..00000000 --- a/tools/sdk/include/bluedroid/p_256_multprecision.h +++ /dev/null @@ -1,62 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2006-2015 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains simple pairing algorithms - * - ******************************************************************************/ -#pragma once - -#include "stack/bt_types.h" - -/* Type definitions */ -typedef unsigned long DWORD; - -#define DWORD_BITS 32 -#define DWORD_BYTES 4 -#define DWORD_BITS_SHIFT 5 - -#define KEY_LENGTH_DWORDS_P192 6 -#define KEY_LENGTH_DWORDS_P256 8 -/* Arithmetic Operations */ - -int multiprecision_compare(DWORD *a, DWORD *b, uint32_t keyLength); -int multiprecision_iszero(DWORD *a, uint32_t keyLength); -void multiprecision_init(DWORD *c, uint32_t keyLength); -void multiprecision_copy(DWORD *c, DWORD *a, uint32_t keyLength); -UINT32 multiprecision_dword_bits (DWORD a); -UINT32 multiprecision_most_signdwords(DWORD *a, uint32_t keyLength); -UINT32 multiprecision_most_signbits(DWORD *a, uint32_t keyLength); -void multiprecision_inv_mod(DWORD *aminus, DWORD *a, uint32_t keyLength); -DWORD multiprecision_add(DWORD *c, DWORD *a, DWORD *b, uint32_t keyLength); // c=a+b -void multiprecision_add_mod(DWORD *c, DWORD *a, DWORD *b, uint32_t keyLength); -DWORD multiprecision_sub(DWORD *c, DWORD *a, DWORD *b, uint32_t keyLength); // c=a-b -void multiprecision_sub_mod(DWORD *c, DWORD *a, DWORD *b, uint32_t keyLength); -void multiprecision_rshift(DWORD *c, DWORD *a, uint32_t keyLength); // c=a>>1, return carrier -void multiprecision_lshift_mod(DWORD *c, DWORD *a, uint32_t keyLength); // c=a<>15) \ -} \ -} -#else -#if (SBC_DSP_OPT==TRUE) -#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) s32OutLow = SBC_Multiply_32_16_Simplified((SINT32)s16In2,s32In1); -#else -#if (SBC_IPAQ_OPT==TRUE) -/*#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) s32OutLow=(SINT32)((SINT32)(s16In2)*(SINT32)(s32In1>>15)); */ -#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) s32OutLow=(SINT32)(((SINT64)s16In2*(SINT64)s32In1)>>15); -#if (SBC_IS_64_MULT_IN_IDCT == TRUE) -#define SBC_MULT_32_32(s32In2, s32In1, s32OutLow) \ -{ \ - s64Temp = ((SINT64) s32In2) * ((SINT64) s32In1)>>31; \ - s32OutLow = (SINT32) s64Temp; \ -} -#endif -#else -#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) \ -{ \ - s32In1Temp = s32In1; \ - s32In2Temp = (SINT32)s16In2; \ - \ - /* Multiply one +ve and the other -ve number */ \ - if (s32In1Temp < 0) \ - { \ - s32In1Temp ^= 0xFFFFFFFF; \ - s32In1Temp++; \ - s32OutLow = (s32In2Temp * (s32In1Temp >> 16)); \ - s32OutLow += (( s32In2Temp * (s32In1Temp & 0xFFFF)) >> 16); \ - s32OutLow ^= 0xFFFFFFFF; \ - s32OutLow++; \ - } \ - else \ - { \ - s32OutLow = (s32In2Temp * (s32In1Temp >> 16)); \ - s32OutLow += (( s32In2Temp * (s32In1Temp & 0xFFFF)) >> 16); \ - } \ - s32OutLow <<= 1; \ -} -#if (SBC_IS_64_MULT_IN_IDCT == TRUE) -#define SBC_MULT_64(s32In1, s32In2, s32OutLow, s32OutHi) \ -{\ - s32OutLow=(SINT32)(((SINT64)s32In1*(SINT64)s32In2)& 0x00000000FFFFFFFF);\ - s32OutHi=(SINT32)(((SINT64)s32In1*(SINT64)s32In2)>>32);\ -} -#define SBC_MULT_32_32(s32In2, s32In1, s32OutLow) \ -{ \ - s32HiTemp = 0; \ - SBC_MULT_64(s32In2,s32In1 , s32OutLow, s32HiTemp); \ - s32OutLow = (((s32OutLow>>15)&0x1FFFF) | (s32HiTemp << 17)); \ -} -#endif - -#endif -#endif -#endif - -#endif diff --git a/tools/sdk/include/bluedroid/sbc_enc_func_declare.h b/tools/sdk/include/bluedroid/sbc_enc_func_declare.h deleted file mode 100644 index cc85b716..00000000 --- a/tools/sdk/include/bluedroid/sbc_enc_func_declare.h +++ /dev/null @@ -1,57 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Function declarations. - * - ******************************************************************************/ - -#ifndef SBC_FUNCDECLARE_H -#define SBC_FUNCDECLARE_H - -/*#include "sbc_encoder.h"*/ -/* Global data */ -#if (SBC_IS_64_MULT_IN_WINDOW_ACCU == FALSE) -extern const SINT16 gas32CoeffFor4SBs[]; -extern const SINT16 gas32CoeffFor8SBs[]; -#else -extern const SINT32 gas32CoeffFor4SBs[]; -extern const SINT32 gas32CoeffFor8SBs[]; -#endif - -/* Global functions*/ - -extern void sbc_enc_bit_alloc_mono(SBC_ENC_PARAMS *CodecParams); -extern void sbc_enc_bit_alloc_ste(SBC_ENC_PARAMS *CodecParams); - -extern void SbcAnalysisInit (void); - -extern void SbcAnalysisFilter4(SBC_ENC_PARAMS *strEncParams); -extern void SbcAnalysisFilter8(SBC_ENC_PARAMS *strEncParams); - -extern void SBC_FastIDCT8 (SINT32 *pInVect, SINT32 *pOutVect); -extern void SBC_FastIDCT4 (SINT32 *x0, SINT32 *pOutVect); - -extern void EncPacking(SBC_ENC_PARAMS *strEncParams); -extern void EncQuantizer(SBC_ENC_PARAMS *); -#if (SBC_DSP_OPT==TRUE) -SINT32 SBC_Multiply_32_16_Simplified(SINT32 s32In2Temp, SINT32 s32In1Temp); -#endif -#endif - diff --git a/tools/sdk/include/bluedroid/sbc_encoder.h b/tools/sdk/include/bluedroid/sbc_encoder.h deleted file mode 100644 index 8a507a7d..00000000 --- a/tools/sdk/include/bluedroid/sbc_encoder.h +++ /dev/null @@ -1,201 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains constants and structures used by Encoder. - * - ******************************************************************************/ - -#ifndef SBC_ENCODER_H -#define SBC_ENCODER_H - -#define ENCODER_VERSION "0025" - -#ifdef BUILDCFG -#include "common/bt_target.h" -#endif - -/*DEFINES*/ -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -#define SBC_MAX_NUM_OF_SUBBANDS 8 -#define SBC_MAX_NUM_OF_CHANNELS 2 -#define SBC_MAX_NUM_OF_BLOCKS 16 - -#define SBC_LOUDNESS 0 -#define SBC_SNR 1 - -#define SUB_BANDS_8 8 -#define SUB_BANDS_4 4 - -#define SBC_sf16000 0 -#define SBC_sf32000 1 -#define SBC_sf44100 2 -#define SBC_sf48000 3 - -#define SBC_MONO 0 -#define SBC_DUAL 1 -#define SBC_STEREO 2 -#define SBC_JOINT_STEREO 3 - -#define SBC_BLOCK_0 4 -#define SBC_BLOCK_1 8 -#define SBC_BLOCK_2 12 -#define SBC_BLOCK_3 16 - -#define SBC_NULL 0 - -#ifndef SBC_MAX_NUM_FRAME -#define SBC_MAX_NUM_FRAME 1 -#endif - -#ifndef SBC_DSP_OPT -#define SBC_DSP_OPT FALSE -#endif - -/* Set SBC_USE_ARM_PRAGMA to TRUE to use "#pragma arm section zidata" */ -#ifndef SBC_USE_ARM_PRAGMA -#define SBC_USE_ARM_PRAGMA FALSE -#endif - -/* Set SBC_ARM_ASM_OPT to TRUE in case the target is an ARM */ -/* this will replace all the 32 and 64 bit mult by in line assembly code */ -#ifndef SBC_ARM_ASM_OPT -#define SBC_ARM_ASM_OPT FALSE -#endif - -/* green hill compiler option -> Used to distinguish the syntax for inline assembly code*/ -#ifndef SBC_GHS_COMPILER -#define SBC_GHS_COMPILER FALSE -#endif - -/* ARM compiler option -> Used to distinguish the syntax for inline assembly code */ -#ifndef SBC_ARM_COMPILER -#define SBC_ARM_COMPILER TRUE -#endif - -/* Set SBC_IPAQ_OPT to TRUE in case the target is an ARM */ -/* 32 and 64 bit mult will be performed using SINT64 ( usualy __int64 ) cast that usualy give optimal performance if supported */ -#ifndef SBC_IPAQ_OPT -#define SBC_IPAQ_OPT TRUE -#endif - -/* Debug only: set SBC_IS_64_MULT_IN_WINDOW_ACCU to TRUE to use 64 bit multiplication in the windowing */ -/* -> not recomended, more MIPS for the same restitution. */ -#ifndef SBC_IS_64_MULT_IN_WINDOW_ACCU -#define SBC_IS_64_MULT_IN_WINDOW_ACCU FALSE -#endif /*SBC_IS_64_MULT_IN_WINDOW_ACCU */ - -/* Set SBC_IS_64_MULT_IN_IDCT to TRUE to use 64 bits multiplication in the DCT of Matrixing */ -/* -> more MIPS required for a better audio quality. comparasion with the SIG utilities shows a division by 10 of the RMS */ -/* CAUTION: It only apply in the if SBC_FAST_DCT is set to TRUE */ -#ifndef SBC_IS_64_MULT_IN_IDCT -#define SBC_IS_64_MULT_IN_IDCT FALSE -#endif /*SBC_IS_64_MULT_IN_IDCT */ - -/* set SBC_IS_64_MULT_IN_QUANTIZER to TRUE to use 64 bits multiplication in the quantizer */ -/* setting this flag to FALSE add whistling noise at 5.5 and 11 KHz usualy not perceptible by human's hears. */ -#ifndef SBC_IS_64_MULT_IN_QUANTIZER -#define SBC_IS_64_MULT_IN_QUANTIZER TRUE -#endif /*SBC_IS_64_MULT_IN_IDCT */ - -/* Debug only: set this flag to FALSE to disable fast DCT algorithm */ -#ifndef SBC_FAST_DCT -#define SBC_FAST_DCT TRUE -#endif /*SBC_FAST_DCT */ - -/* In case we do not use joint stereo mode the flag save some RAM and ROM in case it is set to FALSE */ -#ifndef SBC_JOINT_STE_INCLUDED -#define SBC_JOINT_STE_INCLUDED TRUE -#endif - -/* TRUE -> application should provide PCM buffer, FALSE PCM buffer reside in SBC_ENC_PARAMS */ -#ifndef SBC_NO_PCM_CPY_OPTION -#define SBC_NO_PCM_CPY_OPTION FALSE -#endif - -#define MINIMUM_ENC_VX_BUFFER_SIZE (8*10*2) -#ifndef ENC_VX_BUFFER_SIZE -#define ENC_VX_BUFFER_SIZE (MINIMUM_ENC_VX_BUFFER_SIZE + 64) -/*#define ENC_VX_BUFFER_SIZE MINIMUM_ENC_VX_BUFFER_SIZE + 1024*/ -#endif - -#ifndef SBC_FOR_EMBEDDED_LINUX -#define SBC_FOR_EMBEDDED_LINUX FALSE -#endif - -/*constants used for index calculation*/ -#define SBC_BLK (SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS) - -#include "sbc_types.h" - -typedef struct SBC_ENC_PARAMS_TAG { - SINT16 s16SamplingFreq; /* 16k, 32k, 44.1k or 48k*/ - SINT16 s16ChannelMode; /* mono, dual, streo or joint streo*/ - SINT16 s16NumOfSubBands; /* 4 or 8 */ - SINT16 s16NumOfChannels; - SINT16 s16NumOfBlocks; /* 4, 8, 12 or 16*/ - SINT16 s16AllocationMethod; /* loudness or SNR*/ - SINT16 s16BitPool; /* 16*numOfSb for mono & dual; - 32*numOfSb for stereo & joint stereo */ - UINT16 u16BitRate; - UINT8 u8NumPacketToEncode; /* number of sbc frame to encode. Default is 1 */ -#if (SBC_JOINT_STE_INCLUDED == TRUE) - SINT16 as16Join[SBC_MAX_NUM_OF_SUBBANDS]; /*1 if JS, 0 otherwise*/ -#endif - - SINT16 s16MaxBitNeed; - SINT16 as16ScaleFactor[SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS]; - - SINT16 *ps16NextPcmBuffer; -#if (SBC_NO_PCM_CPY_OPTION == TRUE) - SINT16 *ps16PcmBuffer; -#else - SINT16 as16PcmBuffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS]; -#endif - - SINT16 s16ScartchMemForBitAlloc[16]; - - SINT32 s32SbBuffer[SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS * SBC_MAX_NUM_OF_BLOCKS]; - - SINT16 as16Bits[SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS]; - - UINT8 *pu8Packet; - UINT8 *pu8NextPacket; - UINT16 FrameHeader; - UINT16 u16PacketLength; - -} SBC_ENC_PARAMS; - -#ifdef __cplusplus -extern "C" -{ -#endif -extern void SBC_Encoder(SBC_ENC_PARAMS *strEncParams); -extern void SBC_Encoder_Init(SBC_ENC_PARAMS *strEncParams); -#ifdef __cplusplus -} -#endif -#endif diff --git a/tools/sdk/include/bluedroid/sbc_if.h b/tools/sdk/include/bluedroid/sbc_if.h deleted file mode 100644 index 993b0663..00000000 --- a/tools/sdk/include/bluedroid/sbc_if.h +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _SBC_IF_H -#define _SBC_IF_H - -#define PCM_BUFFER_SIZE 512 - -/* - SBC_Init - called once for each track played - - pcm_sample_freq - 4000 to 48000 - channels - 1 mono 2 stereo - bits_per_sample - 8 or 16 - return - 0 sucess -*/ - -int SBC_init(int pcm_sample_freq, int channels, int bits_per_sample); - -/* - SBC_write - called repeatedly with pcm_in pointer - increasing by length until track is finished. - - pcm_in - pointer to PCM buffer - length - any - sbc_out - pointer to SBC output buffer - return - number of bytes written to sbc_out -*/ - -int SBC_write(unsigned char *pcm_in, int length, unsigned char *sbc_out); - -#endif diff --git a/tools/sdk/include/bluedroid/sbc_types.h b/tools/sdk/include/bluedroid/sbc_types.h deleted file mode 100644 index c6e4575b..00000000 --- a/tools/sdk/include/bluedroid/sbc_types.h +++ /dev/null @@ -1,59 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Data type declarations. - * - ******************************************************************************/ - -#ifndef SBC_TYPES_H -#define SBC_TYPES_H - -#include - -#ifdef BUILDCFG -#include "common/bt_target.h" -#endif - -#include "stack/bt_types.h" - -typedef short SINT16; -typedef long SINT32; - -#if (SBC_IPAQ_OPT == TRUE) - -#if (SBC_FOR_EMBEDDED_LINUX == TRUE) -typedef long long SINT64; -#else -typedef int64_t SINT64; -#endif - -#elif (SBC_IS_64_MULT_IN_WINDOW_ACCU == TRUE) || (SBC_IS_64_MULT_IN_IDCT == TRUE) - -#if (SBC_FOR_EMBEDDED_LINUX == TRUE) -typedef long long SINT64; -#else -typedef int64_t SINT64; -#endif - -#endif - -#define abs32(x) ( (x >= 0) ? x : (-x) ) - -#endif diff --git a/tools/sdk/include/bluedroid/sdpint.h b/tools/sdk/include/bluedroid/sdpint.h deleted file mode 100644 index c459edea..00000000 --- a/tools/sdk/include/bluedroid/sdpint.h +++ /dev/null @@ -1,316 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains internally used SDP definitions - * - ******************************************************************************/ - -#ifndef SDP_INT_H -#define SDP_INT_H - -#include "common/bt_target.h" -#include "common/bt_defs.h" -#include "stack/sdp_api.h" -#include "stack/l2c_api.h" - -#if (SDP_INCLUDED == TRUE) -/* Continuation length - we use a 2-byte offset */ -#define SDP_CONTINUATION_LEN 2 -#define SDP_MAX_CONTINUATION_LEN 16 /* As per the spec */ - -/* Timeout definitions. */ -#define SDP_INACT_TIMEOUT 30 /* Inactivity timeout */ - - -/* Define the Out-Flow default values. */ -#define SDP_OFLOW_QOS_FLAG 0 -#define SDP_OFLOW_SERV_TYPE 0 -#define SDP_OFLOW_TOKEN_RATE 0 -#define SDP_OFLOW_TOKEN_BUCKET_SIZE 0 -#define SDP_OFLOW_PEAK_BANDWIDTH 0 -#define SDP_OFLOW_LATENCY 0 -#define SDP_OFLOW_DELAY_VARIATION 0 - -/* Define the In-Flow default values. */ -#define SDP_IFLOW_QOS_FLAG 0 -#define SDP_IFLOW_SERV_TYPE 0 -#define SDP_IFLOW_TOKEN_RATE 0 -#define SDP_IFLOW_TOKEN_BUCKET_SIZE 0 -#define SDP_IFLOW_PEAK_BANDWIDTH 0 -#define SDP_IFLOW_LATENCY 0 -#define SDP_IFLOW_DELAY_VARIATION 0 - -#define SDP_LINK_TO 0 - -/* Define the type of device notification. */ -/* (Inquiry Scan and Page Scan) */ -#define SDP_DEVICE_NOTI_LEN sizeof (BT_HDR) + \ - HCIC_PREAMBLE_SIZE + \ - HCIC_PARAM_SIZE_WRITE_PARAM1 - -#define SDP_DEVICE_NOTI_FLAG 0x03 - -/* Define the Protocol Data Unit (PDU) types. -*/ -#define SDP_PDU_ERROR_RESPONSE 0x01 -#define SDP_PDU_SERVICE_SEARCH_REQ 0x02 -#define SDP_PDU_SERVICE_SEARCH_RSP 0x03 -#define SDP_PDU_SERVICE_ATTR_REQ 0x04 -#define SDP_PDU_SERVICE_ATTR_RSP 0x05 -#define SDP_PDU_SERVICE_SEARCH_ATTR_REQ 0x06 -#define SDP_PDU_SERVICE_SEARCH_ATTR_RSP 0x07 - -/* Max UUIDs and attributes we support per sequence */ -#define MAX_UUIDS_PER_SEQ 8 -#define MAX_ATTR_PER_SEQ 8 - -/* Max length we support for any attribute */ -// btla-specific ++ -#ifdef SDP_MAX_ATTR_LEN -#define MAX_ATTR_LEN SDP_MAX_ATTR_LEN -#else -#define MAX_ATTR_LEN 256 -#endif -// btla-specific -- - -/* Internal UUID sequence representation */ -typedef struct { - UINT16 len; - UINT8 value[MAX_UUID_SIZE]; -} tUID_ENT; - -typedef struct { - UINT16 num_uids; - tUID_ENT uuid_entry[MAX_UUIDS_PER_SEQ]; -} tSDP_UUID_SEQ; - - -/* Internal attribute sequence definitions */ -typedef struct { - UINT16 start; - UINT16 end; -} tATT_ENT; - -typedef struct { - UINT16 num_attr; - tATT_ENT attr_entry[MAX_ATTR_PER_SEQ]; -} tSDP_ATTR_SEQ; - - -/* Define the attribute element of the SDP database record */ -typedef struct { - UINT32 len; /* Number of bytes in the entry */ - UINT8 *value_ptr; /* Points to attr_pad */ - UINT16 id; - UINT8 type; -} tSDP_ATTRIBUTE; - -/* An SDP record consists of a handle, and 1 or more attributes */ -typedef struct { - UINT32 record_handle; - UINT32 free_pad_ptr; - UINT16 num_attributes; - tSDP_ATTRIBUTE attribute[SDP_MAX_REC_ATTR]; - UINT8 attr_pad[SDP_MAX_PAD_LEN]; -} tSDP_RECORD; - - -/* Define the SDP database */ -typedef struct { - UINT32 di_primary_handle; /* Device ID Primary record or NULL if nonexistent */ - UINT16 num_records; - tSDP_RECORD record[SDP_MAX_RECORDS]; -} tSDP_DB; - -enum { - SDP_IS_SEARCH, - SDP_IS_ATTR_SEARCH, -}; - -#if SDP_SERVER_ENABLED == TRUE -/* Continuation information for the SDP server response */ -typedef struct { - UINT16 next_attr_index; /* attr index for next continuation response */ - UINT16 next_attr_start_id; /* attr id to start with for the attr index in next cont. response */ - tSDP_RECORD *prev_sdp_rec; /* last sdp record that was completely sent in the response */ - BOOLEAN last_attr_seq_desc_sent; /* whether attr seq length has been sent previously */ - UINT16 attr_offset; /* offset within the attr to keep trak of partial attributes in the responses */ -} tSDP_CONT_INFO; -#endif /* SDP_SERVER_ENABLED == TRUE */ - -/* Define the SDP Connection Control Block */ -typedef struct { -#define SDP_STATE_IDLE 0 -#define SDP_STATE_CONN_SETUP 1 -#define SDP_STATE_CFG_SETUP 2 -#define SDP_STATE_CONNECTED 3 - UINT8 con_state; - -#define SDP_FLAGS_IS_ORIG 0x01 -#define SDP_FLAGS_HIS_CFG_DONE 0x02 -#define SDP_FLAGS_MY_CFG_DONE 0x04 - UINT8 con_flags; - - BD_ADDR device_address; - TIMER_LIST_ENT timer_entry; - UINT16 rem_mtu_size; - UINT16 connection_id; - UINT16 list_len; /* length of the response in the GKI buffer */ - UINT8 *rsp_list; /* pointer to GKI buffer holding response */ - -#if SDP_CLIENT_ENABLED == TRUE - tSDP_DISCOVERY_DB *p_db; /* Database to save info into */ - tSDP_DISC_CMPL_CB *p_cb; /* Callback for discovery done */ - tSDP_DISC_CMPL_CB2 *p_cb2; /* Callback for discovery done piggy back with the user data */ - void *user_data; /* piggy back user data */ - UINT32 handles[SDP_MAX_DISC_SERVER_RECS]; /* Discovered server record handles */ - UINT16 num_handles; /* Number of server handles */ - UINT16 cur_handle; /* Current handle being processed */ - UINT16 transaction_id; - UINT16 disconnect_reason; /* Disconnect reason */ -#if (defined(SDP_BROWSE_PLUS) && SDP_BROWSE_PLUS == TRUE) - UINT16 cur_uuid_idx; -#endif - -#define SDP_DISC_WAIT_CONN 0 -#define SDP_DISC_WAIT_HANDLES 1 -#define SDP_DISC_WAIT_ATTR 2 -#define SDP_DISC_WAIT_SEARCH_ATTR 3 -#define SDP_DISC_WAIT_CANCEL 5 - - UINT8 disc_state; - UINT8 is_attr_search; -#endif /* SDP_CLIENT_ENABLED == TRUE */ - -#if SDP_SERVER_ENABLED == TRUE - UINT16 cont_offset; /* Continuation state data in the server response */ - tSDP_CONT_INFO cont_info; /* structure to hold continuation information for the server response */ -#endif /* SDP_SERVER_ENABLED == TRUE */ - -} tCONN_CB; - - -/* The main SDP control block */ -typedef struct { - tL2CAP_CFG_INFO l2cap_my_cfg; /* My L2CAP config */ - tCONN_CB ccb[SDP_MAX_CONNECTIONS]; -#if SDP_SERVER_ENABLED == TRUE - tSDP_DB server_db; -#endif - tL2CAP_APPL_INFO reg_info; /* L2CAP Registration info */ - UINT16 max_attr_list_size; /* Max attribute list size to use */ - UINT16 max_recs_per_search; /* Max records we want per seaarch */ - UINT8 trace_level; -} tSDP_CB; - -#ifdef __cplusplus -extern "C" { -#endif -/* Global SDP data */ -#if SDP_DYNAMIC_MEMORY == FALSE -extern tSDP_CB sdp_cb; -#else -extern tSDP_CB *sdp_cb_ptr; -#define sdp_cb (*sdp_cb_ptr) -#endif - -#ifdef __cplusplus -} -#endif - -/* Functions provided by sdp_main.c */ -extern void sdp_init (void); -extern void sdp_deinit (void); -extern void sdp_disconnect (tCONN_CB *p_ccb, UINT16 reason); - -#if (defined(SDP_DEBUG) && SDP_DEBUG == TRUE) -extern UINT16 sdp_set_max_attr_list_size (UINT16 max_size); -#endif - -/* Functions provided by sdp_conn.c -*/ -extern void sdp_conn_rcv_l2e_conn_ind (BT_HDR *p_msg); -extern void sdp_conn_rcv_l2e_conn_cfm (BT_HDR *p_msg); -extern void sdp_conn_rcv_l2e_disc (BT_HDR *p_msg); -extern void sdp_conn_rcv_l2e_config_ind (BT_HDR *p_msg); -extern void sdp_conn_rcv_l2e_config_cfm (BT_HDR *p_msg); -extern void sdp_conn_rcv_l2e_conn_failed (BT_HDR *p_msg); -extern void sdp_conn_rcv_l2e_connected (BT_HDR *p_msg); -extern void sdp_conn_rcv_l2e_conn_failed (BT_HDR *p_msg); -extern void sdp_conn_rcv_l2e_data (BT_HDR *p_msg); -extern void sdp_conn_timeout (tCONN_CB *p_ccb); - -extern tCONN_CB *sdp_conn_originate (UINT8 *p_bd_addr); - -/* Functions provided by sdp_utils.c -*/ -extern tCONN_CB *sdpu_find_ccb_by_cid (UINT16 cid); -extern tCONN_CB *sdpu_find_ccb_by_db (tSDP_DISCOVERY_DB *p_db); -extern tCONN_CB *sdpu_allocate_ccb (void); -extern void sdpu_release_ccb (tCONN_CB *p_ccb); - -extern UINT8 *sdpu_build_attrib_seq (UINT8 *p_out, UINT16 *p_attr, UINT16 num_attrs); -extern UINT8 *sdpu_build_attrib_entry (UINT8 *p_out, tSDP_ATTRIBUTE *p_attr); -extern void sdpu_build_n_send_error (tCONN_CB *p_ccb, UINT16 trans_num, UINT16 error_code, char *p_error_text); - -extern UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq); -extern UINT8 *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq); - -extern UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 type, UINT32 *p_len); -extern BOOLEAN sdpu_is_base_uuid (UINT8 *p_uuid); -extern BOOLEAN sdpu_compare_uuid_arrays (UINT8 *p_uuid1, UINT32 len1, UINT8 *p_uuid2, UINT16 len2); -extern BOOLEAN sdpu_compare_bt_uuids (tBT_UUID *p_uuid1, tBT_UUID *p_uuid2); -extern BOOLEAN sdpu_compare_uuid_with_attr (tBT_UUID *p_btuuid, tSDP_DISC_ATTR *p_attr); - -extern void sdpu_sort_attr_list( UINT16 num_attr, tSDP_DISCOVERY_DB *p_db ); -extern UINT16 sdpu_get_list_len( tSDP_UUID_SEQ *uid_seq, tSDP_ATTR_SEQ *attr_seq ); -extern UINT16 sdpu_get_attrib_seq_len(tSDP_RECORD *p_rec, tSDP_ATTR_SEQ *attr_seq); -extern UINT16 sdpu_get_attrib_entry_len(tSDP_ATTRIBUTE *p_attr); -extern UINT8 *sdpu_build_partial_attrib_entry (UINT8 *p_out, tSDP_ATTRIBUTE *p_attr, UINT16 len, UINT16 *offset); -extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8 *p_uuid128); - -/* Functions provided by sdp_db.c -*/ -extern tSDP_RECORD *sdp_db_service_search (tSDP_RECORD *p_rec, tSDP_UUID_SEQ *p_seq); -extern tSDP_RECORD *sdp_db_find_record (UINT32 handle); -extern tSDP_ATTRIBUTE *sdp_db_find_attr_in_rec (tSDP_RECORD *p_rec, UINT16 start_attr, UINT16 end_attr); - - -/* Functions provided by sdp_server.c -*/ -#if SDP_SERVER_ENABLED == TRUE -extern void sdp_server_handle_client_req (tCONN_CB *p_ccb, BT_HDR *p_msg); -#else -#define sdp_server_handle_client_req(p_ccb, p_msg) -#endif - -/* Functions provided by sdp_discovery.c -*/ -#if SDP_CLIENT_ENABLED == TRUE -extern void sdp_disc_connected (tCONN_CB *p_ccb); -extern void sdp_disc_server_rsp (tCONN_CB *p_ccb, BT_HDR *p_msg); -#else -#define sdp_disc_connected(p_ccb) -#define sdp_disc_server_rsp(p_ccb, p_msg) -#endif - -#endif ///SDP_INCLUDED == TRUE - -#endif diff --git a/tools/sdk/include/bluedroid/smp_int.h b/tools/sdk/include/bluedroid/smp_int.h deleted file mode 100644 index 029869ef..00000000 --- a/tools/sdk/include/bluedroid/smp_int.h +++ /dev/null @@ -1,539 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains internally used SMP definitions - * - ******************************************************************************/ -#ifndef SMP_INT_H -#define SMP_INT_H - -#if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE) - -#include "stack/btu.h" -#include "stack/btm_ble_api.h" -#include "stack/btm_api.h" -#include "stack/smp_api.h" - -#define SMP_MODEL_ENCRYPTION_ONLY 0 /* Legacy mode, Just Works model */ -#define SMP_MODEL_PASSKEY 1 /* Legacy mode, Passkey Entry model, this side inputs the key */ -#define SMP_MODEL_OOB 2 /* Legacy mode, OOB model */ -#define SMP_MODEL_KEY_NOTIF 3 /* Legacy mode, Passkey Entry model, this side displays the key */ -#define SMP_MODEL_SEC_CONN_JUSTWORKS 4 /* Secure Connections mode, Just Works model */ -#define SMP_MODEL_SEC_CONN_NUM_COMP 5 /* Secure Connections mode, Numeric Comparison model */ -#define SMP_MODEL_SEC_CONN_PASSKEY_ENT 6 /* Secure Connections mode, Passkey Entry model, */ -/* this side inputs the key */ -#define SMP_MODEL_SEC_CONN_PASSKEY_DISP 7 /* Secure Connections mode, Passkey Entry model, */ -/* this side displays the key */ -#define SMP_MODEL_SEC_CONN_OOB 8 /* Secure Connections mode, OOB model */ -#define SMP_MODEL_OUT_OF_RANGE 9 -typedef UINT8 tSMP_ASSO_MODEL; - - -#ifndef SMP_MAX_CONN -#define SMP_MAX_CONN 2 -#endif - -#define SMP_WAIT_FOR_RSP_TOUT 30 - -#define SMP_OPCODE_INIT 0x04 - -/* SMP events */ -#define SMP_PAIRING_REQ_EVT SMP_OPCODE_PAIRING_REQ -#define SMP_PAIRING_RSP_EVT SMP_OPCODE_PAIRING_RSP -#define SMP_CONFIRM_EVT SMP_OPCODE_CONFIRM -#define SMP_RAND_EVT SMP_OPCODE_RAND -#define SMP_PAIRING_FAILED_EVT SMP_OPCODE_PAIRING_FAILED -#define SMP_ENCRPTION_INFO_EVT SMP_OPCODE_ENCRYPT_INFO -#define SMP_MASTER_ID_EVT SMP_OPCODE_MASTER_ID -#define SMP_ID_INFO_EVT SMP_OPCODE_IDENTITY_INFO -#define SMP_ID_ADDR_EVT SMP_OPCODE_ID_ADDR -#define SMP_SIGN_INFO_EVT SMP_OPCODE_SIGN_INFO -#define SMP_SECURITY_REQ_EVT SMP_OPCODE_SEC_REQ - -#define SMP_PAIR_PUBLIC_KEY_EVT SMP_OPCODE_PAIR_PUBLIC_KEY -#define SMP_PAIR_KEYPRESS_NOTIFICATION_EVT SMP_OPCODE_PAIR_KEYPR_NOTIF - -#define SMP_PAIR_COMMITM_EVT SMP_OPCODE_PAIR_COMMITM - -#define SMP_SELF_DEF_EVT (SMP_PAIR_COMMITM_EVT + 1) -#define SMP_KEY_READY_EVT (SMP_SELF_DEF_EVT) -#define SMP_ENCRYPTED_EVT (SMP_SELF_DEF_EVT + 1) -#define SMP_L2CAP_CONN_EVT (SMP_SELF_DEF_EVT + 2) -#define SMP_L2CAP_DISCONN_EVT (SMP_SELF_DEF_EVT + 3) -#define SMP_IO_RSP_EVT (SMP_SELF_DEF_EVT + 4) -#define SMP_API_SEC_GRANT_EVT (SMP_SELF_DEF_EVT + 5) -#define SMP_TK_REQ_EVT (SMP_SELF_DEF_EVT + 6) -#define SMP_AUTH_CMPL_EVT (SMP_SELF_DEF_EVT + 7) -#define SMP_ENC_REQ_EVT (SMP_SELF_DEF_EVT + 8) -#define SMP_BOND_REQ_EVT (SMP_SELF_DEF_EVT + 9) -#define SMP_DISCARD_SEC_REQ_EVT (SMP_SELF_DEF_EVT + 10) - -#define SMP_PAIR_DHKEY_CHCK_EVT SMP_OPCODE_PAIR_DHKEY_CHECK - -#define SMP_PUBL_KEY_EXCH_REQ_EVT (SMP_SELF_DEF_EVT + 11) /* request to start public */ -/* key exchange */ - -#define SMP_LOC_PUBL_KEY_CRTD_EVT (SMP_SELF_DEF_EVT + 12) /* local public key created */ - -#define SMP_BOTH_PUBL_KEYS_RCVD_EVT (SMP_SELF_DEF_EVT + 13) /* both local and peer public */ -/* keys are saved in cb */ - -#define SMP_SC_DHKEY_CMPLT_EVT (SMP_SELF_DEF_EVT + 14) /* DHKey computation is completed,*/ -/* time to start SC phase1 */ - -#define SMP_HAVE_LOC_NONCE_EVT (SMP_SELF_DEF_EVT + 15) /* new local nonce is generated */ -/*and saved in p_cb->rand */ - -#define SMP_SC_PHASE1_CMPLT_EVT (SMP_SELF_DEF_EVT + 16) /* time to start SC phase2 */ - -#define SMP_SC_CALC_NC_EVT (SMP_SELF_DEF_EVT + 17) /* request to calculate number */ -/* for user check. Used only in the */ -/* numeric compare protocol */ - -/* Request to display the number for user check to the user.*/ -/* Used only in the numeric compare protocol */ -#define SMP_SC_DSPL_NC_EVT (SMP_SELF_DEF_EVT + 18) - -#define SMP_SC_NC_OK_EVT (SMP_SELF_DEF_EVT + 19) /* user confirms 'OK' numeric */ -/*comparison request */ - -/* both local and peer DHKey Checks are already present - it is used on slave to prevent race condition */ -#define SMP_SC_2_DHCK_CHKS_PRES_EVT (SMP_SELF_DEF_EVT + 20) - -/* same meaning as SMP_KEY_READY_EVT to separate between SC and legacy actions */ -#define SMP_SC_KEY_READY_EVT (SMP_SELF_DEF_EVT + 21) -#define SMP_KEYPRESS_NOTIFICATION_EVENT (SMP_SELF_DEF_EVT + 22) - -#define SMP_SC_OOB_DATA_EVT (SMP_SELF_DEF_EVT + 23) /* SC OOB data from some */ -/* repository is provided */ - -#define SMP_CR_LOC_SC_OOB_DATA_EVT (SMP_SELF_DEF_EVT + 24) -#define SMP_MAX_EVT SMP_CR_LOC_SC_OOB_DATA_EVT - -typedef UINT8 tSMP_EVENT; - -/* Assumption it's only using the low 8 bits, if bigger than that, need to expand it to 16 bits */ -#define SMP_SEC_KEY_MASK 0x00ff - -#define SMP_PASSKEY_MASK 0xfff00000 - -/* SMP pairing state */ -enum { - SMP_STATE_IDLE, - SMP_STATE_WAIT_APP_RSP, - SMP_STATE_SEC_REQ_PENDING, - SMP_STATE_PAIR_REQ_RSP, - SMP_STATE_WAIT_CONFIRM, - SMP_STATE_CONFIRM, - SMP_STATE_RAND, - SMP_STATE_PUBLIC_KEY_EXCH, - SMP_STATE_SEC_CONN_PHS1_START, - SMP_STATE_WAIT_COMMITMENT, - SMP_STATE_WAIT_NONCE, - SMP_STATE_SEC_CONN_PHS2_START, - SMP_STATE_WAIT_DHK_CHECK, - SMP_STATE_DHK_CHECK, - SMP_STATE_ENCRYPTION_PENDING, - SMP_STATE_BOND_PENDING, - SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA, - SMP_STATE_MAX -}; -typedef UINT8 tSMP_STATE; - -/* SMP over BR/EDR events */ -#define SMP_BR_PAIRING_REQ_EVT SMP_OPCODE_PAIRING_REQ -#define SMP_BR_PAIRING_RSP_EVT SMP_OPCODE_PAIRING_RSP -#define SMP_BR_CONFIRM_EVT SMP_OPCODE_CONFIRM /* not expected over BR/EDR */ -#define SMP_BR_RAND_EVT SMP_OPCODE_RAND /* not expected over BR/EDR */ -#define SMP_BR_PAIRING_FAILED_EVT SMP_OPCODE_PAIRING_FAILED -#define SMP_BR_ENCRPTION_INFO_EVT SMP_OPCODE_ENCRYPT_INFO /* not expected over BR/EDR */ -#define SMP_BR_MASTER_ID_EVT SMP_OPCODE_MASTER_ID /* not expected over BR/EDR */ -#define SMP_BR_ID_INFO_EVT SMP_OPCODE_IDENTITY_INFO -#define SMP_BR_ID_ADDR_EVT SMP_OPCODE_ID_ADDR -#define SMP_BR_SIGN_INFO_EVT SMP_OPCODE_SIGN_INFO -#define SMP_BR_SECURITY_REQ_EVT SMP_OPCODE_SEC_REQ /* not expected over BR/EDR */ -#define SMP_BR_PAIR_PUBLIC_KEY_EVT SMP_OPCODE_PAIR_PUBLIC_KEY /* not expected over BR/EDR */ -#define SMP_BR_PAIR_DHKEY_CHCK_EVT SMP_OPCODE_PAIR_DHKEY_CHECK /* not expected over BR/EDR */ -#define SMP_BR_PAIR_KEYPR_NOTIF_EVT SMP_OPCODE_PAIR_KEYPR_NOTIF /* not expected over BR/EDR */ -#define SMP_BR_SELF_DEF_EVT SMP_BR_PAIR_KEYPR_NOTIF_EVT -#define SMP_BR_KEY_READY_EVT (SMP_BR_SELF_DEF_EVT + 1) -#define SMP_BR_ENCRYPTED_EVT (SMP_BR_SELF_DEF_EVT + 2) -#define SMP_BR_L2CAP_CONN_EVT (SMP_BR_SELF_DEF_EVT + 3) -#define SMP_BR_L2CAP_DISCONN_EVT (SMP_BR_SELF_DEF_EVT + 4) -#define SMP_BR_KEYS_RSP_EVT (SMP_BR_SELF_DEF_EVT + 5) -#define SMP_BR_API_SEC_GRANT_EVT (SMP_BR_SELF_DEF_EVT + 6) -#define SMP_BR_TK_REQ_EVT (SMP_BR_SELF_DEF_EVT + 7) -#define SMP_BR_AUTH_CMPL_EVT (SMP_BR_SELF_DEF_EVT + 8) -#define SMP_BR_ENC_REQ_EVT (SMP_BR_SELF_DEF_EVT + 9) -#define SMP_BR_BOND_REQ_EVT (SMP_BR_SELF_DEF_EVT + 10) -#define SMP_BR_DISCARD_SEC_REQ_EVT (SMP_BR_SELF_DEF_EVT + 11) -#define SMP_BR_MAX_EVT (SMP_BR_SELF_DEF_EVT + 12) -typedef UINT8 tSMP_BR_EVENT; - -/* SMP over BR/EDR pairing states */ -enum { - SMP_BR_STATE_IDLE = SMP_STATE_IDLE, - SMP_BR_STATE_WAIT_APP_RSP, - SMP_BR_STATE_PAIR_REQ_RSP, - SMP_BR_STATE_BOND_PENDING, - SMP_BR_STATE_MAX -}; -typedef UINT8 tSMP_BR_STATE; - -/* random and encrption activity state */ -enum { - SMP_GEN_COMPARE = 1, - SMP_GEN_CONFIRM, - - SMP_GEN_DIV_LTK, - SMP_GEN_DIV_CSRK, - SMP_GEN_RAND_V, - SMP_GEN_TK, - SMP_GEN_SRAND_MRAND, - SMP_GEN_SRAND_MRAND_CONT, - SMP_GENERATE_PRIVATE_KEY_0_7, - SMP_GENERATE_PRIVATE_KEY_8_15, - SMP_GENERATE_PRIVATE_KEY_16_23, - SMP_GENERATE_PRIVATE_KEY_24_31, - SMP_GEN_NONCE_0_7, - SMP_GEN_NONCE_8_15 -}; - -enum { - SMP_KEY_TYPE_TK, - SMP_KEY_TYPE_CFM, - SMP_KEY_TYPE_CMP, - SMP_KEY_TYPE_PEER_DHK_CHCK, - SMP_KEY_TYPE_STK, - SMP_KEY_TYPE_LTK -}; -typedef struct { - UINT8 key_type; - UINT8 *p_data; -} tSMP_KEY; - -typedef union { - UINT8 *p_data; /* UINT8 type data pointer */ - tSMP_KEY key; - UINT16 reason; - UINT32 passkey; - tSMP_OOB_DATA_TYPE req_oob_type; -} tSMP_INT_DATA; - -/* internal status mask */ -#define SMP_PAIR_FLAGS_WE_STARTED_DD (1) -#define SMP_PAIR_FLAGS_PEER_STARTED_DD (1 << 1) -#define SMP_PAIR_FLAGS_CMD_CONFIRM (1 << SMP_OPCODE_CONFIRM) /* 1 << 3 */ -#define SMP_PAIR_FLAG_ENC_AFTER_PAIR (1 << 4) -#define SMP_PAIR_FLAG_HAVE_PEER_DHK_CHK (1 << 5) /* used on slave to resolve race condition */ -#define SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY (1 << 6) /* used on slave to resolve race condition */ -#define SMP_PAIR_FLAG_HAVE_PEER_COMM (1 << 7) /* used to resolve race condition */ -#define SMP_PAIR_FLAG_HAVE_LOCAL_PUBL_KEY (1 << 8) /* used on slave to resolve race condition */ - -/* check if authentication requirement need MITM protection */ -#define SMP_NO_MITM_REQUIRED(x) (((x) & SMP_AUTH_YN_BIT) == 0) - -#define SMP_ENCRYT_KEY_SIZE 16 -#define SMP_ENCRYT_DATA_SIZE 16 -#define SMP_ECNCRPYT_STATUS HCI_SUCCESS - -typedef struct { - BD_ADDR bd_addr; - BT_HDR *p_copy; -} tSMP_REQ_Q_ENTRY; - -/* SMP control block */ -typedef struct { - tSMP_CALLBACK *p_callback; - TIMER_LIST_ENT rsp_timer_ent; - UINT8 trace_level; - BD_ADDR pairing_bda; - tSMP_STATE state; - BOOLEAN derive_lk; - BOOLEAN id_addr_rcvd; - tBLE_ADDR_TYPE id_addr_type; - BD_ADDR id_addr; - BOOLEAN smp_over_br; - tSMP_BR_STATE br_state; /* if SMP over BR/ERD has priority over SMP */ - UINT8 failure; - UINT8 status; - UINT8 role; - UINT16 flags; - UINT8 cb_evt; - tSMP_SEC_LEVEL sec_level; - BOOLEAN connect_initialized; - BT_OCTET16 confirm; - BT_OCTET16 rconfirm; - BT_OCTET16 rrand; /* for SC this is peer nonce */ - BT_OCTET16 rand; /* for SC this is local nonce */ - BT_OCTET32 private_key; - BT_OCTET32 dhkey; - BT_OCTET16 commitment; - BT_OCTET16 remote_commitment; - BT_OCTET16 local_random; /* local randomizer - passkey or OOB randomizer */ - BT_OCTET16 peer_random; /* peer randomizer - passkey or OOB randomizer */ - BT_OCTET16 dhkey_check; - BT_OCTET16 remote_dhkey_check; - tSMP_PUBLIC_KEY loc_publ_key; - tSMP_PUBLIC_KEY peer_publ_key; - tSMP_OOB_DATA_TYPE req_oob_type; - tSMP_SC_OOB_DATA sc_oob_data; - tSMP_IO_CAP peer_io_caps; - tSMP_IO_CAP local_io_capability; - tSMP_OOB_FLAG peer_oob_flag; - tSMP_OOB_FLAG loc_oob_flag; - tSMP_AUTH_REQ peer_auth_req; - tSMP_AUTH_REQ loc_auth_req; - BOOLEAN secure_connections_only_mode_required;/* TRUE if locally SM is required to operate */ - /* either in Secure Connections mode or not at all */ - tSMP_ASSO_MODEL selected_association_model; - BOOLEAN le_secure_connections_mode_is_used; - BOOLEAN le_sc_kp_notif_is_used; - tSMP_SC_KEY_TYPE local_keypress_notification; - tSMP_SC_KEY_TYPE peer_keypress_notification; - UINT8 round; /* authentication stage 1 round for passkey association model */ - UINT32 number_to_display; - BT_OCTET16 mac_key; - UINT8 peer_enc_size; - UINT8 loc_enc_size; - UINT8 peer_i_key; - UINT8 peer_r_key; - UINT8 local_i_key; - UINT8 local_r_key; - - BT_OCTET16 tk; - BT_OCTET16 ltk; - UINT16 div; - BT_OCTET16 csrk; /* storage for local CSRK */ - UINT16 ediv; - BT_OCTET8 enc_rand; - UINT8 rand_enc_proc_state; - UINT8 addr_type; - BD_ADDR local_bda; - BOOLEAN is_pair_cancel; - BOOLEAN discard_sec_req; - UINT8 rcvd_cmd_code; - UINT8 rcvd_cmd_len; - UINT16 total_tx_unacked; - BOOLEAN wait_for_authorization_complete; - BOOLEAN use_static_passkey; - UINT32 static_passkey; -} tSMP_CB; - -/* Server Action functions are of this type */ -typedef void (*tSMP_ACT)(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); - - -#ifdef __cplusplus -extern "C" -{ -#endif - -#if SMP_DYNAMIC_MEMORY == FALSE -extern tSMP_CB smp_cb; -#else -extern tSMP_CB *smp_cb_ptr; -#define smp_cb (*smp_cb_ptr) -#endif - -#ifdef __cplusplus -} -#endif - -/* Functions provided by att_main.c */ -extern void smp_init (void); - -/* smp main */ -extern void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data); - -extern void smp_proc_sec_request(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_set_fail_nc (BOOLEAN enable); -extern void smp_set_fail_conf (BOOLEAN enable); -extern void smp_set_passk_entry_fail(BOOLEAN enable); -extern void smp_set_oob_fail(BOOLEAN enable); -extern void smp_set_peer_sc_notif(BOOLEAN enable); -extern void smp_aes_cmac_rfc4493_chk (UINT8 *key, UINT8 *msg, UINT8 msg_len, - UINT8 mac_len, UINT8 *mac); -extern void smp_f4_calc_chk (UINT8 *U, UINT8 *V, UINT8 *X, UINT8 *Z, UINT8 *mac); -extern void smp_g2_calc_chk (UINT8 *U, UINT8 *V, UINT8 *X, UINT8 *Y); -extern void smp_h6_calc_chk (UINT8 *key, UINT8 *key_id, UINT8 *mac); -extern void smp_f5_key_calc_chk (UINT8 *w, UINT8 *mac); -extern void smp_f5_mackey_or_ltk_calc_chk(UINT8 *t, UINT8 *counter, - UINT8 *key_id, UINT8 *n1, - UINT8 *n2, UINT8 *a1, UINT8 *a2, - UINT8 *length, UINT8 *mac); -extern void smp_f5_calc_chk (UINT8 *w, UINT8 *n1, UINT8 *n2, UINT8 *a1, UINT8 *a2, - UINT8 *mac_key, UINT8 *ltk); -extern void smp_f6_calc_chk (UINT8 *w, UINT8 *n1, UINT8 *n2, UINT8 *r, - UINT8 *iocap, UINT8 *a1, UINT8 *a2, UINT8 *mac); -/* smp_main */ -extern void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data); -extern tSMP_STATE smp_get_state(void); -extern void smp_set_state(tSMP_STATE state); - -/* smp_br_main */ -extern void smp_br_state_machine_event(tSMP_CB *p_cb, tSMP_BR_EVENT event, void *p_data); -extern tSMP_BR_STATE smp_get_br_state(void); -extern void smp_set_br_state(tSMP_BR_STATE state); - - -/* smp_act.c */ -extern void smp_send_pair_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_send_confirm(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_send_pair_fail(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_send_rand(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_send_pair_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_send_commitment(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_send_dhkey_check(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_send_keypress_notification(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_proc_pair_fail(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_proc_confirm(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_proc_rand(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_process_pairing_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_proc_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_proc_master_id(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_proc_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_proc_id_addr(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_proc_sec_grant(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_proc_sec_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_proc_sl_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_start_enc(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_enc_cmpl(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_proc_discard(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_pairing_cmpl(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_decide_association_model(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_proc_compare(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_check_auth_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_process_io_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_send_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_send_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_send_csrk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_send_ltk_reply(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_pair_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_idle_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_send_pair_rsp(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_key_distribution(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_proc_srk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_generate_csrk(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_key_pick_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_both_have_public_keys(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_start_secure_connection_phase1(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_process_local_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_process_pairing_commitment(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_process_peer_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_process_dhkey_check(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_match_dhkey_checks(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_process_keypress_notification(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_move_to_secure_connections_phase2(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_phase_2_dhkey_checks_are_present(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_wait_for_both_public_keys(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_start_passkey_verification(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_process_secure_connection_oob_data(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_process_secure_connection_long_term_key(void); -extern void smp_set_local_oob_keys(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_set_local_oob_random_commitment(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_set_derive_link_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_derive_link_key_from_long_term_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_br_process_pairing_command(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_br_process_security_grant(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_br_process_slave_keys_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_br_send_pair_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_br_check_authorization_request(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_br_select_next_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_br_process_link_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_key_distribution_by_transport(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_br_pairing_complete(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); - -/* smp_l2c */ -extern void smp_l2cap_if_init (void); -extern void smp_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf); - -/* smp_util.c */ -extern BOOLEAN smp_send_cmd(UINT8 cmd_code, tSMP_CB *p_cb); -extern void smp_cb_cleanup(tSMP_CB *p_cb); -extern void smp_reset_control_value(tSMP_CB *p_cb); -extern void smp_proc_pairing_cmpl(tSMP_CB *p_cb); -extern void smp_convert_string_to_tk(BT_OCTET16 tk, UINT32 passkey); -extern void smp_mask_enc_key(UINT8 loc_enc_size, UINT8 *p_data); -extern void smp_rsp_timeout(TIMER_LIST_ENT *p_tle); -extern void smp_xor_128(BT_OCTET16 a, BT_OCTET16 b); -extern BOOLEAN smp_encrypt_data (UINT8 *key, UINT8 key_len, - UINT8 *plain_text, UINT8 pt_len, - tSMP_ENC *p_out); -extern BOOLEAN smp_command_has_invalid_parameters(tSMP_CB *p_cb); -extern void smp_reject_unexpected_pairing_command(BD_ADDR bd_addr); -extern tSMP_ASSO_MODEL smp_select_association_model(tSMP_CB *p_cb); -extern void smp_reverse_array(UINT8 *arr, UINT8 len); -extern UINT8 smp_calculate_random_input(UINT8 *random, UINT8 round); -extern void smp_collect_local_io_capabilities(UINT8 *iocap, tSMP_CB *p_cb); -extern void smp_collect_peer_io_capabilities(UINT8 *iocap, tSMP_CB *p_cb); -extern void smp_collect_local_ble_address(UINT8 *le_addr, tSMP_CB *p_cb); -extern void smp_collect_peer_ble_address(UINT8 *le_addr, tSMP_CB *p_cb); -extern BOOLEAN smp_check_commitment(tSMP_CB *p_cb); -extern void smp_save_secure_connections_long_term_key(tSMP_CB *p_cb); -extern BOOLEAN smp_calculate_f5_mackey_and_long_term_key(tSMP_CB *p_cb); -extern void smp_remove_fixed_channel(tSMP_CB *p_cb); -extern BOOLEAN smp_request_oob_data(tSMP_CB *p_cb); - -/* smp_keys.c */ -extern void smp_generate_srand_mrand_confirm (tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_generate_compare (tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_generate_stk (tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_generate_ltk(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_generate_passkey (tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_generate_rand_cont(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_create_private_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_use_oob_private_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_compute_dhkey(tSMP_CB *p_cb); -extern void smp_calculate_local_commitment(tSMP_CB *p_cb); -extern void smp_calculate_peer_commitment(tSMP_CB *p_cb, BT_OCTET16 output_buf); -extern void smp_calculate_numeric_comparison_display_number(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_calculate_local_dhkey_check(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_calculate_peer_dhkey_check(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); -extern void smp_start_nonce_generation(tSMP_CB *p_cb); -extern BOOLEAN smp_calculate_link_key_from_long_term_key(tSMP_CB *p_cb); -extern BOOLEAN smp_calculate_long_term_key_from_link_key(tSMP_CB *p_cb); -extern void smp_calculate_f4(UINT8 *u, UINT8 *v, UINT8 *x, UINT8 z, UINT8 *c); -extern UINT32 smp_calculate_g2(UINT8 *u, UINT8 *v, UINT8 *x, UINT8 *y); -extern BOOLEAN smp_calculate_f5(UINT8 *w, UINT8 *n1, UINT8 *n2, UINT8 *a1, UINT8 *a2, - UINT8 *mac_key, UINT8 *ltk); -extern BOOLEAN smp_calculate_f5_mackey_or_long_term_key(UINT8 *t, UINT8 *counter, - UINT8 *key_id, UINT8 *n1, UINT8 *n2, UINT8 *a1, - UINT8 *a2, UINT8 *length, UINT8 *mac); -extern BOOLEAN smp_calculate_f5_key(UINT8 *w, UINT8 *t); -extern BOOLEAN smp_calculate_f6(UINT8 *w, UINT8 *n1, UINT8 *n2, UINT8 *r, UINT8 *iocap, - UINT8 *a1, UINT8 *a2, UINT8 *f3); -extern BOOLEAN smp_calculate_h6(UINT8 *w, UINT8 *keyid, UINT8 *h2); -#if SMP_DEBUG == TRUE -extern void smp_debug_print_nbyte_little_endian (UINT8 *p, const UINT8 *key_name, - UINT8 len); -#endif - -/* smp_cmac.c */ -extern BOOLEAN aes_cipher_msg_auth_code(BT_OCTET16 key, UINT8 *input, UINT16 length, - UINT16 tlen, UINT8 *p_signature); -extern void print128(BT_OCTET16 x, const UINT8 *key_name); - -#endif ///BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE - -#endif /* SMP_INT_H */ diff --git a/tools/sdk/include/bluedroid/srvc_api.h b/tools/sdk/include/bluedroid/srvc_api.h deleted file mode 100644 index e84a86be..00000000 --- a/tools/sdk/include/bluedroid/srvc_api.h +++ /dev/null @@ -1,210 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2013 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef SRVC_DIS_API_H -#define SRVC_DIS_API_H - -#include "common/bt_target.h" -#include "stack/gatt_api.h" -#include "stack/gattdefs.h" - -#define DIS_SUCCESS GATT_SUCCESS -#define DIS_ILLEGAL_PARAM GATT_ILLEGAL_PARAMETER -#define DIS_NO_RESOURCES GATT_NO_RESOURCES -typedef UINT8 tDIS_STATUS; - - -/***************************************************************************** -** Data structure for DIS -*****************************************************************************/ - -#define DIS_ATTR_SYS_ID_BIT 0x0001 -#define DIS_ATTR_MODEL_NUM_BIT 0x0002 -#define DIS_ATTR_SERIAL_NUM_BIT 0x0004 -#define DIS_ATTR_FW_NUM_BIT 0x0008 -#define DIS_ATTR_HW_NUM_BIT 0x0010 -#define DIS_ATTR_SW_NUM_BIT 0x0020 -#define DIS_ATTR_MANU_NAME_BIT 0x0040 -#define DIS_ATTR_IEEE_DATA_BIT 0x0080 -#define DIS_ATTR_PNP_ID_BIT 0x0100 -typedef UINT16 tDIS_ATTR_MASK; - -#define DIS_ATTR_ALL_MASK 0xffff - -typedef tDIS_ATTR_MASK tDIS_ATTR_BIT ; - -typedef struct { - UINT16 len; - UINT8 *p_data; -} tDIS_STRING; - -typedef struct { - UINT16 vendor_id; - UINT16 product_id; - UINT16 product_version; - UINT8 vendor_id_src; - -} tDIS_PNP_ID; - -typedef union { - UINT64 system_id; - tDIS_PNP_ID pnp_id; - tDIS_STRING data_str; -} tDIS_ATTR; - -#define DIS_MAX_STRING_DATA 7 - -typedef struct { - UINT16 attr_mask; - UINT64 system_id; - tDIS_PNP_ID pnp_id; - UINT8 *data_string[DIS_MAX_STRING_DATA]; -} tDIS_VALUE; - - -typedef void (tDIS_READ_CBACK)(BD_ADDR addr, tDIS_VALUE *p_dis_value); - -/***************************************************************************** -** Data structure used by Battery Service -*****************************************************************************/ -typedef struct { - BD_ADDR remote_bda; - BOOLEAN need_rsp; - UINT16 clt_cfg; -} tBA_WRITE_DATA; - -#define BA_READ_CLT_CFG_REQ 1 -#define BA_READ_PRE_FMT_REQ 2 -#define BA_READ_RPT_REF_REQ 3 -#define BA_READ_LEVEL_REQ 4 -#define BA_WRITE_CLT_CFG_REQ 5 - -typedef void (tBA_CBACK)(UINT8 app_id, UINT8 event, tBA_WRITE_DATA *p_data); - -#define BA_LEVEL_NOTIFY 0x01 -#define BA_LEVEL_PRE_FMT 0x02 -#define BA_LEVEL_RPT_REF 0x04 -typedef UINT8 tBA_LEVEL_DESCR; - -typedef struct { - BOOLEAN is_pri; - tBA_LEVEL_DESCR ba_level_descr; - tGATT_TRANSPORT transport; - tBA_CBACK *p_cback; - -} tBA_REG_INFO; - -typedef union { - UINT8 ba_level; - UINT16 clt_cfg; - tGATT_CHAR_RPT_REF rpt_ref; - tGATT_CHAR_PRES pres_fmt; -} tBA_RSP_DATA; - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif -/***************************************************************************** -** Service Engine API -*****************************************************************************/ -/******************************************************************************* -** -** Function srvc_eng_init -** -** Description Initializa the GATT Service engine, register a GATT application -** as for a central service management. -** -*******************************************************************************/ -extern tGATT_STATUS srvc_eng_init (void); - - -/***************************************************************************** -** DIS Server Function -*****************************************************************************/ - -/******************************************************************************* -** -** Function DIS_SrInit -** -** Description Initializa the Device Information Service Server. -** -*******************************************************************************/ -extern tDIS_STATUS DIS_SrInit (tDIS_ATTR_MASK dis_attr_mask); -/******************************************************************************* -** -** Function DIS_SrUpdate -** -** Description Update the DIS server attribute values -** -*******************************************************************************/ -extern tDIS_STATUS DIS_SrUpdate(tDIS_ATTR_BIT dis_attr_bit, tDIS_ATTR *p_info); -/***************************************************************************** -** DIS Client Function -*****************************************************************************/ -/******************************************************************************* -** -** Function DIS_ReadDISInfo -** -** Description Read remote device DIS information. -** -** Returns void -** -*******************************************************************************/ -extern BOOLEAN DIS_ReadDISInfo(BD_ADDR peer_bda, tDIS_READ_CBACK *p_cback, - tDIS_ATTR_MASK mask); - -/******************************************************************************* -** BATTERY SERVICE API -*******************************************************************************/ -/******************************************************************************* -** -** Function Battery_Instantiate -** -** Description Instantiate a Battery service -** -*******************************************************************************/ -extern UINT16 Battery_Instantiate (UINT8 app_id, tBA_REG_INFO *p_reg_info); - -/******************************************************************************* -** -** Function Battery_Rsp -** -** Description Respond to a battery service request -** -*******************************************************************************/ -extern void Battery_Rsp (UINT8 app_id, tGATT_STATUS st, UINT8 event, tBA_RSP_DATA *p_rsp); -/******************************************************************************* -** -** Function Battery_Notify -** -** Description Send battery level notification -** -*******************************************************************************/ -extern void Battery_Notify (UINT8 app_id, BD_ADDR remote_bda, UINT8 battery_level); - - -#ifdef __cplusplus - -} -#endif - -#endif diff --git a/tools/sdk/include/bluedroid/srvc_battery_int.h b/tools/sdk/include/bluedroid/srvc_battery_int.h deleted file mode 100644 index 7aee0ff1..00000000 --- a/tools/sdk/include/bluedroid/srvc_battery_int.h +++ /dev/null @@ -1,79 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef SRVC_BATTERY_INT_H -#define SRVC_BATTERY_INT_H - -#include "common/bt_target.h" -#include "srvc_api.h" -#include "stack/gatt_api.h" - -#ifndef BA_MAX_INT_NUM -#define BA_MAX_INT_NUM 4 -#endif - -#define BATTERY_LEVEL_SIZE 1 - - -typedef struct { - UINT8 app_id; - UINT16 ba_level_hdl; - UINT16 clt_cfg_hdl; - UINT16 rpt_ref_hdl; - UINT16 pres_fmt_hdl; - - tBA_CBACK *p_cback; - - UINT16 pending_handle; - UINT8 pending_clcb_idx; - UINT8 pending_evt; - -} tBA_INST; - -typedef struct { - tBA_INST battery_inst[BA_MAX_INT_NUM]; - UINT8 inst_id; - BOOLEAN enabled; - -} tBATTERY_CB; - -#ifdef __cplusplus -extern "C" { -#endif - -/* Global GATT data */ -#if GATT_DYNAMIC_MEMORY == FALSE -extern tBATTERY_CB battery_cb; -#else -extern tBATTERY_CB *battery_cb_ptr; -#define battery_cb (*battery_cb_ptr) -#endif - - -extern BOOLEAN battery_valid_handle_range(UINT16 handle); - -extern UINT8 battery_s_write_attr_value(UINT8 clcb_idx, tGATT_WRITE_REQ *p_value, - tGATT_STATUS *p_status); -extern UINT8 battery_s_read_attr_value (UINT8 clcb_idx, UINT16 handle, tGATT_VALUE *p_value, BOOLEAN is_long, tGATT_STATUS *p_status); - - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/tools/sdk/include/bluedroid/srvc_dis_int.h b/tools/sdk/include/bluedroid/srvc_dis_int.h deleted file mode 100644 index 4d5913ab..00000000 --- a/tools/sdk/include/bluedroid/srvc_dis_int.h +++ /dev/null @@ -1,82 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef SRVC_DIS_INT_H -#define SRVC_DIS_INT_H - -#include "common/bt_target.h" -#include "srvc_api.h" -#include "stack/gatt_api.h" - -#define DIS_MAX_CHAR_NUM 9 - - -typedef struct { - UINT16 uuid; - UINT16 handle; -} tDIS_DB_ENTRY; - -#define DIS_SYSTEM_ID_SIZE 8 -#define DIS_PNP_ID_SIZE 7 - - - -typedef struct { - tDIS_DB_ENTRY dis_attr[DIS_MAX_CHAR_NUM]; - tDIS_VALUE dis_value; - - tDIS_READ_CBACK *p_read_dis_cback; - - UINT16 service_handle; - UINT16 max_handle; - - BOOLEAN enabled; - - UINT8 dis_read_uuid_idx; - - tDIS_ATTR_MASK request_mask; -} tDIS_CB; - - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Global GATT data */ -#if GATT_DYNAMIC_MEMORY == FALSE -extern tDIS_CB dis_cb; -#else -extern tDIS_CB *dis_cb_ptr; -#define dis_cb (*dis_cb_ptr) -#endif - - -extern BOOLEAN dis_valid_handle_range(UINT16 handle); -extern UINT8 dis_read_attr_value (UINT8 clcb_idx, UINT16 handle, tGATT_VALUE *p_value, - BOOLEAN is_long, tGATT_STATUS *p_status); -extern UINT8 dis_write_attr_value(tGATT_WRITE_REQ *p_data, tGATT_STATUS *p_status); - -extern void dis_c_cmpl_cback (tSRVC_CLCB *p_clcb, tGATTC_OPTYPE op, - tGATT_STATUS status, tGATT_CL_COMPLETE *p_data); - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/tools/sdk/include/bluedroid/stack/a2d_api.h b/tools/sdk/include/bluedroid/stack/a2d_api.h deleted file mode 100644 index 7509544f..00000000 --- a/tools/sdk/include/bluedroid/stack/a2d_api.h +++ /dev/null @@ -1,256 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2000-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * nterface to A2DP Application Programming Interface - * - ******************************************************************************/ -#ifndef A2D_API_H -#define A2D_API_H -#include "stack/sdp_api.h" -#if (A2D_INCLUDED == TRUE) -/***************************************************************************** -** constants -*****************************************************************************/ - -/* Profile supported features */ -#define A2D_SUPF_PLAYER 0x0001 -#define A2D_SUPF_MIC 0x0002 -#define A2D_SUPF_TUNER 0x0004 -#define A2D_SUPF_MIXER 0x0008 - -#define A2D_SUPF_HEADPHONE 0x0001 -#define A2D_SUPF_SPEAKER 0x0002 -#define A2D_SUPF_RECORDER 0x0004 -#define A2D_SUPF_AMP 0x0008 - -/* AV Media Types */ -#define A2D_MEDIA_TYPE_AUDIO 0x00 /* audio media type + RFA */ -#define A2D_MEDIA_TYPE_VIDEO 0x10 /* video media type + RFA */ -#define A2D_MEDIA_TYPE_MULTI 0x20 /* multimedia media type + RFA */ - -/* AV Media Codec Type (Audio Codec ID) */ -#define A2D_MEDIA_CT_SBC 0x00 /* SBC media codec type */ -#define A2D_MEDIA_CT_M12 0x01 /* MPEG-1, 2 Audio media codec type */ -#define A2D_MEDIA_CT_M24 0x02 /* MPEG-2, 4 AAC media codec type */ -#define A2D_MEDIA_CT_ATRAC 0x04 /* ATRAC family media codec type */ - -#define A2D_SUCCESS 0 /* Success */ -#define A2D_FAIL 0x0A /* Failed */ -#define A2D_BUSY 0x0B /* A2D_FindService is already in progress */ -#define A2D_INVALID_PARAMS 0x0C /* bad parameters */ -#define A2D_WRONG_CODEC 0x0D /* wrong codec info */ -#define A2D_BAD_CODEC_TYPE 0xC1 /* Media Codec Type is not valid */ -#define A2D_NS_CODEC_TYPE 0xC2 /* Media Codec Type is not supported */ -#define A2D_BAD_SAMP_FREQ 0xC3 /* Sampling Frequency is not valid or multiple values have been selected */ -#define A2D_NS_SAMP_FREQ 0xC4 /* Sampling Frequency is not supported */ -#define A2D_BAD_CH_MODE 0xC5 /* Channel Mode is not valid or multiple values have been selected */ -#define A2D_NS_CH_MODE 0xC6 /* Channel Mode is not supported */ -#define A2D_BAD_SUBBANDS 0xC7 /* None or multiple values have been selected for Number of Subbands */ -#define A2D_NS_SUBBANDS 0xC8 /* Number of Subbands is not supported */ -#define A2D_BAD_ALLOC_MTHD 0xC9 /* None or multiple values have been selected for Allocation Method */ -#define A2D_NS_ALLOC_MTHD 0xCA /* Allocation Method is not supported */ -#define A2D_BAD_MIN_BITPOOL 0xCB /* Minimum Bitpool Value is not valid */ -#define A2D_NS_MIN_BITPOOL 0xCC /* Minimum Bitpool Value is not supported */ -#define A2D_BAD_MAX_BITPOOL 0xCD /* Maximum Bitpool Value is not valid */ -#define A2D_NS_MAX_BITPOOL 0xCE /* Maximum Bitpool Value is not supported */ -#define A2D_BAD_LAYER 0xCF /* None or multiple values have been selected for Layer */ -#define A2D_NS_LAYER 0xD0 /* Layer is not supported */ -#define A2D_NS_CRC 0xD1 /* CRC is not supported */ -#define A2D_NS_MPF 0xD2 /* MPF-2 is not supported */ -#define A2D_NS_VBR 0xD3 /* VBR is not supported */ -#define A2D_BAD_BIT_RATE 0xD4 /* None or multiple values have been selected for Bit Rate */ -#define A2D_NS_BIT_RATE 0xD5 /* Bit Rate is not supported */ -#define A2D_BAD_OBJ_TYPE 0xD6 /* Either 1) Object type is not valid (b3-b0) or 2) None or multiple values have been selected for Object Type */ -#define A2D_NS_OBJ_TYPE 0xD7 /* Object type is not supported */ -#define A2D_BAD_CHANNEL 0xD8 /* None or multiple values have been selected for Channels */ -#define A2D_NS_CHANNEL 0xD9 /* Channels is not supported */ -#define A2D_BAD_BLOCK_LEN 0xDD /* None or multiple values have been selected for Block Length */ -#define A2D_BAD_CP_TYPE 0xE0 /* The requested CP Type is not supported. */ -#define A2D_BAD_CP_FORMAT 0xE1 /* The format of Content Protection Service Capability/Content Protection Scheme Dependent Data is not correct. */ - -typedef UINT8 tA2D_STATUS; - -/* the return values from A2D_BitsSet() */ -#define A2D_SET_ONE_BIT 1 /* one and only one bit is set */ -#define A2D_SET_ZERO_BIT 0 /* all bits clear */ -#define A2D_SET_MULTL_BIT 2 /* multiple bits are set */ - -/***************************************************************************** -** type definitions -*****************************************************************************/ - -/* This data type is used in A2D_FindService() to initialize the SDP database - * to hold the result service search. */ -typedef struct { - UINT32 db_len; /* Length, in bytes, of the discovery database */ - UINT16 num_attr;/* The number of attributes in p_attrs */ - tSDP_DISCOVERY_DB *p_db; /* Pointer to the discovery database */ - UINT16 *p_attrs; /* The attributes filter. If NULL, A2DP API sets the attribute filter - * to be ATTR_ID_SERVICE_CLASS_ID_LIST, ATTR_ID_BT_PROFILE_DESC_LIST, - * ATTR_ID_SUPPORTED_FEATURES, ATTR_ID_SERVICE_NAME and ATTR_ID_PROVIDER_NAME. - * If not NULL, the input is taken as the filter. */ -} tA2D_SDP_DB_PARAMS; - -/* This data type is used in tA2D_FIND_CBACK to report the result of the SDP discovery process. */ -typedef struct { - UINT16 service_len; /* Length, in bytes, of the service name */ - UINT16 provider_len; /* Length, in bytes, of the provider name */ - char *p_service_name; /* Pointer the service name. This character string may not be null terminated. - * Use the service_len parameter to safely copy this string */ - char *p_provider_name;/* Pointer the provider name. This character string may not be null terminated. - * Use the provider_len parameter to safely copy this string */ - UINT16 features; /* Profile supported features */ - UINT16 avdt_version; /* AVDTP protocol version */ -} tA2D_Service; - -/* This is the callback to notify the result of the SDP discovery process. */ -typedef void (tA2D_FIND_CBACK)(BOOLEAN found, tA2D_Service *p_service); - - -/***************************************************************************** -** external function declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif -/****************************************************************************** -** -** Function A2D_AddRecord -** -** Description This function is called by a server application to add -** SRC or SNK information to an SDP record. Prior to -** calling this function the application must call -** SDP_CreateRecord() to create an SDP record. -** -** Input Parameters: -** service_uuid: Indicates SRC or SNK. -** -** p_service_name: Pointer to a null-terminated character -** string containing the service name. -** -** p_provider_name: Pointer to a null-terminated character -** string containing the provider name. -** -** features: Profile supported features. -** -** sdp_handle: SDP handle returned by SDP_CreateRecord(). -** -** Output Parameters: -** None. -** -** Returns A2D_SUCCESS if function execution succeeded, -** A2D_INVALID_PARAMS if bad parameters are given. -** A2D_FAIL if function execution failed. -** -******************************************************************************/ -extern tA2D_STATUS A2D_AddRecord(UINT16 service_uuid, char *p_service_name, char *p_provider_name, - UINT16 features, UINT32 sdp_handle); - -/****************************************************************************** -** -** Function A2D_FindService -** -** Description This function is called by a client application to -** perform service discovery and retrieve SRC or SNK SDP -** record information from a server. Information is -** returned for the first service record found on the -** server that matches the service UUID. The callback -** function will be executed when service discovery is -** complete. There can only be one outstanding call to -** A2D_FindService() at a time; the application must wait -** for the callback before it makes another call to -** the function. -** -** Input Parameters: -** service_uuid: Indicates SRC or SNK. -** -** bd_addr: BD address of the peer device. -** -** p_db: Pointer to the information to initialize -** the discovery database. -** -** p_cback: Pointer to the A2D_FindService() -** callback function. -** -** Output Parameters: -** None. -** -** Returns A2D_SUCCESS if function execution succeeded, -** A2D_INVALID_PARAMS if bad parameters are given. -** A2D_BUSY if discovery is already in progress. -** A2D_FAIL if function execution failed. -** -******************************************************************************/ -extern tA2D_STATUS A2D_FindService(UINT16 service_uuid, BD_ADDR bd_addr, - tA2D_SDP_DB_PARAMS *p_db, tA2D_FIND_CBACK *p_cback); - -/****************************************************************************** -** -** Function A2D_SetTraceLevel -** -** Description Sets the trace level for A2D. If 0xff is passed, the -** current trace level is returned. -** -** Input Parameters: -** new_level: The level to set the A2D tracing to: -** 0xff-returns the current setting. -** 0-turns off tracing. -** >= 1-Errors. -** >= 2-Warnings. -** >= 3-APIs. -** >= 4-Events. -** >= 5-Debug. -** -** Returns The new trace level or current trace level if -** the input parameter is 0xff. -** -******************************************************************************/ -extern UINT8 A2D_SetTraceLevel (UINT8 new_level); - -/****************************************************************************** -** Function A2D_BitsSet -** -** Description Check the given num for the number of bits set -** Returns A2D_SET_ONE_BIT, if one and only one bit is set -** A2D_SET_ZERO_BIT, if all bits clear -** A2D_SET_MULTL_BIT, if multiple bits are set -******************************************************************************/ -extern UINT8 A2D_BitsSet(UINT8 num); - -#ifdef __cplusplus -} -#endif - -/******************************************************************************* -** -** Function A2D_Init -** -** Description This function is called at stack startup to allocate the -** control block (if using dynamic memory), and initializes the -** control block and tracing level. -** -** Returns void -** -*******************************************************************************/ -extern void A2D_Init(void); -extern void A2D_Deinit(void); -#endif ///A2D_INCLUDED -#endif /* A2D_API_H */ diff --git a/tools/sdk/include/bluedroid/stack/a2d_sbc.h b/tools/sdk/include/bluedroid/stack/a2d_sbc.h deleted file mode 100644 index 98b63e46..00000000 --- a/tools/sdk/include/bluedroid/stack/a2d_sbc.h +++ /dev/null @@ -1,213 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2000-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * nterface to low complexity subband codec (SBC) - * - ******************************************************************************/ -#ifndef A2D_SBC_H -#define A2D_SBC_H -#if (A2D_INCLUDED == TRUE) -/***************************************************************************** -** Constants -*****************************************************************************/ -/* the length of the SBC Media Payload header. */ -#define A2D_SBC_MPL_HDR_LEN 1 - -/* the LOSC of SBC media codec capabilitiy */ -#define A2D_SBC_INFO_LEN 6 - -/* for Codec Specific Information Element */ -#define A2D_SBC_IE_SAMP_FREQ_MSK 0xF0 /* b7-b4 sampling frequency */ -#define A2D_SBC_IE_SAMP_FREQ_16 0x80 /* b7:16 kHz */ -#define A2D_SBC_IE_SAMP_FREQ_32 0x40 /* b6:32 kHz */ -#define A2D_SBC_IE_SAMP_FREQ_44 0x20 /* b5:44.1kHz */ -#define A2D_SBC_IE_SAMP_FREQ_48 0x10 /* b4:48 kHz */ - -#define A2D_SBC_IE_CH_MD_MSK 0x0F /* b3-b0 channel mode */ -#define A2D_SBC_IE_CH_MD_MONO 0x08 /* b3: mono */ -#define A2D_SBC_IE_CH_MD_DUAL 0x04 /* b2: dual */ -#define A2D_SBC_IE_CH_MD_STEREO 0x02 /* b1: stereo */ -#define A2D_SBC_IE_CH_MD_JOINT 0x01 /* b0: joint stereo */ - -#define A2D_SBC_IE_BLOCKS_MSK 0xF0 /* b7-b4 number of blocks */ -#define A2D_SBC_IE_BLOCKS_4 0x80 /* 4 blocks */ -#define A2D_SBC_IE_BLOCKS_8 0x40 /* 8 blocks */ -#define A2D_SBC_IE_BLOCKS_12 0x20 /* 12blocks */ -#define A2D_SBC_IE_BLOCKS_16 0x10 /* 16blocks */ - -#define A2D_SBC_IE_SUBBAND_MSK 0x0C /* b3-b2 number of subbands */ -#define A2D_SBC_IE_SUBBAND_4 0x08 /* b3: 4 */ -#define A2D_SBC_IE_SUBBAND_8 0x04 /* b2: 8 */ - -#define A2D_SBC_IE_ALLOC_MD_MSK 0x03 /* b1-b0 allocation mode */ -#define A2D_SBC_IE_ALLOC_MD_S 0x02 /* b1: SNR */ -#define A2D_SBC_IE_ALLOC_MD_L 0x01 /* b0: loundess */ - -#define A2D_SBC_IE_MIN_BITPOOL 2 -#define A2D_SBC_IE_MAX_BITPOOL 250 - -/* for media payload header */ -#define A2D_SBC_HDR_F_MSK 0x80 -#define A2D_SBC_HDR_S_MSK 0x40 -#define A2D_SBC_HDR_L_MSK 0x20 -#define A2D_SBC_HDR_NUM_MSK 0x0F - -/***************************************************************************** -** Type Definitions -*****************************************************************************/ - -/* data type for the SBC Codec Information Element*/ -typedef struct { - UINT8 samp_freq; /* Sampling frequency */ - UINT8 ch_mode; /* Channel mode */ - UINT8 block_len; /* Block length */ - UINT8 num_subbands; /* Number of subbands */ - UINT8 alloc_mthd; /* Allocation method */ - UINT8 max_bitpool; /* Maximum bitpool */ - UINT8 min_bitpool; /* Minimum bitpool */ -} tA2D_SBC_CIE; - - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif -/****************************************************************************** -** -** Function A2D_SbcChkFrInit -** -** Description check if need to init the descramble control block. -** -** Returns nothing. -******************************************************************************/ -extern void A2D_SbcChkFrInit(UINT8 *p_pkt); - -/****************************************************************************** -** -** Function A2D_SbcDescramble -** -** Description descramble the packet. -** -** Returns nothing. -******************************************************************************/ -extern void A2D_SbcDescramble(UINT8 *p_pkt, UINT16 len); - -/****************************************************************************** -** -** Function A2D_BldSbcInfo -** -** Description This function is called by an application to build -** the SBC Media Codec Capabilities byte sequence -** beginning from the LOSC octet. -** Input Parameters: -** media_type: Indicates Audio, or Multimedia. -** -** p_ie: The SBC Codec Information Element information. -** -** Output Parameters: -** p_result: the resulting codec info byte sequence. -** -** Returns A2D_SUCCESS if function execution succeeded. -** Error status code, otherwise. -******************************************************************************/ -extern tA2D_STATUS A2D_BldSbcInfo(UINT8 media_type, tA2D_SBC_CIE *p_ie, - UINT8 *p_result); - -/****************************************************************************** -** -** Function A2D_ParsSbcInfo -** -** Description This function is called by an application to parse -** the SBC Media Codec Capabilities byte sequence -** beginning from the LOSC octet. -** Input Parameters: -** p_info: the byte sequence to parse. -** -** for_caps: TRUE, if the byte sequence is for get capabilities response. -** -** Output Parameters: -** p_ie: The SBC Codec Information Element information. -** -** Returns A2D_SUCCESS if function execution succeeded. -** Error status code, otherwise. -******************************************************************************/ -extern tA2D_STATUS A2D_ParsSbcInfo(tA2D_SBC_CIE *p_ie, UINT8 *p_info, - BOOLEAN for_caps); - -/****************************************************************************** -** -** Function A2D_BldSbcMplHdr -** -** Description This function is called by an application to parse -** the SBC Media Payload header. -** Input Parameters: -** frag: 1, if fragmented. 0, otherwise. -** -** start: 1, if the starting packet of a fragmented frame. -** -** last: 1, if the last packet of a fragmented frame. -** -** num: If frag is 1, this is the number of remaining fragments -** (including this fragment) of this frame. -** If frag is 0, this is the number of frames in this packet. -** -** Output Parameters: -** p_dst: the resulting media payload header byte sequence. -** -** Returns void. -******************************************************************************/ -extern void A2D_BldSbcMplHdr(UINT8 *p_dst, BOOLEAN frag, BOOLEAN start, - BOOLEAN last, UINT8 num); - -/****************************************************************************** -** -** Function A2D_ParsSbcMplHdr -** -** Description This function is called by an application to parse -** the SBC Media Payload header. -** Input Parameters: -** p_src: the byte sequence to parse.. -** -** Output Parameters: -** frag: 1, if fragmented. 0, otherwise. -** -** start: 1, if the starting packet of a fragmented frame. -** -** last: 1, if the last packet of a fragmented frame. -** -** num: If frag is 1, this is the number of remaining fragments -** (including this fragment) of this frame. -** If frag is 0, this is the number of frames in this packet. -** -** Returns void. -******************************************************************************/ -extern void A2D_ParsSbcMplHdr(UINT8 *p_src, BOOLEAN *p_frag, - BOOLEAN *p_start, BOOLEAN *p_last, - UINT8 *p_num); -#ifdef __cplusplus -} -#endif - -#endif ///A2D_INCLUDED == TRUE - -#endif /* A2D_SBC_H */ diff --git a/tools/sdk/include/bluedroid/stack/avct_api.h b/tools/sdk/include/bluedroid/stack/avct_api.h deleted file mode 100644 index 3d59df66..00000000 --- a/tools/sdk/include/bluedroid/stack/avct_api.h +++ /dev/null @@ -1,279 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2003-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This interface file contains the interface to the Audio Video Control - * Transport Protocol (AVCTP). - * - ******************************************************************************/ -#ifndef AVCT_API_H -#define AVCT_API_H - -#include "stack/bt_types.h" -#include "common/bt_target.h" - -/***************************************************************************** -** Constants -*****************************************************************************/ - -/* API function return value result codes. */ -#define AVCT_SUCCESS 0 /* Function successful */ -#define AVCT_NO_RESOURCES 1 /* Not enough resources */ -#define AVCT_BAD_HANDLE 2 /* Bad handle */ -#define AVCT_PID_IN_USE 3 /* PID already in use */ -#define AVCT_NOT_OPEN 4 /* Connection not open */ - -/* PSM for AVCT. */ -#define AVCT_PSM 0x0017 -#define AVCT_BR_PSM 0x001B - -/* Protocol revision numbers */ -#define AVCT_REV_1_0 0x0100 -#define AVCT_REV_1_2 0x0102 -#define AVCT_REV_1_3 0x0103 -#define AVCT_REV_1_4 0x0104 - -/* the layer_specific settings */ -#define AVCT_DATA_CTRL 0x0001 /* for the control channel */ -#define AVCT_DATA_BROWSE 0x0002 /* for the browsing channel */ -#define AVCT_DATA_PARTIAL 0x0100 /* Only have room for a partial message */ - -#define AVCT_MIN_CONTROL_MTU 48 /* Per the AVRC spec, minimum MTU for the control channel */ -#define AVCT_MIN_BROWSE_MTU 335 /* Per the AVRC spec, minimum MTU for the browsing channel */ - -/* Message offset. The number of bytes needed by the protocol stack for the -** protocol headers of an AVCTP message packet. -*/ -#define AVCT_MSG_OFFSET 15 -#define AVCT_BROWSE_OFFSET 17 /* the default offset for browsing channel */ - -/* Connection role. */ -#define AVCT_INT 0 /* Initiator connection */ -#define AVCT_ACP 1 /* Acceptor connection */ - -/* Control role. */ -#define AVCT_TARGET 1 /* target */ -#define AVCT_CONTROL 2 /* controller */ -#define AVCT_PASSIVE 4 /* If conflict, allow the other side to succeed */ - -/* Command/Response indicator. */ -#define AVCT_CMD 0 /* Command message */ -#define AVCT_RSP 2 /* Response message */ -#define AVCT_REJ 3 /* Message rejected */ - -/* Control callback events. */ -#define AVCT_CONNECT_CFM_EVT 0 /* Connection confirm */ -#define AVCT_CONNECT_IND_EVT 1 /* Connection indication */ -#define AVCT_DISCONNECT_CFM_EVT 2 /* Disconnect confirm */ -#define AVCT_DISCONNECT_IND_EVT 3 /* Disconnect indication */ -#define AVCT_CONG_IND_EVT 4 /* Congestion indication */ -#define AVCT_UNCONG_IND_EVT 5 /* Uncongestion indication */ -#define AVCT_BROWSE_CONN_CFM_EVT 6 /* Browse Connection confirm */ -#define AVCT_BROWSE_CONN_IND_EVT 7 /* Browse Connection indication */ -#define AVCT_BROWSE_DISCONN_CFM_EVT 8 /* Browse Disconnect confirm */ -#define AVCT_BROWSE_DISCONN_IND_EVT 9 /* Browse Disconnect indication */ -#define AVCT_BROWSE_CONG_IND_EVT 10 /* Congestion indication */ -#define AVCT_BROWSE_UNCONG_IND_EVT 11 /* Uncongestion indication */ - - -/* General purpose failure result code for callback events. */ -#define AVCT_RESULT_FAIL 5 - -/***************************************************************************** -** Type Definitions -*****************************************************************************/ - -/* Control callback function. */ -typedef void (tAVCT_CTRL_CBACK)(UINT8 handle, UINT8 event, UINT16 result, - BD_ADDR peer_addr); - -/* Message callback function */ -/* p_pkt->layer_specific is AVCT_DATA_CTRL or AVCT_DATA_BROWSE */ -typedef void (tAVCT_MSG_CBACK)(UINT8 handle, UINT8 label, UINT8 cr, - BT_HDR *p_pkt); - -/* Structure used by AVCT_CreateConn. */ -typedef struct { - tAVCT_CTRL_CBACK *p_ctrl_cback; /* Control callback */ - tAVCT_MSG_CBACK *p_msg_cback; /* Message callback */ - UINT16 pid; /* Profile ID */ - UINT8 role; /* Initiator/acceptor role */ - UINT8 control; /* Control role (Control/Target) */ -} tAVCT_CC; - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/******************************************************************************* -** -** Function AVCT_Register -** -** Description This is the system level registration function for the -** AVCTP protocol. This function initializes AVCTP and -** prepares the protocol stack for its use. This function -** must be called once by the system or platform using AVCTP -** before the other functions of the API an be used. -** -** -** Returns void -** -*******************************************************************************/ -extern void AVCT_Register(UINT16 mtu, UINT16 mtu_br, UINT8 sec_mask); - -/******************************************************************************* -** -** Function AVCT_Deregister -** -** Description This function is called to deregister use AVCTP protocol. -** It is called when AVCTP is no longer being used by any -** application in the system. Before this function can be -** called, all connections must be removed with -** AVCT_RemoveConn(). -** -** -** Returns void -** -*******************************************************************************/ -extern void AVCT_Deregister(void); - -/******************************************************************************* -** -** Function AVCT_CreateConn -** -** Description Create an AVCTP connection. There are two types of -** connections, initiator and acceptor, as determined by -** the p_cc->role parameter. When this function is called to -** create an initiator connection, an AVCTP connection to -** the peer device is initiated if one does not already exist. -** If an acceptor connection is created, the connection waits -** passively for an incoming AVCTP connection from a peer device. -** -** -** Returns AVCT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVCT_CreateConn(UINT8 *p_handle, tAVCT_CC *p_cc, - BD_ADDR peer_addr); - -/******************************************************************************* -** -** Function AVCT_RemoveConn -** -** Description Remove an AVCTP connection. This function is called when -** the application is no longer using a connection. If this -** is the last connection to a peer the L2CAP channel for AVCTP -** will be closed. -** -** -** Returns AVCT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVCT_RemoveConn(UINT8 handle); - -/******************************************************************************* -** -** Function AVCT_CreateBrowse -** -** Description Create an AVCTP connection. There are two types of -** connections, initiator and acceptor, as determined by -** the p_cc->role parameter. When this function is called to -** create an initiator connection, an AVCTP connection to -** the peer device is initiated if one does not already exist. -** If an acceptor connection is created, the connection waits -** passively for an incoming AVCTP connection from a peer device. -** -** -** Returns AVCT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVCT_CreateBrowse(UINT8 handle, UINT8 role); - -/******************************************************************************* -** -** Function AVCT_RemoveBrowse -** -** Description Remove an AVCTP connection. This function is called when -** the application is no longer using a connection. If this -** is the last connection to a peer the L2CAP channel for AVCTP -** will be closed. -** -** -** Returns AVCT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVCT_RemoveBrowse(UINT8 handle); - -/******************************************************************************* -** -** Function AVCT_GetBrowseMtu -** -** Description Get the peer_mtu for the AVCTP Browse channel of the given -** connection. -** -** Returns the peer browsing channel MTU. -** -*******************************************************************************/ -extern UINT16 AVCT_GetBrowseMtu (UINT8 handle); - -/******************************************************************************* -** -** Function AVCT_GetPeerMtu -** -** Description Get the peer_mtu for the AVCTP channel of the given -** connection. -** -** Returns the peer MTU size. -** -*******************************************************************************/ -extern UINT16 AVCT_GetPeerMtu (UINT8 handle); - -/******************************************************************************* -** -** Function AVCT_MsgReq -** -** Description Send an AVCTP message to a peer device. In calling -** AVCT_MsgReq(), the application should keep track of the -** congestion state of AVCTP as communicated with events -** AVCT_CONG_IND_EVT and AVCT_UNCONG_IND_EVT. If the -** application calls AVCT_MsgReq() when AVCTP is congested -** the message may be discarded. The application may make its -** first call to AVCT_MsgReq() after it receives an -** AVCT_CONNECT_CFM_EVT or AVCT_CONNECT_IND_EVT on control channel or -** AVCT_BROWSE_CONN_CFM_EVT or AVCT_BROWSE_CONN_IND_EVT on browsing channel. -** -** p_msg->layer_specific must be set to -** AVCT_DATA_CTRL for control channel traffic; -** AVCT_DATA_BROWSE for for browse channel traffic. -** -** Returns AVCT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVCT_MsgReq(UINT8 handle, UINT8 label, UINT8 cr, BT_HDR *p_msg); - -#ifdef __cplusplus -} -#endif - - -#endif /* AVCT_API_H */ diff --git a/tools/sdk/include/bluedroid/stack/avdt_api.h b/tools/sdk/include/bluedroid/stack/avdt_api.h deleted file mode 100644 index 26919697..00000000 --- a/tools/sdk/include/bluedroid/stack/avdt_api.h +++ /dev/null @@ -1,988 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2002-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This interface file contains the interface to the Audio Video - * Distribution Transport Protocol (AVDTP). - * - ******************************************************************************/ -#ifndef AVDT_API_H -#define AVDT_API_H - -#include "stack/bt_types.h" -#include "common/bt_target.h" - -/***************************************************************************** -** Constants -*****************************************************************************/ -#ifndef AVDT_VERSION -#define AVDT_VERSION 0x0102 -#endif -#define AVDT_VERSION_SYNC 0x0103 - -/* API function return value result codes. */ -#define AVDT_SUCCESS 0 /* Function successful */ -#define AVDT_BAD_PARAMS 1 /* Invalid parameters */ -#define AVDT_NO_RESOURCES 2 /* Not enough resources */ -#define AVDT_BAD_HANDLE 3 /* Bad handle */ -#define AVDT_BUSY 4 /* A procedure is already in progress */ -#define AVDT_WRITE_FAIL 5 /* Write failed */ - -/* The index to access the codec type in codec_info[]. */ -#define AVDT_CODEC_TYPE_INDEX 2 - -/* The size in bytes of a Adaptation Layer header. */ -#define AVDT_AL_HDR_SIZE 3 - -/* The size in bytes of a media packet header. */ -#define AVDT_MEDIA_HDR_SIZE 12 - -/* AVDTP 7.5.3 Adaptation Layer Fragmentation - * original length of the un-fragmented transport packet should be specified by - * two bytes length field of Adaptation Layer Header */ -#define AVDT_MAX_MEDIA_SIZE (0xFFFF - AVDT_MEDIA_HDR_SIZE) - -/* The handle is used when reporting MULTI_AV specific events */ -#define AVDT_MULTI_AV_HANDLE 0xFF - -/* The number of bytes needed by the protocol stack for the protocol headers -** of a media packet. This is the size of the media packet header, the -** L2CAP packet header and HCI header. -*/ -#define AVDT_MEDIA_OFFSET 23 - -/* The marker bit is used by the application to mark significant events such -** as frame boundaries in the data stream. This constant is used to check or -** set the marker bit in the m_pt parameter of an AVDT_WriteReq() -** or AVDT_DATA_IND_EVT. -*/ -#define AVDT_MARKER_SET 0x80 - -/* SEP Type. This indicates the stream endpoint type. */ -#define AVDT_TSEP_SRC 0 /* Source SEP */ -#define AVDT_TSEP_SNK 1 /* Sink SEP */ - -/* initiator/acceptor role for adaption */ -#define AVDT_INT 0 /* initiator */ -#define AVDT_ACP 1 /* acceptor */ - -/* Media Type. This indicates the media type of the stream endpoint. */ -#define AVDT_MEDIA_AUDIO 0 /* Audio SEP */ -#define AVDT_MEDIA_VIDEO 1 /* Video SEP */ -#define AVDT_MEDIA_MULTI 2 /* Multimedia SEP */ - -/* for reporting packets */ -#define AVDT_RTCP_PT_SR 200 /* the packet type - SR (Sender Report) */ -#define AVDT_RTCP_PT_RR 201 /* the packet type - RR (Receiver Report) */ -#define AVDT_RTCP_PT_SDES 202 /* the packet type - SDES (Source Description) */ -typedef UINT8 AVDT_REPORT_TYPE; - -#define AVDT_RTCP_SDES_CNAME 1 /* SDES item CNAME */ -#ifndef AVDT_MAX_CNAME_SIZE -#define AVDT_MAX_CNAME_SIZE 28 -#endif - -/* Protocol service capabilities. This indicates the protocol service -** capabilities of a stream endpoint. This value is a mask. -** Multiple values can be combined with a bitwise OR. -*/ -#define AVDT_PSC_TRANS (1<<1) /* Media transport */ -#define AVDT_PSC_REPORT (1<<2) /* Reporting */ -#define AVDT_PSC_RECOV (1<<3) /* Recovery */ -#define AVDT_PSC_HDRCMP (1<<5) /* Header compression */ -#define AVDT_PSC_MUX (1<<6) /* Multiplexing */ -#define AVDT_PSC_DELAY_RPT (1<<8) /* Delay Report */ - -/* Recovery type. This indicates the recovery type. */ -#define AVDT_RECOV_RFC2733 1 /* RFC2733 recovery */ - -/* Header compression capabilities. This indicates the header compression -** capabilities. This value is a mask. Multiple values can be combined -** with a bitwise OR. -*/ -#define AVDT_HDRCMP_MEDIA (1<<5) /* Available for media packets */ -#define AVDT_HDRCMP_RECOV (1<<6) /* Available for recovery packets */ -#define AVDT_HDRCMP_BACKCH (1<<7) /* Back channel supported */ - -/* Multiplexing capabilities mask. */ -#define AVDT_MUX_FRAG (1<<7) /* Allow Adaptation Layer Fragmentation */ - -/* Application service category. This indicates the application -** service category. -*/ -#define AVDT_ASC_PROTECT 4 /* Content protection */ -#define AVDT_ASC_CODEC 7 /* Codec */ - -/* Error codes. The following are error codes defined in the AVDTP and GAVDP -** specifications. These error codes communicate protocol errors between -** AVDTP and the application. More detailed descriptions of the error codes -** and their appropriate use can be found in the AVDTP and GAVDP specifications. -** These error codes are unrelated to the result values returned by the -** AVDTP API functions. -*/ -#define AVDT_ERR_HEADER 0x01 /* Bad packet header format */ -#define AVDT_ERR_LENGTH 0x11 /* Bad packet length */ -#define AVDT_ERR_SEID 0x12 /* Invalid SEID */ -#define AVDT_ERR_IN_USE 0x13 /* The SEP is in use */ -#define AVDT_ERR_NOT_IN_USE 0x14 /* The SEP is not in use */ -#define AVDT_ERR_CATEGORY 0x17 /* Bad service category */ -#define AVDT_ERR_PAYLOAD 0x18 /* Bad payload format */ -#define AVDT_ERR_NSC 0x19 /* Requested command not supported */ -#define AVDT_ERR_INVALID_CAP 0x1A /* Reconfigure attempted invalid capabilities */ -#define AVDT_ERR_RECOV_TYPE 0x22 /* Requested recovery type not defined */ -#define AVDT_ERR_MEDIA_TRANS 0x23 /* Media transport capability not correct */ -#define AVDT_ERR_RECOV_FMT 0x25 /* Recovery service capability not correct */ -#define AVDT_ERR_ROHC_FMT 0x26 /* Header compression service capability not correct */ -#define AVDT_ERR_CP_FMT 0x27 /* Content protection service capability not correct */ -#define AVDT_ERR_MUX_FMT 0x28 /* Multiplexing service capability not correct */ -#define AVDT_ERR_UNSUP_CFG 0x29 /* Configuration not supported */ -#define AVDT_ERR_BAD_STATE 0x31 /* Message cannot be processed in this state */ -#define AVDT_ERR_REPORT_FMT 0x65 /* Report service capability not correct */ -#define AVDT_ERR_SERVICE 0x80 /* Invalid service category */ -#define AVDT_ERR_RESOURCE 0x81 /* Insufficient resources */ -#define AVDT_ERR_INVALID_MCT 0xC1 /* Invalid Media Codec Type */ -#define AVDT_ERR_UNSUP_MCT 0xC2 /* Unsupported Media Codec Type */ -#define AVDT_ERR_INVALID_LEVEL 0xC3 /* Invalid Level */ -#define AVDT_ERR_UNSUP_LEVEL 0xC4 /* Unsupported Level */ -#define AVDT_ERR_INVALID_CP 0xE0 /* Invalid Content Protection Type */ -#define AVDT_ERR_INVALID_FORMAT 0xE1 /* Invalid Content Protection format */ - -/* Additional error codes. This indicates error codes used by AVDTP -** in addition to the ones defined in the specifications. -*/ -#define AVDT_ERR_CONNECT 0x07 /* Connection failed. */ -#define AVDT_ERR_TIMEOUT 0x08 /* Response timeout. */ - -/* Control callback events. */ -#define AVDT_DISCOVER_CFM_EVT 0 /* Discover confirm */ -#define AVDT_GETCAP_CFM_EVT 1 /* Get capabilities confirm */ -#define AVDT_OPEN_CFM_EVT 2 /* Open confirm */ -#define AVDT_OPEN_IND_EVT 3 /* Open indication */ -#define AVDT_CONFIG_IND_EVT 4 /* Configuration indication */ -#define AVDT_START_CFM_EVT 5 /* Start confirm */ -#define AVDT_START_IND_EVT 6 /* Start indication */ -#define AVDT_SUSPEND_CFM_EVT 7 /* Suspend confirm */ -#define AVDT_SUSPEND_IND_EVT 8 /* Suspend indication */ -#define AVDT_CLOSE_CFM_EVT 9 /* Close confirm */ -#define AVDT_CLOSE_IND_EVT 10 /* Close indication */ -#define AVDT_RECONFIG_CFM_EVT 11 /* Reconfiguration confirm */ -#define AVDT_RECONFIG_IND_EVT 12 /* Reconfiguration indication */ -#define AVDT_SECURITY_CFM_EVT 13 /* Security confirm */ -#define AVDT_SECURITY_IND_EVT 14 /* Security indication */ -#define AVDT_WRITE_CFM_EVT 15 /* Write confirm */ -#define AVDT_CONNECT_IND_EVT 16 /* Signaling channel connected */ -#define AVDT_DISCONNECT_IND_EVT 17 /* Signaling channel disconnected */ -#define AVDT_REPORT_CONN_EVT 18 /* Reporting channel connected */ -#define AVDT_REPORT_DISCONN_EVT 19 /* Reporting channel disconnected */ -#define AVDT_DELAY_REPORT_EVT 20 /* Delay report received */ -#define AVDT_DELAY_REPORT_CFM_EVT 21 /* Delay report response received */ - -#define AVDT_MAX_EVT (AVDT_DELAY_REPORT_CFM_EVT) - -/* PSM for AVDT */ -#define AVDT_PSM 0x0019 - -/* Nonsupported protocol command messages. This value is used in tAVDT_CS */ -#define AVDT_NSC_SUSPEND 0x01 /* Suspend command not supported */ -#define AVDT_NSC_RECONFIG 0x02 /* Reconfigure command not supported */ -#define AVDT_NSC_SECURITY 0x04 /* Security command not supported */ - -/* AVDT disconnection reason */ -#define AVDT_DISC_RSN_NORMAL 0 -#define AVDT_DISC_RSN_ABNORMAL (0xce) /* unintentional disconnection */ -/***************************************************************************** -** Type Definitions -*****************************************************************************/ - -typedef struct { - UINT32 ntp_sec; /* NTP time: seconds relative to 0h UTC on 1 January 1900 */ - UINT32 ntp_frac; /* NTP time: the fractional part */ - UINT32 rtp_time; /* timestamp in RTP header */ - UINT32 pkt_count; /* sender's packet count: since starting transmission - * up until the time this SR packet was generated. */ - UINT32 octet_count; /* sender's octet count: same comment */ -} tAVDT_SENDER_INFO; - -typedef struct { - UINT8 frag_lost; /* fraction lost since last RR */ - UINT32 packet_lost; /* cumulative number of packets lost since the beginning */ - UINT32 seq_num_rcvd; /* extended highest sequence number received */ - UINT32 jitter; /* interarrival jitter */ - UINT32 lsr; /* last SR timestamp */ - UINT32 dlsr; /* delay since last SR */ -} tAVDT_REPORT_BLK; - -typedef union { - tAVDT_SENDER_INFO sr; - tAVDT_REPORT_BLK rr; - UINT8 cname[AVDT_MAX_CNAME_SIZE + 1]; -} tAVDT_REPORT_DATA; - -/* This structure contains parameters which are set at registration. */ -typedef struct { - UINT16 ctrl_mtu; /* L2CAP MTU of the AVDTP signaling channel */ - UINT8 ret_tout; /* AVDTP signaling retransmission timeout */ - UINT8 sig_tout; /* AVDTP signaling message timeout */ - UINT8 idle_tout; /* AVDTP idle signaling channel timeout */ - UINT8 sec_mask; /* Security mask for BTM_SetSecurityLevel() */ -} tAVDT_REG; - -/* This structure contains the SEP information. This information is -** transferred during the discovery procedure. -*/ -typedef struct { - BOOLEAN in_use; /* TRUE if stream is currently in use */ - UINT8 seid; /* Stream endpoint identifier */ - UINT8 media_type; /* Media type */ - UINT8 tsep; /* SEP type */ -} tAVDT_SEP_INFO; - -/* This structure contains the SEP configuration. */ -typedef struct { - UINT8 codec_info[AVDT_CODEC_SIZE]; /* Codec capabilities array */ - UINT8 protect_info[AVDT_PROTECT_SIZE]; /* Content protection capabilities */ - UINT8 num_codec; /* Number of media codec information elements */ - UINT8 num_protect; /* Number of content protection information elements */ - UINT16 psc_mask; /* Protocol service capabilities mask */ - UINT8 recov_type; /* Recovery type */ - UINT8 recov_mrws; /* Maximum recovery window size */ - UINT8 recov_mnmp; /* Recovery maximum number of media packets */ - UINT8 hdrcmp_mask; /* Header compression capabilities */ -#if AVDT_MULTIPLEXING == TRUE - UINT8 mux_mask; /* Multiplexing capabilities. AVDT_MUX_XXX bits can be combined with a bitwise OR */ - UINT8 mux_tsid_media; /* TSID for media transport session */ - UINT8 mux_tcid_media; /* TCID for media transport session */ - UINT8 mux_tsid_report; /* TSID for reporting transport session */ - UINT8 mux_tcid_report; /* TCID for reporting transport session */ - UINT8 mux_tsid_recov; /* TSID for recovery transport session */ - UINT8 mux_tcid_recov; /* TCID for recovery transport session */ -#endif -} tAVDT_CFG; - -/* Header structure for callback event parameters. */ -typedef struct { - UINT8 err_code; /* Zero if operation succeeded; nonzero if operation failed */ - UINT8 err_param; /* Error parameter included for some events */ - UINT8 label; /* Transaction label */ - UINT8 seid; /* For internal use only */ - UINT8 sig_id; /* For internal use only */ - UINT8 ccb_idx; /* For internal use only */ -} tAVDT_EVT_HDR; - -/* This data structure is associated with the AVDT_GETCAP_CFM_EVT, -** AVDT_RECONFIG_IND_EVT, and AVDT_RECONFIG_CFM_EVT. -*/ -typedef struct { - tAVDT_EVT_HDR hdr; /* Event header */ - tAVDT_CFG *p_cfg; /* Pointer to configuration for this SEP */ -} tAVDT_CONFIG; - -/* This data structure is associated with the AVDT_CONFIG_IND_EVT. */ -typedef struct { - tAVDT_EVT_HDR hdr; /* Event header */ - tAVDT_CFG *p_cfg; /* Pointer to configuration for this SEP */ - UINT8 int_seid; /* Stream endpoint ID of stream initiating the operation */ -} tAVDT_SETCONFIG; - -/* This data structure is associated with the AVDT_OPEN_IND_EVT and AVDT_OPEN_CFM_EVT. */ -typedef struct { - tAVDT_EVT_HDR hdr; /* Event header */ - UINT16 peer_mtu; /* Transport channel L2CAP MTU of the peer */ - UINT16 lcid; /* L2CAP LCID for media channel */ -} tAVDT_OPEN; - -/* This data structure is associated with the AVDT_SECURITY_IND_EVT -** and AVDT_SECURITY_CFM_EVT. -*/ -typedef struct { - tAVDT_EVT_HDR hdr; /* Event header */ - UINT8 *p_data; /* Pointer to security data */ - UINT16 len; /* Length in bytes of the security data */ -} tAVDT_SECURITY; - -/* This data structure is associated with the AVDT_DISCOVER_CFM_EVT. */ -typedef struct { - tAVDT_EVT_HDR hdr; /* Event header */ - tAVDT_SEP_INFO *p_sep_info; /* Pointer to SEP information */ - UINT8 num_seps; /* Number of stream endpoints */ -} tAVDT_DISCOVER; - -/* This data structure is associated with the AVDT_DELAY_REPORT_EVT. */ -typedef struct { - tAVDT_EVT_HDR hdr; /* Event header */ - UINT16 delay; /* Delay value */ -} tAVDT_DELAY_RPT; - -/* Union of all control callback event data structures */ -typedef union { - tAVDT_EVT_HDR hdr; - tAVDT_DISCOVER discover_cfm; - tAVDT_CONFIG getcap_cfm; - tAVDT_OPEN open_cfm; - tAVDT_OPEN open_ind; - tAVDT_SETCONFIG config_ind; - tAVDT_EVT_HDR start_cfm; - tAVDT_EVT_HDR suspend_cfm; - tAVDT_EVT_HDR close_cfm; - tAVDT_CONFIG reconfig_cfm; - tAVDT_CONFIG reconfig_ind; - tAVDT_SECURITY security_cfm; - tAVDT_SECURITY security_ind; - tAVDT_EVT_HDR connect_ind; - tAVDT_EVT_HDR disconnect_ind; - tAVDT_EVT_HDR report_conn; - tAVDT_DELAY_RPT delay_rpt_cmd; -} tAVDT_CTRL; - -/* This is the control callback function. This function passes control events -** to the application. This function is required for all registered stream -** endpoints and for the AVDT_DiscoverReq() and AVDT_GetCapReq() functions. -** -*/ -typedef void (tAVDT_CTRL_CBACK)(UINT8 handle, BD_ADDR bd_addr, UINT8 event, - tAVDT_CTRL *p_data); - -/* This is the data callback function. It is executed when AVDTP has a media -** packet ready for the application. This function is required for SNK -** endpoints and not applicable for SRC endpoints. -*/ -typedef void (tAVDT_DATA_CBACK)(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, - UINT8 m_pt); - -#if AVDT_MULTIPLEXING == TRUE -/* This is the second version of the data callback function. This version uses -** application buffer assigned by AVDT_SetMediaBuf. Caller can assign different -** buffer during callback or can leave the current buffer for further using. -** This callback is called when AVDTP has a media packet ready for the application. -** This function is required for SNK endpoints and not applicable for SRC endpoints. -*/ -typedef void (tAVDT_MEDIA_CBACK)(UINT8 handle, UINT8 *p_payload, UINT32 payload_len, - UINT32 time_stamp, UINT16 seq_num, UINT8 m_pt, UINT8 marker); -#endif - -#if AVDT_REPORTING == TRUE -/* This is the report callback function. It is executed when AVDTP has a reporting -** packet ready for the application. This function is required for streams -** created with AVDT_PSC_REPORT. -*/ -typedef void (tAVDT_REPORT_CBACK)(UINT8 handle, AVDT_REPORT_TYPE type, - tAVDT_REPORT_DATA *p_data); -#endif - -typedef UINT16 (tAVDT_GETCAP_REQ) (BD_ADDR bd_addr, UINT8 seid, tAVDT_CFG *p_cfg, tAVDT_CTRL_CBACK *p_cback); - -/* This structure contains information required when a stream is created. -** It is passed to the AVDT_CreateStream() function. -*/ -typedef struct { - tAVDT_CFG cfg; /* SEP configuration */ - tAVDT_CTRL_CBACK *p_ctrl_cback; /* Control callback function */ - tAVDT_DATA_CBACK *p_data_cback; /* Data callback function */ -#if AVDT_MULTIPLEXING == TRUE - tAVDT_MEDIA_CBACK *p_media_cback; /* Media callback function. It will be called only if p_data_cback is NULL */ -#endif -#if AVDT_REPORTING == TRUE - tAVDT_REPORT_CBACK *p_report_cback;/* Report callback function. */ -#endif - UINT16 mtu; /* The L2CAP MTU of the transport channel */ - UINT16 flush_to; /* The L2CAP flush timeout of the transport channel */ - UINT8 tsep; /* SEP type */ - UINT8 media_type; /* Media type */ - UINT16 nsc_mask; /* Nonsupported protocol command messages */ -} tAVDT_CS; - -/* AVDT data option mask is used in the write request */ -#define AVDT_DATA_OPT_NONE 0x00 /* No option still add RTP header */ -#define AVDT_DATA_OPT_NO_RTP (0x01 << 0) /* Skip adding RTP header */ - -typedef UINT8 tAVDT_DATA_OPT_MASK; - - - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/******************************************************************************* -** -** Function AVDT_Register -** -** Description This is the system level registration function for the -** AVDTP protocol. This function initializes AVDTP and -** prepares the protocol stack for its use. This function -** must be called once by the system or platform using AVDTP -** before the other functions of the API an be used. -** -** -** Returns void -** -*******************************************************************************/ -extern void AVDT_Register(tAVDT_REG *p_reg, tAVDT_CTRL_CBACK *p_cback); - -/******************************************************************************* -** -** Function AVDT_Deregister -** -** Description This function is called to deregister use AVDTP protocol. -** It is called when AVDTP is no longer being used by any -** application in the system. Before this function can be -** called, all streams must be removed with AVDT_RemoveStream(). -** -** -** Returns void -** -*******************************************************************************/ -extern void AVDT_Deregister(void); - - -/******************************************************************************* -** -** Function AVDT_SINK_Activate -** -** Description Activate SEP of A2DP Sink. In Use parameter is adjusted. -** In Use will be made false in case of activation. A2DP SRC -** will receive in_use as false and can open A2DP Sink -** connection -** -** Returns void -** -*******************************************************************************/ -extern void AVDT_SINK_Activate(void); - -/******************************************************************************* -** -** Function AVDT_SINK_Deactivate -** -** Description Deactivate SEP of A2DP Sink. In Use parameter is adjusted. -** In Use will be made TRUE in case of activation. A2DP SRC -** will receive in_use as true and will not open A2DP Sink -** connection -** -** Returns void. -** -*******************************************************************************/ -extern void AVDT_SINK_Deactivate(void); - -/******************************************************************************* -** -** Function AVDT_AbortReq -** -** Description Trigger Abort request to pass AVDTP Abort related mandatory -** PTS Test case. -** -** Returns void. -** -*******************************************************************************/ -extern void AVDT_AbortReq(UINT8 handle); - -/******************************************************************************* -** -** Function AVDT_CreateStream -** -** Description Create a stream endpoint. After a stream endpoint is -** created an application can initiate a connection between -** this endpoint and an endpoint on a peer device. In -** addition, a peer device can discover, get the capabilities, -** and connect to this endpoint. -** -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_CreateStream(UINT8 *p_handle, tAVDT_CS *p_cs); - -/******************************************************************************* -** -** Function AVDT_RemoveStream -** -** Description Remove a stream endpoint. This function is called when -** the application is no longer using a stream endpoint. -** If this function is called when the endpoint is connected -** the connection is closed and then the stream endpoint -** is removed. -** -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_RemoveStream(UINT8 handle); - -/******************************************************************************* -** -** Function AVDT_DiscoverReq -** -** Description This function initiates a connection to the AVDTP service -** on the peer device, if not already present, and discovers -** the stream endpoints on the peer device. (Please note -** that AVDTP discovery is unrelated to SDP discovery). -** This function can be called at any time regardless of whether -** there is an AVDTP connection to the peer device. -** -** When discovery is complete, an AVDT_DISCOVER_CFM_EVT -** is sent to the application via its callback function. -** The application must not call AVDT_GetCapReq() or -** AVDT_DiscoverReq() again to the same device until -** discovery is complete. -** -** The memory addressed by sep_info is allocated by the -** application. This memory is written to by AVDTP as part -** of the discovery procedure. This memory must remain -** accessible until the application receives the -** AVDT_DISCOVER_CFM_EVT. -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_DiscoverReq(BD_ADDR bd_addr, tAVDT_SEP_INFO *p_sep_info, - UINT8 max_seps, tAVDT_CTRL_CBACK *p_cback); - - -/******************************************************************************* -** -** Function AVDT_GetCapReq -** -** Description This function initiates a connection to the AVDTP service -** on the peer device, if not already present, and gets the -** capabilities of a stream endpoint on the peer device. -** This function can be called at any time regardless of -** whether there is an AVDTP connection to the peer device. -** -** When the procedure is complete, an AVDT_GETCAP_CFM_EVT is -** sent to the application via its callback function. The -** application must not call AVDT_GetCapReq() or -** AVDT_DiscoverReq() again until the procedure is complete. -** -** The memory pointed to by p_cfg is allocated by the -** application. This memory is written to by AVDTP as part -** of the get capabilities procedure. This memory must -** remain accessible until the application receives -** the AVDT_GETCAP_CFM_EVT. -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_GetCapReq(BD_ADDR bd_addr, UINT8 seid, tAVDT_CFG *p_cfg, - tAVDT_CTRL_CBACK *p_cback); - -/******************************************************************************* -** -** Function AVDT_GetAllCapReq -** -** Description This function initiates a connection to the AVDTP service -** on the peer device, if not already present, and gets the -** capabilities of a stream endpoint on the peer device. -** This function can be called at any time regardless of -** whether there is an AVDTP connection to the peer device. -** -** When the procedure is complete, an AVDT_GETCAP_CFM_EVT is -** sent to the application via its callback function. The -** application must not call AVDT_GetCapReq() or -** AVDT_DiscoverReq() again until the procedure is complete. -** -** The memory pointed to by p_cfg is allocated by the -** application. This memory is written to by AVDTP as part -** of the get capabilities procedure. This memory must -** remain accessible until the application receives -** the AVDT_GETCAP_CFM_EVT. -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_GetAllCapReq(BD_ADDR bd_addr, UINT8 seid, tAVDT_CFG *p_cfg, - tAVDT_CTRL_CBACK *p_cback); - -/******************************************************************************* -** -** Function AVDT_DelayReport -** -** Description This functions sends a Delay Report to the peer device -** that is associated with a particular SEID. -** This function is called by SNK device. -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_DelayReport(UINT8 handle, UINT8 seid, UINT16 delay); - -/******************************************************************************* -** -** Function AVDT_OpenReq -** -** Description This function initiates a connection to the AVDTP service -** on the peer device, if not already present, and connects -** to a stream endpoint on a peer device. When the connection -** is completed, an AVDT_OPEN_CFM_EVT is sent to the -** application via the control callback function for this handle. -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_OpenReq(UINT8 handle, BD_ADDR bd_addr, UINT8 seid, - tAVDT_CFG *p_cfg); - - -/******************************************************************************* -** -** Function AVDT_ConfigRsp -** -** Description Respond to a configure request from the peer device. This -** function must be called if the application receives an -** AVDT_CONFIG_IND_EVT through its control callback. -** -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_ConfigRsp(UINT8 handle, UINT8 label, UINT8 error_code, - UINT8 category); - -/******************************************************************************* -** -** Function AVDT_StartReq -** -** Description Start one or more stream endpoints. This initiates the -** transfer of media packets for the streams. All stream -** endpoints must previously be opened. When the streams -** are started, an AVDT_START_CFM_EVT is sent to the -** application via the control callback function for each stream. -** -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_StartReq(UINT8 *p_handles, UINT8 num_handles); - -/******************************************************************************* -** -** Function AVDT_SuspendReq -** -** Description Suspend one or more stream endpoints. This suspends the -** transfer of media packets for the streams. All stream -** endpoints must previously be open and started. When the -** streams are suspended, an AVDT_SUSPEND_CFM_EVT is sent to -** the application via the control callback function for -** each stream. -** -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_SuspendReq(UINT8 *p_handles, UINT8 num_handles); - -/******************************************************************************* -** -** Function AVDT_CloseReq -** -** Description Close a stream endpoint. This stops the transfer of media -** packets and closes the transport channel associated with -** this stream endpoint. When the stream is closed, an -** AVDT_CLOSE_CFM_EVT is sent to the application via the -** control callback function for this handle. -** -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_CloseReq(UINT8 handle); - -/******************************************************************************* -** -** Function AVDT_ReconfigReq -** -** Description Reconfigure a stream endpoint. This allows the application -** to change the codec or content protection capabilities of -** a stream endpoint after it has been opened. This function -** can only be called if the stream is opened but not started -** or if the stream has been suspended. When the procedure -** is completed, an AVDT_RECONFIG_CFM_EVT is sent to the -** application via the control callback function for this handle. -** -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_ReconfigReq(UINT8 handle, tAVDT_CFG *p_cfg); - -/******************************************************************************* -** -** Function AVDT_ReconfigRsp -** -** Description Respond to a reconfigure request from the peer device. -** This function must be called if the application receives -** an AVDT_RECONFIG_IND_EVT through its control callback. -** -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_ReconfigRsp(UINT8 handle, UINT8 label, UINT8 error_code, - UINT8 category); - -/******************************************************************************* -** -** Function AVDT_SecurityReq -** -** Description Send a security request to the peer device. When the -** security procedure is completed, an AVDT_SECURITY_CFM_EVT -** is sent to the application via the control callback function -** for this handle. (Please note that AVDTP security procedures -** are unrelated to Bluetooth link level security.) -** -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_SecurityReq(UINT8 handle, UINT8 *p_data, UINT16 len); - -/******************************************************************************* -** -** Function AVDT_SecurityRsp -** -** Description Respond to a security request from the peer device. -** This function must be called if the application receives -** an AVDT_SECURITY_IND_EVT through its control callback. -** (Please note that AVDTP security procedures are unrelated -** to Bluetooth link level security.) -** -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_SecurityRsp(UINT8 handle, UINT8 label, UINT8 error_code, - UINT8 *p_data, UINT16 len); - -/******************************************************************************* -** -** Function AVDT_WriteReq -** -** Description Send a media packet to the peer device. The stream must -** be started before this function is called. Also, this -** function can only be called if the stream is a SRC. -** -** When AVDTP has sent the media packet and is ready for the -** next packet, an AVDT_WRITE_CFM_EVT is sent to the -** application via the control callback. The application must -** wait for the AVDT_WRITE_CFM_EVT before it makes the next -** call to AVDT_WriteReq(). If the applications calls -** AVDT_WriteReq() before it receives the event the packet -** will not be sent. The application may make its first call -** to AVDT_WriteReq() after it receives an AVDT_START_CFM_EVT -** or AVDT_START_IND_EVT. -** -** The application passes the packet using the BT_HDR structure. -** This structure is described in section 2.1. The offset -** field must be equal to or greater than AVDT_MEDIA_OFFSET. -** This allows enough space in the buffer for the L2CAP and -** AVDTP headers. -** -** The memory pointed to by p_pkt must be a GKI buffer -** allocated by the application. This buffer will be freed -** by the protocol stack; the application must not free -** this buffer. -** -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_WriteReq(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, - UINT8 m_pt); -/******************************************************************************* -** -** Function AVDT_WriteReqOpt -** -** Description Send a media packet to the peer device. The stream must -** be started before this function is called. Also, this -** function can only be called if the stream is a SRC -** -** When AVDTP has sent the media packet and is ready for the -** next packet, an AVDT_WRITE_CFM_EVT is sent to the -** application via the control callback. The application must -** wait for the AVDT_WRITE_CFM_EVT before it makes the next -** call to AVDT_WriteReq(). If the applications calls -** AVDT_WriteReq() before it receives the event the packet -** will not be sent. The application may make its first call -** to AVDT_WriteReq() after it receives an AVDT_START_CFM_EVT -** or AVDT_START_IND_EVT. -** -** The application passes the packet using the BT_HDR structure -** This structure is described in section 2.1. The offset -** field must be equal to or greater than AVDT_MEDIA_OFFSET -** (if NO_RTP is specified, L2CAP_MIN_OFFSET can be used) -** This allows enough space in the buffer for the L2CAP and -** AVDTP headers. -** -** The memory pointed to by p_pkt must be a GKI buffer -** allocated by the application. This buffer will be freed -** by the protocol stack; the application must not free -** this buffer. -** -** The opt parameter allows passing specific options like: -** - NO_RTP : do not add the RTP header to buffer -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_WriteReqOpt(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, - UINT8 m_pt, tAVDT_DATA_OPT_MASK opt); - -/******************************************************************************* -** -** Function AVDT_ConnectReq -** -** Description This function initiates an AVDTP signaling connection -** to the peer device. When the connection is completed, an -** AVDT_CONNECT_IND_EVT is sent to the application via its -** control callback function. If the connection attempt fails -** an AVDT_DISCONNECT_IND_EVT is sent. The security mask -** parameter overrides the outgoing security mask set in -** AVDT_Register(). -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_ConnectReq(BD_ADDR bd_addr, UINT8 sec_mask, - tAVDT_CTRL_CBACK *p_cback); - -/******************************************************************************* -** -** Function AVDT_DisconnectReq -** -** Description This function disconnect an AVDTP signaling connection -** to the peer device. When disconnected an -** AVDT_DISCONNECT_IND_EVT is sent to the application via its -** control callback function. -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_DisconnectReq(BD_ADDR bd_addr, tAVDT_CTRL_CBACK *p_cback); - -/******************************************************************************* -** -** Function AVDT_GetL2CapChannel -** -** Description Get the L2CAP CID used by the handle. -** -** Returns CID if successful, otherwise 0. -** -*******************************************************************************/ -extern UINT16 AVDT_GetL2CapChannel(UINT8 handle); - -/******************************************************************************* -** -** Function AVDT_GetSignalChannel -** -** Description Get the L2CAP CID used by the signal channel of the given handle. -** -** Returns CID if successful, otherwise 0. -** -*******************************************************************************/ -extern UINT16 AVDT_GetSignalChannel(UINT8 handle, BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function AVDT_WriteDataReq -** -** Description Send a media packet to the peer device. The stream must -** be started before this function is called. Also, this -** function can only be called if the stream is a SRC. -** -** When AVDTP has sent the media packet and is ready for the -** next packet, an AVDT_WRITE_CFM_EVT is sent to the -** application via the control callback. The application must -** wait for the AVDT_WRITE_CFM_EVT before it makes the next -** call to AVDT_WriteDataReq(). If the applications calls -** AVDT_WriteDataReq() before it receives the event the packet -** will not be sent. The application may make its first call -** to AVDT_WriteDataReq() after it receives an -** AVDT_START_CFM_EVT or AVDT_START_IND_EVT. -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_WriteDataReq(UINT8 handle, UINT8 *p_data, UINT32 data_len, - UINT32 time_stamp, UINT8 m_pt, UINT8 marker); - -/******************************************************************************* -** -** Function AVDT_SetMediaBuf -** -** Description Assigns buffer for media packets or forbids using of assigned -** buffer if argument p_buf is NULL. This function can only -** be called if the stream is a SNK. -** -** AVDTP uses this buffer to reassemble fragmented media packets. -** When AVDTP receives a complete media packet, it calls the -** p_media_cback assigned by AVDT_CreateStream(). -** This function can be called during callback to assign a -** different buffer for next media packet or can leave the current -** buffer for next packet. -** -** Returns AVDT_SUCCESS if successful, otherwise error. -** -*******************************************************************************/ -extern UINT16 AVDT_SetMediaBuf(UINT8 handle, UINT8 *p_buf, UINT32 buf_len); - -/******************************************************************************* -** -** Function AVDT_SendReport -** -** Description -** -** -** -** Returns -** -*******************************************************************************/ -extern UINT16 AVDT_SendReport(UINT8 handle, AVDT_REPORT_TYPE type, - tAVDT_REPORT_DATA *p_data); - -/****************************************************************************** -** -** Function AVDT_SetTraceLevel -** -** Description Sets the trace level for AVDT. If 0xff is passed, the -** current trace level is returned. -** -** Input Parameters: -** new_level: The level to set the AVDT tracing to: -** 0xff-returns the current setting. -** 0-turns off tracing. -** >= 1-Errors. -** >= 2-Warnings. -** >= 3-APIs. -** >= 4-Events. -** >= 5-Debug. -** -** Returns The new trace level or current trace level if -** the input parameter is 0xff. -** -******************************************************************************/ -extern UINT8 AVDT_SetTraceLevel (UINT8 new_level); - -#ifdef __cplusplus -} -#endif - - -#endif /* AVDT_API_H */ diff --git a/tools/sdk/include/bluedroid/stack/avdtc_api.h b/tools/sdk/include/bluedroid/stack/avdtc_api.h deleted file mode 100644 index 083b0b1c..00000000 --- a/tools/sdk/include/bluedroid/stack/avdtc_api.h +++ /dev/null @@ -1,230 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2002-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This interface file contains the interface AVDTP conformance API. These - * additional API functions and callback events are provided for - * conformance testing purposes only. They are not intended to be used by - * an application. - * - ******************************************************************************/ -#ifndef AVDT_CAPI_H -#define AVDT_CAPI_H - -#include "stack/avdt_api.h" - -/* start AVDTC events here to distinguish from AVDT events */ -#define AVDTC_EVT_BEGIN 0x80 - -#define AVDTC_DISCOVER_IND_EVT (0 + AVDTC_EVT_BEGIN) /* Discover indication */ -#define AVDTC_GETCAP_IND_EVT (1 + AVDTC_EVT_BEGIN) /* Get capabilities indication */ -#define AVDTC_SETCONFIG_CFM_EVT (2 + AVDTC_EVT_BEGIN) /* Set configuration confirm */ -#define AVDTC_GETCONFIG_IND_EVT (3 + AVDTC_EVT_BEGIN) /* Get configuration indication */ -#define AVDTC_GETCONFIG_CFM_EVT (4 + AVDTC_EVT_BEGIN) /* Get configuration confirm */ -#define AVDTC_OPEN_IND_EVT (5 + AVDTC_EVT_BEGIN) /* Open indication */ -#define AVDTC_START_IND_EVT (6 + AVDTC_EVT_BEGIN) /* Start indication */ -#define AVDTC_CLOSE_IND_EVT (7 + AVDTC_EVT_BEGIN) /* Close indication */ -#define AVDTC_SUSPEND_IND_EVT (8 + AVDTC_EVT_BEGIN) /* Suspend indication */ -#define AVDTC_ABORT_IND_EVT (9 + AVDTC_EVT_BEGIN) /* Abort indication */ -#define AVDTC_ABORT_CFM_EVT (10 + AVDTC_EVT_BEGIN) /* Abort confirm */ - -typedef struct { - tAVDT_EVT_HDR hdr; /* Event header */ - UINT8 seid_list[AVDT_NUM_SEPS]; /* Array of SEID values */ - UINT8 num_seps; /* Number of values in array */ -} tAVDT_MULTI; - -/* Union of all control callback event data structures */ -typedef union { - tAVDT_EVT_HDR hdr; - tAVDT_CONFIG getconfig_cfm; - tAVDT_MULTI start_ind; - tAVDT_MULTI suspend_ind; -} tAVDTC_CTRL; - -typedef void tAVDTC_CTRL_CBACK(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDTC_CTRL *p_data); - -#ifdef __cplusplus -extern "C" -{ -#endif - -/******************************************************************************* -** -** Function AVDTC_Init -** -** Description This function is called to begin using the conformance API. -** It must be called after AVDT_Register() and before any -** other API or conformance API functions are called. -** -** Returns void -** -*******************************************************************************/ -extern void AVDTC_Init(tAVDTC_CTRL_CBACK *p_cback); - -/******************************************************************************* -** -** Function AVDTC_DiscoverRsp -** -** Description Send a discover response. -** -** Returns void -** -*******************************************************************************/ -extern void AVDTC_DiscoverRsp(BD_ADDR bd_addr, UINT8 label, - tAVDT_SEP_INFO sep_info[], UINT8 num_seps); - -/******************************************************************************* -** -** Function AVDTC_GetCapRsp -** -** Description Send a get capabilities response. -** -** Returns void -** -*******************************************************************************/ -extern void AVDTC_GetCapRsp(BD_ADDR bd_addr, UINT8 label, tAVDT_CFG *p_cap); - -/******************************************************************************* -** -** Function AVDTC_GetAllCapRsp -** -** Description Send a get all capabilities response. -** -** Returns void -** -*******************************************************************************/ -extern void AVDTC_GetAllCapRsp(BD_ADDR bd_addr, UINT8 label, tAVDT_CFG *p_cap); - -/******************************************************************************* -** -** Function AVDTC_GetConfigReq -** -** Description Send a get configuration request. -** -** Returns void -** -*******************************************************************************/ -extern void AVDTC_GetConfigReq(UINT8 handle); - -/******************************************************************************* -** -** Function AVDTC_GetConfigRsp -** -** Description Send a get configuration response. -** -** Returns void -** -*******************************************************************************/ -extern void AVDTC_GetConfigRsp(UINT8 handle, UINT8 label, tAVDT_CFG *p_cfg); - -/******************************************************************************* -** -** Function AVDTC_OpenReq -** -** Description Send an open request. -** -** Returns void -** -*******************************************************************************/ -extern void AVDTC_OpenReq(UINT8 handle); - -/******************************************************************************* -** -** Function AVDTC_OpenRsp -** -** Description Send an open response. -** -** Returns void -** -*******************************************************************************/ -extern void AVDTC_OpenRsp(UINT8 handle, UINT8 label); - -/******************************************************************************* -** -** Function AVDTC_StartRsp -** -** Description Send a start response. -** -** Returns void -** -*******************************************************************************/ -extern void AVDTC_StartRsp(UINT8 *p_handles, UINT8 num_handles, UINT8 label); - -/******************************************************************************* -** -** Function AVDTC_CloseRsp -** -** Description Send a close response. -** -** Returns void -** -*******************************************************************************/ -extern void AVDTC_CloseRsp(UINT8 handle, UINT8 label); - -/******************************************************************************* -** -** Function AVDTC_SuspendRsp -** -** Description Send a suspend response. -** -** Returns void -** -*******************************************************************************/ -extern void AVDTC_SuspendRsp(UINT8 *p_handles, UINT8 num_handles, UINT8 label); - -/******************************************************************************* -** -** Function AVDTC_AbortReq -** -** Description Send an abort request. -** -** Returns void -** -*******************************************************************************/ -extern void AVDTC_AbortReq(UINT8 handle); - -/******************************************************************************* -** -** Function AVDTC_AbortRsp -** -** Description Send an abort response. -** -** Returns void -** -*******************************************************************************/ -extern void AVDTC_AbortRsp(UINT8 handle, UINT8 label); - -/******************************************************************************* -** -** Function AVDTC_Rej -** -** Description Send a reject message. -** -** Returns void -** -*******************************************************************************/ -extern void AVDTC_Rej(UINT8 handle, BD_ADDR bd_addr, UINT8 cmd, UINT8 label, - UINT8 err_code, UINT8 err_param); - -#ifdef __cplusplus -} -#endif - -#endif /* AVDT_CAPI_H */ diff --git a/tools/sdk/include/bluedroid/stack/avrc_api.h b/tools/sdk/include/bluedroid/stack/avrc_api.h deleted file mode 100644 index c0c0a5ff..00000000 --- a/tools/sdk/include/bluedroid/stack/avrc_api.h +++ /dev/null @@ -1,653 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2006-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * nterface to AVRCP Application Programming Interface - * - ******************************************************************************/ -#ifndef AVRC_API_H -#define AVRC_API_H -#include "common/bt_target.h" -#include "stack/avct_api.h" -#include "stack/sdp_api.h" -#include "stack/avrc_defs.h" -#if (AVRC_INCLUDED == TRUE) -/***************************************************************************** -** constants -*****************************************************************************/ - -/* API function return value result codes. */ -#define AVRC_SUCCESS AVCT_SUCCESS /* 0 Function successful */ -#define AVRC_NO_RESOURCES AVCT_NO_RESOURCES /* 1 Not enough resources */ -#define AVRC_BAD_HANDLE AVCT_BAD_HANDLE /* 2 Bad handle */ -#define AVRC_PID_IN_USE AVCT_PID_IN_USE /* 3 PID already in use */ -#define AVRC_NOT_OPEN AVCT_NOT_OPEN /* 4 Connection not open */ -#define AVRC_MSG_TOO_BIG 5 /* 5 the message length exceed the MTU of the browsing channel */ -#define AVRC_FAIL 0x10 /* 0x10 generic failure */ -#define AVRC_BAD_PARAM 0x11 /* 0x11 bad parameter */ - -/* Control role - same as AVCT_TARGET/AVCT_CONTROL */ -#define AVRC_CT_TARGET 1 /* target */ -#define AVRC_CT_CONTROL 2 /* controller */ -#define AVRC_CT_PASSIVE 4 /* If conflict, allow the other side to succeed */ - -/* Connection role */ -#define AVRC_CONN_INT AVCT_INT /* initiator */ -#define AVRC_CONN_ACP AVCT_ACP /* Acceptor */ - - -/* AVRC CTRL events */ -/* AVRC_OPEN_IND_EVT event is sent when the connection is successfully opened. - * This eventis sent in response to an AVRC_Open(). */ -#define AVRC_OPEN_IND_EVT 0 - -/* AVRC_CLOSE_IND_EVT event is sent when a connection is closed. - * This event can result from a call to AVRC_Close() or when the peer closes - * the connection. It is also sent when a connection attempted through - * AVRC_Open() fails. */ -#define AVRC_CLOSE_IND_EVT 1 - -/* AVRC_CONG_IND_EVT event indicates that AVCTP is congested and cannot send - * any more messages. */ -#define AVRC_CONG_IND_EVT 2 - -/* AVRC_UNCONG_IND_EVT event indicates that AVCTP is uncongested and ready to - * send messages. */ -#define AVRC_UNCONG_IND_EVT 3 - -/* AVRC_BROWSE_OPEN_IND_EVT event is sent when the browse channel is successfully opened. -* This eventis sent in response to an AVRC_Open() or AVRC_OpenBrowse() . */ -#define AVRC_BROWSE_OPEN_IND_EVT 4 - -/* AVRC_BROWSE_CLOSE_IND_EVT event is sent when a browse channel is closed. - * This event can result from a call to AVRC_Close(), AVRC_CloseBrowse() or when the peer closes - * the connection. It is also sent when a connection attempted through - * AVRC_OpenBrowse() fails. */ -#define AVRC_BROWSE_CLOSE_IND_EVT 5 - -/* AVRC_BROWSE_CONG_IND_EVT event indicates that AVCTP browse channel is congested and cannot send - * any more messages. */ -#define AVRC_BROWSE_CONG_IND_EVT 6 - -/* AVRC_BROWSE_UNCONG_IND_EVT event indicates that AVCTP browse channel is uncongested and ready to - * send messages. */ -#define AVRC_BROWSE_UNCONG_IND_EVT 7 - -/* AVRC_CMD_TIMEOUT_EVT event indicates timeout waiting for AVRC command response from the peer */ -#define AVRC_CMD_TIMEOUT_EVT 8 - -/* Supported categories */ -#define AVRC_SUPF_CT_CAT1 0x0001 /* Category 1 */ -#define AVRC_SUPF_CT_CAT2 0x0002 /* Category 2 */ -#define AVRC_SUPF_CT_CAT3 0x0004 /* Category 3 */ -#define AVRC_SUPF_CT_CAT4 0x0008 /* Category 4 */ -#define AVRC_SUPF_CT_BROWSE 0x0040 /* Browsing */ - -#define AVRC_SUPF_TG_CAT1 0x0001 /* Category 1 */ -#define AVRC_SUPF_TG_CAT2 0x0002 /* Category 2 */ -#define AVRC_SUPF_TG_CAT3 0x0004 /* Category 3 */ -#define AVRC_SUPF_TG_CAT4 0x0008 /* Category 4 */ -#define AVRC_SUPF_TG_APP_SETTINGS 0x0010 /* Player Application Settings */ -#define AVRC_SUPF_TG_GROUP_NAVI 0x0020 /* Group Navigation */ -#define AVRC_SUPF_TG_BROWSE 0x0040 /* Browsing */ -#define AVRC_SUPF_TG_MULTI_PLAYER 0x0080 /* Muliple Media Player */ - -#define AVRC_META_SUCCESS AVRC_SUCCESS -#define AVRC_META_FAIL AVRC_FAIL -#define AVRC_METADATA_CMD 0x0000 -#define AVRC_METADATA_RESP 0x0001 - - - -/***************************************************************************** -** data type definitions -*****************************************************************************/ - -/* This data type is used in AVRC_FindService() to initialize the SDP database - * to hold the result service search. */ -typedef struct { - UINT32 db_len; /* Length, in bytes, of the discovery database */ - tSDP_DISCOVERY_DB *p_db; /* Pointer to the discovery database */ - UINT16 num_attr;/* The number of attributes in p_attrs */ - UINT16 *p_attrs; /* The attributes filter. If NULL, AVRCP API sets the attribute filter - * to be ATTR_ID_SERVICE_CLASS_ID_LIST, ATTR_ID_BT_PROFILE_DESC_LIST, - * ATTR_ID_SUPPORTED_FEATURES, ATTR_ID_SERVICE_NAME and ATTR_ID_PROVIDER_NAME. - * If not NULL, the input is taken as the filter. */ -} tAVRC_SDP_DB_PARAMS; - -/* This callback function returns service discovery information to the - * application after the AVRC_FindService() API function is called. The - * implementation of this callback function must copy the p_service_name - * and p_provider_name parameters passed to it as they are not guaranteed - * to remain after the callback function exits. */ -typedef void (tAVRC_FIND_CBACK) (UINT16 status); - - -/* This is the control callback function. This function passes events - * listed in Table 20 to the application. */ -typedef void (tAVRC_CTRL_CBACK) (UINT8 handle, UINT8 event, UINT16 result, - BD_ADDR peer_addr); - - -/* This is the message callback function. It is executed when AVCTP has - * a message packet ready for the application. The implementation of this - * callback function must copy the tAVRC_MSG structure passed to it as it - * is not guaranteed to remain after the callback function exits. */ -typedef void (tAVRC_MSG_CBACK) (UINT8 handle, UINT8 label, UINT8 opcode, - tAVRC_MSG *p_msg); - -typedef struct { - tAVRC_CTRL_CBACK *p_ctrl_cback; /* pointer to application control callback */ - tAVRC_MSG_CBACK *p_msg_cback; /* pointer to application message callback */ - UINT32 company_id; /* the company ID */ - UINT8 conn; /* Connection role (Initiator/acceptor) */ - UINT8 control; /* Control role (Control/Target) */ -} tAVRC_CONN_CB; - - - -/***************************************************************************** -** external function declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/****************************************************************************** -** -** Function AVRC_AddRecord -** -** Description This function is called to build an AVRCP SDP record. -** Prior to calling this function the application must -** call SDP_CreateRecord() to create an SDP record. -** -** Input Parameters: -** service_uuid: Indicates TG(UUID_SERVCLASS_AV_REM_CTRL_TARGET) -** or CT(UUID_SERVCLASS_AV_REMOTE_CONTROL) -** -** p_service_name: Pointer to a null-terminated character -** string containing the service name. -** If service name is not used set this to NULL. -** -** p_provider_name: Pointer to a null-terminated character -** string containing the provider name. -** If provider name is not used set this to NULL. -** -** categories: Supported categories. -** -** sdp_handle: SDP handle returned by SDP_CreateRecord(). -** -** Output Parameters: -** None. -** -** Returns AVRC_SUCCESS if successful. -** AVRC_NO_RESOURCES if not enough resources to build the SDP record. -** -******************************************************************************/ -extern UINT16 AVRC_AddRecord(UINT16 service_uuid, char *p_service_name, - char *p_provider_name, UINT16 categories, UINT32 sdp_handle); - -/****************************************************************************** -** -** Function AVRC_FindService -** -** Description This function is called by the application to perform service -** discovery and retrieve AVRCP SDP record information from a -** peer device. Information is returned for the first service -** record found on the server that matches the service UUID. -** The callback function will be executed when service discovery -** is complete. There can only be one outstanding call to -** AVRC_FindService() at a time; the application must wait for -** the callback before it makes another call to the function. -** The application is responsible for allocating memory for the -** discovery database. It is recommended that the size of the -** discovery database be at least 300 bytes. The application -** can deallocate the memory after the callback function has -** executed. -** -** Input Parameters: -** service_uuid: Indicates TG(UUID_SERVCLASS_AV_REM_CTRL_TARGET) -** or CT(UUID_SERVCLASS_AV_REMOTE_CONTROL) -** -** bd_addr: BD address of the peer device. -** -** p_db: SDP discovery database parameters. -** -** p_cback: Pointer to the callback function. -** -** Output Parameters: -** None. -** -** Returns AVRC_SUCCESS if successful. -** AVRC_BAD_PARAMS if discovery database parameters are invalid. -** AVRC_NO_RESOURCES if there are not enough resources to -** perform the service search. -** -******************************************************************************/ -extern UINT16 AVRC_FindService(UINT16 service_uuid, BD_ADDR bd_addr, - tAVRC_SDP_DB_PARAMS *p_db, tAVRC_FIND_CBACK *p_cback); - -/****************************************************************************** -** -** Function AVRC_Open -** -** Description This function is called to open a connection to AVCTP. -** The connection can be either an initiator or acceptor, as -** determined by the p_ccb->stream parameter. -** The connection can be a target, a controller or for both role, -** as determined by the p_ccb->control parameter. -** By definition, a target connection is an acceptor connection -** that waits for an incoming AVCTP connection from the peer. -** The connection remains available to the application until -** the application closes it by calling AVRC_Close(). The -** application does not need to reopen the connection after an -** AVRC_CLOSE_IND_EVT is received. -** -** Input Parameters: -** p_ccb->company_id: Company Identifier. -** -** p_ccb->p_ctrl_cback: Pointer to control callback function. -** -** p_ccb->p_msg_cback: Pointer to message callback function. -** -** p_ccb->conn: AVCTP connection role. This is set to -** AVCTP_INT for initiator connections and AVCTP_ACP -** for acceptor connections. -** -** p_ccb->control: Control role. This is set to -** AVRC_CT_TARGET for target connections, AVRC_CT_CONTROL -** for control connections or (AVRC_CT_TARGET|AVRC_CT_CONTROL) -** for connections that support both roles. -** -** peer_addr: BD address of peer device. This value is -** only used for initiator connections; for acceptor -** connections it can be set to NULL. -** -** Output Parameters: -** p_handle: Pointer to handle. This parameter is only -** valid if AVRC_SUCCESS is returned. -** -** Returns AVRC_SUCCESS if successful. -** AVRC_NO_RESOURCES if there are not enough resources to open -** the connection. -** -******************************************************************************/ -extern UINT16 AVRC_Open(UINT8 *p_handle, tAVRC_CONN_CB *p_ccb, - BD_ADDR_PTR peer_addr); - -/****************************************************************************** -** -** Function AVRC_Close -** -** Description Close a connection opened with AVRC_Open(). -** This function is called when the -** application is no longer using a connection. -** -** Input Parameters: -** handle: Handle of this connection. -** -** Output Parameters: -** None. -** -** Returns AVRC_SUCCESS if successful. -** AVRC_BAD_HANDLE if handle is invalid. -** -******************************************************************************/ -extern UINT16 AVRC_Close(UINT8 handle); - -/****************************************************************************** -** -** Function AVRC_OpenBrowse -** -** Description This function is called to open a browsing connection to AVCTP. -** The connection can be either an initiator or acceptor, as -** determined by the conn_role. -** The handle is returned by a previous call to AVRC_Open. -** -** Returns AVRC_SUCCESS if successful. -** AVRC_NO_RESOURCES if there are not enough resources to open -** the connection. -** -******************************************************************************/ -extern UINT16 AVRC_OpenBrowse(UINT8 handle, UINT8 conn_role); - -/****************************************************************************** -** -** Function AVRC_CloseBrowse -** -** Description Close a connection opened with AVRC_OpenBrowse(). -** This function is called when the -** application is no longer using a connection. -** -** Returns AVRC_SUCCESS if successful. -** AVRC_BAD_HANDLE if handle is invalid. -** -******************************************************************************/ -extern UINT16 AVRC_CloseBrowse(UINT8 handle); - -/****************************************************************************** -** -** Function AVRC_MsgReq -** -** Description This function is used to send the AVRCP byte stream in p_pkt -** down to AVCTP. -** -** It is expected that p_pkt->offset is at least AVCT_MSG_OFFSET -** p_pkt->layer_specific is AVCT_DATA_CTRL or AVCT_DATA_BROWSE -** p_pkt->event is AVRC_OP_VENDOR, AVRC_OP_PASS_THRU or AVRC_OP_BROWSING -** The above BT_HDR settings are set by the AVRC_Bld* functions. -** -** Returns AVRC_SUCCESS if successful. -** AVRC_BAD_HANDLE if handle is invalid. -** -******************************************************************************/ -extern UINT16 AVRC_MsgReq (UINT8 handle, UINT8 label, UINT8 ctype, BT_HDR *p_pkt); - -/****************************************************************************** -** -** Function AVRC_UnitCmd -** -** Description Send a UNIT INFO command to the peer device. This -** function can only be called for controller role connections. -** Any response message from the peer is passed back through -** the tAVRC_MSG_CBACK callback function. -** -** Input Parameters: -** handle: Handle of this connection. -** -** label: Transaction label. -** -** Output Parameters: -** None. -** -** Returns AVRC_SUCCESS if successful. -** AVRC_BAD_HANDLE if handle is invalid. -** -******************************************************************************/ -extern UINT16 AVRC_UnitCmd(UINT8 handle, UINT8 label); - -/****************************************************************************** -** -** Function AVRC_SubCmd -** -** Description Send a SUBUNIT INFO command to the peer device. This -** function can only be called for controller role connections. -** Any response message from the peer is passed back through -** the tAVRC_MSG_CBACK callback function. -** -** Input Parameters: -** handle: Handle of this connection. -** -** label: Transaction label. -** -** page: Specifies which part of the subunit type table -** is requested. For AVRCP it is typically zero. -** Value range is 0-7. -** -** Output Parameters: -** None. -** -** Returns AVRC_SUCCESS if successful. -** AVRC_BAD_HANDLE if handle is invalid. -** -******************************************************************************/ -extern UINT16 AVRC_SubCmd(UINT8 handle, UINT8 label, UINT8 page); - - -/****************************************************************************** -** -** Function AVRC_PassCmd -** -** Description Send a PASS THROUGH command to the peer device. This -** function can only be called for controller role connections. -** Any response message from the peer is passed back through -** the tAVRC_MSG_CBACK callback function. -** -** Input Parameters: -** handle: Handle of this connection. -** -** label: Transaction label. -** -** p_msg: Pointer to PASS THROUGH message structure. -** -** Output Parameters: -** None. -** -** Returns AVRC_SUCCESS if successful. -** AVRC_BAD_HANDLE if handle is invalid. -** -******************************************************************************/ -extern UINT16 AVRC_PassCmd(UINT8 handle, UINT8 label, tAVRC_MSG_PASS *p_msg); - -/****************************************************************************** -** -** Function AVRC_PassRsp -** -** Description Send a PASS THROUGH response to the peer device. This -** function can only be called for target role connections. -** This function must be called when a PASS THROUGH command -** message is received from the peer through the -** tAVRC_MSG_CBACK callback function. -** -** Input Parameters: -** handle: Handle of this connection. -** -** label: Transaction label. Must be the same value as -** passed with the command message in the callback function. -** -** p_msg: Pointer to PASS THROUGH message structure. -** -** Output Parameters: -** None. -** -** Returns AVRC_SUCCESS if successful. -** AVRC_BAD_HANDLE if handle is invalid. -** -******************************************************************************/ -extern UINT16 AVRC_PassRsp(UINT8 handle, UINT8 label, tAVRC_MSG_PASS *p_msg); - - -/****************************************************************************** -** -** Function AVRC_VendorCmd -** -** Description Send a VENDOR DEPENDENT command to the peer device. This -** function can only be called for controller role connections. -** Any response message from the peer is passed back through -** the tAVRC_MSG_CBACK callback function. -** -** Input Parameters: -** handle: Handle of this connection. -** -** label: Transaction label. -** -** p_msg: Pointer to VENDOR DEPENDENT message structure. -** -** Output Parameters: -** None. -** -** Returns AVRC_SUCCESS if successful. -** AVRC_BAD_HANDLE if handle is invalid. -** -******************************************************************************/ -extern UINT16 AVRC_VendorCmd(UINT8 handle, UINT8 label, tAVRC_MSG_VENDOR *p_msg); - - -/****************************************************************************** -** -** Function AVRC_VendorRsp -** -** Description Send a VENDOR DEPENDENT response to the peer device. This -** function can only be called for target role connections. -** This function must be called when a VENDOR DEPENDENT -** command message is received from the peer through the -** tAVRC_MSG_CBACK callback function. -** -** Input Parameters: -** handle: Handle of this connection. -** -** label: Transaction label. Must be the same value as -** passed with the command message in the callback function. -** -** p_msg: Pointer to VENDOR DEPENDENT message structure. -** -** Output Parameters: -** None. -** -** Returns AVRC_SUCCESS if successful. -** AVRC_BAD_HANDLE if handle is invalid. -** -******************************************************************************/ -extern UINT16 AVRC_VendorRsp(UINT8 handle, UINT8 label, tAVRC_MSG_VENDOR *p_msg); - - -/****************************************************************************** -** -** Function AVRC_SetTraceLevel -** -** Description Sets the trace level for AVRC. If 0xff is passed, the -** current trace level is returned. -** -** Input Parameters: -** new_level: The level to set the AVRC tracing to: -** 0xff-returns the current setting. -** 0-turns off tracing. -** >= 1-Errors. -** >= 2-Warnings. -** >= 3-APIs. -** >= 4-Events. -** >= 5-Debug. -** -** Returns The new trace level or current trace level if -** the input parameter is 0xff. -** -******************************************************************************/ -extern UINT8 AVRC_SetTraceLevel (UINT8 new_level); - -/******************************************************************************* -** -** Function AVRC_Init -** -** Description This function is called at stack startup to allocate the -** control block (if using dynamic memory), and initializes the -** control block and tracing level. -** -** Returns void -** -*******************************************************************************/ -extern void AVRC_Init(void); - -/******************************************************************************* -** -** Function AVRC_Deinit -** -** Description This function is called at stack shotdown to free the -** control block (if using dynamic memory), and deinitializes the -** control block and tracing level. -** -** Returns void -** -*******************************************************************************/ -extern void AVRC_Deinit(void); - -/******************************************************************************* -** -** Function AVRC_ParsCommand -** -** Description This function is used to parse the received command. -** -** Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully. -** Otherwise, the error code defined by AVRCP 1.4 -** -*******************************************************************************/ -extern tAVRC_STS AVRC_ParsCommand (tAVRC_MSG *p_msg, tAVRC_COMMAND *p_result, - UINT8 *p_buf, UINT16 buf_len); - -/******************************************************************************* -** -** Function AVRC_ParsResponse -** -** Description This function is used to parse the received response. -** -** Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully. -** Otherwise, the error code defined by AVRCP 1.4 -** -*******************************************************************************/ -extern tAVRC_STS AVRC_ParsResponse (tAVRC_MSG *p_msg, tAVRC_RESPONSE *p_result, - UINT8 *p_buf, UINT16 buf_len); - -/******************************************************************************* -** -** Function AVRC_BldCommand -** -** Description This function builds the given AVRCP command to the given -** GKI buffer -** -** Returns AVRC_STS_NO_ERROR, if the command is built successfully -** Otherwise, the error code. -** -*******************************************************************************/ -extern tAVRC_STS AVRC_BldCommand( tAVRC_COMMAND *p_cmd, BT_HDR **pp_pkt); - -/******************************************************************************* -** -** Function AVRC_BldResponse -** -** Description This function builds the given AVRCP response to the given -** GKI buffer -** -** Returns AVRC_STS_NO_ERROR, if the response is built successfully -** Otherwise, the error code. -** -*******************************************************************************/ -extern tAVRC_STS AVRC_BldResponse( UINT8 handle, tAVRC_RESPONSE *p_rsp, BT_HDR **pp_pkt); - -/************************************************************************** -** -** Function AVRC_IsValidAvcType -** -** Description Check if correct AVC type is specified -** -** Returns returns TRUE if it is valid -** -** -*******************************************************************************/ -extern BOOLEAN AVRC_IsValidAvcType(UINT8 pdu_id, UINT8 avc_type); - -/******************************************************************************* -** -** Function AVRC_IsValidPlayerAttr -** -** Description Check if the given attrib value is a valid one -** -** -** Returns returns TRUE if it is valid -** -*******************************************************************************/ -extern BOOLEAN AVRC_IsValidPlayerAttr(UINT8 attr); - -#ifdef __cplusplus -} -#endif - -#endif ///AVRC_INCLUDED == TRUE - - -#endif /* AVRC_API_H */ diff --git a/tools/sdk/include/bluedroid/stack/avrc_defs.h b/tools/sdk/include/bluedroid/stack/avrc_defs.h deleted file mode 100644 index 8c56cf53..00000000 --- a/tools/sdk/include/bluedroid/stack/avrc_defs.h +++ /dev/null @@ -1,1362 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2006-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * AVRCP definition and data types - * - ******************************************************************************/ -#ifndef _AVRC_DEFS_H -#define _AVRC_DEFS_H -#include "common/bt_target.h" - -#if (AVRC_INCLUDED == TRUE) -/***************************************************************************** -** constants -*****************************************************************************/ - -/* Profile revision numbers */ -#define AVRC_REV_1_0 0x0100 -#define AVRC_REV_1_3 0x0103 -#define AVRC_REV_1_4 0x0104 - -#define AVRC_PACKET_LEN 512 /* Per the spec, you must support 512 byte RC packets */ - -#define AVRC_MIN_CONTROL_MTU 48 /* Per the spec, minimum MTU for the control channel */ -#define AVRC_MIN_BROWSE_MTU 335 /* Per the spec, minimum MTU for the browsing channel */ - -#define AVRC_META_PDU_OFFSET 4 -#define AVRC_SUB_TYPE_LEN 4 -#define AVRC_UID_SIZE 8 -#define AVRC_FEATURE_MASK_SIZE 16 - -/* command type codes */ -#define AVRC_CMD_CTRL 0 /* Instruct a target to perform an operation */ -#define AVRC_CMD_STATUS 1 /* Check a deviceÂ’s current status */ -#define AVRC_CMD_SPEC_INQ 2 /* Check whether a target supports a particular - control command; all operands are included */ -#define AVRC_CMD_NOTIF 3 /* Used for receiving notification of a change in a deviceÂ’s state */ -#define AVRC_CMD_GEN_INQ 4 /* Check whether a target supports a particular - control command; operands are not included */ - -/* response type codes */ -#define AVRC_RSP_NOT_IMPL 8 /* The target does not implement the command specified - by the opcode and operand, - or doesnÂ’t implement the specified subunit */ -#define AVRC_RSP_ACCEPT 9 /* The target executed or is executing the command */ -#define AVRC_RSP_REJ 10 /* The target implements the command specified by the - opcode but cannot respond because the current state - of the target doesnÂ’t allow it */ -#define AVRC_RSP_IN_TRANS 11 /* The target implements the status command but it is - in a state of transition; the status command may - be retried at a future time */ -#define AVRC_RSP_IMPL_STBL 12 /* For specific inquiry or general inquiy commands, - the target implements the command; for status - commands, the target returns stable and includes - the status results */ -#define AVRC_RSP_CHANGED 13 /* The response frame contains a notification that the - target deviceÂ’s state has changed */ -#define AVRC_RSP_INTERIM 15 /* For control commands, the target has accepted the - request but cannot return information within 100 - milliseconds; for notify commands, the target accepted - the command, and will notify the controller of a change - of target state at a future time */ - -/* subunit type */ -#define AVRC_SUB_MONITOR 0x00 /* Monitor */ -#define AVRC_SUB_AUDIO 0x01 /* Audio */ -#define AVRC_SUB_PRINTER 0x02 /* Printer */ -#define AVRC_SUB_DISC 0x03 /* Disc */ -#define AVRC_SUB_TAPE 0x04 /* Tape recorder/player */ -#define AVRC_SUB_TUNER 0x05 /* Tuner */ -#define AVRC_SUB_CA 0x06 /* CA */ -#define AVRC_SUB_CAMERA 0x07 /* Camera */ -#define AVRC_SUB_PANEL 0x09 /* Panel */ -#define AVRC_SUB_BB 0x0A /* Bulletin Board */ -#define AVRC_SUB_CAM_STOR 0x0B /* Camera Storage */ -#define AVRC_SUB_VENDOR 0x1C /* Vendor unique */ -#define AVRC_SUB_EXT 0x1E /* Subunit type extended to next byte */ -#define AVRC_SUB_UNIT 0x1F /* Unit */ - -/* opcodes - defined by 1394ta */ -#define AVRC_OP_UNIT_INFO 0x30 /* Report unit information */ -#define AVRC_OP_SUB_INFO 0x31 /* Report subunit information */ -#define AVRC_OP_VENDOR 0x00 /* Vendor-dependent commands */ -#define AVRC_OP_PASS_THRU 0x7C /* panel subunit opcode */ -/* opcodes 80-9F and E0-FF are not used by 1394ta.Sneak one for the browsing channel */ -#define AVRC_OP_BROWSE 0xFF /* Browsing */ -#define AVRC_OP_INVALID 0xFE /* invalid one */ - -/* Company ID's -*/ -#define AVRC_CO_BLUETOOTH_SIG 0x00FFFFFF -#define AVRC_CO_WIDCOMM 0x00000361 -#define AVRC_CO_BROADCOM 0x00001018 -#define AVRC_CO_METADATA 0x00001958 /* Unique COMPANY ID for Metadata messages */ - -/* State flag for Passthrough commands -*/ -#define AVRC_STATE_PRESS 0 -#define AVRC_STATE_RELEASE 1 - -/* Operation ID list for Passthrough commands -*/ -#define AVRC_ID_SELECT 0x00 /* select */ -#define AVRC_ID_UP 0x01 /* up */ -#define AVRC_ID_DOWN 0x02 /* down */ -#define AVRC_ID_LEFT 0x03 /* left */ -#define AVRC_ID_RIGHT 0x04 /* right */ -#define AVRC_ID_RIGHT_UP 0x05 /* right-up */ -#define AVRC_ID_RIGHT_DOWN 0x06 /* right-down */ -#define AVRC_ID_LEFT_UP 0x07 /* left-up */ -#define AVRC_ID_LEFT_DOWN 0x08 /* left-down */ -#define AVRC_ID_ROOT_MENU 0x09 /* root menu */ -#define AVRC_ID_SETUP_MENU 0x0A /* setup menu */ -#define AVRC_ID_CONT_MENU 0x0B /* contents menu */ -#define AVRC_ID_FAV_MENU 0x0C /* favorite menu */ -#define AVRC_ID_EXIT 0x0D /* exit */ -#define AVRC_ID_0 0x20 /* 0 */ -#define AVRC_ID_1 0x21 /* 1 */ -#define AVRC_ID_2 0x22 /* 2 */ -#define AVRC_ID_3 0x23 /* 3 */ -#define AVRC_ID_4 0x24 /* 4 */ -#define AVRC_ID_5 0x25 /* 5 */ -#define AVRC_ID_6 0x26 /* 6 */ -#define AVRC_ID_7 0x27 /* 7 */ -#define AVRC_ID_8 0x28 /* 8 */ -#define AVRC_ID_9 0x29 /* 9 */ -#define AVRC_ID_DOT 0x2A /* dot */ -#define AVRC_ID_ENTER 0x2B /* enter */ -#define AVRC_ID_CLEAR 0x2C /* clear */ -#define AVRC_ID_CHAN_UP 0x30 /* channel up */ -#define AVRC_ID_CHAN_DOWN 0x31 /* channel down */ -#define AVRC_ID_PREV_CHAN 0x32 /* previous channel */ -#define AVRC_ID_SOUND_SEL 0x33 /* sound select */ -#define AVRC_ID_INPUT_SEL 0x34 /* input select */ -#define AVRC_ID_DISP_INFO 0x35 /* display information */ -#define AVRC_ID_HELP 0x36 /* help */ -#define AVRC_ID_PAGE_UP 0x37 /* page up */ -#define AVRC_ID_PAGE_DOWN 0x38 /* page down */ -#define AVRC_ID_POWER 0x40 /* power */ -#define AVRC_ID_VOL_UP 0x41 /* volume up */ -#define AVRC_ID_VOL_DOWN 0x42 /* volume down */ -#define AVRC_ID_MUTE 0x43 /* mute */ -#define AVRC_ID_PLAY 0x44 /* play */ -#define AVRC_ID_STOP 0x45 /* stop */ -#define AVRC_ID_PAUSE 0x46 /* pause */ -#define AVRC_ID_RECORD 0x47 /* record */ -#define AVRC_ID_REWIND 0x48 /* rewind */ -#define AVRC_ID_FAST_FOR 0x49 /* fast forward */ -#define AVRC_ID_EJECT 0x4A /* eject */ -#define AVRC_ID_FORWARD 0x4B /* forward */ -#define AVRC_ID_BACKWARD 0x4C /* backward */ -#define AVRC_ID_ANGLE 0x50 /* angle */ -#define AVRC_ID_SUBPICT 0x51 /* subpicture */ -#define AVRC_ID_F1 0x71 /* F1 */ -#define AVRC_ID_F2 0x72 /* F2 */ -#define AVRC_ID_F3 0x73 /* F3 */ -#define AVRC_ID_F4 0x74 /* F4 */ -#define AVRC_ID_F5 0x75 /* F5 */ -#define AVRC_ID_VENDOR 0x7E /* vendor unique */ -#define AVRC_KEYPRESSED_RELEASE 0x80 - -/***************************************************************************** -** Metadata transfer definitions -*****************************************************************************/ - -/* Define the Metadata Packet types -*/ -#define AVRC_PKT_SINGLE 0 -#define AVRC_PKT_START 1 -#define AVRC_PKT_CONTINUE 2 -#define AVRC_PKT_END 3 -#define AVRC_PKT_TYPE_MASK 3 - -/* Define the PDUs carried in the vendor dependant data -*/ -#define AVRC_PDU_GET_CAPABILITIES 0x10 -#define AVRC_PDU_LIST_PLAYER_APP_ATTR 0x11 -#define AVRC_PDU_LIST_PLAYER_APP_VALUES 0x12 -#define AVRC_PDU_GET_CUR_PLAYER_APP_VALUE 0x13 -#define AVRC_PDU_SET_PLAYER_APP_VALUE 0x14 -#define AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT 0x15 -#define AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT 0x16 -#define AVRC_PDU_INFORM_DISPLAY_CHARSET 0x17 -#define AVRC_PDU_INFORM_BATTERY_STAT_OF_CT 0x18 -#define AVRC_PDU_GET_ELEMENT_ATTR 0x20 -#define AVRC_PDU_GET_PLAY_STATUS 0x30 -#define AVRC_PDU_REGISTER_NOTIFICATION 0x31 -#define AVRC_PDU_REQUEST_CONTINUATION_RSP 0x40 -#define AVRC_PDU_ABORT_CONTINUATION_RSP 0x41 -/* added in 1.4 */ -#define AVRC_PDU_SET_ABSOLUTE_VOLUME 0x50 -#define AVRC_PDU_SET_ADDRESSED_PLAYER 0x60 -#define AVRC_PDU_SET_BROWSED_PLAYER 0x70 -#define AVRC_PDU_GET_FOLDER_ITEMS 0x71 -#define AVRC_PDU_CHANGE_PATH 0x72 -#define AVRC_PDU_GET_ITEM_ATTRIBUTES 0x73 -#define AVRC_PDU_PLAY_ITEM 0x74 -#define AVRC_PDU_SEARCH 0x80 -#define AVRC_PDU_ADD_TO_NOW_PLAYING 0x90 -#define AVRC_PDU_GENERAL_REJECT 0xA0 - -/* Define the vendor unique id carried in the pass through data -*/ -#define AVRC_PDU_NEXT_GROUP 0x00 -#define AVRC_PDU_PREV_GROUP 0x01 -/* the only pass through vendor unique commands defined by AVRC is the group navigation commands - * The len for vendor unique data is 5 */ -#define AVRC_PASS_THRU_GROUP_LEN 5 - -#define AVRC_PDU_INVALID 0xff -/* 6.15.3 error status code for general reject */ -#define AVRC_STS_BAD_CMD 0x00 /* Invalid command, sent if TG received a PDU that it did not understand. */ -#define AVRC_STS_BAD_PARAM 0x01 /* Invalid parameter, sent if the TG received a PDU with a parameter ID that it did not understand. Sent if there is only one parameter ID in the PDU. */ -#define AVRC_STS_NOT_FOUND 0x02 /* Specified parameter not found., sent if the parameter ID is understood, but content is wrong or corrupted. */ -#define AVRC_STS_INTERNAL_ERR 0x03 /* Internal Error, sent if there are error conditions not covered by a more specific error code. */ -#define AVRC_STS_NO_ERROR 0x04 /* Operation completed without error. This is the status that should be returned if the operation was successful. */ -#define AVRC_STS_UID_CHANGED 0x05 /* UID Changed - The UIDs on the device have changed */ -/* #define AVRC_STS_GEN_ERROR 0x06 Unknown Error - this is changed to "reserved" */ -#define AVRC_STS_BAD_DIR 0x07 /* Invalid Direction - The Direction parameter is invalid - Change Path*/ -#define AVRC_STS_NOT_DIR 0x08 /* Not a Directory - The UID provided does not refer to a folder item Change Path*/ -#define AVRC_STS_NOT_EXIST 0x09 /* Does Not Exist - The UID provided does not refer to any item Change Path, PlayItem, AddToNowPlaying, GetItemAttributes*/ -#define AVRC_STS_BAD_SCOPE 0x0a /* Invalid Scope - The scope parameter is invalid GetFolderItems, PlayItem, AddToNowPlayer, GetItemAttributes, */ -#define AVRC_STS_BAD_RANGE 0x0b /* Range Out of Bounds - The start of range provided is not valid GetFolderItems*/ -#define AVRC_STS_UID_IS_DIR 0x0c /* UID is a Directory - The UID provided refers to a directory, which cannot be handled by this media player PlayItem, AddToNowPlaying */ -#define AVRC_STS_IN_USE 0x0d /* Media in Use - The media is not able to be used for this operation at this time PlayItem, AddToNowPlaying */ -#define AVRC_STS_NOW_LIST_FULL 0x0e /* Now Playing List Full - No more items can be added to the Now Playing List AddToNowPlaying*/ -#define AVRC_STS_SEARCH_NOT_SUP 0x0f /* Search Not Supported - The Browsed Media Player does not support search Search */ -#define AVRC_STS_SEARCH_BUSY 0x10 /* Search in Progress - A search operation is already in progress Search*/ -#define AVRC_STS_BAD_PLAYER_ID 0x11 /* Invalid Player Id - The specified Player Id does not refer to a valid player SetAddressedPlayer, SetBrowsedPlayer*/ -#define AVRC_STS_PLAYER_N_BR 0x12 /* Player Not Browsable - The Player Id supplied refers to a Media Player which does not support browsing. SetBrowsedPlayer */ -#define AVRC_STS_PLAYER_N_ADDR 0x13 /* Player Not Addressed. The Player Id supplied refers to a player which is not currently addressed, and the command is not able to be performed if the player is not set as addressed. Search, SetBrowsedPlayer*/ -#define AVRC_STS_BAD_SEARCH_RES 0x14 /* No valid Search Results - The Search result list does not contain valid entries, e.g. after being invalidated due to change of browsed player GetFolderItems */ -#define AVRC_STS_NO_AVAL_PLAYER 0x15 /* No available players ALL */ -#define AVRC_STS_ADDR_PLAYER_CHG 0x16 /* Addressed Player Changed - Register Notification */ -typedef UINT8 tAVRC_STS; - - -/* Define the Capability IDs -*/ -#define AVRC_CAP_COMPANY_ID 0x02 -#define AVRC_CAP_EVENTS_SUPPORTED 0x03 -#define AVRC_COMPANY_ID_LEN 3 -#define AVRC_CAPABILITY_OFFSET 2 - -/* Define the Player Application Settings IDs -*/ -#define AVRC_PLAYER_SETTING_EQUALIZER 0x01 -#define AVRC_PLAYER_SETTING_REPEAT 0x02 -#define AVRC_PLAYER_SETTING_SHUFFLE 0x03 -#define AVRC_PLAYER_SETTING_SCAN 0x04 -#define AVRC_PLAYER_SETTING_LOW_MENU_EXT 0x80 -#define AVRC_PLAYER_SETTING_HIGH_MENU_EXT 0xff - -/* Define the possible values of the Player Application Settings -*/ -#define AVRC_PLAYER_VAL_OFF 0x01 -#define AVRC_PLAYER_VAL_ON 0x02 -#define AVRC_PLAYER_VAL_SINGLE_REPEAT 0x02 -#define AVRC_PLAYER_VAL_ALL_REPEAT 0x03 -#define AVRC_PLAYER_VAL_GROUP_REPEAT 0x04 -#define AVRC_PLAYER_VAL_ALL_SHUFFLE 0x02 -#define AVRC_PLAYER_VAL_GROUP_SHUFFLE 0x03 -#define AVRC_PLAYER_VAL_ALL_SCAN 0x02 -#define AVRC_PLAYER_VAL_GROUP_SCAN 0x03 - -/* Define the possible values of Battery Status PDU -*/ -#define AVRC_BATTERY_STATUS_NORMAL 0x00 -#define AVRC_BATTERY_STATUS_WARNING 0x01 -#define AVRC_BATTERY_STATUS_CRITICAL 0x02 -#define AVRC_BATTERY_STATUS_EXTERNAL 0x03 -#define AVRC_BATTERY_STATUS_FULL_CHARGE 0x04 -typedef UINT8 tAVRC_BATTERY_STATUS; - -/* Define character set */ -#define AVRC_CHAR_SET_SIZE 2 - -/* Define the Media Attribute IDs -*/ -#define AVRC_MEDIA_ATTR_ID_TITLE 0x00000001 -#define AVRC_MEDIA_ATTR_ID_ARTIST 0x00000002 -#define AVRC_MEDIA_ATTR_ID_ALBUM 0x00000003 -#define AVRC_MEDIA_ATTR_ID_TRACK_NUM 0x00000004 -#define AVRC_MEDIA_ATTR_ID_NUM_TRACKS 0x00000005 -#define AVRC_MEDIA_ATTR_ID_GENRE 0x00000006 -#define AVRC_MEDIA_ATTR_ID_PLAYING_TIME 0x00000007 /* in miliseconds */ -#define AVRC_MAX_NUM_MEDIA_ATTR_ID 7 - -/* Define the possible values of play state -*/ -#define AVRC_PLAYSTATE_RESP_MSG_SIZE 9 -#define AVRC_PLAYSTATE_STOPPED 0x00 /* Stopped */ -#define AVRC_PLAYSTATE_PLAYING 0x01 /* Playing */ -#define AVRC_PLAYSTATE_PAUSED 0x02 /* Paused */ -#define AVRC_PLAYSTATE_FWD_SEEK 0x03 /* Fwd Seek*/ -#define AVRC_PLAYSTATE_REV_SEEK 0x04 /* Rev Seek*/ -#define AVRC_PLAYSTATE_ERROR 0xFF /* Error */ -typedef UINT8 tAVRC_PLAYSTATE; - -/* Define the events that can be registered for notifications -*/ -#define AVRC_EVT_PLAY_STATUS_CHANGE 0x01 -#define AVRC_EVT_TRACK_CHANGE 0x02 -#define AVRC_EVT_TRACK_REACHED_END 0x03 -#define AVRC_EVT_TRACK_REACHED_START 0x04 -#define AVRC_EVT_PLAY_POS_CHANGED 0x05 -#define AVRC_EVT_BATTERY_STATUS_CHANGE 0x06 -#define AVRC_EVT_SYSTEM_STATUS_CHANGE 0x07 -#define AVRC_EVT_APP_SETTING_CHANGE 0x08 -/* added in AVRCP 1.4 */ -#define AVRC_EVT_NOW_PLAYING_CHANGE 0x09 -#define AVRC_EVT_AVAL_PLAYERS_CHANGE 0x0a -#define AVRC_EVT_ADDR_PLAYER_CHANGE 0x0b -#define AVRC_EVT_UIDS_CHANGE 0x0c -#define AVRC_EVT_VOLUME_CHANGE 0x0d - -/* the number of events that can be registered for notifications */ -#define AVRC_NUM_NOTIF_EVENTS 0x0d - -#define AVRC_EVT_MSG_LEN_1 0x01 -#define AVRC_EVT_MSG_LEN_2 0x02 -#define AVRC_EVT_MSG_LEN_5 0x05 -#define AVRC_EVT_MSG_LEN_9 0x09 - -#define AVRC_MAX_VOLUME 0x7F - -/* Define the possible values of system status -*/ -#define AVRC_SYSTEMSTATE_PWR_ON 0x00 -#define AVRC_SYSTEMSTATE_PWR_OFF 0x01 -#define AVRC_SYSTEMSTATE_PWR_UNPLUGGED 0x02 -typedef UINT8 tAVRC_SYSTEMSTATE; - -/* the frequently used character set ids */ -#define AVRC_CHARSET_ID_ASCII ((UINT16) 0x0003) /* ASCII */ -#define AVRC_CHARSET_ID_UTF8 ((UINT16) 0x006a) /* UTF-8 */ -#define AVRC_CHARSET_ID_UTF16 ((UINT16) 0x03f7) /* 1015 */ -#define AVRC_CHARSET_ID_UTF32 ((UINT16) 0x03f9) /* 1017 */ - -/***************************************************************************** -** Advanced Control -*****************************************************************************/ -#define AVRC_ITEM_PLAYER 0x01 -#define AVRC_ITEM_FOLDER 0x02 -#define AVRC_ITEM_MEDIA 0x03 - -#define AVRC_SCOPE_PLAYER_LIST 0x00 /* Media Player Item - Contains all available media players */ -#define AVRC_SCOPE_FILE_SYSTEM 0x01 /* Folder Item, Media Element Item - - The virtual filesystem containing the media content of the browsed player */ -#define AVRC_SCOPE_SEARCH 0x02 /* Media Element Item The results of a search operation on the browsed player */ -#define AVRC_SCOPE_NOW_PLAYING 0x03 /* Media Element Item The Now Playing list (or queue) of the addressed player */ - -#define AVRC_FOLDER_ITEM_COUNT_NONE 0xFF - -/* folder type */ -#define AVRC_FOLDER_TYPE_MIXED 0x00 -#define AVRC_FOLDER_TYPE_TITLES 0x01 -#define AVRC_FOLDER_TYPE_ALNUMS 0x02 -#define AVRC_FOLDER_TYPE_ARTISTS 0x03 -#define AVRC_FOLDER_TYPE_GENRES 0x04 -#define AVRC_FOLDER_TYPE_PLAYLISTS 0x05 -#define AVRC_FOLDER_TYPE_YEARS 0x06 - -/* major player type */ -#define AVRC_MJ_TYPE_AUDIO 0x01 /* Audio */ -#define AVRC_MJ_TYPE_VIDEO 0x02 /* Video */ -#define AVRC_MJ_TYPE_BC_AUDIO 0x04 /* Broadcasting Audio */ -#define AVRC_MJ_TYPE_BC_VIDEO 0x08 /* Broadcasting Video */ -#define AVRC_MJ_TYPE_INVALID 0xF0 - -/* player sub type */ -#define AVRC_SUB_TYPE_NONE 0x00 -#define AVRC_SUB_TYPE_AUDIO_BOOK 0x01 /* Audio Book */ -#define AVRC_SUB_TYPE_PODCAST 0x02 /* Podcast */ -#define AVRC_SUB_TYPE_INVALID 0xFC - -/* media item - media type */ -#define AVRC_MEDIA_TYPE_AUDIO 0x00 -#define AVRC_MEDIA_TYPE_VIDEO 0x01 - -#define AVRC_DIR_UP 0x00 /* Folder Up */ -#define AVRC_DIR_DOWN 0x01 /* Folder Down */ - -#define AVRC_UID_SIZE 8 -typedef UINT8 tAVRC_UID[AVRC_UID_SIZE]; - -/***************************************************************************** -** player attribute - supported features -*****************************************************************************/ -#define AVRC_PF_SELECT_BIT_NO 0 -#define AVRC_PF_SELECT_MASK 0x01 -#define AVRC_PF_SELECT_OFF 0 -#define AVRC_PF_SELECT_SUPPORTED(x) ((x)[AVRC_PF_SELECT_OFF] & AVRC_PF_SELECT_MASK) - -#define AVRC_PF_UP_BIT_NO 1 -#define AVRC_PF_UP_MASK 0x02 -#define AVRC_PF_UP_OFF 0 -#define AVRC_PF_UP_SUPPORTED(x) ((x)[AVRC_PF_UP_OFF] & AVRC_PF_UP_MASK) - -#define AVRC_PF_DOWN_BIT_NO 2 -#define AVRC_PF_DOWN_MASK 0x04 -#define AVRC_PF_DOWN_OFF 0 -#define AVRC_PF_DOWN_SUPPORTED(x) ((x)[AVRC_PF_DOWN_OFF] & AVRC_PF_DOWN_MASK) - -#define AVRC_PF_LEFT_BIT_NO 3 -#define AVRC_PF_LEFT_MASK 0x08 -#define AVRC_PF_LEFT_OFF 0 -#define AVRC_PF_LEFT_SUPPORTED(x) ((x)[AVRC_PF_LEFT_OFF] & AVRC_PF_LEFT_MASK) - -#define AVRC_PF_RIGHT_BIT_NO 4 -#define AVRC_PF_RIGHT_MASK 0x10 -#define AVRC_PF_RIGHT_OFF 0 -#define AVRC_PF_RIGHT_SUPPORTED(x) ((x)[AVRC_PF_RIGHT_OFF] & AVRC_PF_RIGHT_MASK) - -#define AVRC_PF_RIGHTUP_BIT_NO 5 -#define AVRC_PF_RIGHTUP_MASK 0x20 -#define AVRC_PF_RIGHTUP_OFF 0 -#define AVRC_PF_RIGHTUP_SUPPORTED(x) ((x)[AVRC_PF_RIGHTUP_OFF] & AVRC_PF_RIGHTUP_MASK) - -#define AVRC_PF_RIGHTDOWN_BIT_NO 6 -#define AVRC_PF_RIGHTDOWN_MASK 0x40 -#define AVRC_PF_RIGHTDOWN_OFF 0 -#define AVRC_PF_RIGHTDOWN_SUPPORTED(x) ((x)[AVRC_PF_RIGHTDOWN_OFF] & AVRC_PF_RIGHTDOWN_MASK) - -#define AVRC_PF_LEFTUP_BIT_NO 7 -#define AVRC_PF_LEFTUP_MASK 0x80 -#define AVRC_PF_LEFTUP_OFF 0 -#define AVRC_PF_LEFTUP_SUPPORTED(x) ((x)[AVRC_PF_LEFTUP_OFF] & AVRC_PF_LEFTUP_MASK) - -#define AVRC_PF_LEFTDOWN_BIT_NO 8 -#define AVRC_PF_LEFTDOWN_MASK 0x01 -#define AVRC_PF_LEFTDOWN_OFF 1 -#define AVRC_PF_LEFTDOWN_SUPPORTED(x) ((x)[AVRC_PF_LEFTDOWN_OFF] & AVRC_PF_LEFTDOWN_MASK) - -#define AVRC_PF_ROOT_MENU_BIT_NO 9 -#define AVRC_PF_ROOT_MENU_MASK 0x02 -#define AVRC_PF_ROOT_MENU_OFF 1 -#define AVRC_PF_ROOT_MENU_SUPPORTED(x) ((x)[AVRC_PF_ROOT_MENU_OFF] & AVRC_PF_ROOT_MENU_MASK) - -#define AVRC_PF_SETUP_MENU_BIT_NO 10 -#define AVRC_PF_SETUP_MENU_MASK 0x04 -#define AVRC_PF_SETUP_MENU_OFF 1 -#define AVRC_PF_SETUP_MENU_SUPPORTED(x) ((x)[AVRC_PF_SETUP_MENU_OFF] & AVRC_PF_SETUP_MENU_MASK) - -#define AVRC_PF_CONTENTS_MENU_BIT_NO 11 -#define AVRC_PF_CONTENTS_MENU_MASK 0x08 -#define AVRC_PF_CONTENTS_MENU_OFF 1 -#define AVRC_PF_CONTENTS_MENU_SUPPORTED(x) ((x)[AVRC_PF_CONTENTS_MENU_OFF] & AVRC_PF_CONTENTS_MENU_MASK) - -#define AVRC_PF_FAVORITE_MENU_BIT_NO 12 -#define AVRC_PF_FAVORITE_MENU_MASK 0x10 -#define AVRC_PF_FAVORITE_MENU_OFF 1 -#define AVRC_PF_FAVORITE_MENU_SUPPORTED(x) ((x)[AVRC_PF_FAVORITE_MENU_OFF] & AVRC_PF_FAVORITE_MENU_MASK) - -#define AVRC_PF_EXIT_BIT_NO 13 -#define AVRC_PF_EXIT_MASK 0x20 -#define AVRC_PF_EXIT_OFF 1 -#define AVRC_PF_EXIT_SUPPORTED(x) ((x)[AVRC_PF_EXIT_OFF] & AVRC_PF_EXIT_MASK) - -#define AVRC_PF_0_BIT_NO 14 -#define AVRC_PF_0_MASK 0x40 -#define AVRC_PF_0_OFF 1 -#define AVRC_PF_0_SUPPORTED(x) ((x)[AVRC_PF_0_OFF] & AVRC_PF_0_MASK) - -#define AVRC_PF_1_BIT_NO 15 -#define AVRC_PF_1_MASK 0x80 -#define AVRC_PF_1_OFF 1 -#define AVRC_PF_1_SUPPORTED(x) ((x)[AVRC_PF_1_OFF] & AVRC_PF_1_MASK) - -#define AVRC_PF_2_BIT_NO 16 -#define AVRC_PF_2_MASK 0x01 -#define AVRC_PF_2_OFF 2 -#define AVRC_PF_2_SUPPORTED(x) ((x)[AVRC_PF_2_OFF] & AVRC_PF_2_MASK) - -#define AVRC_PF_3_BIT_NO 17 -#define AVRC_PF_3_MASK 0x02 -#define AVRC_PF_3_OFF 2 -#define AVRC_PF_3_SUPPORTED(x) ((x)[AVRC_PF_3_OFF] & AVRC_PF_3_MASK) - -#define AVRC_PF_4_BIT_NO 18 -#define AVRC_PF_4_MASK 0x04 -#define AVRC_PF_4_OFF 2 -#define AVRC_PF_4_SUPPORTED(x) ((x)[AVRC_PF_4_OFF] & AVRC_PF_4_MASK) - -#define AVRC_PF_5_BIT_NO 19 -#define AVRC_PF_5_MASK 0x08 -#define AVRC_PF_5_OFF 2 -#define AVRC_PF_5_SUPPORTED(x) ((x)[AVRC_PF_5_OFF] & AVRC_PF_5_MASK) - -#define AVRC_PF_6_BIT_NO 20 -#define AVRC_PF_6_MASK 0x10 -#define AVRC_PF_6_OFF 2 -#define AVRC_PF_6_SUPPORTED(x) ((x)[AVRC_PF_6_OFF] & AVRC_PF_6_MASK) - -#define AVRC_PF_7_BIT_NO 21 -#define AVRC_PF_7_MASK 0x20 -#define AVRC_PF_7_OFF 2 -#define AVRC_PF_7_SUPPORTED(x) ((x)[AVRC_PF_7_OFF] & AVRC_PF_7_MASK) - -#define AVRC_PF_8_BIT_NO 22 -#define AVRC_PF_8_MASK 0x40 -#define AVRC_PF_8_OFF 2 -#define AVRC_PF_8_SUPPORTED(x) ((x)[AVRC_PF_8_OFF] & AVRC_PF_8_MASK) - -#define AVRC_PF_9_BIT_NO 23 -#define AVRC_PF_9_MASK 0x80 -#define AVRC_PF_9_OFF 2 -#define AVRC_PF_9_SUPPORTED(x) ((x)[AVRC_PF_9_OFF] & AVRC_PF_9_MASK) - -#define AVRC_PF_DOT_BIT_NO 24 -#define AVRC_PF_DOT_MASK 0x01 -#define AVRC_PF_DOT_OFF 3 -#define AVRC_PF_DOT_SUPPORTED(x) ((x)[AVRC_PF_DOT_OFF] & AVRC_PF_DOT_MASK) - -#define AVRC_PF_ENTER_BIT_NO 25 -#define AVRC_PF_ENTER_MASK 0x02 -#define AVRC_PF_ENTER_OFF 3 -#define AVRC_PF_ENTER_SUPPORTED(x) ((x)[AVRC_PF_ENTER_OFF] & AVRC_PF_ENTER_MASK) - -#define AVRC_PF_CLEAR_BIT_NO 26 -#define AVRC_PF_CLEAR_MASK 0x04 -#define AVRC_PF_CLEAR_OFF 3 -#define AVRC_PF_CLEAR_SUPPORTED(x) ((x)[AVRC_PF_CLEAR_OFF] & AVRC_PF_CLEAR_MASK) - -#define AVRC_PF_CHNL_UP_BIT_NO 27 -#define AVRC_PF_CHNL_UP_MASK 0x08 -#define AVRC_PF_CHNL_UP_OFF 3 -#define AVRC_PF_CHNL_UP_SUPPORTED(x) ((x)[AVRC_PF_CHNL_UP_OFF] & AVRC_PF_CHNL_UP_MASK) - -#define AVRC_PF_CHNL_DOWN_BIT_NO 28 -#define AVRC_PF_CHNL_DOWN_MASK 0x10 -#define AVRC_PF_CHNL_DOWN_OFF 3 -#define AVRC_PF_CHNL_DOWN_SUPPORTED(x) ((x)[AVRC_PF_CHNL_DOWN_OFF] & AVRC_PF_CHNL_DOWN_MASK) - -#define AVRC_PF_PREV_CHNL_BIT_NO 29 -#define AVRC_PF_PREV_CHNL_MASK 0x20 -#define AVRC_PF_PREV_CHNL_OFF 3 -#define AVRC_PF_PREV_CHNL_SUPPORTED(x) ((x)[AVRC_PF_PREV_CHNL_OFF] & AVRC_PF_PREV_CHNL_MASK) - -#define AVRC_PF_SOUND_SEL_BIT_NO 30 -#define AVRC_PF_SOUND_SEL_MASK 0x40 -#define AVRC_PF_SOUND_SEL_OFF 3 -#define AVRC_PF_SOUND_SEL_SUPPORTED(x) ((x)[AVRC_PF_SOUND_SEL_OFF] & AVRC_PF_SOUND_SEL_MASK) - -#define AVRC_PF_INPUT_SEL_BIT_NO 31 -#define AVRC_PF_INPUT_SEL_MASK 0x80 -#define AVRC_PF_INPUT_SEL_OFF 3 -#define AVRC_PF_INPUT_SEL_SUPPORTED(x) ((x)[AVRC_PF_INPUT_SEL_OFF] & AVRC_PF_INPUT_SEL_MASK) - -#define AVRC_PF_DISP_INFO_BIT_NO 32 -#define AVRC_PF_DISP_INFO_MASK 0x01 -#define AVRC_PF_DISP_INFO_OFF 4 -#define AVRC_PF_DISP_INFO_SUPPORTED(x) ((x)[AVRC_PF_DISP_INFO_OFF] & AVRC_PF_DISP_INFO_MASK) - -#define AVRC_PF_HELP_BIT_NO 33 -#define AVRC_PF_HELP_MASK 0x02 -#define AVRC_PF_HELP_OFF 4 -#define AVRC_PF_HELP_SUPPORTED(x) ((x)[AVRC_PF_HELP_OFF] & AVRC_PF_HELP_MASK) - -#define AVRC_PF_PAGE_UP_BIT_NO 34 -#define AVRC_PF_PAGE_UP_MASK 0x04 -#define AVRC_PF_PAGE_UP_OFF 4 -#define AVRC_PF_PAGE_UP_SUPPORTED(x) ((x)[AVRC_PF_PAGE_UP_OFF] & AVRC_PF_PAGE_UP_MASK) - -#define AVRC_PF_PAGE_DOWN_BIT_NO 35 -#define AVRC_PF_PAGE_DOWN_MASK 0x08 -#define AVRC_PF_PAGE_DOWN_OFF 4 -#define AVRC_PF_PAGE_DOWN_SUPPORTED(x) ((x)[AVRC_PF_PAGE_DOWN_OFF] & AVRC_PF_PAGE_DOWN_MASK) - -#define AVRC_PF_POWER_BIT_NO 36 -#define AVRC_PF_POWER_MASK 0x10 -#define AVRC_PF_POWER_OFF 4 -#define AVRC_PF_POWER_SUPPORTED(x) ((x)[AVRC_PF_POWER_OFF] & AVRC_PF_POWER_MASK) - -#define AVRC_PF_VOL_UP_BIT_NO 37 -#define AVRC_PF_VOL_UP_MASK 0x20 -#define AVRC_PF_VOL_UP_OFF 4 -#define AVRC_PF_VOL_UP_SUPPORTED(x) ((x)[AVRC_PF_VOL_UP_OFF] & AVRC_PF_VOL_UP_MASK) - -#define AVRC_PF_VOL_DOWN_BIT_NO 38 -#define AVRC_PF_VOL_DOWN_MASK 0x40 -#define AVRC_PF_VOL_DOWN_OFF 4 -#define AVRC_PF_VOL_DOWN_SUPPORTED(x) ((x)[AVRC_PF_VOL_DOWN_OFF] & AVRC_PF_VOL_DOWN_MASK) - -#define AVRC_PF_MUTE_BIT_NO 39 -#define AVRC_PF_MUTE_MASK 0x80 -#define AVRC_PF_MUTE_OFF 4 -#define AVRC_PF_MUTE_SUPPORTED(x) ((x)[AVRC_PF_MUTE_OFF] & AVRC_PF_MUTE_MASK) - -#define AVRC_PF_PLAY_BIT_NO 40 -#define AVRC_PF_PLAY_MASK 0x01 -#define AVRC_PF_PLAY_OFF 5 -#define AVRC_PF_PLAY_SUPPORTED(x) ((x)[AVRC_PF_PLAY_OFF] & AVRC_PF_PLAY_MASK) - -#define AVRC_PF_STOP_BIT_NO 41 -#define AVRC_PF_STOP_MASK 0x02 -#define AVRC_PF_STOP_OFF 5 -#define AVRC_PF_STOP_SUPPORTED(x) ((x)[AVRC_PF_STOP_OFF] & AVRC_PF_STOP_MASK) - -#define AVRC_PF_PAUSE_BIT_NO 42 -#define AVRC_PF_PAUSE_MASK 0x04 -#define AVRC_PF_PAUSE_OFF 5 -#define AVRC_PF_PAUSE_SUPPORTED(x) ((x)[AVRC_PF_PAUSE_OFF] & AVRC_PF_PAUSE_MASK) - -#define AVRC_PF_RECORD_BIT_NO 43 -#define AVRC_PF_RECORD_MASK 0x08 -#define AVRC_PF_RECORD_OFF 5 -#define AVRC_PF_RECORD_SUPPORTED(x) ((x)[AVRC_PF_RECORD_OFF] & AVRC_PF_RECORD_MASK) - -#define AVRC_PF_REWIND_BIT_NO 44 -#define AVRC_PF_REWIND_MASK 0x10 -#define AVRC_PF_REWIND_OFF 5 -#define AVRC_PF_REWIND_SUPPORTED(x) ((x)[AVRC_PF_REWIND_OFF] & AVRC_PF_REWIND_MASK) - -#define AVRC_PF_FAST_FWD_BIT_NO 45 -#define AVRC_PF_FAST_FWD_MASK 0x20 -#define AVRC_PF_FAST_FWD_OFF 5 -#define AVRC_PF_FAST_FWD_SUPPORTED(x) ((x)[AVRC_PF_FAST_FWD_OFF] & AVRC_PF_FAST_FWD_MASK) - -#define AVRC_PF_EJECT_BIT_NO 46 -#define AVRC_PF_EJECT_MASK 0x40 -#define AVRC_PF_EJECT_OFF 5 -#define AVRC_PF_EJECT_SUPPORTED(x) ((x)[AVRC_PF_EJECT_OFF] & AVRC_PF_EJECT_MASK) - -#define AVRC_PF_FORWARD_BIT_NO 47 -#define AVRC_PF_FORWARD_MASK 0x80 -#define AVRC_PF_FORWARD_OFF 5 -#define AVRC_PF_FORWARD_SUPPORTED(x) ((x)[AVRC_PF_FORWARD_OFF] & AVRC_PF_FORWARD_MASK) - -#define AVRC_PF_BACKWARD_BIT_NO 48 -#define AVRC_PF_BACKWARD_MASK 0x01 -#define AVRC_PF_BACKWARD_OFF 6 -#define AVRC_PF_BACKWARD_SUPPORTED(x) ((x)[AVRC_PF_BACKWARD_OFF] & AVRC_PF_BACKWARD_MASK) - -#define AVRC_PF_ANGLE_BIT_NO 49 -#define AVRC_PF_ANGLE_MASK 0x02 -#define AVRC_PF_ANGLE_OFF 6 -#define AVRC_PF_ANGLE_SUPPORTED(x) ((x)[AVRC_PF_ANGLE_OFF] & AVRC_PF_ANGLE_MASK) - -#define AVRC_PF_SUBPICTURE_BIT_NO 50 -#define AVRC_PF_SUBPICTURE_MASK 0x04 -#define AVRC_PF_SUBPICTURE_OFF 6 -#define AVRC_PF_SUBPICTURE_SUPPORTED(x) ((x)[AVRC_PF_SUBPICTURE_OFF] & AVRC_PF_SUBPICTURE_MASK) - -#define AVRC_PF_F1_BIT_NO 51 -#define AVRC_PF_F1_MASK 0x08 -#define AVRC_PF_F1_OFF 6 -#define AVRC_PF_F1_SUPPORTED(x) ((x)[AVRC_PF_F1_OFF] & AVRC_PF_F1_MASK) - -#define AVRC_PF_F2_BIT_NO 52 -#define AVRC_PF_F2_MASK 0x10 -#define AVRC_PF_F2_OFF 6 -#define AVRC_PF_F2_SUPPORTED(x) ((x)[AVRC_PF_F2_OFF] & AVRC_PF_F2_MASK) - -#define AVRC_PF_F3_BIT_NO 53 -#define AVRC_PF_F3_MASK 0x20 -#define AVRC_PF_F3_OFF 6 -#define AVRC_PF_F3_SUPPORTED(x) ((x)[AVRC_PF_F3_OFF] & AVRC_PF_F3_MASK) - -#define AVRC_PF_F4_BIT_NO 54 -#define AVRC_PF_F4_MASK 0x40 -#define AVRC_PF_F4_OFF 6 -#define AVRC_PF_F4_SUPPORTED(x) ((x)[AVRC_PF_F4_OFF] & AVRC_PF_F4_MASK) - -#define AVRC_PF_F5_BIT_NO 55 -#define AVRC_PF_F5_MASK 0x80 -#define AVRC_PF_F5_OFF 6 -#define AVRC_PF_F5_SUPPORTED(x) ((x)[AVRC_PF_F5_OFF] & AVRC_PF_F5_MASK) - -/* Vendor unique. This PASSTHROUGH command is supported. */ -#define AVRC_PF_VENDOR_BIT_NO 56 -#define AVRC_PF_VENDOR_MASK 0x01 -#define AVRC_PF_VENDOR_OFF 7 -#define AVRC_PF_VENDOR_SUPPORTED(x) ((x)[AVRC_PF_VENDOR_OFF] & AVRC_PF_VENDOR_MASK) - -/* Basic Group Navigation. This overrules the SDP entry as it is set per player.7 */ -#define AVRC_PF_GROUP_NAVI_BIT_NO 57 -#define AVRC_PF_GROUP_NAVI_MASK 0x02 -#define AVRC_PF_GROUP_NAVI_OFF 7 -#define AVRC_PF_GROUP_NAVI_SUPPORTED(x) ((x)[AVRC_PF_GROUP_NAVI_OFF] & AVRC_PF_GROUP_NAVI_MASK) - -/* Advanced Control Player. This bit is set if the player supports at least AVRCP 1.4. */ -#define AVRC_PF_ADV_CTRL_BIT_NO 58 -#define AVRC_PF_ADV_CTRL_MASK 0x04 -#define AVRC_PF_ADV_CTRL_OFF 7 -#define AVRC_PF_ADV_CTRL_SUPPORTED(x) ((x)[AVRC_PF_ADV_CTRL_OFF] & AVRC_PF_ADV_CTRL_MASK) - -/* Browsing. This bit is set if the player supports browsing. */ -#define AVRC_PF_BROWSE_BIT_NO 59 -#define AVRC_PF_BROWSE_MASK 0x08 -#define AVRC_PF_BROWSE_OFF 7 -#define AVRC_PF_BROWSE_SUPPORTED(x) ((x)[AVRC_PF_BROWSE_OFF] & AVRC_PF_BROWSE_MASK) - -/* Searching. This bit is set if the player supports searching. */ -#define AVRC_PF_SEARCH_BIT_NO 60 -#define AVRC_PF_SEARCH_MASK 0x10 -#define AVRC_PF_SEARCH_OFF 7 -#define AVRC_PF_SEARCH_SUPPORTED(x) ((x)[AVRC_PF_SEARCH_OFF] & AVRC_PF_SEARCH_MASK) - -/* AddToNowPlaying. This bit is set if the player supports the AddToNowPlaying command. */ -#define AVRC_PF_ADD2NOWPLAY_BIT_NO 61 -#define AVRC_PF_ADD2NOWPLAY_MASK 0x20 -#define AVRC_PF_ADD2NOWPLAY_OFF 7 -#define AVRC_PF_ADD2NOWPLAY_SUPPORTED(x) ((x)[AVRC_PF_ADD2NOWPLAY_OFF] & AVRC_PF_ADD2NOWPLAY_MASK) - -/* UIDs unique in player browse tree. This bit is set if the player is able to maintain unique UIDs across the player browse tree. */ -#define AVRC_PF_UID_UNIQUE_BIT_NO 62 -#define AVRC_PF_UID_UNIQUE_MASK 0x40 -#define AVRC_PF_UID_UNIQUE_OFF 7 -#define AVRC_PF_UID_UNIQUE_SUPPORTED(x) ((x)[AVRC_PF_UID_UNIQUE_OFF] & AVRC_PF_UID_UNIQUE_MASK) - -/* OnlyBrowsableWhenAddressed. This bit is set if the player is only able to be browsed when it is set as the Addressed Player. */ -#define AVRC_PF_BR_WH_ADDR_BIT_NO 63 -#define AVRC_PF_BR_WH_ADDR_MASK 0x80 -#define AVRC_PF_BR_WH_ADDR_OFF 7 -#define AVRC_PF_BR_WH_ADDR_SUPPORTED(x) ((x)[AVRC_PF_BR_WH_ADDR_OFF] & AVRC_PF_BR_WH_ADDR_MASK) - -/* OnlySearchableWhenAddressed. This bit is set if the player is only able to be searched when it is set as the Addressed player. */ -#define AVRC_PF_SEARCH_WH_ADDR_BIT_NO 64 -#define AVRC_PF_SEARCH_WH_ADDR_MASK 0x01 -#define AVRC_PF_SEARCH_WH_ADDR_OFF 8 -#define AVRC_PF_SEARCH_WH_ADDR_SUPPORTED(x) ((x)[AVRC_PF_SEARCH_WH_ADDR_OFF] & AVRC_PF_SEARCH_WH_ADDR_MASK) - -/* NowPlaying. This bit is set if the player supports the NowPlaying folder. Note that for all players that support browsing this bit shall be set */ -#define AVRC_PF_NOW_PLAY_BIT_NO 65 -#define AVRC_PF_NOW_PLAY_MASK 0x02 -#define AVRC_PF_NOW_PLAY_OFF 8 -#define AVRC_PF_NOW_PLAY_SUPPORTED(x) ((x)[AVRC_PF_NOW_PLAY_OFF] & AVRC_PF_NOW_PLAY_MASK) - -/* UIDPersistency. This bit is set if the Player is able to persist UID values between AVRCP Browse Reconnect */ -#define AVRC_PF_UID_PERSIST_BIT_NO 66 -#define AVRC_PF_UID_PERSIST_MASK 0x04 -#define AVRC_PF_UID_PERSIST_OFF 8 -#define AVRC_PF_UID_PERSIST_SUPPORTED(x) ((x)[AVRC_PF_UID_PERSIST_OFF] & AVRC_PF_UID_PERSIST_MASK) - -/***************************************************************************** -** data type definitions -*****************************************************************************/ - -/* -This structure contains the header parameters of an AV/C message. -*/ -typedef struct { - UINT8 ctype; /* Command type. */ - UINT8 subunit_type; /* Subunit type. */ - UINT8 subunit_id; /* Subunit ID. This value is typically ignored in AVRCP, - * except for VENDOR DEPENDENT messages when the value is - * vendor-dependent. Value range is 0-7. */ - UINT8 opcode; /* Op Code (passthrough, vendor, etc) */ -} tAVRC_HDR; - -/* This structure contains a UNIT INFO message. */ -typedef struct { - tAVRC_HDR hdr; /* Message header. */ - UINT32 company_id; /* Company identifier. */ - UINT8 unit_type; /* Unit type. Uses the same values as subunit type. */ - UINT8 unit; /* This value is vendor dependent and typically zero. */ -} tAVRC_MSG_UNIT; - -/* This structure contains a SUBUNIT INFO message. */ -typedef struct { - tAVRC_HDR hdr; /* Message header. */ - UINT8 subunit_type[AVRC_SUB_TYPE_LEN]; - /* Array containing subunit type values. */ - BOOLEAN panel; /* TRUE if the panel subunit type is in the - * subunit_type array, FALSE otherwise. */ - UINT8 page; /* Specifies which part of the subunit type table is - * returned. For AVRCP it is typically zero. - * Value range is 0-7. */ -} tAVRC_MSG_SUB; - -/* This structure contains a VENDOR DEPENDENT message. */ -typedef struct { - tAVRC_HDR hdr; /* Message header. */ - UINT32 company_id; /* Company identifier. */ - UINT8 *p_vendor_data;/* Pointer to vendor dependent data. */ - UINT16 vendor_len; /* Length in bytes of vendor dependent data. */ -} tAVRC_MSG_VENDOR; - -/* PASS THROUGH message structure */ -typedef struct { - tAVRC_HDR hdr; /* hdr.ctype Unused. - * hdr.subunit_type Unused. - * hdr.subunit_id Unused. */ - UINT8 op_id; /* Operation ID. */ - UINT8 state; /* Keypress state. */ - UINT8 *p_pass_data;/* Pointer to data. This parameter is only valid - * when the op_id is AVRC_ID_VENDOR.*/ - UINT8 pass_len; /* Length in bytes of data. This parameter is only - * valid when the op_id is AVRC_ID_VENDOR.*/ -} tAVRC_MSG_PASS; - -/* Command/Response indicator. */ -#define AVRC_CMD AVCT_CMD /* Command message */ -#define AVRC_RSP AVCT_RSP /* Response message */ - -/* Browsing channel message structure */ -typedef struct { - tAVRC_HDR hdr; /* hdr.ctype AVRC_CMD or AVRC_RSP. - * hdr.subunit_type Unused. - * hdr.subunit_id Unused. */ - UINT8 *p_browse_data; /* Pointer to data. */ - UINT16 browse_len; /* Length in bytes of data. */ - BT_HDR *p_browse_pkt; /* The GKI buffer received. Set to NULL, if the callback function wants to keep the buffer */ -} tAVRC_MSG_BROWSE; - -/* This is a union of all message type structures. */ -typedef union { - tAVRC_HDR hdr; /* Message header. */ - tAVRC_MSG_UNIT unit; /* UNIT INFO message. */ - tAVRC_MSG_SUB sub; /* SUBUNIT INFO message. */ - tAVRC_MSG_VENDOR vendor; /* VENDOR DEPENDENT message. */ - tAVRC_MSG_PASS pass; /* PASS THROUGH message. */ - tAVRC_MSG_BROWSE browse; /* messages thru browsing channel */ -} tAVRC_MSG; - -/* macros */ -#define AVRC_IS_VALID_CAP_ID(a) (((a == AVRC_CAP_COMPANY_ID) || (a == AVRC_CAP_EVENTS_SUPPORTED)) ? TRUE : FALSE) - -#define AVRC_IS_VALID_EVENT_ID(a) (((a >= AVRC_EVT_PLAY_STATUS_CHANGE) && \ - (a <= AVRC_EVT_APP_SETTING_CHANGE)) ? TRUE : FALSE) - -#define AVRC_IS_VALID_ATTRIBUTE(a) (((((a > 0) && a <= AVRC_PLAYER_SETTING_SCAN)) || \ - (a >= AVRC_PLAYER_SETTING_LOW_MENU_EXT)) ? TRUE : FALSE) - -#define AVRC_IS_VALID_MEDIA_ATTRIBUTE(a) ((a >= AVRC_MEDIA_ATTR_ID_TITLE) && \ - (a <= AVRC_MEDIA_ATTR_ID_PLAYING_TIME) ? TRUE : FALSE) - -#define AVRC_IS_VALID_BATTERY_STATUS(a) ((a <= AVRC_BATTERY_STATUS_FULL_CHARGE) ? TRUE : FALSE) - -#define AVRC_IS_VALID_SYSTEM_STATUS(a) ((a <= AVRC_SYSTEMSTATE_PWR_UNPLUGGED) ? TRUE : FALSE) - -#define AVRC_IS_VALID_GROUP(a) ((a <= AVRC_PDU_PREV_GROUP) ? TRUE : FALSE) - -/* Company ID is 24-bit integer We can not use the macros in stack/bt_types.h */ -#define AVRC_CO_ID_TO_BE_STREAM(p, u32) {*(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)(u32); } -#define AVRC_BE_STREAM_TO_CO_ID(u32, p) {u32 = (((UINT32)(*((p) + 2))) + (((UINT32)(*((p) + 1))) << 8) + (((UINT32)(*(p))) << 16)); (p) += 3;} - -/***************************************************************************** -** data type definitions -*****************************************************************************/ -#define AVRC_MAX_APP_ATTR_SIZE 16 -#define AVRC_MAX_CHARSET_SIZE 16 -#define AVRC_MAX_ELEM_ATTR_SIZE 8 - - -/***************************************************************************** -** Metadata transfer Building/Parsing definitions -*****************************************************************************/ - -typedef struct { - UINT16 charset_id; - UINT16 str_len; - UINT8 *p_str; -} tAVRC_FULL_NAME; - -typedef struct { - UINT16 str_len; - UINT8 *p_str; -} tAVRC_NAME; - - -#ifndef AVRC_CAP_MAX_NUM_COMP_ID -#define AVRC_CAP_MAX_NUM_COMP_ID 4 -#endif - -#ifndef AVRC_CAP_MAX_NUM_EVT_ID -#define AVRC_CAP_MAX_NUM_EVT_ID 16 -#endif - -typedef union { - UINT32 company_id[AVRC_CAP_MAX_NUM_COMP_ID]; - UINT8 event_id[AVRC_CAP_MAX_NUM_EVT_ID]; -} tAVRC_CAPS_PARAM; - -typedef struct { - UINT8 attr_id; - UINT8 attr_val; -} tAVRC_APP_SETTING; - -typedef struct { - UINT8 attr_id; - UINT16 charset_id; - UINT8 str_len; - UINT8 *p_str; -} tAVRC_APP_SETTING_TEXT; - -typedef UINT8 tAVRC_FEATURE_MASK[AVRC_FEATURE_MASK_SIZE]; - -typedef struct { - UINT16 player_id; /* A unique identifier for this media player.*/ - UINT8 major_type; /* Use AVRC_MJ_TYPE_AUDIO, AVRC_MJ_TYPE_VIDEO, AVRC_MJ_TYPE_BC_AUDIO, or AVRC_MJ_TYPE_BC_VIDEO.*/ - UINT32 sub_type; /* Use AVRC_SUB_TYPE_NONE, AVRC_SUB_TYPE_AUDIO_BOOK, or AVRC_SUB_TYPE_PODCAST*/ - UINT8 play_status; /* Use AVRC_PLAYSTATE_STOPPED, AVRC_PLAYSTATE_PLAYING, AVRC_PLAYSTATE_PAUSED, AVRC_PLAYSTATE_FWD_SEEK, - AVRC_PLAYSTATE_REV_SEEK, or AVRC_PLAYSTATE_ERROR*/ - tAVRC_FEATURE_MASK features; /* Supported feature bit mask*/ - tAVRC_FULL_NAME name; /* The player name, name length and character set id.*/ -} tAVRC_ITEM_PLAYER; - -typedef struct { - tAVRC_UID uid; /* The uid of this folder */ - UINT8 type; /* Use AVRC_FOLDER_TYPE_MIXED, AVRC_FOLDER_TYPE_TITLES, - AVRC_FOLDER_TYPE_ALNUMS, AVRC_FOLDER_TYPE_ARTISTS, AVRC_FOLDER_TYPE_GENRES, - AVRC_FOLDER_TYPE_PLAYLISTS, or AVRC_FOLDER_TYPE_YEARS.*/ - BOOLEAN playable; /* TRUE, if the folder can be played. */ - tAVRC_FULL_NAME name; /* The folder name, name length and character set id. */ -} tAVRC_ITEM_FOLDER; - -typedef struct { - UINT32 attr_id; /* Use AVRC_MEDIA_ATTR_ID_TITLE, AVRC_MEDIA_ATTR_ID_ARTIST, AVRC_MEDIA_ATTR_ID_ALBUM, - AVRC_MEDIA_ATTR_ID_TRACK_NUM, AVRC_MEDIA_ATTR_ID_NUM_TRACKS, - AVRC_MEDIA_ATTR_ID_GENRE, AVRC_MEDIA_ATTR_ID_PLAYING_TIME */ - tAVRC_FULL_NAME name; /* The attribute value, value length and character set id. */ -} tAVRC_ATTR_ENTRY; - -typedef struct { - tAVRC_UID uid; /* The uid of this media element item */ - UINT8 type; /* Use AVRC_MEDIA_TYPE_AUDIO or AVRC_MEDIA_TYPE_VIDEO. */ - tAVRC_FULL_NAME name; /* The media name, name length and character set id. */ - UINT8 attr_count; /* The number of attributes in p_attr_list */ - tAVRC_ATTR_ENTRY *p_attr_list; /* Attribute entry list. */ -} tAVRC_ITEM_MEDIA; - -typedef struct { - UINT8 item_type; /* AVRC_ITEM_PLAYER, AVRC_ITEM_FOLDER, or AVRC_ITEM_MEDIA */ - union { - tAVRC_ITEM_PLAYER player; /* The properties of a media player item.*/ - tAVRC_ITEM_FOLDER folder; /* The properties of a folder item.*/ - tAVRC_ITEM_MEDIA media; /* The properties of a media item.*/ - } u; -} tAVRC_ITEM; - -/* GetCapability */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 capability_id; -} tAVRC_GET_CAPS_CMD; - -/* ListPlayerAppValues */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 attr_id; -} tAVRC_LIST_APP_VALUES_CMD; - -/* GetCurAppValue */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 num_attr; - UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE]; -} tAVRC_GET_CUR_APP_VALUE_CMD; - -/* SetAppValue */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 num_val; - tAVRC_APP_SETTING *p_vals; -} tAVRC_SET_APP_VALUE_CMD; - -/* GetAppAttrTxt */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 num_attr; - UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE]; -} tAVRC_GET_APP_ATTR_TXT_CMD; - -/* GetAppValueTxt */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 attr_id; - UINT8 num_val; - UINT8 vals[AVRC_MAX_APP_ATTR_SIZE]; -} tAVRC_GET_APP_VAL_TXT_CMD; - -/* InformCharset */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 num_id; - UINT16 charsets[AVRC_MAX_CHARSET_SIZE]; -} tAVRC_INFORM_CHARSET_CMD; - -/* InformBatteryStatus */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 battery_status; -} tAVRC_BATTERY_STATUS_CMD; - -/* GetElemAttrs */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 num_attr; - UINT32 attrs[AVRC_MAX_ELEM_ATTR_SIZE]; -} tAVRC_GET_ELEM_ATTRS_CMD; - -/* RegNotify */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 event_id; - UINT32 param; -} tAVRC_REG_NOTIF_CMD; - -/* SetAddrPlayer */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT16 player_id; -} tAVRC_SET_ADDR_PLAYER_CMD; - -/* SetBrowsedPlayer */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT16 player_id; -} tAVRC_SET_BR_PLAYER_CMD; - -/* SetAbsVolume */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 volume; -} tAVRC_SET_VOLUME_CMD; - -/* GetFolderItems */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 scope; - UINT32 start_item; - UINT32 end_item; - UINT8 attr_count; - UINT32 *p_attr_list; -} tAVRC_GET_ITEMS_CMD; - -/* ChangePath */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT16 uid_counter; - UINT8 direction; - tAVRC_UID folder_uid; -} tAVRC_CHG_PATH_CMD; - -/* GetItemAttrs */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 scope; - tAVRC_UID uid; - UINT16 uid_counter; - UINT8 attr_count; - UINT32 *p_attr_list; -} tAVRC_GET_ATTRS_CMD; - -/* Search */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - tAVRC_FULL_NAME string; -} tAVRC_SEARCH_CMD; - -/* PlayItem */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 scope; - tAVRC_UID uid; - UINT16 uid_counter; -} tAVRC_PLAY_ITEM_CMD; - -/* AddToNowPlaying */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 scope; - tAVRC_UID uid; - UINT16 uid_counter; -} tAVRC_ADD_TO_PLAY_CMD; - -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ -} tAVRC_CMD; - -/* Continue and Abort */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (assigned by AVRC_BldCommand according to pdu) */ - UINT8 target_pdu; -} tAVRC_NEXT_CMD; - -typedef union { - UINT8 pdu; - tAVRC_CMD cmd; - tAVRC_GET_CAPS_CMD get_caps; /* GetCapability */ - tAVRC_CMD list_app_attr; /* ListPlayerAppAttr */ - tAVRC_LIST_APP_VALUES_CMD list_app_values; /* ListPlayerAppValues */ - tAVRC_GET_CUR_APP_VALUE_CMD get_cur_app_val; /* GetCurAppValue */ - tAVRC_SET_APP_VALUE_CMD set_app_val; /* SetAppValue */ - tAVRC_GET_APP_ATTR_TXT_CMD get_app_attr_txt; /* GetAppAttrTxt */ - tAVRC_GET_APP_VAL_TXT_CMD get_app_val_txt; /* GetAppValueTxt */ - tAVRC_INFORM_CHARSET_CMD inform_charset; /* InformCharset */ - tAVRC_BATTERY_STATUS_CMD inform_battery_status; /* InformBatteryStatus */ - tAVRC_GET_ELEM_ATTRS_CMD get_elem_attrs; /* GetElemAttrs */ - tAVRC_CMD get_play_status; /* GetPlayStatus */ - tAVRC_REG_NOTIF_CMD reg_notif; /* RegNotify */ - tAVRC_NEXT_CMD continu; /* Continue */ - tAVRC_NEXT_CMD abort; /* Abort */ - - tAVRC_SET_ADDR_PLAYER_CMD addr_player; /* SetAddrPlayer */ - tAVRC_SET_VOLUME_CMD volume; /* SetAbsVolume */ - tAVRC_SET_BR_PLAYER_CMD br_player; /* SetBrowsedPlayer */ - tAVRC_GET_ITEMS_CMD get_items; /* GetFolderItems */ - tAVRC_CHG_PATH_CMD chg_path; /* ChangePath */ - tAVRC_GET_ATTRS_CMD get_attrs; /* GetItemAttrs */ - tAVRC_SEARCH_CMD search; /* Search */ - tAVRC_PLAY_ITEM_CMD play_item; /* PlayItem */ - tAVRC_ADD_TO_PLAY_CMD add_to_play; /* AddToNowPlaying */ -} tAVRC_COMMAND; - -/* GetCapability */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ - UINT8 capability_id; - UINT8 count; - tAVRC_CAPS_PARAM param; -} tAVRC_GET_CAPS_RSP; - -/* ListPlayerAppAttr */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ - UINT8 num_attr; - UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE]; -} tAVRC_LIST_APP_ATTR_RSP; - -/* ListPlayerAppValues */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ - UINT8 num_val; - UINT8 vals[AVRC_MAX_APP_ATTR_SIZE]; -} tAVRC_LIST_APP_VALUES_RSP; - -/* GetCurAppValue */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ - UINT8 num_val; - tAVRC_APP_SETTING *p_vals; -} tAVRC_GET_CUR_APP_VALUE_RSP; - -/* GetAppAttrTxt */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ - UINT8 num_attr; - tAVRC_APP_SETTING_TEXT *p_attrs; -} tAVRC_GET_APP_ATTR_TXT_RSP; - -/* GetElemAttrs */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ - UINT8 num_attr; - tAVRC_ATTR_ENTRY *p_attrs; -} tAVRC_GET_ELEM_ATTRS_RSP; - -/* GetPlayStatus */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ - UINT32 song_len; - UINT32 song_pos; - UINT8 play_status; -} tAVRC_GET_PLAY_STATUS_RSP; - -/* notification event parameter for AddressedPlayer change */ -typedef struct { - UINT16 player_id; - UINT16 uid_counter; -} tAVRC_ADDR_PLAYER_PARAM; - -#ifndef AVRC_MAX_APP_SETTINGS -#define AVRC_MAX_APP_SETTINGS 8 -#endif - -/* notification event parameter for Player Application setting change */ -typedef struct { - UINT8 num_attr; - UINT8 attr_id[AVRC_MAX_APP_SETTINGS]; - UINT8 attr_value[AVRC_MAX_APP_SETTINGS]; -} tAVRC_PLAYER_APP_PARAM; - -typedef union { - tAVRC_PLAYSTATE play_status; - tAVRC_UID track; - UINT32 play_pos; - tAVRC_BATTERY_STATUS battery_status; - tAVRC_SYSTEMSTATE system_status; - tAVRC_PLAYER_APP_PARAM player_setting; - tAVRC_ADDR_PLAYER_PARAM addr_player; - UINT16 uid_counter; - UINT8 volume; -} tAVRC_NOTIF_RSP_PARAM; - -/* RegNotify */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ - UINT8 event_id; - tAVRC_NOTIF_RSP_PARAM param; -} tAVRC_REG_NOTIF_RSP; - -/* SetAbsVolume */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ - UINT8 volume; -} tAVRC_SET_VOLUME_RSP; - -/* SetBrowsedPlayer */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ - UINT16 uid_counter; - UINT32 num_items; - UINT16 charset_id; - UINT8 folder_depth; - tAVRC_NAME *p_folders; -} tAVRC_SET_BR_PLAYER_RSP; - -/* GetFolderItems */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ - UINT16 uid_counter; - UINT16 item_count; - tAVRC_ITEM *p_item_list; -} tAVRC_GET_ITEMS_RSP; - -/* ChangePath */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ - UINT32 num_items; -} tAVRC_CHG_PATH_RSP; - -/* GetItemAttrs */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ - UINT8 attr_count; - tAVRC_ATTR_ENTRY *p_attr_list; -} tAVRC_GET_ATTRS_RSP; - -/* Search */ -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ - UINT16 uid_counter; - UINT32 num_items; -} tAVRC_SEARCH_RSP; - - -typedef struct { - UINT8 pdu; - tAVRC_STS status; - UINT8 opcode; /* Op Code (copied from avrc_cmd.opcode by AVRC_BldResponse user. invalid one to generate according to pdu) */ -} tAVRC_RSP; - -typedef union { - UINT8 pdu; - tAVRC_RSP rsp; - tAVRC_GET_CAPS_RSP get_caps; /* GetCapability */ - tAVRC_LIST_APP_ATTR_RSP list_app_attr; /* ListPlayerAppAttr */ - tAVRC_LIST_APP_VALUES_RSP list_app_values; /* ListPlayerAppValues */ - tAVRC_GET_CUR_APP_VALUE_RSP get_cur_app_val; /* GetCurAppValue */ - tAVRC_RSP set_app_val; /* SetAppValue */ - tAVRC_GET_APP_ATTR_TXT_RSP get_app_attr_txt; /* GetAppAttrTxt */ - tAVRC_GET_APP_ATTR_TXT_RSP get_app_val_txt; /* GetAppValueTxt */ - tAVRC_RSP inform_charset; /* InformCharset */ - tAVRC_RSP inform_battery_status; /* InformBatteryStatus */ - tAVRC_GET_ELEM_ATTRS_RSP get_elem_attrs; /* GetElemAttrs */ - tAVRC_GET_PLAY_STATUS_RSP get_play_status; /* GetPlayStatus */ - tAVRC_REG_NOTIF_RSP reg_notif; /* RegNotify */ - tAVRC_RSP continu; /* Continue */ - tAVRC_RSP abort; /* Abort */ - - tAVRC_RSP addr_player; /* SetAddrPlayer */ - tAVRC_SET_VOLUME_RSP volume; /* SetAbsVolume */ - tAVRC_SET_BR_PLAYER_RSP br_player; /* SetBrowsedPlayer */ - tAVRC_GET_ITEMS_RSP get_items; /* GetFolderItems */ - tAVRC_CHG_PATH_RSP chg_path; /* ChangePath */ - tAVRC_GET_ATTRS_RSP get_attrs; /* GetItemAttrs */ - tAVRC_SEARCH_RSP search; /* Search */ - tAVRC_RSP play_item; /* PlayItem */ - tAVRC_RSP add_to_play; /* AddToNowPlaying */ -} tAVRC_RESPONSE; - -#endif ///AVRC_INCLUDED == TRUE -#endif diff --git a/tools/sdk/include/bluedroid/stack/bt_types.h b/tools/sdk/include/bluedroid/stack/bt_types.h deleted file mode 100644 index ec44cb87..00000000 --- a/tools/sdk/include/bluedroid/stack/bt_types.h +++ /dev/null @@ -1,793 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef BT_TYPES_H -#define BT_TYPES_H - -#include -#include - -#ifndef FALSE -# define FALSE false -#endif - -#ifndef TRUE -# define TRUE true -#endif - -typedef uint8_t UINT8; -typedef uint16_t UINT16; -typedef uint32_t UINT32; -typedef uint64_t UINT64; - -typedef int8_t INT8; -typedef int16_t INT16; -typedef int32_t INT32; -typedef bool BOOLEAN; - -#define PACKED __packed -// #define INLINE __inline - -#define BCM_STRCPY_S(x1,x2,x3) strcpy((x1),(x3)) -#define BCM_STRNCPY_S(x1,x2,x3,x4) strncpy((x1),(x3),(x4)) - -/* READ WELL !! -** -** This section defines global events. These are events that cross layers. -** Any event that passes between layers MUST be one of these events. Tasks -** can use their own events internally, but a FUNDAMENTAL design issue is -** that global events MUST be one of these events defined below. -** -** The convention used is the the event name contains the layer that the -** event is going to. -*/ -#define BT_EVT_MASK 0xFF00 -#define BT_SUB_EVT_MASK 0x00FF -#define BT_STATIC_RAND_ADDR_MASK 0xC0 -/* To Bluetooth Upper Layers */ -/************************************/ -#define BT_EVT_TO_BTU_L2C_EVT 0x0900 /* L2CAP event */ -#define BT_EVT_TO_BTU_HCI_EVT 0x1000 /* HCI Event */ -#define BT_EVT_TO_BTU_HCI_BR_EDR_EVT (0x0000 | BT_EVT_TO_BTU_HCI_EVT) /* event from BR/EDR controller */ -#define BT_EVT_TO_BTU_HCI_AMP1_EVT (0x0001 | BT_EVT_TO_BTU_HCI_EVT) /* event from local AMP 1 controller */ -#define BT_EVT_TO_BTU_HCI_AMP2_EVT (0x0002 | BT_EVT_TO_BTU_HCI_EVT) /* event from local AMP 2 controller */ -#define BT_EVT_TO_BTU_HCI_AMP3_EVT (0x0003 | BT_EVT_TO_BTU_HCI_EVT) /* event from local AMP 3 controller */ - -#define BT_EVT_TO_BTU_HCI_ACL 0x1100 /* ACL Data from HCI */ -#define BT_EVT_TO_BTU_HCI_SCO 0x1200 /* SCO Data from HCI */ -#define BT_EVT_TO_BTU_HCIT_ERR 0x1300 /* HCI Transport Error */ - -#define BT_EVT_TO_BTU_SP_EVT 0x1400 /* Serial Port Event */ -#define BT_EVT_TO_BTU_SP_DATA 0x1500 /* Serial Port Data */ - -#define BT_EVT_TO_BTU_HCI_CMD 0x1600 /* HCI command from upper layer */ - - -#define BT_EVT_TO_BTU_L2C_SEG_XMIT 0x1900 /* L2CAP segment(s) transmitted */ - -#define BT_EVT_PROXY_INCOMING_MSG 0x1A00 /* BlueStackTester event: incoming message from target */ - -#define BT_EVT_BTSIM 0x1B00 /* Insight BTSIM event */ -#define BT_EVT_BTISE 0x1C00 /* Insight Script Engine event */ - -/* To LM */ -/************************************/ -#define BT_EVT_TO_LM_HCI_CMD 0x2000 /* HCI Command */ -#define BT_EVT_TO_LM_HCI_ACL 0x2100 /* HCI ACL Data */ -#define BT_EVT_TO_LM_HCI_SCO 0x2200 /* HCI SCO Data */ -#define BT_EVT_TO_LM_HCIT_ERR 0x2300 /* HCI Transport Error */ -#define BT_EVT_TO_LM_LC_EVT 0x2400 /* LC event */ -#define BT_EVT_TO_LM_LC_LMP 0x2500 /* LC Received LMP command frame */ -#define BT_EVT_TO_LM_LC_ACL 0x2600 /* LC Received ACL data */ -#define BT_EVT_TO_LM_LC_SCO 0x2700 /* LC Received SCO data (not used) */ -#define BT_EVT_TO_LM_LC_ACL_TX 0x2800 /* LMP data transmit complete */ -#define BT_EVT_TO_LM_LC_LMPC_TX 0x2900 /* LMP Command transmit complete */ -#define BT_EVT_TO_LM_LOCAL_ACL_LB 0x2a00 /* Data to be locally loopbacked */ -#define BT_EVT_TO_LM_HCI_ACL_ACK 0x2b00 /* HCI ACL Data ack (not used) */ -#define BT_EVT_TO_LM_DIAG 0x2c00 /* LM Diagnostics commands */ - - -#define BT_EVT_TO_BTM_CMDS 0x2f00 -#define BT_EVT_TO_BTM_PM_MDCHG_EVT (0x0001 | BT_EVT_TO_BTM_CMDS) - -#define BT_EVT_TO_TCS_CMDS 0x3000 - -#define BT_EVT_TO_CTP_CMDS 0x3300 - -/* ftp events */ -#define BT_EVT_TO_FTP_SRVR_CMDS 0x3600 -#define BT_EVT_TO_FTP_CLNT_CMDS 0x3700 - -#define BT_EVT_TO_BTU_SAP 0x3800 /* SIM Access Profile events */ - -/* opp events */ -#define BT_EVT_TO_OPP_SRVR_CMDS 0x3900 -#define BT_EVT_TO_OPP_CLNT_CMDS 0x3a00 - -/* gap events */ -#define BT_EVT_TO_GAP_MSG 0x3b00 - -/* for NFC */ -/************************************/ -#define BT_EVT_TO_NFC_NCI 0x4000 /* NCI Command, Notification or Data*/ -#define BT_EVT_TO_NFC_INIT 0x4100 /* Initialization message */ -#define BT_EVT_TO_NCI_LP 0x4200 /* Low power */ -#define BT_EVT_TO_NFC_ERR 0x4300 /* Error notification to NFC Task */ - -#define BT_EVT_TO_NFCCSIM_NCI 0x4a00 /* events to NFCC simulation (NCI packets) */ - -/* HCISU Events */ - -#define BT_EVT_HCISU 0x5000 - -// btla-specific ++ -#define BT_EVT_TO_HCISU_RECONFIG_EVT (0x0001 | BT_EVT_HCISU) -#define BT_EVT_TO_HCISU_UPDATE_BAUDRATE_EVT (0x0002 | BT_EVT_HCISU) -#define BT_EVT_TO_HCISU_LP_ENABLE_EVT (0x0003 | BT_EVT_HCISU) -#define BT_EVT_TO_HCISU_LP_DISABLE_EVT (0x0004 | BT_EVT_HCISU) -// btla-specific -- -#define BT_EVT_TO_HCISU_LP_APP_SLEEPING_EVT (0x0005 | BT_EVT_HCISU) -#define BT_EVT_TO_HCISU_LP_ALLOW_BT_SLEEP_EVT (0x0006 | BT_EVT_HCISU) -#define BT_EVT_TO_HCISU_LP_WAKEUP_HOST_EVT (0x0007 | BT_EVT_HCISU) -#define BT_EVT_TO_HCISU_LP_RCV_H4IBSS_EVT (0x0008 | BT_EVT_HCISU) -#define BT_EVT_TO_HCISU_H5_RESET_EVT (0x0009 | BT_EVT_HCISU) -#define BT_EVT_HCISU_START_QUICK_TIMER (0x000a | BT_EVT_HCISU) - -#define BT_EVT_DATA_TO_AMP_1 0x5100 -#define BT_EVT_DATA_TO_AMP_15 0x5f00 - -/* HSP Events */ - -#define BT_EVT_BTU_HSP2 0x6000 - -#define BT_EVT_TO_BTU_HSP2_EVT (0x0001 | BT_EVT_BTU_HSP2) - -/* BPP Events */ -#define BT_EVT_TO_BPP_PR_CMDS 0x6100 /* Printer Events */ -#define BT_EVT_TO_BPP_SND_CMDS 0x6200 /* BPP Sender Events */ - -/* BIP Events */ -#define BT_EVT_TO_BIP_CMDS 0x6300 - -/* HCRP Events */ - -#define BT_EVT_BTU_HCRP 0x7000 - -#define BT_EVT_TO_BTU_HCRP_EVT (0x0001 | BT_EVT_BTU_HCRP) -#define BT_EVT_TO_BTU_HCRPM_EVT (0x0002 | BT_EVT_BTU_HCRP) - - -#define BT_EVT_BTU_HFP 0x8000 -#define BT_EVT_TO_BTU_HFP_EVT (0x0001 | BT_EVT_BTU_HFP) - -#define BT_EVT_BTU_IPC_EVT 0x9000 -#define BT_EVT_BTU_IPC_LOGMSG_EVT (0x0000 | BT_EVT_BTU_IPC_EVT) -#define BT_EVT_BTU_IPC_ACL_EVT (0x0001 | BT_EVT_BTU_IPC_EVT) -#define BT_EVT_BTU_IPC_BTU_EVT (0x0002 | BT_EVT_BTU_IPC_EVT) -#define BT_EVT_BTU_IPC_L2C_EVT (0x0003 | BT_EVT_BTU_IPC_EVT) -#define BT_EVT_BTU_IPC_L2C_MSG_EVT (0x0004 | BT_EVT_BTU_IPC_EVT) -#define BT_EVT_BTU_IPC_BTM_EVT (0x0005 | BT_EVT_BTU_IPC_EVT) -#define BT_EVT_BTU_IPC_AVDT_EVT (0x0006 | BT_EVT_BTU_IPC_EVT) -#define BT_EVT_BTU_IPC_SLIP_EVT (0x0007 | BT_EVT_BTU_IPC_EVT) -#define BT_EVT_BTU_IPC_MGMT_EVT (0x0008 | BT_EVT_BTU_IPC_EVT) -#define BT_EVT_BTU_IPC_BTTRC_EVT (0x0009 | BT_EVT_BTU_IPC_EVT) -#define BT_EVT_BTU_IPC_BURST_EVT (0x000A | BT_EVT_BTU_IPC_EVT) - - -/* BTIF Events */ -#define BT_EVT_BTIF 0xA000 -#define BT_EVT_CONTEXT_SWITCH_EVT (0x0001 | BT_EVT_BTIF) - -/* Define the header of each buffer used in the Bluetooth stack. -*/ -typedef struct { - uint16_t event; - uint16_t len; - uint16_t offset; - uint16_t layer_specific; - uint8_t data[]; -} BT_HDR; - -#define BT_HDR_SIZE (sizeof (BT_HDR)) - -#define BT_PSM_SDP 0x0001 -#define BT_PSM_RFCOMM 0x0003 -#define BT_PSM_TCS 0x0005 -#define BT_PSM_CTP 0x0007 -#define BT_PSM_BNEP 0x000F -#define BT_PSM_HIDC 0x0011 -#define BT_PSM_HIDI 0x0013 -#define BT_PSM_UPNP 0x0015 -#define BT_PSM_AVCTP 0x0017 -#define BT_PSM_AVDTP 0x0019 -#define BT_PSM_AVCTP_13 0x001B /* Advanced Control - Browsing */ -#define BT_PSM_UDI_CP 0x001D /* Unrestricted Digital Information Profile C-Plane */ -#define BT_PSM_ATT 0x001F /* Attribute Protocol */ - - -/* These macros extract the HCI opcodes from a buffer -*/ -#define HCI_GET_CMD_HDR_OPCODE(p) (UINT16)((*((UINT8 *)((p) + 1) + p->offset) + \ - (*((UINT8 *)((p) + 1) + p->offset + 1) << 8))) -#define HCI_GET_CMD_HDR_PARAM_LEN(p) (UINT8) (*((UINT8 *)((p) + 1) + p->offset + 2)) - -#define HCI_GET_EVT_HDR_OPCODE(p) (UINT8)(*((UINT8 *)((p) + 1) + p->offset)) -#define HCI_GET_EVT_HDR_PARAM_LEN(p) (UINT8) (*((UINT8 *)((p) + 1) + p->offset + 1)) - - -/******************************************************************************** -** Macros to get and put bytes to and from a stream (Little Endian format). -*/ -#define UINT32_TO_STREAM(p, u32) {*(p)++ = (UINT8)(u32); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 24);} -#define UINT24_TO_STREAM(p, u24) {*(p)++ = (UINT8)(u24); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)((u24) >> 16);} -#define UINT16_TO_STREAM(p, u16) {*(p)++ = (UINT8)(u16); *(p)++ = (UINT8)((u16) >> 8);} -#define UINT8_TO_STREAM(p, u8) {*(p)++ = (UINT8)(u8);} -#define INT8_TO_STREAM(p, u8) {*(p)++ = (INT8)(u8);} -#define ARRAY32_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < 32; ijk++) *(p)++ = (UINT8) a[31 - ijk];} -#define ARRAY16_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < 16; ijk++) *(p)++ = (UINT8) a[15 - ijk];} -#define ARRAY8_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < 8; ijk++) *(p)++ = (UINT8) a[7 - ijk];} -#define BDADDR_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *(p)++ = (UINT8) a[BD_ADDR_LEN - 1 - ijk];} -#define LAP_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < LAP_LEN; ijk++) *(p)++ = (UINT8) a[LAP_LEN - 1 - ijk];} -#define DEVCLASS_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < DEV_CLASS_LEN;ijk++) *(p)++ = (UINT8) a[DEV_CLASS_LEN - 1 - ijk];} -#define ARRAY_TO_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[ijk];} -#define REVERSE_ARRAY_TO_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[len - 1 - ijk];} - -#define STREAM_TO_UINT8(u8, p) {u8 = (UINT8)(*(p)); (p) += 1;} -#define STREAM_TO_UINT16(u16, p) {u16 = ((UINT16)(*(p)) + (((UINT16)(*((p) + 1))) << 8)); (p) += 2;} -#define STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) ); (p) += 3;} -#define STREAM_TO_UINT32(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) + ((((UINT32)(*((p) + 3)))) << 24)); (p) += 4;} -#define STREAM_TO_BDADDR(a, p) {register int ijk; register UINT8 *pbda = (UINT8 *)a + BD_ADDR_LEN - 1; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *pbda-- = *p++;} -#define STREAM_TO_ARRAY32(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + 31; for (ijk = 0; ijk < 32; ijk++) *_pa-- = *p++;} -#define STREAM_TO_ARRAY16(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + 15; for (ijk = 0; ijk < 16; ijk++) *_pa-- = *p++;} -#define STREAM_TO_ARRAY8(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + 7; for (ijk = 0; ijk < 8; ijk++) *_pa-- = *p++;} -#define STREAM_TO_DEVCLASS(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + DEV_CLASS_LEN - 1; for (ijk = 0; ijk < DEV_CLASS_LEN; ijk++) *_pa-- = *p++;} -#define STREAM_TO_LAP(a, p) {register int ijk; register UINT8 *plap = (UINT8 *)a + LAP_LEN - 1; for (ijk = 0; ijk < LAP_LEN; ijk++) *plap-- = *p++;} -#define STREAM_TO_ARRAY(a, p, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;} -#define REVERSE_STREAM_TO_ARRAY(a, p, len) {register int ijk; register UINT8 *_pa = (UINT8 *)a + len - 1; for (ijk = 0; ijk < len; ijk++) *_pa-- = *p++;} - -#define STREAM_SKIP_UINT8(p) do { (p) += 1; } while (0) -#define STREAM_SKIP_UINT16(p) do { (p) += 2; } while (0) - -/******************************************************************************** -** Macros to get and put bytes to and from a field (Little Endian format). -** These are the same as to stream, except the pointer is not incremented. -*/ -#define UINT32_TO_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)(u32); *((UINT8 *)(p)+1) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+3) = (UINT8)((u32) >> 24);} -#define UINT24_TO_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)(u24); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u24) >> 16);} -#define UINT16_TO_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)(u16); *((UINT8 *)(p)+1) = (UINT8)((u16) >> 8);} -#define UINT8_TO_FIELD(p, u8) {*(UINT8 *)(p) = (UINT8)(u8);} - - -/******************************************************************************** -** Macros to get and put bytes to and from a stream (Big Endian format) -*/ -#define UINT64_TO_BE_STREAM(p, u64) {*(p)++ = (UINT8)((u64) >> 56); *(p)++ = (UINT8)((u64) >> 48); *(p)++ = (UINT8)((u64) >> 40); *(p)++ = (UINT8)((u64) >> 32); *(p)++ = (UINT8)((u64) >> 24); *(p)++ = (UINT8)((u64) >> 16); *(p)++ = (UINT8)((u64) >> 8); *(p)++ = (UINT8)(u64); } -#define UINT32_TO_BE_STREAM(p, u32) {*(p)++ = (UINT8)((u32) >> 24); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)(u32); } -#define UINT24_TO_BE_STREAM(p, u24) {*(p)++ = (UINT8)((u24) >> 16); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)(u24);} -#define UINT16_TO_BE_STREAM(p, u16) {*(p)++ = (UINT8)((u16) >> 8); *(p)++ = (UINT8)(u16);} -#define UINT8_TO_BE_STREAM(p, u8) {*(p)++ = (UINT8)(u8);} -#define ARRAY_TO_BE_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[ijk];} -#define ARRAY_TO_BE_STREAM_REVERSE(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[len - ijk - 1];} - -#define BE_STREAM_TO_UINT8(u8, p) {u8 = (UINT8)(*(p)); (p) += 1;} -#define BE_STREAM_TO_UINT16(u16, p) {u16 = (UINT16)(((UINT16)(*(p)) << 8) + (UINT16)(*((p) + 1))); (p) += 2;} -#define BE_STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*((p) + 2))) + ((UINT32)(*((p) + 1)) << 8) + ((UINT32)(*(p)) << 16)); (p) += 3;} -#define BE_STREAM_TO_UINT32(u32, p) {u32 = ((UINT32)(*((p) + 3)) + ((UINT32)(*((p) + 2)) << 8) + ((UINT32)(*((p) + 1)) << 16) + ((UINT32)(*(p)) << 24)); (p) += 4;} -#define BE_STREAM_TO_ARRAY(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;} - - -/******************************************************************************** -** Macros to get and put bytes to and from a field (Big Endian format). -** These are the same as to stream, except the pointer is not incremented. -*/ -#define UINT32_TO_BE_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)((u32) >> 24); *((UINT8 *)(p)+1) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+3) = (UINT8)(u32); } -#define UINT24_TO_BE_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)((u24) >> 16); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)(u24);} -#define UINT16_TO_BE_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)((u16) >> 8); *((UINT8 *)(p)+1) = (UINT8)(u16);} -#define UINT8_TO_BE_FIELD(p, u8) {*(UINT8 *)(p) = (UINT8)(u8);} - - -/* Common Bluetooth field definitions */ -#define BD_ADDR_LEN 6 /* Device address length */ -typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */ -typedef UINT8 *BD_ADDR_PTR; /* Pointer to Device Address */ - -#define AMP_KEY_TYPE_GAMP 0 -#define AMP_KEY_TYPE_WIFI 1 -#define AMP_KEY_TYPE_UWB 2 -typedef UINT8 tAMP_KEY_TYPE; - -#define BT_OCTET8_LEN 8 -typedef UINT8 BT_OCTET8[BT_OCTET8_LEN]; /* octet array: size 16 */ - -#define LINK_KEY_LEN 16 -typedef UINT8 LINK_KEY[LINK_KEY_LEN]; /* Link Key */ - -#define AMP_LINK_KEY_LEN 32 -typedef UINT8 AMP_LINK_KEY[AMP_LINK_KEY_LEN]; /* Dedicated AMP and GAMP Link Keys */ - -#define BT_OCTET16_LEN 16 -typedef UINT8 BT_OCTET16[BT_OCTET16_LEN]; /* octet array: size 16 */ - -#define PIN_CODE_LEN 16 -typedef UINT8 PIN_CODE[PIN_CODE_LEN]; /* Pin Code (upto 128 bits) MSB is 0 */ -typedef UINT8 *PIN_CODE_PTR; /* Pointer to Pin Code */ - -#define BT_OCTET32_LEN 32 -typedef UINT8 BT_OCTET32[BT_OCTET32_LEN]; /* octet array: size 32 */ - -#define DEV_CLASS_LEN 3 -typedef UINT8 DEV_CLASS[DEV_CLASS_LEN]; /* Device class */ -typedef UINT8 *DEV_CLASS_PTR; /* Pointer to Device class */ - -#define EXT_INQ_RESP_LEN 3 -typedef UINT8 EXT_INQ_RESP[EXT_INQ_RESP_LEN];/* Extended Inquiry Response */ -typedef UINT8 *EXT_INQ_RESP_PTR; /* Pointer to Extended Inquiry Response */ - -#define BD_NAME_LEN 248 -typedef UINT8 BD_NAME[BD_NAME_LEN + 1]; /* Device name */ -typedef UINT8 *BD_NAME_PTR; /* Pointer to Device name */ - -#define BD_FEATURES_LEN 8 -typedef UINT8 BD_FEATURES[BD_FEATURES_LEN]; /* LMP features supported by device */ - -#define BT_EVENT_MASK_LEN 8 -typedef UINT8 BT_EVENT_MASK[BT_EVENT_MASK_LEN]; /* Event Mask */ - -#define LAP_LEN 3 -typedef UINT8 LAP[LAP_LEN]; /* IAC as passed to Inquiry (LAP) */ -typedef UINT8 INQ_LAP[LAP_LEN]; /* IAC as passed to Inquiry (LAP) */ - -#define RAND_NUM_LEN 16 -typedef UINT8 RAND_NUM[RAND_NUM_LEN]; - -#define ACO_LEN 12 -typedef UINT8 ACO[ACO_LEN]; /* Authenticated ciphering offset */ - -#define COF_LEN 12 -typedef UINT8 COF[COF_LEN]; /* ciphering offset number */ - -typedef struct { - UINT8 qos_flags; /* TBD */ - UINT8 service_type; /* see below */ - UINT32 token_rate; /* bytes/second */ - UINT32 token_bucket_size; /* bytes */ - UINT32 peak_bandwidth; /* bytes/second */ - UINT32 latency; /* microseconds */ - UINT32 delay_variation; /* microseconds */ -} FLOW_SPEC; - -/* Values for service_type */ -#define NO_TRAFFIC 0 -#define BEST_EFFORT 1 -#define GUARANTEED 2 - -/* Service class of the CoD */ -#define SERV_CLASS_NETWORKING (1 << 1) -#define SERV_CLASS_RENDERING (1 << 2) -#define SERV_CLASS_CAPTURING (1 << 3) -#define SERV_CLASS_OBJECT_TRANSFER (1 << 4) -#define SERV_CLASS_OBJECT_AUDIO (1 << 5) -#define SERV_CLASS_OBJECT_TELEPHONY (1 << 6) -#define SERV_CLASS_OBJECT_INFORMATION (1 << 7) - -/* Second byte */ -#define SERV_CLASS_LIMITED_DISC_MODE (0x20) - -/* Field size definitions. Note that byte lengths are rounded up. */ -#define ACCESS_CODE_BIT_LEN 72 -#define ACCESS_CODE_BYTE_LEN 9 -#define SHORTENED_ACCESS_CODE_BIT_LEN 68 - -typedef UINT8 ACCESS_CODE[ACCESS_CODE_BYTE_LEN]; - -#define SYNTH_TX 1 /* want synth code to TRANSMIT at this freq */ -#define SYNTH_RX 2 /* want synth code to RECEIVE at this freq */ - -#define SYNC_REPS 1 /* repeats of sync word transmitted to start of burst */ - -/* Bluetooth CLK27 */ -#define BT_CLK27 (2 << 26) - -/* Bluetooth CLK12 is 1.28 sec */ -#define BT_CLK12_TO_MS(x) ((x) * 1280) -#define BT_MS_TO_CLK12(x) ((x) / 1280) -#define BT_CLK12_TO_SLOTS(x) ((x) << 11) - -/* Bluetooth CLK is 0.625 msec */ -#define BT_CLK_TO_MS(x) (((x) * 5 + 3) / 8) -#define BT_MS_TO_CLK(x) (((x) * 8 + 2) / 5) - -#define BT_CLK_TO_MICROSECS(x) (((x) * 5000 + 3) / 8) -#define BT_MICROSECS_TO_CLK(x) (((x) * 8 + 2499) / 5000) - -/* Maximum UUID size - 16 bytes, and structure to hold any type of UUID. */ -#define MAX_UUID_SIZE 16 -typedef struct { -#define LEN_UUID_16 2 -#define LEN_UUID_32 4 -#define LEN_UUID_128 16 - - UINT16 len; - - union { - UINT16 uuid16; - UINT32 uuid32; - UINT8 uuid128[MAX_UUID_SIZE]; - } uu; - -} tBT_UUID; - -#define BT_EIR_FLAGS_TYPE 0x01 -#define BT_EIR_MORE_16BITS_UUID_TYPE 0x02 -#define BT_EIR_COMPLETE_16BITS_UUID_TYPE 0x03 -#define BT_EIR_MORE_32BITS_UUID_TYPE 0x04 -#define BT_EIR_COMPLETE_32BITS_UUID_TYPE 0x05 -#define BT_EIR_MORE_128BITS_UUID_TYPE 0x06 -#define BT_EIR_COMPLETE_128BITS_UUID_TYPE 0x07 -#define BT_EIR_SHORTENED_LOCAL_NAME_TYPE 0x08 -#define BT_EIR_COMPLETE_LOCAL_NAME_TYPE 0x09 -#define BT_EIR_TX_POWER_LEVEL_TYPE 0x0A -#define BT_EIR_OOB_BD_ADDR_TYPE 0x0C -#define BT_EIR_OOB_COD_TYPE 0x0D -#define BT_EIR_OOB_SSP_HASH_C_TYPE 0x0E -#define BT_EIR_OOB_SSP_RAND_R_TYPE 0x0F -#define BT_EIR_MANUFACTURER_SPECIFIC_TYPE 0xFF - -#define BT_OOB_COD_SIZE 3 -#define BT_OOB_HASH_C_SIZE 16 -#define BT_OOB_RAND_R_SIZE 16 - -/* Broadcom proprietary UUIDs and reserved PSMs -** -** The lowest 4 bytes byte of the UUID or GUID depends on the feature. Typically, -** the value of those bytes will be the PSM or SCN, but it is up to the features. -*/ -#define BRCM_PROPRIETARY_UUID_BASE 0xDA, 0x23, 0x41, 0x02, 0xA3, 0xBB, 0xC1, 0x71, 0xBA, 0x09, 0x6f, 0x21 -#define BRCM_PROPRIETARY_GUID_BASE 0xda23, 0x4102, 0xa3, 0xbb, 0xc1, 0x71, 0xba, 0x09, 0x6f, 0x21 - -/* We will not allocate a PSM in the reserved range to 3rd party apps -*/ -#define BRCM_RESERVED_PSM_START 0x5AE1 -#define BRCM_RESERVED_PSM_END 0x5AFF - -#define BRCM_UTILITY_SERVICE_PSM 0x5AE1 -#define BRCM_MATCHER_PSM 0x5AE3 - -/* Connection statistics -*/ - -/* Structure to hold connection stats */ -#ifndef BT_CONN_STATS_DEFINED -#define BT_CONN_STATS_DEFINED - -/* These bits are used in the bIsConnected field */ -#define BT_CONNECTED_USING_BREDR 1 -#define BT_CONNECTED_USING_AMP 2 - -typedef struct { - UINT32 is_connected; - INT32 rssi; - UINT32 bytes_sent; - UINT32 bytes_rcvd; - UINT32 duration; -} tBT_CONN_STATS; - -#endif - - -/***************************************************************************** -** Low Energy definitions -** -** Address types -*/ -#define BLE_ADDR_PUBLIC 0x00 -#define BLE_ADDR_RANDOM 0x01 -#define BLE_ADDR_PUBLIC_ID 0x02 -#define BLE_ADDR_RANDOM_ID 0x03 -#define BLE_ADDR_TYPE_MAX BLE_ADDR_RANDOM_ID -#define BLE_ADDR_UNKNOWN_TYPE 0XFF -typedef UINT8 tBLE_ADDR_TYPE; -#define BLE_ADDR_TYPE_MASK (BLE_ADDR_RANDOM | BLE_ADDR_PUBLIC) - -#define BT_TRANSPORT_INVALID 0 -#define BT_TRANSPORT_BR_EDR 1 -#define BT_TRANSPORT_LE 2 -typedef UINT8 tBT_TRANSPORT; - -#define BLE_ADDR_IS_STATIC(x) ((x[0] & 0xC0) == 0xC0) - -typedef struct { - tBLE_ADDR_TYPE type; - BD_ADDR bda; -} tBLE_BD_ADDR; - -/* Device Types -*/ -#define BT_DEVICE_TYPE_BREDR 0x01 -#define BT_DEVICE_TYPE_BLE 0x02 -#define BT_DEVICE_TYPE_DUMO 0x03 -typedef UINT8 tBT_DEVICE_TYPE; -/*****************************************************************************/ - - -/* Define trace levels */ -#define BT_TRACE_LEVEL_NONE 0 /* No trace messages to be generated */ -#define BT_TRACE_LEVEL_ERROR 1 /* Error condition trace messages */ -#define BT_TRACE_LEVEL_WARNING 2 /* Warning condition trace messages */ -#define BT_TRACE_LEVEL_API 3 /* API traces */ -#define BT_TRACE_LEVEL_EVENT 4 /* Debug messages for events */ -#define BT_TRACE_LEVEL_DEBUG 5 /* Full debug messages */ -#define BT_TRACE_LEVEL_VERBOSE 6 /* Verbose debug messages */ - -#define MAX_TRACE_LEVEL 6 - - -/* Define New Trace Type Definition */ -/* TRACE_CTRL_TYPE 0x^^000000*/ -#define TRACE_CTRL_MASK 0xff000000 -#define TRACE_GET_CTRL(x) ((((UINT32)(x)) & TRACE_CTRL_MASK) >> 24) - -#define TRACE_CTRL_GENERAL 0x00000000 -#define TRACE_CTRL_STR_RESOURCE 0x01000000 -#define TRACE_CTRL_SEQ_FLOW 0x02000000 -#define TRACE_CTRL_MAX_NUM 3 - -/* LAYER SPECIFIC 0x00^^0000*/ -#define TRACE_LAYER_MASK 0x00ff0000 -#define TRACE_GET_LAYER(x) ((((UINT32)(x)) & TRACE_LAYER_MASK) >> 16) - -#define TRACE_LAYER_NONE 0x00000000 -#define TRACE_LAYER_USB 0x00010000 -#define TRACE_LAYER_SERIAL 0x00020000 -#define TRACE_LAYER_SOCKET 0x00030000 -#define TRACE_LAYER_RS232 0x00040000 -#define TRACE_LAYER_TRANS_MAX_NUM 5 -#define TRACE_LAYER_TRANS_ALL 0x007f0000 -#define TRACE_LAYER_LC 0x00050000 -#define TRACE_LAYER_LM 0x00060000 -#define TRACE_LAYER_HCI 0x00070000 -#define TRACE_LAYER_L2CAP 0x00080000 -#define TRACE_LAYER_RFCOMM 0x00090000 -#define TRACE_LAYER_SDP 0x000a0000 -#define TRACE_LAYER_TCS 0x000b0000 -#define TRACE_LAYER_OBEX 0x000c0000 -#define TRACE_LAYER_BTM 0x000d0000 -#define TRACE_LAYER_GAP 0x000e0000 -#define TRACE_LAYER_ICP 0x00110000 -#define TRACE_LAYER_HSP2 0x00120000 -#define TRACE_LAYER_SPP 0x00130000 -#define TRACE_LAYER_CTP 0x00140000 -#define TRACE_LAYER_BPP 0x00150000 -#define TRACE_LAYER_HCRP 0x00160000 -#define TRACE_LAYER_FTP 0x00170000 -#define TRACE_LAYER_OPP 0x00180000 -#define TRACE_LAYER_BTU 0x00190000 -#define TRACE_LAYER_GKI 0x001a0000 -#define TRACE_LAYER_BNEP 0x001b0000 -#define TRACE_LAYER_PAN 0x001c0000 -#define TRACE_LAYER_HFP 0x001d0000 -#define TRACE_LAYER_HID 0x001e0000 -#define TRACE_LAYER_BIP 0x001f0000 -#define TRACE_LAYER_AVP 0x00200000 -#define TRACE_LAYER_A2D 0x00210000 -#define TRACE_LAYER_SAP 0x00220000 -#define TRACE_LAYER_AMP 0x00230000 -#define TRACE_LAYER_MCA 0x00240000 -#define TRACE_LAYER_ATT 0x00250000 -#define TRACE_LAYER_SMP 0x00260000 -#define TRACE_LAYER_NFC 0x00270000 -#define TRACE_LAYER_NCI 0x00280000 -#define TRACE_LAYER_LLCP 0x00290000 -#define TRACE_LAYER_NDEF 0x002a0000 -#define TRACE_LAYER_RW 0x002b0000 -#define TRACE_LAYER_CE 0x002c0000 -#define TRACE_LAYER_P2P 0x002d0000 -#define TRACE_LAYER_SNEP 0x002e0000 -#define TRACE_LAYER_CHO 0x002f0000 -#define TRACE_LAYER_NFA 0x00300000 - -#define TRACE_LAYER_MAX_NUM 0x0031 - - -/* TRACE_ORIGINATOR 0x0000^^00*/ -#define TRACE_ORG_MASK 0x0000ff00 -#define TRACE_GET_ORG(x) ((((UINT32)(x)) & TRACE_ORG_MASK) >> 8) - -#define TRACE_ORG_STACK 0x00000000 -#define TRACE_ORG_HCI_TRANS 0x00000100 -#define TRACE_ORG_PROTO_DISP 0x00000200 -#define TRACE_ORG_RPC 0x00000300 -#define TRACE_ORG_GKI 0x00000400 -#define TRACE_ORG_APPL 0x00000500 -#define TRACE_ORG_SCR_WRAPPER 0x00000600 -#define TRACE_ORG_SCR_ENGINE 0x00000700 -#define TRACE_ORG_USER_SCR 0x00000800 -#define TRACE_ORG_TESTER 0x00000900 -#define TRACE_ORG_MAX_NUM 10 /* 32-bit mask; must be < 32 */ -#define TRACE_LITE_ORG_MAX_NUM 6 -#define TRACE_ORG_ALL 0x03ff -#define TRACE_ORG_RPC_TRANS 0x04 - -#define TRACE_ORG_REG 0x00000909 -#define TRACE_ORG_REG_SUCCESS 0x0000090a - -/* TRACE_TYPE 0x000000^^*/ -#define TRACE_TYPE_MASK 0x000000ff -#define TRACE_GET_TYPE(x) (((UINT32)(x)) & TRACE_TYPE_MASK) - -#define TRACE_TYPE_ERROR 0x00000000 -#define TRACE_TYPE_WARNING 0x00000001 -#define TRACE_TYPE_API 0x00000002 -#define TRACE_TYPE_EVENT 0x00000003 -#define TRACE_TYPE_DEBUG 0x00000004 -#define TRACE_TYPE_STACK_ONLY_MAX TRACE_TYPE_DEBUG -#define TRACE_TYPE_TX 0x00000005 -#define TRACE_TYPE_RX 0x00000006 -#define TRACE_TYPE_DEBUG_ASSERT 0x00000007 -#define TRACE_TYPE_GENERIC 0x00000008 -#define TRACE_TYPE_REG 0x00000009 -#define TRACE_TYPE_REG_SUCCESS 0x0000000a -#define TRACE_TYPE_CMD_TX 0x0000000b -#define TRACE_TYPE_EVT_TX 0x0000000c -#define TRACE_TYPE_ACL_TX 0x0000000d -#define TRACE_TYPE_CMD_RX 0x0000000e -#define TRACE_TYPE_EVT_RX 0x0000000f -#define TRACE_TYPE_ACL_RX 0x00000010 -#define TRACE_TYPE_TARGET_TRACE 0x00000011 -#define TRACE_TYPE_SCO_TX 0x00000012 -#define TRACE_TYPE_SCO_RX 0x00000013 - - -#define TRACE_TYPE_MAX_NUM 20 -#define TRACE_TYPE_ALL 0xffff - -/* Define color for script type */ -#define SCR_COLOR_DEFAULT 0 -#define SCR_COLOR_TYPE_COMMENT 1 -#define SCR_COLOR_TYPE_COMMAND 2 -#define SCR_COLOR_TYPE_EVENT 3 -#define SCR_COLOR_TYPE_SELECT 4 - -/* Define protocol trace flag values */ -#define SCR_PROTO_TRACE_HCI_SUMMARY 0x00000001 -#define SCR_PROTO_TRACE_HCI_DATA 0x00000002 -#define SCR_PROTO_TRACE_L2CAP 0x00000004 -#define SCR_PROTO_TRACE_RFCOMM 0x00000008 -#define SCR_PROTO_TRACE_SDP 0x00000010 -#define SCR_PROTO_TRACE_TCS 0x00000020 -#define SCR_PROTO_TRACE_OBEX 0x00000040 -#define SCR_PROTO_TRACE_OAPP 0x00000080 /* OBEX Application Profile */ -#define SCR_PROTO_TRACE_AMP 0x00000100 -#define SCR_PROTO_TRACE_BNEP 0x00000200 -#define SCR_PROTO_TRACE_AVP 0x00000400 -#define SCR_PROTO_TRACE_MCA 0x00000800 -#define SCR_PROTO_TRACE_ATT 0x00001000 -#define SCR_PROTO_TRACE_SMP 0x00002000 -#define SCR_PROTO_TRACE_NCI 0x00004000 -#define SCR_PROTO_TRACE_LLCP 0x00008000 -#define SCR_PROTO_TRACE_NDEF 0x00010000 -#define SCR_PROTO_TRACE_RW 0x00020000 -#define SCR_PROTO_TRACE_CE 0x00040000 -#define SCR_PROTO_TRACE_SNEP 0x00080000 -#define SCR_PROTO_TRACE_CHO 0x00100000 -#define SCR_PROTO_TRACE_ALL 0x001fffff -#define SCR_PROTO_TRACE_HCI_LOGGING_VSE 0x0800 /* Brcm vs event for logmsg and protocol traces */ - -#define MAX_SCRIPT_TYPE 5 - -#define TCS_PSM_INTERCOM 5 -#define TCS_PSM_CORDLESS 7 -#define BT_PSM_BNEP 0x000F -/* Define PSMs HID uses */ -#define HID_PSM_CONTROL 0x0011 -#define HID_PSM_INTERRUPT 0x0013 - -/* Define a function for logging */ -typedef void (BT_LOG_FUNC) (int trace_type, const char *fmt_str, ...); - -/* bd addr length and type */ -#ifndef BD_ADDR_LEN -#define BD_ADDR_LEN 6 -typedef uint8_t BD_ADDR[BD_ADDR_LEN]; -#endif - -// From bd.c - -/***************************************************************************** -** Constants -*****************************************************************************/ - -/* global constant for "any" bd addr */ -static const BD_ADDR bd_addr_any = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; -static const BD_ADDR bd_addr_null = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - -/***************************************************************************** -** Functions -*****************************************************************************/ - -/******************************************************************************* -** -** Function bdcpy -** -** Description Copy bd addr b to a. -** -** -** Returns void -** -*******************************************************************************/ -static inline void bdcpy(BD_ADDR a, const BD_ADDR b) -{ - int i; - - for (i = BD_ADDR_LEN; i != 0; i--) { - *a++ = *b++; - } -} - -/******************************************************************************* -** -** Function bdcmp -** -** Description Compare bd addr b to a. -** -** -** Returns Zero if b==a, nonzero otherwise (like memcmp). -** -*******************************************************************************/ -static inline int bdcmp(const BD_ADDR a, const BD_ADDR b) -{ - int i; - - for (i = BD_ADDR_LEN; i != 0; i--) { - if (*a++ != *b++) { - return -1; - } - } - return 0; -} - -/******************************************************************************* -** -** Function bdcmpany -** -** Description Compare bd addr to "any" bd addr. -** -** -** Returns Zero if a equals bd_addr_any. -** -*******************************************************************************/ -static inline int bdcmpany(const BD_ADDR a) -{ - return bdcmp(a, bd_addr_any); -} - -/******************************************************************************* -** -** Function bdsetany -** -** Description Set bd addr to "any" bd addr. -** -** -** Returns void -** -*******************************************************************************/ -static inline void bdsetany(BD_ADDR a) -{ - bdcpy(a, bd_addr_any); -} -#endif diff --git a/tools/sdk/include/bluedroid/stack/btm_api.h b/tools/sdk/include/bluedroid/stack/btm_api.h deleted file mode 100644 index c483268a..00000000 --- a/tools/sdk/include/bluedroid/stack/btm_api.h +++ /dev/null @@ -1,4100 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains the Bluetooth Manager (BTM) API function external - * definitions. - * - ******************************************************************************/ -#ifndef BTM_API_H -#define BTM_API_H - -#include "common/bt_defs.h" -#include "common/bt_target.h" -#include "stack/hcidefs.h" - -#if SDP_INCLUDED == TRUE -#include "stack/sdp_api.h" -#endif - -#if SMP_INCLUDED == TRUE -#include "stack/smp_api.h" -#endif -/***************************************************************************** -** DEVICE CONTROL and COMMON -*****************************************************************************/ -/***************************** -** Device Control Constants -******************************/ -/* Maximum number of bytes allowed for vendor specific command parameters */ -#define BTM_MAX_VENDOR_SPECIFIC_LEN HCI_COMMAND_SIZE - -/* BTM application return status codes */ -enum { - BTM_SUCCESS = 0, /* 0 Command succeeded */ - BTM_CMD_STARTED, /* 1 Command started OK. */ - BTM_BUSY, /* 2 Device busy with another command */ - BTM_NO_RESOURCES, /* 3 No resources to issue command */ - BTM_MODE_UNSUPPORTED, /* 4 Request for 1 or more unsupported modes */ - BTM_ILLEGAL_VALUE, /* 5 Illegal parameter value */ - BTM_WRONG_MODE, /* 6 Device in wrong mode for request */ - BTM_UNKNOWN_ADDR, /* 7 Unknown remote BD address */ - BTM_DEVICE_TIMEOUT, /* 8 Device timeout */ - BTM_BAD_VALUE_RET, /* 9 A bad value was received from HCI */ - BTM_ERR_PROCESSING, /* 10 Generic error */ - BTM_NOT_AUTHORIZED, /* 11 Authorization failed */ - BTM_DEV_RESET, /* 12 Device has been reset */ - BTM_CMD_STORED, /* 13 request is stored in control block */ - BTM_ILLEGAL_ACTION, /* 14 state machine gets illegal command */ - BTM_DELAY_CHECK, /* 15 delay the check on encryption */ - BTM_SCO_BAD_LENGTH, /* 16 Bad SCO over HCI data length */ - BTM_SUCCESS_NO_SECURITY, /* 17 security passed, no security set */ - BTM_FAILED_ON_SECURITY, /* 18 security failed */ - BTM_REPEATED_ATTEMPTS, /* 19 repeated attempts for LE security requests */ - BTM_MODE4_LEVEL4_NOT_SUPPORTED, /* 20 Secure Connections Only Mode can't be supported */ - BTM_PEER_LE_DATA_LEN_UNSUPPORTED, /* 21 peer setting data length is unsupported*/ - BTM_CONTROL_LE_DATA_LEN_UNSUPPORTED,/* 22 controller setting data length is unsupported*/ - BTM_SET_PRIVACY_SUCCESS, /* 23 enable/disable local privacy success */ - BTM_SET_PRIVACY_FAIL, /* 24 enable/disable local privacy failed*/ - BTM_SET_STATIC_RAND_ADDR_FAIL, /* 25 Command failed */ - BTM_INVALID_STATIC_RAND_ADDR, /* 26 invalid static rand addr */ -}; - -typedef uint8_t tBTM_STATUS; - -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) -typedef enum { - BTM_BR_ONE, /*0 First state or BR/EDR scan 1*/ - BTM_BLE_ONE, /*1BLE scan 1*/ - BTM_BR_TWO, /*2 BR/EDR scan 2*/ - BTM_BLE_TWO, /*3 BLE scan 2*/ - BTM_FINISH, /*4 End of Interleave Scan, or normal scan*/ - BTM_NO_INTERLEAVING /*5 No Interleaving*/ -} btm_inq_state; -#endif - - - -/************************* -** Device Control Types -**************************/ -#define BTM_DEVICE_ROLE_BR 0x01 -#define BTM_DEVICE_ROLE_DUAL 0x02 -#define BTM_MAX_DEVICE_ROLE BTM_DEVICE_ROLE_DUAL -typedef UINT8 tBTM_DEVICE_ROLE; - -/* Device name of peer (may be truncated to save space in BTM database) */ -typedef UINT8 tBTM_BD_NAME[BTM_MAX_REM_BD_NAME_LEN + 1]; - -/* Structure returned with local version information */ -typedef struct { - UINT8 hci_version; - UINT16 hci_revision; - UINT8 lmp_version; - UINT16 manufacturer; - UINT16 lmp_subversion; -} tBTM_VERSION_INFO; - -/* Structure returned with Vendor Specific Command complete callback */ -typedef struct { - UINT16 opcode; - UINT16 param_len; - UINT8 *p_param_buf; -} tBTM_VSC_CMPL; - -#define BTM_VSC_CMPL_DATA_SIZE (BTM_MAX_VENDOR_SPECIFIC_LEN + sizeof(tBTM_VSC_CMPL)) -/************************************************** -** Device Control and General Callback Functions -***************************************************/ -/* Callback function for when device status changes. Appl must poll for -** what the new state is (BTM_IsDeviceUp). The event occurs whenever the stack -** has detected that the controller status has changed. This asynchronous event -** is enabled/disabled by calling BTM_RegisterForDeviceStatusNotif(). -*/ -enum { - BTM_DEV_STATUS_UP, - BTM_DEV_STATUS_DOWN, - BTM_DEV_STATUS_CMD_TOUT -}; - -typedef UINT8 tBTM_DEV_STATUS; - -typedef struct { - UINT16 rx_len; - UINT16 tx_len; -}tBTM_LE_SET_PKT_DATA_LENGTH_PARAMS; - -typedef struct { - UINT16 min_conn_int; - UINT16 max_conn_int; - UINT16 conn_int; - UINT16 slave_latency; - UINT16 supervision_tout; -}tBTM_LE_UPDATE_CONN_PRAMS; - -typedef enum{ - BTM_WHITELIST_REMOVE = 0X00, - BTM_WHITELIST_ADD = 0X01, -}tBTM_WL_OPERATION; - - -typedef void (tBTM_DEV_STATUS_CB) (tBTM_DEV_STATUS status); - - -/* Callback function for when a vendor specific event occurs. The length and -** array of returned parameter bytes are included. This asynchronous event -** is enabled/disabled by calling BTM_RegisterForVSEvents(). -*/ -typedef void (tBTM_VS_EVT_CB) (UINT8 len, UINT8 *p); - - -/* General callback function for notifying an application that a synchronous -** BTM function is complete. The pointer contains the address of any returned data. -*/ -typedef void (tBTM_CMPL_CB) (void *p1); - -/* VSC callback function for notifying an application that a synchronous -** BTM function is complete. The pointer contains the address of any returned data. -*/ -typedef void (tBTM_VSC_CMPL_CB) (tBTM_VSC_CMPL *p1); - -/* Callback for apps to check connection and inquiry filters. -** Parameters are the BD Address of remote and the Dev Class of remote. -** If the app returns none zero, the connection or inquiry result will be dropped. -*/ -typedef UINT8 (tBTM_FILTER_CB) (BD_ADDR bd_addr, DEV_CLASS dc); - -typedef void (tBTM_UPDATE_CONN_PARAM_CBACK) (UINT8 status, BD_ADDR bd_addr, tBTM_LE_UPDATE_CONN_PRAMS *update_conn_params); - -typedef void (tBTM_SET_PKT_DATA_LENGTH_CBACK) (UINT8 status, tBTM_LE_SET_PKT_DATA_LENGTH_PARAMS *data_length_params); - -typedef void (tBTM_SET_RAND_ADDR_CBACK) (UINT8 status); - -typedef void (tBTM_ADD_WHITELIST_CBACK) (UINT8 status, tBTM_WL_OPERATION wl_opration); - -typedef void (tBTM_SET_LOCAL_PRIVACY_CBACK) (UINT8 status); - - -/***************************************************************************** -** DEVICE DISCOVERY - Inquiry, Remote Name, Discovery, Class of Device -*****************************************************************************/ -/******************************* -** Device Discovery Constants -********************************/ -/* Discoverable modes */ -#define BTM_NON_DISCOVERABLE 0 -#define BTM_LIMITED_DISCOVERABLE 1 -#define BTM_GENERAL_DISCOVERABLE 2 -#define BTM_DISCOVERABLE_MASK (BTM_LIMITED_DISCOVERABLE|BTM_GENERAL_DISCOVERABLE) -#define BTM_MAX_DISCOVERABLE BTM_GENERAL_DISCOVERABLE -/* high byte for BLE Discoverable modes */ -#define BTM_BLE_NON_DISCOVERABLE 0x0000 -#define BTM_BLE_LIMITED_DISCOVERABLE 0x0100 -#define BTM_BLE_GENERAL_DISCOVERABLE 0x0200 -#define BTM_BLE_MAX_DISCOVERABLE BTM_BLE_GENERAL_DISCOVERABLE -#define BTM_BLE_DISCOVERABLE_MASK (BTM_BLE_NON_DISCOVERABLE|BTM_BLE_LIMITED_DISCOVERABLE|BTM_BLE_GENERAL_DISCOVERABLE) - -/* Connectable modes */ -#define BTM_NON_CONNECTABLE 0 -#define BTM_CONNECTABLE 1 -#define BTM_CONNECTABLE_MASK (BTM_NON_CONNECTABLE | BTM_CONNECTABLE) -/* high byte for BLE Connectable modes */ -#define BTM_BLE_NON_CONNECTABLE 0x0000 -#define BTM_BLE_CONNECTABLE 0x0100 -#define BTM_BLE_MAX_CONNECTABLE BTM_BLE_CONNECTABLE -#define BTM_BLE_CONNECTABLE_MASK (BTM_BLE_NON_CONNECTABLE | BTM_BLE_CONNECTABLE) - -/* Inquiry modes - * Note: These modes are associated with the inquiry active values (BTM_*ACTIVE) */ -#define BTM_INQUIRY_NONE 0 -#define BTM_GENERAL_INQUIRY 0x01 -#define BTM_LIMITED_INQUIRY 0x02 -#define BTM_BR_INQUIRY_MASK (BTM_GENERAL_INQUIRY | BTM_LIMITED_INQUIRY) - -/* high byte of inquiry mode for BLE inquiry mode */ -#define BTM_BLE_INQUIRY_NONE 0x00 -#define BTM_BLE_GENERAL_INQUIRY 0x10 -#define BTM_BLE_LIMITED_INQUIRY 0x20 -#define BTM_BLE_INQUIRY_MASK (BTM_BLE_GENERAL_INQUIRY|BTM_BLE_LIMITED_INQUIRY) - -/* BTM_IsInquiryActive return values (Bit Mask) - * Note: These bit masks are associated with the inquiry modes (BTM_*_INQUIRY) */ -#define BTM_INQUIRY_INACTIVE 0x0 /* no inquiry in progress */ -#define BTM_GENERAL_INQUIRY_ACTIVE BTM_GENERAL_INQUIRY /* a general inquiry is in progress */ -#define BTM_LIMITED_INQUIRY_ACTIVE BTM_LIMITED_INQUIRY /* a limited inquiry is in progress */ -#define BTM_PERIODIC_INQUIRY_ACTIVE 0x8 /* a periodic inquiry is active */ -#define BTM_SSP_INQUIRY_ACTIVE 0x4 /* SSP is active, so inquiry is disallowed (work around for FW bug) */ -#define BTM_LE_GENERAL_INQUIRY_ACTIVE BTM_BLE_GENERAL_INQUIRY /* a general inquiry is in progress */ -#define BTM_LE_LIMITED_INQUIRY_ACTIVE BTM_BLE_LIMITED_INQUIRY /* a limited inquiry is in progress */ - -/* inquiry activity mask */ -#define BTM_BR_INQ_ACTIVE_MASK (BTM_GENERAL_INQUIRY_ACTIVE|BTM_LIMITED_INQUIRY_ACTIVE|BTM_PERIODIC_INQUIRY_ACTIVE) /* BR/EDR inquiry activity mask */ -#define BTM_BLE_SCAN_ACTIVE_MASK 0x01F0 /* LE scan activity mask */ -#define BTM_BLE_INQ_ACTIVE_MASK (BTM_LE_GENERAL_INQUIRY_ACTIVE|BTM_LE_LIMITED_INQUIRY_ACTIVE) /* LE inquiry activity mask*/ -#define BTM_INQUIRY_ACTIVE_MASK (BTM_BR_INQ_ACTIVE_MASK | BTM_BLE_INQ_ACTIVE_MASK) /* inquiry activity mask */ - -/* Define scan types */ -#define BTM_SCAN_TYPE_STANDARD 0 -#define BTM_SCAN_TYPE_INTERLACED 1 /* 1.2 devices only */ - -/* Define inquiry results mode */ -#define BTM_INQ_RESULT_STANDARD 0 -#define BTM_INQ_RESULT_WITH_RSSI 1 -#define BTM_INQ_RESULT_EXTENDED 2 - -#define BTM_INQ_RES_IGNORE_RSSI 0x7f /* RSSI value not supplied (ignore it) */ - -/* Inquiry Filter Condition types (see tBTM_INQ_PARMS) */ -#define BTM_CLR_INQUIRY_FILTER 0 /* Inquiry Filtering is turned off */ -#define BTM_FILTER_COND_DEVICE_CLASS HCI_FILTER_COND_DEVICE_CLASS /* Filter on device class */ -#define BTM_FILTER_COND_BD_ADDR HCI_FILTER_COND_BD_ADDR /* Filter on device addr */ - -/* State of the remote name retrieval during inquiry operations. -** Used in the tBTM_INQ_INFO structure, and returned in the -** BTM_InqDbRead, BTM_InqDbFirst, and BTM_InqDbNext functions. -** The name field is valid when the state returned is -** BTM_INQ_RMT_NAME_DONE */ -#define BTM_INQ_RMT_NAME_EMPTY 0 -#define BTM_INQ_RMT_NAME_PENDING 1 -#define BTM_INQ_RMT_NAME_DONE 2 -#define BTM_INQ_RMT_NAME_FAILED 3 - -/********************************* - *** Class of Device constants *** - *********************************/ -#define BTM_FORMAT_TYPE_1 0x00 - -/**************************** -** minor device class field -*****************************/ - -/* 0x00 is used as unclassified for all minor device classes */ -#define BTM_COD_MINOR_UNCLASSIFIED 0x00 - -/* minor device class field for Computer Major Class */ -/* #define BTM_COD_MINOR_UNCLASSIFIED 0x00 */ -#define BTM_COD_MINOR_DESKTOP_WORKSTATION 0x04 -#define BTM_COD_MINOR_SERVER_COMPUTER 0x08 -#define BTM_COD_MINOR_LAPTOP 0x0C -#define BTM_COD_MINOR_HANDHELD_PC_PDA 0x10 /* clam shell */ -#define BTM_COD_MINOR_PALM_SIZE_PC_PDA 0x14 -#define BTM_COD_MINOR_WEARABLE_COMPUTER 0x18 /* watch sized */ - -/* minor device class field for Phone Major Class */ -/* #define BTM_COD_MINOR_UNCLASSIFIED 0x00 */ -#define BTM_COD_MINOR_CELLULAR 0x04 -#define BTM_COD_MINOR_CORDLESS 0x08 -#define BTM_COD_MINOR_SMART_PHONE 0x0C -#define BTM_COD_MINOR_WIRED_MDM_V_GTWY 0x10 /* wired modem or voice gatway */ -#define BTM_COD_MINOR_ISDN_ACCESS 0x14 - -/* minor device class field for LAN Access Point Major Class */ -/* Load Factor Field bit 5-7 */ -#define BTM_COD_MINOR_FULLY_AVAILABLE 0x00 -#define BTM_COD_MINOR_1_17_UTILIZED 0x20 -#define BTM_COD_MINOR_17_33_UTILIZED 0x40 -#define BTM_COD_MINOR_33_50_UTILIZED 0x60 -#define BTM_COD_MINOR_50_67_UTILIZED 0x80 -#define BTM_COD_MINOR_67_83_UTILIZED 0xA0 -#define BTM_COD_MINOR_83_99_UTILIZED 0xC0 -#define BTM_COD_MINOR_NO_SERVICE_AVAILABLE 0xE0 -/* sub-Field bit 2-4 */ -/* #define BTM_COD_MINOR_UNCLASSIFIED 0x00 */ - -/* minor device class field for Audio/Video Major Class */ -/* #define BTM_COD_MINOR_UNCLASSIFIED 0x00 */ -#define BTM_COD_MINOR_CONFM_HEADSET 0x04 -#define BTM_COD_MINOR_CONFM_HANDSFREE 0x08 -#define BTM_COD_MINOR_MICROPHONE 0x10 -#define BTM_COD_MINOR_LOUDSPEAKER 0x14 -#define BTM_COD_MINOR_HEADPHONES 0x18 -#define BTM_COD_MINOR_PORTABLE_AUDIO 0x1C -#define BTM_COD_MINOR_CAR_AUDIO 0x20 -#define BTM_COD_MINOR_SET_TOP_BOX 0x24 -#define BTM_COD_MINOR_HIFI_AUDIO 0x28 -#define BTM_COD_MINOR_VCR 0x2C -#define BTM_COD_MINOR_VIDEO_CAMERA 0x30 -#define BTM_COD_MINOR_CAMCORDER 0x34 -#define BTM_COD_MINOR_VIDEO_MONITOR 0x38 -#define BTM_COD_MINOR_VIDDISP_LDSPKR 0x3C -#define BTM_COD_MINOR_VIDEO_CONFERENCING 0x40 -#define BTM_COD_MINOR_GAMING_TOY 0x48 - -/* minor device class field for Peripheral Major Class */ -/* Bits 6-7 independently specify mouse, keyboard, or combo mouse/keyboard */ -#define BTM_COD_MINOR_KEYBOARD 0x40 -#define BTM_COD_MINOR_POINTING 0x80 -#define BTM_COD_MINOR_COMBO 0xC0 -/* Bits 2-5 OR'd with selection from bits 6-7 */ -/* #define BTM_COD_MINOR_UNCLASSIFIED 0x00 */ -#define BTM_COD_MINOR_JOYSTICK 0x04 -#define BTM_COD_MINOR_GAMEPAD 0x08 -#define BTM_COD_MINOR_REMOTE_CONTROL 0x0C -#define BTM_COD_MINOR_SENSING_DEVICE 0x10 -#define BTM_COD_MINOR_DIGITIZING_TABLET 0x14 -#define BTM_COD_MINOR_CARD_READER 0x18 /* e.g. SIM card reader */ -#define BTM_COD_MINOR_DIGITAL_PAN 0x1C -#define BTM_COD_MINOR_HAND_SCANNER 0x20 -#define BTM_COD_MINOR_HAND_GESTURAL_INPUT 0x24 - -/* minor device class field for Imaging Major Class */ -/* Bits 5-7 independently specify display, camera, scanner, or printer */ -#define BTM_COD_MINOR_DISPLAY 0x10 -#define BTM_COD_MINOR_CAMERA 0x20 -#define BTM_COD_MINOR_SCANNER 0x40 -#define BTM_COD_MINOR_PRINTER 0x80 -/* Bits 2-3 Reserved */ -/* #define BTM_COD_MINOR_UNCLASSIFIED 0x00 */ - -/* minor device class field for Wearable Major Class */ -/* Bits 2-7 meaningful */ -#define BTM_COD_MINOR_WRIST_WATCH 0x04 -#define BTM_COD_MINOR_PAGER 0x08 -#define BTM_COD_MINOR_JACKET 0x0C -#define BTM_COD_MINOR_HELMET 0x10 -#define BTM_COD_MINOR_GLASSES 0x14 - -/* minor device class field for Toy Major Class */ -/* Bits 2-7 meaningful */ -#define BTM_COD_MINOR_ROBOT 0x04 -#define BTM_COD_MINOR_VEHICLE 0x08 -#define BTM_COD_MINOR_DOLL_ACTION_FIGURE 0x0C -#define BTM_COD_MINOR_CONTROLLER 0x10 -#define BTM_COD_MINOR_GAME 0x14 - -/* minor device class field for Health Major Class */ -/* Bits 2-7 meaningful */ -#define BTM_COD_MINOR_BLOOD_MONITOR 0x04 -#define BTM_COD_MINOR_THERMOMETER 0x08 -#define BTM_COD_MINOR_WEIGHING_SCALE 0x0C -#define BTM_COD_MINOR_GLUCOSE_METER 0x10 -#define BTM_COD_MINOR_PULSE_OXIMETER 0x14 -#define BTM_COD_MINOR_HEART_PULSE_MONITOR 0x18 -#define BTM_COD_MINOR_HEALTH_DATA_DISPLAY 0x1C -#define BTM_COD_MINOR_STEP_COUNTER 0x20 -#define BTM_COD_MINOR_BODY_COM_ANALYZER 0x24 -#define BTM_COD_MINOR_PEAK_FLOW_MONITOR 0x28 -#define BTM_COD_MINOR_MEDICATION_MONITOR 0x2C -#define BTM_COD_MINOR_KNEE_PROSTHESIS 0x30 -#define BTM_COD_MINOR_ANKLE_PROSTHESIS 0x34 - - -/*************************** -** major device class field -****************************/ -#define BTM_COD_MAJOR_MISCELLANEOUS 0x00 -#define BTM_COD_MAJOR_COMPUTER 0x01 -#define BTM_COD_MAJOR_PHONE 0x02 -#define BTM_COD_MAJOR_LAN_ACCESS_PT 0x03 -#define BTM_COD_MAJOR_AUDIO 0x04 -#define BTM_COD_MAJOR_PERIPHERAL 0x05 -#define BTM_COD_MAJOR_IMAGING 0x06 -#define BTM_COD_MAJOR_WEARABLE 0x07 -#define BTM_COD_MAJOR_TOY 0x08 -#define BTM_COD_MAJOR_HEALTH 0x09 -#define BTM_COD_MAJOR_UNCLASSIFIED 0x1F - -/*************************** -** service class fields -****************************/ -#define BTM_COD_SERVICE_LMTD_DISCOVER 0x0020 -#define BTM_COD_SERVICE_POSITIONING 0x0100 -#define BTM_COD_SERVICE_NETWORKING 0x0200 -#define BTM_COD_SERVICE_RENDERING 0x0400 -#define BTM_COD_SERVICE_CAPTURING 0x0800 -#define BTM_COD_SERVICE_OBJ_TRANSFER 0x1000 -#define BTM_COD_SERVICE_AUDIO 0x2000 -#define BTM_COD_SERVICE_TELEPHONY 0x4000 -#define BTM_COD_SERVICE_INFORMATION 0x8000 - -/* class of device field macros */ -#define BTM_COD_FORMAT_TYPE(u8, pd) {u8 = pd[2]&0x03;} -#define BTM_COD_MINOR_CLASS(u8, pd) {u8 = pd[2]&0xFC;} -#define BTM_COD_MAJOR_CLASS(u8, pd) {u8 = pd[1]&0x1F;} -#define BTM_COD_SERVICE_CLASS(u16, pd) {u16 = pd[0]; u16<<=8; u16 += pd[1]&0xE0;} - -/* to set the fields (assumes that format type is always 0) */ -#define FIELDS_TO_COD(pd, mn, mj, sv) {pd[2] = mn; pd[1] = \ - mj+ ((sv)&BTM_COD_SERVICE_CLASS_LO_B); \ - pd[0] = (sv) >> 8;} - -/* the COD masks */ -#define BTM_COD_FORMAT_TYPE_MASK 0x03 -#define BTM_COD_MINOR_CLASS_MASK 0xFC -#define BTM_COD_MAJOR_CLASS_MASK 0x1F -#define BTM_COD_SERVICE_CLASS_LO_B 0x00E0 -#define BTM_COD_SERVICE_CLASS_MASK 0xFFE0 - - -/* BTM service definitions -** Used for storing EIR data to bit mask -*/ -enum { - BTM_EIR_UUID_SERVCLASS_SERVICE_DISCOVERY_SERVER, - /* BTM_EIR_UUID_SERVCLASS_BROWSE_GROUP_DESCRIPTOR, */ - /* BTM_EIR_UUID_SERVCLASS_PUBLIC_BROWSE_GROUP, */ - BTM_EIR_UUID_SERVCLASS_SERIAL_PORT, - BTM_EIR_UUID_SERVCLASS_LAN_ACCESS_USING_PPP, - BTM_EIR_UUID_SERVCLASS_DIALUP_NETWORKING, - BTM_EIR_UUID_SERVCLASS_IRMC_SYNC, - BTM_EIR_UUID_SERVCLASS_OBEX_OBJECT_PUSH, - BTM_EIR_UUID_SERVCLASS_OBEX_FILE_TRANSFER, - BTM_EIR_UUID_SERVCLASS_IRMC_SYNC_COMMAND, - BTM_EIR_UUID_SERVCLASS_HEADSET, - BTM_EIR_UUID_SERVCLASS_CORDLESS_TELEPHONY, - BTM_EIR_UUID_SERVCLASS_AUDIO_SOURCE, - BTM_EIR_UUID_SERVCLASS_AUDIO_SINK, - BTM_EIR_UUID_SERVCLASS_AV_REM_CTRL_TARGET, - /* BTM_EIR_UUID_SERVCLASS_ADV_AUDIO_DISTRIBUTION, */ - BTM_EIR_UUID_SERVCLASS_AV_REMOTE_CONTROL, - /* BTM_EIR_UUID_SERVCLASS_VIDEO_CONFERENCING, */ - BTM_EIR_UUID_SERVCLASS_INTERCOM, - BTM_EIR_UUID_SERVCLASS_FAX, - BTM_EIR_UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, - /* BTM_EIR_UUID_SERVCLASS_WAP, */ - /* BTM_EIR_UUID_SERVCLASS_WAP_CLIENT, */ - BTM_EIR_UUID_SERVCLASS_PANU, - BTM_EIR_UUID_SERVCLASS_NAP, - BTM_EIR_UUID_SERVCLASS_GN, - BTM_EIR_UUID_SERVCLASS_DIRECT_PRINTING, - /* BTM_EIR_UUID_SERVCLASS_REFERENCE_PRINTING, */ - BTM_EIR_UUID_SERVCLASS_IMAGING, - BTM_EIR_UUID_SERVCLASS_IMAGING_RESPONDER, - BTM_EIR_UUID_SERVCLASS_IMAGING_AUTO_ARCHIVE, - BTM_EIR_UUID_SERVCLASS_IMAGING_REF_OBJECTS, - BTM_EIR_UUID_SERVCLASS_HF_HANDSFREE, - BTM_EIR_UUID_SERVCLASS_AG_HANDSFREE, - BTM_EIR_UUID_SERVCLASS_DIR_PRT_REF_OBJ_SERVICE, - /* BTM_EIR_UUID_SERVCLASS_REFLECTED_UI, */ - BTM_EIR_UUID_SERVCLASS_BASIC_PRINTING, - BTM_EIR_UUID_SERVCLASS_PRINTING_STATUS, - BTM_EIR_UUID_SERVCLASS_HUMAN_INTERFACE, - BTM_EIR_UUID_SERVCLASS_CABLE_REPLACEMENT, - BTM_EIR_UUID_SERVCLASS_HCRP_PRINT, - BTM_EIR_UUID_SERVCLASS_HCRP_SCAN, - /* BTM_EIR_UUID_SERVCLASS_COMMON_ISDN_ACCESS, */ - /* BTM_EIR_UUID_SERVCLASS_VIDEO_CONFERENCING_GW, */ - /* BTM_EIR_UUID_SERVCLASS_UDI_MT, */ - /* BTM_EIR_UUID_SERVCLASS_UDI_TA, */ - /* BTM_EIR_UUID_SERVCLASS_VCP, */ - BTM_EIR_UUID_SERVCLASS_SAP, - BTM_EIR_UUID_SERVCLASS_PBAP_PCE, - BTM_EIR_UUID_SERVCLASS_PBAP_PSE, - /* BTM_EIR_UUID_SERVCLASS_TE_PHONE_ACCESS, */ - /* BTM_EIR_UUID_SERVCLASS_ME_PHONE_ACCESS, */ - BTM_EIR_UUID_SERVCLASS_PHONE_ACCESS, - BTM_EIR_UUID_SERVCLASS_HEADSET_HS, - BTM_EIR_UUID_SERVCLASS_PNP_INFORMATION, - /* BTM_EIR_UUID_SERVCLASS_GENERIC_NETWORKING, */ - /* BTM_EIR_UUID_SERVCLASS_GENERIC_FILETRANSFER, */ - /* BTM_EIR_UUID_SERVCLASS_GENERIC_AUDIO, */ - /* BTM_EIR_UUID_SERVCLASS_GENERIC_TELEPHONY, */ - /* BTM_EIR_UUID_SERVCLASS_UPNP_SERVICE, */ - /* BTM_EIR_UUID_SERVCLASS_UPNP_IP_SERVICE, */ - /* BTM_EIR_UUID_SERVCLASS_ESDP_UPNP_IP_PAN, */ - /* BTM_EIR_UUID_SERVCLASS_ESDP_UPNP_IP_LAP, */ - /* BTM_EIR_UUID_SERVCLASS_ESDP_UPNP_IP_L2CAP, */ - BTM_EIR_UUID_SERVCLASS_VIDEO_SOURCE, - BTM_EIR_UUID_SERVCLASS_VIDEO_SINK, - /* BTM_EIR_UUID_SERVCLASS_VIDEO_DISTRIBUTION */ - /* BTM_EIR_UUID_SERVCLASS_HDP_PROFILE */ - BTM_EIR_UUID_SERVCLASS_MESSAGE_ACCESS, - BTM_EIR_UUID_SERVCLASS_MESSAGE_NOTIFICATION, - BTM_EIR_UUID_SERVCLASS_HDP_SOURCE, - BTM_EIR_UUID_SERVCLASS_HDP_SINK, - BTM_EIR_MAX_SERVICES -}; - -/* search result in EIR of inquiry database */ -#define BTM_EIR_FOUND 0 -#define BTM_EIR_NOT_FOUND 1 -#define BTM_EIR_UNKNOWN 2 - -typedef UINT8 tBTM_EIR_SEARCH_RESULT; - -#define BTM_EIR_FLAGS_TYPE HCI_EIR_FLAGS_TYPE /* 0x01 */ -#define BTM_EIR_MORE_16BITS_UUID_TYPE HCI_EIR_MORE_16BITS_UUID_TYPE /* 0x02 */ -#define BTM_EIR_COMPLETE_16BITS_UUID_TYPE HCI_EIR_COMPLETE_16BITS_UUID_TYPE /* 0x03 */ -#define BTM_EIR_MORE_32BITS_UUID_TYPE HCI_EIR_MORE_32BITS_UUID_TYPE /* 0x04 */ -#define BTM_EIR_COMPLETE_32BITS_UUID_TYPE HCI_EIR_COMPLETE_32BITS_UUID_TYPE /* 0x05 */ -#define BTM_EIR_MORE_128BITS_UUID_TYPE HCI_EIR_MORE_128BITS_UUID_TYPE /* 0x06 */ -#define BTM_EIR_COMPLETE_128BITS_UUID_TYPE HCI_EIR_COMPLETE_128BITS_UUID_TYPE /* 0x07 */ -#define BTM_EIR_SHORTENED_LOCAL_NAME_TYPE HCI_EIR_SHORTENED_LOCAL_NAME_TYPE /* 0x08 */ -#define BTM_EIR_COMPLETE_LOCAL_NAME_TYPE HCI_EIR_COMPLETE_LOCAL_NAME_TYPE /* 0x09 */ -#define BTM_EIR_TX_POWER_LEVEL_TYPE HCI_EIR_TX_POWER_LEVEL_TYPE /* 0x0A */ -#define BTM_EIR_MANUFACTURER_SPECIFIC_TYPE HCI_EIR_MANUFACTURER_SPECIFIC_TYPE /* 0xFF */ - -/* the following EIR tags are defined to OOB, not regular EIR data */ -#define BTM_EIR_OOB_BD_ADDR_TYPE HCI_EIR_OOB_BD_ADDR_TYPE /* 6 bytes */ -#define BTM_EIR_OOB_COD_TYPE HCI_EIR_OOB_COD_TYPE /* 3 bytes */ -#define BTM_EIR_OOB_SSP_HASH_C_TYPE HCI_EIR_OOB_SSP_HASH_C_TYPE /* 16 bytes */ -#define BTM_EIR_OOB_SSP_RAND_R_TYPE HCI_EIR_OOB_SSP_RAND_R_TYPE /* 16 bytes */ - -#define BTM_OOB_MANDATORY_SIZE 8 /* include 2 bytes length & 6 bytes bd_addr */ -#define BTM_OOB_DATA_LEN_SIZE 2 -#define BTM_OOB_BD_ADDR_SIZE 6 -#define BTM_OOB_COD_SIZE BT_OOB_COD_SIZE -#define BTM_OOB_HASH_C_SIZE BT_OOB_HASH_C_SIZE -#define BTM_OOB_RAND_R_SIZE BT_OOB_RAND_R_SIZE - - -#if BLE_INCLUDED == TRUE -#define BTM_BLE_SEC_NONE 0 -#define BTM_BLE_SEC_ENCRYPT 1 /* encrypt the link using current key */ -#define BTM_BLE_SEC_ENCRYPT_NO_MITM 2 -#define BTM_BLE_SEC_ENCRYPT_MITM 3 -typedef UINT8 tBTM_BLE_SEC_ACT; -#endif -/************************************************************************************************ -** BTM Services MACROS handle array of UINT32 bits for more than 32 services -*************************************************************************************************/ -/* Determine the number of UINT32's necessary for services */ -#define BTM_EIR_ARRAY_BITS 32 /* Number of bits in each array element */ -#define BTM_EIR_SERVICE_ARRAY_SIZE (((UINT32)BTM_EIR_MAX_SERVICES / BTM_EIR_ARRAY_BITS) + \ - (((UINT32)BTM_EIR_MAX_SERVICES % BTM_EIR_ARRAY_BITS) ? 1 : 0)) - -/* MACRO to set the service bit mask in a bit stream */ -#define BTM_EIR_SET_SERVICE(p, service) (((UINT32 *)(p))[(((UINT32)(service)) / BTM_EIR_ARRAY_BITS)] |= \ - ((UINT32)1 << (((UINT32)(service)) % BTM_EIR_ARRAY_BITS))) - - -/* MACRO to clear the service bit mask in a bit stream */ -#define BTM_EIR_CLR_SERVICE(p, service) (((UINT32 *)(p))[(((UINT32)(service)) / BTM_EIR_ARRAY_BITS)] &= \ - ~((UINT32)1 << (((UINT32)(service)) % BTM_EIR_ARRAY_BITS))) - -/* MACRO to check the service bit mask in a bit stream */ -#define BTM_EIR_HAS_SERVICE(p, service) ((((UINT32 *)(p))[(((UINT32)(service)) / BTM_EIR_ARRAY_BITS)] & \ - ((UINT32)1 << (((UINT32)(service)) % BTM_EIR_ARRAY_BITS))) >> (((UINT32)(service)) % BTM_EIR_ARRAY_BITS)) - -/* start of EIR in HCI buffer, 4 bytes = HCI Command(2) + Length(1) + FEC_Req(1) */ -#define BTM_HCI_EIR_OFFSET (BT_HDR_SIZE + 4) - -/*************************** -** Device Discovery Types -****************************/ -/* Definitions of the parameters passed to BTM_StartInquiry and -** BTM_SetPeriodicInquiryMode. -*/ -typedef struct { /* contains the two device class condition fields */ - DEV_CLASS dev_class; - DEV_CLASS dev_class_mask; -} tBTM_COD_COND; - - -typedef union { /* contains the inquiry filter condition */ - BD_ADDR bdaddr_cond; - tBTM_COD_COND cod_cond; -} tBTM_INQ_FILT_COND; - - -typedef struct { /* contains the parameters passed to the inquiry functions */ - UINT8 mode; /* general or limited */ - UINT8 duration; /* duration of the inquiry (1.28 sec increments) */ - UINT8 max_resps; /* maximum number of responses to return */ - BOOLEAN report_dup; /* report duplicated inquiry response with higher RSSI value */ - UINT8 filter_cond_type; /* new devices, BD ADDR, COD, or No filtering */ - tBTM_INQ_FILT_COND filter_cond; /* filter value based on filter cond type */ -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - UINT8 intl_duration[4]; /*duration array storing the interleave scan's time portions*/ -#endif -} tBTM_INQ_PARMS; - -#define BTM_INQ_RESULT_BR 0x01 -#define BTM_INQ_RESULT_BLE 0x02 - -#if (BLE_INCLUDED == TRUE) -#define BTM_BLE_EVT_CONN_ADV 0x00 -#define BTM_BLE_EVT_CONN_DIR_ADV 0x01 -#define BTM_BLE_EVT_DISC_ADV 0x02 -#define BTM_BLE_EVT_NON_CONN_ADV 0x03 -#define BTM_BLE_EVT_SCAN_RSP 0x04 -typedef UINT8 tBTM_BLE_EVT_TYPE; -#endif - -/* These are the fields returned in each device's response to the inquiry. It -** is returned in the results callback if registered. -*/ -typedef struct { - UINT16 clock_offset; - BD_ADDR remote_bd_addr; - DEV_CLASS dev_class; - UINT8 page_scan_rep_mode; - UINT8 page_scan_per_mode; - UINT8 page_scan_mode; - INT8 rssi; /* Set to BTM_INQ_RES_IGNORE_RSSI if not valid */ - UINT32 eir_uuid[BTM_EIR_SERVICE_ARRAY_SIZE]; - BOOLEAN eir_complete_list; -#if (BLE_INCLUDED == TRUE) - tBT_DEVICE_TYPE device_type; - UINT8 inq_result_type; - UINT8 ble_addr_type; - tBTM_BLE_EVT_TYPE ble_evt_type; - UINT8 flag; - UINT8 adv_data_len; - UINT8 scan_rsp_len; -#endif -} tBTM_INQ_RESULTS; - - -/* This is the inquiry response information held in its database by BTM, and available -** to applications via BTM_InqDbRead, BTM_InqDbFirst, and BTM_InqDbNext. -*/ -typedef struct { - tBTM_INQ_RESULTS results; - - BOOLEAN appl_knows_rem_name; /* set by application if it knows the remote name of the peer device. - This is later used by application to determine if remote name request is - required to be done. Having the flag here avoid duplicate store of inquiry results */ -#if ( BLE_INCLUDED == TRUE) - UINT16 remote_name_len; - tBTM_BD_NAME remote_name; - UINT8 remote_name_state; - UINT8 remote_name_type; -#endif - -} tBTM_INQ_INFO; - - -/* Structure returned with inquiry complete callback */ -typedef struct { - tBTM_STATUS status; - UINT8 num_resp; /* Number of results from the current inquiry */ -} tBTM_INQUIRY_CMPL; - - -/* Structure returned with remote name request */ -typedef struct { - UINT16 status; - BD_ADDR bd_addr; - UINT16 length; - BD_NAME remote_bd_name; -} tBTM_REMOTE_DEV_NAME; - -typedef struct { - UINT8 pcm_intf_rate; /* PCM interface rate: 0: 128kbps, 1: 256 kbps; - 2:512 bps; 3: 1024kbps; 4: 2048kbps */ - UINT8 frame_type; /* frame type: 0: short; 1: long */ - UINT8 sync_mode; /* sync mode: 0: slave; 1: master */ - UINT8 clock_mode; /* clock mode: 0: slave; 1: master */ - -} tBTM_SCO_PCM_PARAM; - -/**************************************** -** Device Discovery Callback Functions -*****************************************/ -/* Callback function for asynchronous notifications when the BTM inquiry DB -** changes. First param is inquiry database, second is if added to or removed -** from the inquiry database. -*/ -typedef void (tBTM_INQ_DB_CHANGE_CB) (void *p1, BOOLEAN is_new); - -/* Callback function for notifications when the BTM gets inquiry response. -** First param is inquiry results database, second is pointer of EIR. -*/ -typedef void (tBTM_INQ_RESULTS_CB) (tBTM_INQ_RESULTS *p_inq_results, UINT8 *p_eir); - -/***************************************************************************** -** ACL CHANNEL MANAGEMENT -*****************************************************************************/ -/****************** -** ACL Constants -*******************/ - -/* ACL modes */ -#define BTM_ACL_MODE_NORMAL HCI_MODE_ACTIVE -#define BTM_ACL_MODE_HOLD HCI_MODE_HOLD -#define BTM_ACL_MODE_SNIFF HCI_MODE_SNIFF -#define BTM_ACL_MODE_PARK HCI_MODE_PARK - -/* Returned with structure in role switch callback (tBTM_ROLE_SWITCH_CMPL) */ -#define BTM_ROLE_MASTER HCI_ROLE_MASTER -#define BTM_ROLE_SLAVE HCI_ROLE_SLAVE -#define BTM_ROLE_UNDEFINED 0xff /* undefined value (error status) */ - -/* ACL Packet Types */ -#define BTM_ACL_PKT_TYPES_MASK_DM1 HCI_PKT_TYPES_MASK_DM1 -#define BTM_ACL_PKT_TYPES_MASK_DH1 HCI_PKT_TYPES_MASK_DH1 -#define BTM_ACL_PKT_TYPES_MASK_DM3 HCI_PKT_TYPES_MASK_DM3 -#define BTM_ACL_PKT_TYPES_MASK_DH3 HCI_PKT_TYPES_MASK_DH3 -#define BTM_ACL_PKT_TYPES_MASK_DM5 HCI_PKT_TYPES_MASK_DM5 -#define BTM_ACL_PKT_TYPES_MASK_DH5 HCI_PKT_TYPES_MASK_DH5 -#define BTM_ACL_PKT_TYPES_MASK_NO_2_DH1 HCI_PKT_TYPES_MASK_NO_2_DH1 -#define BTM_ACL_PKT_TYPES_MASK_NO_3_DH1 HCI_PKT_TYPES_MASK_NO_3_DH1 -#define BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 HCI_PKT_TYPES_MASK_NO_2_DH3 -#define BTM_ACL_PKT_TYPES_MASK_NO_3_DH3 HCI_PKT_TYPES_MASK_NO_3_DH3 -#define BTM_ACL_PKT_TYPES_MASK_NO_2_DH5 HCI_PKT_TYPES_MASK_NO_2_DH5 -#define BTM_ACL_PKT_TYPES_MASK_NO_3_DH5 HCI_PKT_TYPES_MASK_NO_3_DH5 - -/*************** -** ACL Types -****************/ - -/* Structure returned with Role Switch information (in tBTM_CMPL_CB callback function) -** in response to BTM_SwitchRole call. -*/ -typedef struct { - UINT8 hci_status; /* HCI status returned with the event */ - UINT8 role; /* BTM_ROLE_MASTER or BTM_ROLE_SLAVE */ - BD_ADDR remote_bd_addr; /* Remote BD addr involved with the switch */ -} tBTM_ROLE_SWITCH_CMPL; - -/* Structure returned with QoS information (in tBTM_CMPL_CB callback function) -** in response to BTM_SetQoS call. -*/ -typedef struct { - FLOW_SPEC flow; - UINT16 handle; - UINT8 status; -} tBTM_QOS_SETUP_CMPL; - - -/* Structure returned with read RSSI event (in tBTM_CMPL_CB callback function) -** in response to BTM_ReadRSSI call. -*/ -typedef struct { - tBTM_STATUS status; - UINT8 hci_status; - INT8 rssi; - BD_ADDR rem_bda; -} tBTM_RSSI_RESULTS; - -/* Structure returned with read current TX power event (in tBTM_CMPL_CB callback function) -** in response to BTM_ReadTxPower call. -*/ -typedef struct { - tBTM_STATUS status; - UINT8 hci_status; - INT8 tx_power; - BD_ADDR rem_bda; -} tBTM_TX_POWER_RESULTS; - -/* Structure returned with read link quality event (in tBTM_CMPL_CB callback function) -** in response to BTM_ReadLinkQuality call. -*/ -typedef struct { - tBTM_STATUS status; - UINT8 hci_status; - UINT8 link_quality; - BD_ADDR rem_bda; -} tBTM_LINK_QUALITY_RESULTS; - -/* Structure returned with read inq tx power quality event (in tBTM_CMPL_CB callback function) -** in response to BTM_ReadInquiryRspTxPower call. -*/ -typedef struct { - tBTM_STATUS status; - UINT8 hci_status; - INT8 tx_power; -} tBTM_INQ_TXPWR_RESULTS; - -enum { - BTM_BL_CONN_EVT, - BTM_BL_DISCN_EVT, - BTM_BL_UPDATE_EVT, - BTM_BL_ROLE_CHG_EVT, - BTM_BL_COLLISION_EVT -}; -typedef UINT8 tBTM_BL_EVENT; -typedef UINT16 tBTM_BL_EVENT_MASK; - -#define BTM_BL_CONN_MASK 0x0001 -#define BTM_BL_DISCN_MASK 0x0002 -#define BTM_BL_UPDATE_MASK 0x0004 -#define BTM_BL_ROLE_CHG_MASK 0x0008 - -/* Device features mask definitions */ -#define BTM_FEATURE_BYTES_PER_PAGE HCI_FEATURE_BYTES_PER_PAGE -#define BTM_EXT_FEATURES_PAGE_MAX HCI_EXT_FEATURES_PAGE_MAX - -/* the data type associated with BTM_BL_CONN_EVT */ -typedef struct { - tBTM_BL_EVENT event; /* The event reported. */ - BD_ADDR_PTR p_bda; /* The address of the newly connected device */ - DEV_CLASS_PTR p_dc; /* The device class */ - BD_NAME_PTR p_bdn; /* The device name */ - UINT8 *p_features; /* pointer to the remote device's features page[0] (supported features page) */ -#if BLE_INCLUDED == TRUE - UINT16 handle; /* connection handle */ - tBT_TRANSPORT transport; /* link is LE or not */ -#endif -} tBTM_BL_CONN_DATA; - -/* the data type associated with BTM_BL_DISCN_EVT */ -typedef struct { - tBTM_BL_EVENT event; /* The event reported. */ - BD_ADDR_PTR p_bda; /* The address of the disconnected device */ -#if BLE_INCLUDED == TRUE - UINT16 handle; /* disconnected connection handle */ - tBT_TRANSPORT transport; /* link is LE link or not */ -#endif -} tBTM_BL_DISCN_DATA; - -/* Busy-Level shall have the inquiry_paging mask set when - * inquiry/paging is in progress, Else the number of ACL links */ -#define BTM_BL_INQUIRY_PAGING_MASK 0x10 -#define BTM_BL_INQUIRY_STARTED (BTM_BL_INQUIRY_PAGING_MASK | 0x1) -#define BTM_BL_INQUIRY_CANCELLED (BTM_BL_INQUIRY_PAGING_MASK | 0x2) -#define BTM_BL_INQUIRY_COMPLETE (BTM_BL_INQUIRY_PAGING_MASK | 0x3) -#define BTM_BL_PAGING_STARTED (BTM_BL_INQUIRY_PAGING_MASK | 0x4) -#define BTM_BL_PAGING_COMPLETE (BTM_BL_INQUIRY_PAGING_MASK | 0x5) -/* the data type associated with BTM_BL_UPDATE_EVT */ -typedef struct { - tBTM_BL_EVENT event; /* The event reported. */ - UINT8 busy_level;/* when paging or inquiring, level is 10. - * Otherwise, the number of ACL links. */ - UINT8 busy_level_flags; /* Notifies actual inquiry/page activities */ -} tBTM_BL_UPDATE_DATA; - -/* the data type associated with BTM_BL_ROLE_CHG_EVT */ -typedef struct { - tBTM_BL_EVENT event; /* The event reported. */ - BD_ADDR_PTR p_bda; /* The address of the peer connected device */ - UINT8 new_role; - UINT8 hci_status; /* HCI status returned with the event */ -} tBTM_BL_ROLE_CHG_DATA; - -typedef union { - tBTM_BL_EVENT event; /* The event reported. */ - tBTM_BL_CONN_DATA conn; /* The data associated with BTM_BL_CONN_EVT */ - tBTM_BL_DISCN_DATA discn; /* The data associated with BTM_BL_DISCN_EVT */ - tBTM_BL_UPDATE_DATA update; /* The data associated with BTM_BL_UPDATE_EVT */ - tBTM_BL_ROLE_CHG_DATA role_chg;/*The data associated with BTM_BL_ROLE_CHG_EVT */ -} tBTM_BL_EVENT_DATA; - -/* Callback function for notifications when the BTM busy level -** changes. -*/ -typedef void (tBTM_BL_CHANGE_CB) (tBTM_BL_EVENT_DATA *p_data); - -/*************************** -** ACL Callback Functions -****************************/ -/* Callback function for notifications when the BTM ACL connection DB -** changes. First param is BD address, second is if added or removed. -** Registered through BTM_AclRegisterForChanges call. -*/ -#if BLE_INCLUDED == TRUE -typedef void (tBTM_ACL_DB_CHANGE_CB) (BD_ADDR p_bda, DEV_CLASS p_dc, - BD_NAME p_bdn, UINT8 *features, - BOOLEAN is_new, UINT16 handle, - tBT_TRANSPORT transport); -#else -typedef void (tBTM_ACL_DB_CHANGE_CB) (BD_ADDR p_bda, DEV_CLASS p_dc, - BD_NAME p_bdn, UINT8 *features, - BOOLEAN is_new); -#endif -/***************************************************************************** -** SCO CHANNEL MANAGEMENT -*****************************************************************************/ -/****************** -** SCO Constants -*******************/ - -/* Define an invalid SCO index and an invalid HCI handle */ -#define BTM_INVALID_SCO_INDEX 0xFFFF -#define BTM_INVALID_HCI_HANDLE 0xFFFF - -/* Define an invalid SCO disconnect reason */ -#define BTM_INVALID_SCO_DISC_REASON 0xFFFF - -/* Define first active SCO index */ -#define BTM_FIRST_ACTIVE_SCO_INDEX BTM_MAX_SCO_LINKS - -/* Define SCO packet types used in APIs */ -#define BTM_SCO_PKT_TYPES_MASK_HV1 HCI_ESCO_PKT_TYPES_MASK_HV1 -#define BTM_SCO_PKT_TYPES_MASK_HV2 HCI_ESCO_PKT_TYPES_MASK_HV2 -#define BTM_SCO_PKT_TYPES_MASK_HV3 HCI_ESCO_PKT_TYPES_MASK_HV3 -#define BTM_SCO_PKT_TYPES_MASK_EV3 HCI_ESCO_PKT_TYPES_MASK_EV3 -#define BTM_SCO_PKT_TYPES_MASK_EV4 HCI_ESCO_PKT_TYPES_MASK_EV4 -#define BTM_SCO_PKT_TYPES_MASK_EV5 HCI_ESCO_PKT_TYPES_MASK_EV5 -#define BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 HCI_ESCO_PKT_TYPES_MASK_NO_2_EV3 -#define BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 HCI_ESCO_PKT_TYPES_MASK_NO_3_EV3 -#define BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 HCI_ESCO_PKT_TYPES_MASK_NO_2_EV5 -#define BTM_SCO_PKT_TYPES_MASK_NO_3_EV5 HCI_ESCO_PKT_TYPES_MASK_NO_3_EV5 - -#define BTM_SCO_LINK_ONLY_MASK (BTM_SCO_PKT_TYPES_MASK_HV1 | \ - BTM_SCO_PKT_TYPES_MASK_HV2 | \ - BTM_SCO_PKT_TYPES_MASK_HV3) - -#define BTM_ESCO_LINK_ONLY_MASK (BTM_SCO_PKT_TYPES_MASK_EV3 | \ - BTM_SCO_PKT_TYPES_MASK_EV4 | \ - BTM_SCO_PKT_TYPES_MASK_EV5) - -#define BTM_SCO_LINK_ALL_PKT_MASK (BTM_SCO_LINK_ONLY_MASK | \ - BTM_ESCO_LINK_ONLY_MASK) - -#define BTM_VALID_SCO_ALL_PKT_TYPE HCI_VALID_SCO_ALL_PKT_TYPE - -/* Passed in BTM_CreateSco if the packet type parameter should be ignored */ -#define BTM_IGNORE_SCO_PKT_TYPE 0 - -/*************** -** SCO Types -****************/ -#define BTM_LINK_TYPE_SCO HCI_LINK_TYPE_SCO -#define BTM_LINK_TYPE_ESCO HCI_LINK_TYPE_ESCO -typedef UINT8 tBTM_SCO_TYPE; - - -/******************* -** SCO Routing Path -********************/ -#define BTM_SCO_ROUTE_PCM (0) // HCI_BRCM_SCO_ROUTE_PCM -#define BTM_SCO_ROUTE_HCI (1) // HCI_BRCM_SCO_ROUTE_HCI -typedef UINT8 tBTM_SCO_ROUTE_TYPE; - - -/******************* -** SCO Codec Types -********************/ -// TODO(google) This should use common definitions -// in hci/include/hci_audio.h -#define BTM_SCO_CODEC_NONE 0x0000 -#define BTM_SCO_CODEC_CVSD 0x0001 -#define BTM_SCO_CODEC_MSBC 0x0002 -typedef UINT16 tBTM_SCO_CODEC_TYPE; - - - -/******************* -** SCO Air Mode Types -********************/ -#define BTM_SCO_AIR_MODE_U_LAW 0 -#define BTM_SCO_AIR_MODE_A_LAW 1 -#define BTM_SCO_AIR_MODE_CVSD 2 -#define BTM_SCO_AIR_MODE_TRANSPNT 3 -typedef UINT8 tBTM_SCO_AIR_MODE_TYPE; - -/******************* -** SCO Voice Settings -********************/ -#define BTM_VOICE_SETTING_CVSD ((UINT16) (HCI_INP_CODING_LINEAR | \ - HCI_INP_DATA_FMT_2S_COMPLEMENT | \ - HCI_INP_SAMPLE_SIZE_16BIT | \ - HCI_AIR_CODING_FORMAT_CVSD)) - -#define BTM_VOICE_SETTING_TRANS ((UINT16) (HCI_INP_CODING_LINEAR | \ - HCI_INP_DATA_FMT_2S_COMPLEMENT | \ - HCI_INP_SAMPLE_SIZE_16BIT | \ - HCI_AIR_CODING_FORMAT_TRANSPNT)) - -/******************* -** SCO Data Status -********************/ -enum { - BTM_SCO_DATA_CORRECT, - BTM_SCO_DATA_PAR_ERR, - BTM_SCO_DATA_NONE, - BTM_SCO_DATA_PAR_LOST -}; -typedef UINT8 tBTM_SCO_DATA_FLAG; - -/*************************** -** SCO Callback Functions -****************************/ -typedef void (tBTM_SCO_CB) (UINT16 sco_inx); -typedef void (tBTM_SCO_DATA_CB) (UINT16 sco_inx, BT_HDR *p_data, tBTM_SCO_DATA_FLAG status); - -/****************** -** eSCO Constants -*******************/ -#define BTM_64KBITS_RATE 0x00001f40 /* 64 kbits/sec data rate */ - -/* Retransmission effort */ -#define BTM_ESCO_RETRANS_OFF 0 -#define BTM_ESCO_RETRANS_POWER 1 -#define BTM_ESCO_RETRANS_QUALITY 2 -#define BTM_ESCO_RETRANS_DONTCARE 0xff - -/* Max Latency Don't Care */ -#define BTM_ESCO_MAX_LAT_DONTCARE 0xffff - -/*************** -** eSCO Types -****************/ -/* tBTM_ESCO_CBACK event types */ -#define BTM_ESCO_CHG_EVT 1 -#define BTM_ESCO_CONN_REQ_EVT 2 -typedef UINT8 tBTM_ESCO_EVT; - -/* Passed into BTM_SetEScoMode() */ -typedef struct { - UINT32 tx_bw; - UINT32 rx_bw; - UINT16 max_latency; - UINT16 voice_contfmt; /* Voice Settings or Content Format */ - UINT16 packet_types; - UINT8 retrans_effort; -} tBTM_ESCO_PARAMS; - -typedef struct { - UINT16 max_latency; - UINT16 packet_types; - UINT8 retrans_effort; -} tBTM_CHG_ESCO_PARAMS; - -/* Returned by BTM_ReadEScoLinkParms() */ -typedef struct { - UINT16 rx_pkt_len; - UINT16 tx_pkt_len; - BD_ADDR bd_addr; - UINT8 link_type; /* BTM_LINK_TYPE_SCO or BTM_LINK_TYPE_ESCO */ - UINT8 tx_interval; - UINT8 retrans_window; - UINT8 air_mode; -} tBTM_ESCO_DATA; - -typedef struct { - UINT16 sco_inx; - UINT16 rx_pkt_len; - UINT16 tx_pkt_len; - BD_ADDR bd_addr; - UINT8 hci_status; - UINT8 tx_interval; - UINT8 retrans_window; -} tBTM_CHG_ESCO_EVT_DATA; - -typedef struct { - UINT16 sco_inx; - BD_ADDR bd_addr; - DEV_CLASS dev_class; - tBTM_SCO_TYPE link_type; -} tBTM_ESCO_CONN_REQ_EVT_DATA; - -typedef union { - tBTM_CHG_ESCO_EVT_DATA chg_evt; - tBTM_ESCO_CONN_REQ_EVT_DATA conn_evt; -} tBTM_ESCO_EVT_DATA; - -/*************************** -** eSCO Callback Functions -****************************/ -typedef void (tBTM_ESCO_CBACK) (tBTM_ESCO_EVT event, tBTM_ESCO_EVT_DATA *p_data); - - -/***************************************************************************** -** SECURITY MANAGEMENT -*****************************************************************************/ -/******************************* -** Security Manager Constants -********************************/ - -/* Security Mode (BTM_SetSecurityMode) */ -#define BTM_SEC_MODE_UNDEFINED 0 -#define BTM_SEC_MODE_NONE 1 -#define BTM_SEC_MODE_SERVICE 2 -#define BTM_SEC_MODE_LINK 3 -#define BTM_SEC_MODE_SP 4 -#define BTM_SEC_MODE_SP_DEBUG 5 -#define BTM_SEC_MODE_SC 6 - -/* Maximum Number of BTM Security Modes */ -#define BTM_SEC_MODES_MAX 7 - -/* Security Service Levels [bit mask] (BTM_SetSecurityLevel) -** Encryption should not be used without authentication -*/ -#define BTM_SEC_NONE 0x0000 /* Nothing required */ -#define BTM_SEC_IN_AUTHORIZE 0x0001 /* Inbound call requires authorization */ -#define BTM_SEC_IN_AUTHENTICATE 0x0002 /* Inbound call requires authentication */ -#define BTM_SEC_IN_ENCRYPT 0x0004 /* Inbound call requires encryption */ -#define BTM_SEC_OUT_AUTHORIZE 0x0008 /* Outbound call requires authorization */ -#define BTM_SEC_OUT_AUTHENTICATE 0x0010 /* Outbound call requires authentication */ -#define BTM_SEC_OUT_ENCRYPT 0x0020 /* Outbound call requires encryption */ -#define BTM_SEC_MODE4_LEVEL4 0x0040 /* Secure Connections Only Mode */ -#define BTM_SEC_FORCE_MASTER 0x0100 /* Need to switch connection to be master */ -#define BTM_SEC_ATTEMPT_MASTER 0x0200 /* Try to switch connection to be master */ -#define BTM_SEC_FORCE_SLAVE 0x0400 /* Need to switch connection to be master */ -#define BTM_SEC_ATTEMPT_SLAVE 0x0800 /* Try to switch connection to be slave */ -#define BTM_SEC_IN_MITM 0x1000 /* inbound Do man in the middle protection */ -#define BTM_SEC_OUT_MITM 0x2000 /* outbound Do man in the middle protection */ -#define BTM_SEC_IN_MIN_16_DIGIT_PIN 0x4000 /* enforce a minimum of 16 digit for sec mode 2 */ - -/* Security Flags [bit mask] (BTM_GetSecurityFlags) -*/ -#define BTM_SEC_FLAG_AUTHORIZED 0x01 -#define BTM_SEC_FLAG_AUTHENTICATED 0x02 -#define BTM_SEC_FLAG_ENCRYPTED 0x04 -#define BTM_SEC_FLAG_LKEY_KNOWN 0x10 -#define BTM_SEC_FLAG_LKEY_AUTHED 0x20 - -/* PIN types */ -#define BTM_PIN_TYPE_VARIABLE HCI_PIN_TYPE_VARIABLE -#define BTM_PIN_TYPE_FIXED HCI_PIN_TYPE_FIXED - -/* Link Key types used to generate the new link key. -** returned in link key notification callback function -*/ -#define BTM_LKEY_TYPE_COMBINATION HCI_LKEY_TYPE_COMBINATION -#define BTM_LKEY_TYPE_LOCAL_UNIT HCI_LKEY_TYPE_LOCAL_UNIT -#define BTM_LKEY_TYPE_REMOTE_UNIT HCI_LKEY_TYPE_REMOTE_UNIT -#define BTM_LKEY_TYPE_DEBUG_COMB HCI_LKEY_TYPE_DEBUG_COMB -#define BTM_LKEY_TYPE_UNAUTH_COMB HCI_LKEY_TYPE_UNAUTH_COMB -#define BTM_LKEY_TYPE_AUTH_COMB HCI_LKEY_TYPE_AUTH_COMB -#define BTM_LKEY_TYPE_CHANGED_COMB HCI_LKEY_TYPE_CHANGED_COMB - -#define BTM_LKEY_TYPE_UNAUTH_COMB_P_256 HCI_LKEY_TYPE_UNAUTH_COMB_P_256 -#define BTM_LKEY_TYPE_AUTH_COMB_P_256 HCI_LKEY_TYPE_AUTH_COMB_P_256 - -#define BTM_LTK_DERIVED_LKEY_OFFSET 0x20 /* "easy" requirements for LK derived from LTK */ -#define BTM_LKEY_TYPE_IGNORE 0xff /* used when event is response from - hci return link keys request */ - -typedef UINT8 tBTM_LINK_KEY_TYPE; - -/* Protocol level security (BTM_SetSecurityLevel) */ -#define BTM_SEC_PROTO_L2CAP 0 -#define BTM_SEC_PROTO_SDP 1 -#define BTM_SEC_PROTO_TCS 2 -#define BTM_SEC_PROTO_RFCOMM 3 -#define BTM_SEC_PROTO_OBEX 4 -#define BTM_SEC_PROTO_BNEP 5 -#define BTM_SEC_PROTO_HID 6 /* HID */ -#define BTM_SEC_PROTO_AVDT 7 -#define BTM_SEC_PROTO_MCA 8 - -/* Determine the number of UINT32's necessary for security services */ -#define BTM_SEC_ARRAY_BITS 32 /* Number of bits in each array element */ -#define BTM_SEC_SERVICE_ARRAY_SIZE (((UINT32)BTM_SEC_MAX_SERVICES / BTM_SEC_ARRAY_BITS) + \ - (((UINT32)BTM_SEC_MAX_SERVICES % BTM_SEC_ARRAY_BITS) ? 1 : 0)) - -/* Security service definitions (BTM_SetSecurityLevel) -** Used for Authorization APIs -*/ -#define BTM_SEC_SERVICE_SDP_SERVER 0 -#define BTM_SEC_SERVICE_SERIAL_PORT 1 -#define BTM_SEC_SERVICE_LAN_ACCESS 2 -#define BTM_SEC_SERVICE_DUN 3 -#define BTM_SEC_SERVICE_IRMC_SYNC 4 -#define BTM_SEC_SERVICE_IRMC_SYNC_CMD 5 -#define BTM_SEC_SERVICE_OBEX 6 -#define BTM_SEC_SERVICE_OBEX_FTP 7 -#define BTM_SEC_SERVICE_HEADSET 8 -#define BTM_SEC_SERVICE_CORDLESS 9 -#define BTM_SEC_SERVICE_INTERCOM 10 -#define BTM_SEC_SERVICE_FAX 11 -#define BTM_SEC_SERVICE_HEADSET_AG 12 -#define BTM_SEC_SERVICE_PNP_INFO 13 -#define BTM_SEC_SERVICE_GEN_NET 14 -#define BTM_SEC_SERVICE_GEN_FILE 15 -#define BTM_SEC_SERVICE_GEN_AUDIO 16 -#define BTM_SEC_SERVICE_GEN_TEL 17 -#define BTM_SEC_SERVICE_CTP_DATA 18 -#define BTM_SEC_SERVICE_HCRP_CTRL 19 -#define BTM_SEC_SERVICE_HCRP_DATA 20 -#define BTM_SEC_SERVICE_HCRP_NOTIF 21 -#define BTM_SEC_SERVICE_BPP_JOB 22 -#define BTM_SEC_SERVICE_BPP_STATUS 23 -#define BTM_SEC_SERVICE_BPP_REF 24 -#define BTM_SEC_SERVICE_BNEP_PANU 25 -#define BTM_SEC_SERVICE_BNEP_GN 26 -#define BTM_SEC_SERVICE_BNEP_NAP 27 -#define BTM_SEC_SERVICE_HF_HANDSFREE 28 -#define BTM_SEC_SERVICE_AG_HANDSFREE 29 -#define BTM_SEC_SERVICE_TE_PHONE_ACCESS 30 -#define BTM_SEC_SERVICE_ME_PHONE_ACCESS 31 - -#define BTM_SEC_SERVICE_HIDH_SEC_CTRL 32 -#define BTM_SEC_SERVICE_HIDH_NOSEC_CTRL 33 -#define BTM_SEC_SERVICE_HIDH_INTR 34 -#define BTM_SEC_SERVICE_BIP 35 -#define BTM_SEC_SERVICE_BIP_REF 36 -#define BTM_SEC_SERVICE_AVDTP 37 -#define BTM_SEC_SERVICE_AVDTP_NOSEC 38 -#define BTM_SEC_SERVICE_AVCTP 39 -#define BTM_SEC_SERVICE_SAP 40 -#define BTM_SEC_SERVICE_PBAP 41 -#define BTM_SEC_SERVICE_RFC_MUX 42 -#define BTM_SEC_SERVICE_AVCTP_BROWSE 43 -#define BTM_SEC_SERVICE_MAP 44 -#define BTM_SEC_SERVICE_MAP_NOTIF 45 -#define BTM_SEC_SERVICE_MCAP_CTRL 46 -#define BTM_SEC_SERVICE_MCAP_DATA 47 -#define BTM_SEC_SERVICE_HDP_SNK 48 -#define BTM_SEC_SERVICE_HDP_SRC 49 -#define BTM_SEC_SERVICE_ATT 50 - -/* Update these as services are added */ -#define BTM_SEC_SERVICE_FIRST_EMPTY 51 - -#ifndef BTM_SEC_MAX_SERVICES -#define BTM_SEC_MAX_SERVICES 65 -#endif - -/************************************************************************************************ -** Security Services MACROS handle array of UINT32 bits for more than 32 trusted services -*************************************************************************************************/ -/* MACRO to set the security service bit mask in a bit stream */ -#define BTM_SEC_SET_SERVICE(p, service) (((UINT32 *)(p))[(((UINT32)(service)) / BTM_SEC_ARRAY_BITS)] |= \ - ((UINT32)1 << (((UINT32)(service)) % BTM_SEC_ARRAY_BITS))) - - -/* MACRO to clear the security service bit mask in a bit stream */ -#define BTM_SEC_CLR_SERVICE(p, service) (((UINT32 *)(p))[(((UINT32)(service)) / BTM_SEC_ARRAY_BITS)] &= \ - ~((UINT32)1 << (((UINT32)(service)) % BTM_SEC_ARRAY_BITS))) - -/* MACRO to check the security service bit mask in a bit stream (Returns TRUE or FALSE) */ -#define BTM_SEC_IS_SERVICE_TRUSTED(p, service) (((((UINT32 *)(p))[(((UINT32)(service)) / BTM_SEC_ARRAY_BITS)]) & \ - (UINT32)(((UINT32)1 << (((UINT32)(service)) % BTM_SEC_ARRAY_BITS)))) ? TRUE : FALSE) - -/* MACRO to copy two trusted device bitmask */ -#define BTM_SEC_COPY_TRUSTED_DEVICE(p_src, p_dst) {UINT32 trst; for (trst = 0; trst < BTM_SEC_SERVICE_ARRAY_SIZE; trst++) \ - ((UINT32 *)(p_dst))[trst] = ((UINT32 *)(p_src))[trst];} - -/* MACRO to clear two trusted device bitmask */ -#define BTM_SEC_CLR_TRUSTED_DEVICE(p_dst) {UINT32 trst; for (trst = 0; trst < BTM_SEC_SERVICE_ARRAY_SIZE; trst++) \ - ((UINT32 *)(p_dst))[trst] = 0;} - -/* Following bits can be provided by host in the trusted_mask array */ -/* 0..31 bits of mask[0] (Least Significant Word) */ -#define BTM_SEC_TRUST_SDP_SERVER (1 << BTM_SEC_SERVICE_SDP_SERVER) -#define BTM_SEC_TRUST_SERIAL_PORT (1 << BTM_SEC_SERVICE_SERIAL_PORT) -#define BTM_SEC_TRUST_LAN_ACCESS (1 << BTM_SEC_SERVICE_LAN_ACCESS) -#define BTM_SEC_TRUST_DUN (1 << BTM_SEC_SERVICE_DUN) -#define BTM_SEC_TRUST_IRMC_SYNC (1 << BTM_SEC_SERVICE_IRMC_SYNC) -#define BTM_SEC_TRUST_IRMC_SYNC_CMD (1 << BTM_SEC_SERVICE_IRMC_SYNC_CMD) -#define BTM_SEC_TRUST_OBEX (1 << BTM_SEC_SERVICE_OBEX) -#define BTM_SEC_TRUST_OBEX_FTP (1 << BTM_SEC_SERVICE_OBEX_FTP) -#define BTM_SEC_TRUST_HEADSET (1 << BTM_SEC_SERVICE_HEADSET) -#define BTM_SEC_TRUST_CORDLESS (1 << BTM_SEC_SERVICE_CORDLESS) -#define BTM_SEC_TRUST_INTERCOM (1 << BTM_SEC_SERVICE_INTERCOM) -#define BTM_SEC_TRUST_FAX (1 << BTM_SEC_SERVICE_FAX) -#define BTM_SEC_TRUST_HEADSET_AG (1 << BTM_SEC_SERVICE_HEADSET_AG) -#define BTM_SEC_TRUST_PNP_INFO (1 << BTM_SEC_SERVICE_PNP_INFO) -#define BTM_SEC_TRUST_GEN_NET (1 << BTM_SEC_SERVICE_GEN_NET) -#define BTM_SEC_TRUST_GEN_FILE (1 << BTM_SEC_SERVICE_GEN_FILE) -#define BTM_SEC_TRUST_GEN_AUDIO (1 << BTM_SEC_SERVICE_GEN_AUDIO) -#define BTM_SEC_TRUST_GEN_TEL (1 << BTM_SEC_SERVICE_GEN_TEL) -#define BTM_SEC_TRUST_CTP_DATA (1 << BTM_SEC_SERVICE_CTP_DATA) -#define BTM_SEC_TRUST_HCRP_CTRL (1 << BTM_SEC_SERVICE_HCRP_CTRL) -#define BTM_SEC_TRUST_HCRP_DATA (1 << BTM_SEC_SERVICE_HCRP_DATA) -#define BTM_SEC_TRUST_HCRP_NOTIF (1 << BTM_SEC_SERVICE_HCRP_NOTIF) -#define BTM_SEC_TRUST_BPP_JOB (1 << BTM_SEC_SERVICE_JOB) -#define BTM_SEC_TRUST_BPP_STATUS (1 << BTM_SEC_SERVICE_STATUS) -#define BTM_SEC_TRUST_BPP_REF (1 << BTM_SEC_SERVICE_REF) -#define BTM_SEC_TRUST_BNEP_PANU (1 << BTM_SEC_SERVICE_BNEP_PANU) -#define BTM_SEC_TRUST_BNEP_GN (1 << BTM_SEC_SERVICE_BNEP_GN) -#define BTM_SEC_TRUST_BNEP_NAP (1 << BTM_SEC_SERVICE_BNEP_NAP) -#define BTM_SEC_TRUST_HFP_HF (1 << BTM_SEC_SERVICE_HF_HANDSFREE) -#define BTM_SEC_TRUST_HFP_AG (1 << BTM_SEC_SERVICE_AG_HANDSFREE) -#define BTM_SEC_TRUST_TE_PHONE_ACCESS (1 << BTM_SEC_SERVICE_TE_PHONE_ACCESS) -#define BTM_SEC_TRUST_ME_PHONE_ACCESS (1 << BTM_SEC_SERVICE_ME_PHONE_ACCESS) - -/* 0..31 bits of mask[1] (Most Significant Word) */ -#define BTM_SEC_TRUST_HIDH_CTRL (1 << (BTM_SEC_SERVICE_HIDH_SEC_CTRL - 32)) -#define BTM_SEC_TRUST_HIDH_NOSEC_CTRL (1 << (BTM_SEC_SERVICE_HIDH_NOSEC_CTRL - 32)) -#define BTM_SEC_TRUST_HIDH_INTR (1 << (BTM_SEC_SERVICE_HIDH_INTR - 32)) -#define BTM_SEC_TRUST_BIP (1 << (BTM_SEC_SERVICE_BIP - 32)) -#define BTM_SEC_TRUST_BIP_REF (1 << (BTM_SEC_SERVICE_BIP_REF - 32)) -#define BTM_SEC_TRUST_AVDTP (1 << (BTM_SEC_SERVICE_AVDTP - 32)) -#define BTM_SEC_TRUST_AVDTP_NOSEC (1 << (BTM_SEC_SERVICE_AVDTP_NOSEC - 32)) -#define BTM_SEC_TRUST_AVCTP (1 << (BTM_SEC_SERVICE_AVCTP - 32)) -#define BTM_SEC_TRUST_SAP (1 << (BTM_SEC_SERVICE_SAP - 32)) -#define BTM_SEC_TRUST_PBAP (1 << (BTM_SEC_SERVICE_PBAP - 32)) -#define BTM_SEC_TRUST_RFC_MUX (1 << (BTM_SEC_SERVICE_RFC_MUX - 32)) -#define BTM_SEC_TRUST_AVCTP_BROWSE (1 << (BTM_SEC_SERVICE_AVCTP_BROWSE - 32)) -#define BTM_SEC_TRUST_MAP (1 << (BTM_SEC_SERVICE_MAP - 32)) -#define BTM_SEC_TRUST_MAP_NOTIF (1 << (BTM_SEC_SERVICE_MAP_NOTIF - 32)) -#define BTM_SEC_TRUST_MCAP_CTRL (1 << (BTM_SEC_SERVICE_MCAP_CTRL - 32)) -#define BTM_SEC_TRUST_MCAP_DATA (1 << (BTM_SEC_SERVICE_MCAP_DATA - 32)) -#define BTM_SEC_TRUST_HDP_SNK (1 << (BTM_SEC_SERVICE_HDP_SNK - 32)) -#define BTM_SEC_TRUST_HDP_SRC (1 << (BTM_SEC_SERVICE_HDP_SRC - 32)) - -#define BTM_SEC_TRUST_ALL 0xFFFFFFFF /* for each array element */ - -/**************************************** -** Security Manager Callback Functions -*****************************************/ -/* Authorize device for service. Parameters are -** BD Address of remote -** Device Class of remote -** BD Name of remote -** Service name -** Service Id (NULL - unknown service or unused -** [BTM_SEC_SERVICE_NAME_LEN set to 0]) -** Is originator of the connection -** Result of the operation -*/ -typedef UINT8 (tBTM_AUTHORIZE_CALLBACK) (BD_ADDR bd_addr, DEV_CLASS dev_class, - tBTM_BD_NAME bd_name, UINT8 *service_name, - UINT8 service_id, BOOLEAN is_originator); - -/* Get PIN for the connection. Parameters are -** BD Address of remote -** Device Class of remote -** BD Name of remote -** Flag indicating the minimum pin code length to be 16 digits -*/ -typedef UINT8 (tBTM_PIN_CALLBACK) (BD_ADDR bd_addr, DEV_CLASS dev_class, - tBTM_BD_NAME bd_name, BOOLEAN min_16_digit); - -/* New Link Key for the connection. Parameters are -** BD Address of remote -** Link Key -** Key Type: Combination, Local Unit, or Remote Unit -*/ -typedef UINT8 (tBTM_LINK_KEY_CALLBACK) (BD_ADDR bd_addr, DEV_CLASS dev_class, - tBTM_BD_NAME bd_name, UINT8 *key, - UINT8 key_type); - - -/* Remote Name Resolved. Parameters are -** BD Address of remote -** BD Name of remote -*/ -typedef void (tBTM_RMT_NAME_CALLBACK) (BD_ADDR bd_addr, DEV_CLASS dc, - tBTM_BD_NAME bd_name); - - -/* Authentication complete for the connection. Parameters are -** BD Address of remote -** Device Class of remote -** BD Name of remote -** -*/ -typedef UINT8 (tBTM_AUTH_COMPLETE_CALLBACK) (BD_ADDR bd_addr, DEV_CLASS dev_class, - tBTM_BD_NAME bd_name, int result); - -enum { - BTM_SP_IO_REQ_EVT, /* received IO_CAPABILITY_REQUEST event */ - BTM_SP_IO_RSP_EVT, /* received IO_CAPABILITY_RESPONSE event */ - BTM_SP_CFM_REQ_EVT, /* received USER_CONFIRMATION_REQUEST event */ - BTM_SP_KEY_NOTIF_EVT, /* received USER_PASSKEY_NOTIFY event */ - BTM_SP_KEY_REQ_EVT, /* received USER_PASSKEY_REQUEST event */ - BTM_SP_KEYPRESS_EVT, /* received KEYPRESS_NOTIFY event */ - BTM_SP_LOC_OOB_EVT, /* received result for READ_LOCAL_OOB_DATA command */ - BTM_SP_RMT_OOB_EVT, /* received REMOTE_OOB_DATA_REQUEST event */ - BTM_SP_COMPLT_EVT, /* received SIMPLE_PAIRING_COMPLETE event */ - BTM_SP_UPGRADE_EVT /* check if the application wants to upgrade the link key */ -}; -typedef UINT8 tBTM_SP_EVT; - -/* relate to ESP_IO_CAP_xxx in esp_gap_ble_api.h */ -#define BTM_IO_CAP_OUT 0 /* DisplayOnly */ -#define BTM_IO_CAP_IO 1 /* DisplayYesNo */ -#define BTM_IO_CAP_IN 2 /* KeyboardOnly */ -#define BTM_IO_CAP_NONE 3 /* NoInputNoOutput */ -#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE -#define BTM_IO_CAP_KBDISP 4 /* Keyboard display */ -#define BTM_IO_CAP_MAX 5 -#else -#define BTM_IO_CAP_MAX 4 -#endif - -typedef UINT8 tBTM_IO_CAP; - -#define BTM_MAX_PASSKEY_VAL (999999) -#define BTM_MIN_PASSKEY_VAL (0) - -#define BTM_AUTH_SP_NO 0 /* MITM Protection Not Required - Single Profile/non-bonding - Numeric comparison with automatic accept allowed */ -#define BTM_AUTH_SP_YES 1 /* MITM Protection Required - Single Profile/non-bonding - Use IO Capabilities to determine authentication procedure */ -#define BTM_AUTH_AP_NO 2 /* MITM Protection Not Required - All Profiles/dedicated bonding - Numeric comparison with automatic accept allowed */ -#define BTM_AUTH_AP_YES 3 /* MITM Protection Required - All Profiles/dedicated bonding - Use IO Capabilities to determine authentication procedure */ -#define BTM_AUTH_SPGB_NO 4 /* MITM Protection Not Required - Single Profiles/general bonding - Numeric comparison with automatic accept allowed */ -#define BTM_AUTH_SPGB_YES 5 /* MITM Protection Required - Single Profiles/general bonding - Use IO Capabilities to determine authentication procedure */ -#define BTM_AUTH_DD_BOND 2 /* this bit is ORed to the BTM_AUTH_SP_* when IO exchange for dedicated bonding */ -#define BTM_AUTH_GB_BIT 4 /* the genernal bonding bit */ -#define BTM_AUTH_BONDS 6 /* the general/dedicated bonding bits */ -#define BTM_AUTH_YN_BIT 1 /* this is the Yes or No bit */ - -#define BTM_BLE_ENC_KEY_MASK (1 << 0) -#define BTM_BLE_ID_KEY_MASK (1 << 1) -#define BTM_BLE_CSR_KEY_MASK (1 << 2) -#define BTM_BLE_LINK_KEY_MASK (1 << 3) - -#define BTM_BLE_INITIATOR_KEY_SIZE 15 -#define BTM_BLE_RESPONDER_KEY_SIZE 15 -#define BTM_BLE_MAX_KEY_SIZE 16 -#define BTM_BLE_MIN_KEY_SIZE 7 - -typedef UINT8 tBTM_AUTH_REQ; - -enum { - BTM_OOB_NONE, - BTM_OOB_PRESENT -#if BTM_OOB_INCLUDED == TRUE - , BTM_OOB_UNKNOWN -#endif -}; -typedef UINT8 tBTM_OOB_DATA; - -/* data type for BTM_SP_IO_REQ_EVT */ -typedef struct { - BD_ADDR bd_addr; /* peer address */ - tBTM_IO_CAP io_cap; /* local IO capabilities */ - tBTM_OOB_DATA oob_data; /* OOB data present (locally) for the peer device */ - tBTM_AUTH_REQ auth_req; /* Authentication required (for local device) */ - BOOLEAN is_orig; /* TRUE, if local device initiated the SP process */ -} tBTM_SP_IO_REQ; - -/* data type for BTM_SP_IO_RSP_EVT */ -typedef struct { - BD_ADDR bd_addr; /* peer address */ - tBTM_IO_CAP io_cap; /* peer IO capabilities */ - tBTM_OOB_DATA oob_data; /* OOB data present at peer device for the local device */ - tBTM_AUTH_REQ auth_req; /* Authentication required for peer device */ -} tBTM_SP_IO_RSP; - -/* data type for BTM_SP_CFM_REQ_EVT */ -typedef struct { - BD_ADDR bd_addr; /* peer address */ - DEV_CLASS dev_class; /* peer CoD */ - tBTM_BD_NAME bd_name; /* peer device name */ - UINT32 num_val; /* the numeric value for comparison. If just_works, do not show this number to UI */ - BOOLEAN just_works; /* TRUE, if "Just Works" association model */ - tBTM_AUTH_REQ loc_auth_req; /* Authentication required for local device */ - tBTM_AUTH_REQ rmt_auth_req; /* Authentication required for peer device */ - tBTM_IO_CAP loc_io_caps; /* IO Capabilities of the local device */ - tBTM_IO_CAP rmt_io_caps; /* IO Capabilities of the remot device */ -} tBTM_SP_CFM_REQ; - -/* data type for BTM_SP_KEY_REQ_EVT */ -typedef struct { - BD_ADDR bd_addr; /* peer address */ - DEV_CLASS dev_class; /* peer CoD */ - tBTM_BD_NAME bd_name; /* peer device name */ -} tBTM_SP_KEY_REQ; - -/* data type for BTM_SP_KEY_NOTIF_EVT */ -typedef struct { - BD_ADDR bd_addr; /* peer address */ - DEV_CLASS dev_class; /* peer CoD */ - tBTM_BD_NAME bd_name; /* peer device name */ - UINT32 passkey; /* passkey */ -} tBTM_SP_KEY_NOTIF; - -enum { - BTM_SP_KEY_STARTED, /* 0 - passkey entry started */ - BTM_SP_KEY_ENTERED, /* 1 - passkey digit entered */ - BTM_SP_KEY_ERASED, /* 2 - passkey digit erased */ - BTM_SP_KEY_CLEARED, /* 3 - passkey cleared */ - BTM_SP_KEY_COMPLT, /* 4 - passkey entry completed */ - BTM_SP_KEY_OUT_OF_RANGE /* 5 - out of range */ -}; -typedef UINT8 tBTM_SP_KEY_TYPE; - -/* data type for BTM_SP_KEYPRESS_EVT */ -typedef struct { - BD_ADDR bd_addr; /* peer address */ - tBTM_SP_KEY_TYPE notif_type; -} tBTM_SP_KEYPRESS; - -/* data type for BTM_SP_LOC_OOB_EVT */ -typedef struct { - tBTM_STATUS status; /* */ - BT_OCTET16 c; /* Simple Pairing Hash C */ - BT_OCTET16 r; /* Simple Pairing Randomnizer R */ -} tBTM_SP_LOC_OOB; - -/* data type for BTM_SP_RMT_OOB_EVT */ -typedef struct { - BD_ADDR bd_addr; /* peer address */ - DEV_CLASS dev_class; /* peer CoD */ - tBTM_BD_NAME bd_name; /* peer device name */ -} tBTM_SP_RMT_OOB; - - -/* data type for BTM_SP_COMPLT_EVT */ -typedef struct { - BD_ADDR bd_addr; /* peer address */ - DEV_CLASS dev_class; /* peer CoD */ - tBTM_BD_NAME bd_name; /* peer device name */ - tBTM_STATUS status; /* status of the simple pairing process */ -} tBTM_SP_COMPLT; - -/* data type for BTM_SP_UPGRADE_EVT */ -typedef struct { - BD_ADDR bd_addr; /* peer address */ - BOOLEAN upgrade; /* TRUE, to upgrade the link key */ -} tBTM_SP_UPGRADE; - -typedef union { - tBTM_SP_IO_REQ io_req; /* BTM_SP_IO_REQ_EVT */ - tBTM_SP_IO_RSP io_rsp; /* BTM_SP_IO_RSP_EVT */ - tBTM_SP_CFM_REQ cfm_req; /* BTM_SP_CFM_REQ_EVT */ - tBTM_SP_KEY_NOTIF key_notif; /* BTM_SP_KEY_NOTIF_EVT */ - tBTM_SP_KEY_REQ key_req; /* BTM_SP_KEY_REQ_EVT */ - tBTM_SP_KEYPRESS key_press; /* BTM_SP_KEYPRESS_EVT */ - tBTM_SP_LOC_OOB loc_oob; /* BTM_SP_LOC_OOB_EVT */ - tBTM_SP_RMT_OOB rmt_oob; /* BTM_SP_RMT_OOB_EVT */ - tBTM_SP_COMPLT complt; /* BTM_SP_COMPLT_EVT */ - tBTM_SP_UPGRADE upgrade; /* BTM_SP_UPGRADE_EVT */ -} tBTM_SP_EVT_DATA; - -/* Simple Pairing Events. Called by the stack when Simple Pairing related -** events occur. -*/ -typedef UINT8 (tBTM_SP_CALLBACK) (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data); - - -typedef void (tBTM_MKEY_CALLBACK) (BD_ADDR bd_addr, UINT8 status, UINT8 key_flag) ; - -/* Encryption enabled/disabled complete: Optionally passed with BTM_SetEncryption. -** Parameters are -** BD Address of remote -** optional data passed in by BTM_SetEncryption -** tBTM_STATUS - result of the operation -*/ -typedef void (tBTM_SEC_CBACK) (BD_ADDR bd_addr, tBT_TRANSPORT trasnport, - void *p_ref_data, tBTM_STATUS result); - -/* Bond Cancel complete. Parameters are -** Result of the cancel operation -** -*/ -typedef void (tBTM_BOND_CANCEL_CMPL_CALLBACK) (tBTM_STATUS result); - -/* LE related event and data structure -*/ -/* relate to ESP_LE_KEY_xxx in esp_gap_ble_api.h */ -#if (SMP_INCLUDED == TRUE) -#define BTM_LE_IO_REQ_EVT SMP_IO_CAP_REQ_EVT /* received IO_CAPABILITY_REQUEST event */ -#define BTM_LE_SEC_REQUEST_EVT SMP_SEC_REQUEST_EVT /* security request event */ -#define BTM_LE_KEY_NOTIF_EVT SMP_PASSKEY_NOTIF_EVT /* received USER_PASSKEY_NOTIFY event */ -#define BTM_LE_KEY_REQ_EVT SMP_PASSKEY_REQ_EVT /* received USER_PASSKEY_REQUEST event */ -#define BTM_LE_OOB_REQ_EVT SMP_OOB_REQ_EVT /* OOB data request event */ -#define BTM_LE_NC_REQ_EVT SMP_NC_REQ_EVT /* Numeric Comparison request event */ -#define BTM_LE_PR_KEYPR_NOT_EVT SMP_PEER_KEYPR_NOT_EVT /* Peer keypress notification recd event */ -/* SC OOB request event (both local and peer OOB data) can be expected in response */ -#define BTM_LE_SC_OOB_REQ_EVT SMP_SC_OOB_REQ_EVT -/* SC OOB local data set is created (as result of SMP_CrLocScOobData(...)) */ -#define BTM_LE_SC_LOC_OOB_EVT SMP_SC_LOC_OOB_DATA_UP_EVT -#define BTM_LE_BR_KEYS_REQ_EVT SMP_BR_KEYS_REQ_EVT /* SMP over BR keys request event */ -#define BTM_LE_COMPLT_EVT SMP_COMPLT_EVT /* SMP complete event */ -#define BTM_LE_LAST_FROM_SMP BTM_LE_BR_KEYS_REQ_EVT -#define BTM_LE_KEY_EVT BTM_LE_LAST_FROM_SMP + 1 /* KEY update event */ -#endif ///SMP_INCLUDED == TRUE -typedef UINT8 tBTM_LE_EVT; - -#if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE) -#define BTM_LE_KEY_NONE 0 -#define BTM_LE_KEY_PENC SMP_SEC_KEY_TYPE_ENC /* encryption information of peer device */ -#define BTM_LE_KEY_PID SMP_SEC_KEY_TYPE_ID /* identity key of the peer device */ -#define BTM_LE_KEY_PCSRK SMP_SEC_KEY_TYPE_CSRK /* peer SRK */ -#define BTM_LE_KEY_PLK SMP_SEC_KEY_TYPE_LK -#define BTM_LE_KEY_LLK (SMP_SEC_KEY_TYPE_LK << 4) -#define BTM_LE_KEY_LENC (SMP_SEC_KEY_TYPE_ENC << 4) /* master role security information:div */ -#define BTM_LE_KEY_LID (SMP_SEC_KEY_TYPE_ID << 4) /* master device ID key */ -#define BTM_LE_KEY_LCSRK (SMP_SEC_KEY_TYPE_CSRK << 4) /* local CSRK has been deliver to peer */ -#endif ///BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE -typedef UINT8 tBTM_LE_KEY_TYPE; - -/* relate to ESP_LE_AUTH_xxx in esp_gap_ble_api.h */ -#if (SMP_INCLUDED == TRUE) -#define BTM_LE_AUTH_REQ_NO_BOND SMP_AUTH_NO_BOND /* 0 */ -#define BTM_LE_AUTH_REQ_BOND SMP_AUTH_GEN_BOND /* 1 << 0 */ -#define BTM_LE_AUTH_REQ_MITM SMP_AUTH_YN_BIT /* 1 << 2 */ -#endif ///SMP_INCLUDED == TRUE -typedef UINT8 tBTM_LE_AUTH_REQ; -#if (SMP_INCLUDED == TRUE) -#define BTM_LE_SC_SUPPORT_BIT SMP_SC_SUPPORT_BIT /* (1 << 3) */ -#define BTM_LE_KP_SUPPORT_BIT SMP_KP_SUPPORT_BIT /* (1 << 4) */ - -#define BTM_LE_AUTH_REQ_SC_ONLY SMP_AUTH_SC_ENC_ONLY /* 1 << 3 */ -#define BTM_LE_AUTH_REQ_SC_BOND SMP_AUTH_SC_GB /* 1001 */ -#define BTM_LE_AUTH_REQ_SC_MITM SMP_AUTH_SC_MITM_NB /* 1100 */ -#define BTM_LE_AUTH_REQ_SC_MITM_BOND SMP_AUTH_SC_MITM_GB /* 1101 */ -#define BTM_LE_AUTH_REQ_MASK SMP_AUTH_MASK /* 0x1D */ - -/* LE security level */ -#define BTM_LE_SEC_NONE SMP_SEC_NONE -#define BTM_LE_SEC_UNAUTHENTICATE SMP_SEC_UNAUTHENTICATE /* 1 */ -#define BTM_LE_SEC_AUTHENTICATED SMP_SEC_AUTHENTICATED /* 4 */ -#endif ///SMP_INCLUDED == TRUE -typedef UINT8 tBTM_LE_SEC; - - -typedef struct { - tBTM_IO_CAP io_cap; /* local IO capabilities */ - UINT8 oob_data; /* OOB data present (locally) for the peer device */ - tBTM_LE_AUTH_REQ auth_req; /* Authentication request (for local device) contain bonding and MITM info */ - UINT8 max_key_size; /* max encryption key size */ - tBTM_LE_KEY_TYPE init_keys; /* keys to be distributed, bit mask */ - tBTM_LE_KEY_TYPE resp_keys; /* keys to be distributed, bit mask */ -} tBTM_LE_IO_REQ; - -#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE -/* data type for tBTM_LE_COMPLT */ -typedef struct { - UINT8 reason; - UINT8 sec_level; - BOOLEAN is_pair_cancel; - BOOLEAN smp_over_br; -} tBTM_LE_COMPLT; -#endif - -/* BLE encryption keys */ -typedef struct { - BT_OCTET16 ltk; - BT_OCTET8 rand; - UINT16 ediv; - UINT8 sec_level; - UINT8 key_size; -} tBTM_LE_PENC_KEYS; - -/* BLE CSRK keys */ -typedef struct { - UINT32 counter; - BT_OCTET16 csrk; - UINT8 sec_level; -} tBTM_LE_PCSRK_KEYS; - -/* BLE Encryption reproduction keys */ -typedef struct { - BT_OCTET16 ltk; - UINT16 div; - UINT8 key_size; - UINT8 sec_level; -} tBTM_LE_LENC_KEYS; - -/* BLE SRK keys */ -typedef struct { - UINT32 counter; - UINT16 div; - UINT8 sec_level; - BT_OCTET16 csrk; -} tBTM_LE_LCSRK_KEYS; - -typedef struct { - BT_OCTET16 irk; - tBLE_ADDR_TYPE addr_type; - BD_ADDR static_addr; -} tBTM_LE_PID_KEYS; - -typedef union { - tBTM_LE_PENC_KEYS penc_key; /* received peer encryption key */ - tBTM_LE_PCSRK_KEYS pcsrk_key; /* received peer device SRK */ - tBTM_LE_PID_KEYS pid_key; /* peer device ID key */ - tBTM_LE_LENC_KEYS lenc_key; /* local encryption reproduction keys LTK = = d1(ER,DIV,0)*/ - tBTM_LE_LCSRK_KEYS lcsrk_key; /* local device CSRK = d1(ER,DIV,1)*/ -} tBTM_LE_KEY_VALUE; - -typedef struct { - tBTM_LE_KEY_TYPE key_type; - tBTM_LE_KEY_VALUE *p_key_value; -} tBTM_LE_KEY; - -typedef union { - tBTM_LE_IO_REQ io_req; /* BTM_LE_IO_REQ_EVT */ - UINT32 key_notif; /* BTM_LE_KEY_NOTIF_EVT */ - /* BTM_LE_NC_REQ_EVT */ - /* no callback data for BTM_LE_KEY_REQ_EVT */ - /* and BTM_LE_OOB_REQ_EVT */ -#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE - tBTM_LE_COMPLT complt; /* BTM_LE_COMPLT_EVT */ - tSMP_OOB_DATA_TYPE req_oob_type; -#endif - tBTM_LE_KEY key; -} tBTM_LE_EVT_DATA; - -/* Simple Pairing Events. Called by the stack when Simple Pairing related -** events occur. -*/ -typedef UINT8 (tBTM_LE_CALLBACK) (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_DATA *p_data); - -#define BTM_BLE_KEY_TYPE_ID 1 -#define BTM_BLE_KEY_TYPE_ER 2 -#define BTM_BLE_KEY_TYPE_COUNTER 3 //tobe obsolete - -typedef struct { - BT_OCTET16 ir; - BT_OCTET16 irk; - BT_OCTET16 dhk; - -} tBTM_BLE_LOCAL_ID_KEYS; - -typedef union { - tBTM_BLE_LOCAL_ID_KEYS id_keys; - BT_OCTET16 er; -} tBTM_BLE_LOCAL_KEYS; - - -/* New LE identity key for local device. -*/ -typedef void (tBTM_LE_KEY_CALLBACK) (UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key); - - -/*************************** -** Security Manager Types -****************************/ -/* Structure that applications use to register with BTM_SecRegister */ -typedef struct { - tBTM_AUTHORIZE_CALLBACK *p_authorize_callback; - tBTM_PIN_CALLBACK *p_pin_callback; - tBTM_LINK_KEY_CALLBACK *p_link_key_callback; - tBTM_AUTH_COMPLETE_CALLBACK *p_auth_complete_callback; - tBTM_BOND_CANCEL_CMPL_CALLBACK *p_bond_cancel_cmpl_callback; - tBTM_SP_CALLBACK *p_sp_callback; -#if BLE_INCLUDED == TRUE -#if SMP_INCLUDED == TRUE - tBTM_LE_CALLBACK *p_le_callback; -#endif - tBTM_LE_KEY_CALLBACK *p_le_key_callback; -#endif -} tBTM_APPL_INFO; - -/* Callback function for when a link supervision timeout event occurs. -** This asynchronous event is enabled/disabled by calling BTM_RegForLstoEvt(). -*/ -typedef void (tBTM_LSTO_CBACK) (BD_ADDR remote_bda, UINT16 timeout); - -/***************************************************************************** -** POWER MANAGEMENT -*****************************************************************************/ -/**************************** -** Power Manager Constants -*****************************/ -/* BTM Power manager status codes */ -enum { - BTM_PM_STS_ACTIVE = HCI_MODE_ACTIVE, - BTM_PM_STS_HOLD = HCI_MODE_HOLD, - BTM_PM_STS_SNIFF = HCI_MODE_SNIFF, - BTM_PM_STS_PARK = HCI_MODE_PARK, - BTM_PM_STS_SSR, /* report the SSR parameters in HCI_SNIFF_SUB_RATE_EVT */ - BTM_PM_STS_PENDING, /* when waiting for status from controller */ - BTM_PM_STS_ERROR /* when HCI command status returns error */ -}; -typedef UINT8 tBTM_PM_STATUS; - -/* BTM Power manager modes */ -enum { - BTM_PM_MD_ACTIVE = BTM_PM_STS_ACTIVE, - BTM_PM_MD_HOLD = BTM_PM_STS_HOLD, - BTM_PM_MD_SNIFF = BTM_PM_STS_SNIFF, - BTM_PM_MD_PARK = BTM_PM_STS_PARK, - BTM_PM_MD_FORCE = 0x10 /* OR this to force ACL link to a certain mode */ -}; -typedef UINT8 tBTM_PM_MODE; - -#define BTM_PM_SET_ONLY_ID 0x80 - -/* Operation codes */ -#define BTM_PM_REG_SET 1 /* The module wants to set the desired power mode */ -#define BTM_PM_REG_NOTIF 2 /* The module wants to receive mode change event */ -#define BTM_PM_DEREG 4 /* The module does not want to involve with PM anymore */ - -/************************ -** Power Manager Types -*************************/ -typedef struct { - UINT16 max; - UINT16 min; - UINT16 attempt; - UINT16 timeout; - tBTM_PM_MODE mode; -} tBTM_PM_PWR_MD; - -/************************************* -** Power Manager Callback Functions -**************************************/ -typedef void (tBTM_PM_STATUS_CBACK) (BD_ADDR p_bda, tBTM_PM_STATUS status, - UINT16 value, UINT8 hci_status); - - -/************************ -** Stored Linkkey Types -*************************/ -#define BTM_CB_EVT_DELETE_STORED_LINK_KEYS 4 - -typedef struct { - UINT8 event; - UINT8 status; - UINT16 num_keys; - -} tBTM_DELETE_STORED_LINK_KEY_COMPLETE; - -/* MIP evnets, callbacks */ -enum { - BTM_MIP_MODE_CHG_EVT, - BTM_MIP_DISCONNECT_EVT, - BTM_MIP_PKTS_COMPL_EVT, - BTM_MIP_RXDATA_EVT -}; -typedef UINT8 tBTM_MIP_EVT; - -typedef struct { - tBTM_MIP_EVT event; - BD_ADDR bd_addr; - UINT16 mip_id; -} tBTM_MIP_MODE_CHANGE; - -typedef struct { - tBTM_MIP_EVT event; - UINT16 mip_id; - UINT8 disc_reason; -} tBTM_MIP_CONN_TIMEOUT; - -#define BTM_MIP_MAX_RX_LEN 17 - -typedef struct { - tBTM_MIP_EVT event; - UINT16 mip_id; - UINT8 rx_len; - UINT8 rx_data[BTM_MIP_MAX_RX_LEN]; -} tBTM_MIP_RXDATA; - -typedef struct { - tBTM_MIP_EVT event; - BD_ADDR bd_addr; - UINT8 data[11]; /* data[0] shows Vender-specific device type */ -} tBTM_MIP_EIR_HANDSHAKE; - -typedef struct { - tBTM_MIP_EVT event; - UINT16 num_sent; /* Number of packets completed at the controller */ -} tBTM_MIP_PKTS_COMPL; - -typedef union { - tBTM_MIP_EVT event; - tBTM_MIP_MODE_CHANGE mod_chg; - tBTM_MIP_CONN_TIMEOUT conn_tmo; - tBTM_MIP_EIR_HANDSHAKE eir; - tBTM_MIP_PKTS_COMPL completed; - tBTM_MIP_RXDATA rxdata; -} tBTM_MIP_EVENT_DATA; - -/* MIP event callback function */ -typedef void (tBTM_MIP_EVENTS_CB) (tBTM_MIP_EVT event, tBTM_MIP_EVENT_DATA data); - -/* MIP Device query callback function */ -typedef BOOLEAN (tBTM_MIP_QUERY_CB) (BD_ADDR dev_addr, UINT8 *p_mode, LINK_KEY link_key); - -#define BTM_CONTRL_ACTIVE 1 /* ACL link on, SCO link ongoing, sniff mode */ -#define BTM_CONTRL_SCAN 2 /* Scan state - paging/inquiry/trying to connect*/ -#define BTM_CONTRL_IDLE 3 /* Idle state - page scan, LE advt, inquiry scan */ - -typedef UINT8 tBTM_CONTRL_STATE; - -/***************************************************************************** -** EXTERNAL FUNCTION DECLARATIONS -*****************************************************************************/ -/* -#ifdef __cplusplus -extern "C" { -#endif -*/ -/***************************************************************************** -** DEVICE CONTROL and COMMON FUNCTIONS -*****************************************************************************/ - -/******************************************************************************* -** -** Function BTM_DeviceReset -** -** Description This function is called to reset the controller.The Callback function -** if provided is called when startup of the device has -** completed. -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_DeviceReset (tBTM_CMPL_CB *p_cb); - - -/******************************************************************************* -** -** Function BTM_IsDeviceUp -** -** Description This function is called to check if the device is up. -** -** Returns TRUE if device is up, else FALSE -** -*******************************************************************************/ -//extern -BOOLEAN BTM_IsDeviceUp (void); - - -/******************************************************************************* -** -** Function BTM_SetLocalDeviceName -** -** Description This function is called to set the local device name. -** -** Returns BTM_CMD_STARTED if successful, otherwise an error -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetLocalDeviceName (char *p_name); - -/******************************************************************************* -** -** Function BTM_SetDeviceClass -** -** Description This function is called to set the local device class -** -** Returns BTM_SUCCESS if successful, otherwise an error -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetDeviceClass (DEV_CLASS dev_class); - - -/******************************************************************************* -** -** Function BTM_ReadLocalDeviceName -** -** Description This function is called to read the local device name. -** -** Returns status of the operation -** If success, BTM_SUCCESS is returned and p_name points stored -** local device name -** If BTM doesn't store local device name, BTM_NO_RESOURCES is -** is returned and p_name is set to NULL -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ReadLocalDeviceName (char **p_name); - -/******************************************************************************* -** -** Function BTM_ReadLocalDeviceNameFromController -** -** Description Get local device name from controller. Do not use cached -** name (used to get chip-id prior to btm reset complete). -** -** Returns BTM_CMD_STARTED if successful, otherwise an error -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ReadLocalDeviceNameFromController (tBTM_CMPL_CB *p_rln_cmpl_cback); - -/******************************************************************************* -** -** Function BTM_ReadDeviceClass -** -** Description This function is called to read the local device class -** -** Returns pointer to the device class -** -*******************************************************************************/ -//extern -UINT8 *BTM_ReadDeviceClass (void); - - -/******************************************************************************* -** -** Function BTM_ReadLocalFeatures -** -** Description This function is called to read the local features -** -** Returns pointer to the local features string -** -*******************************************************************************/ -//extern -UINT8 *BTM_ReadLocalFeatures (void); - -/******************************************************************************* -** -** Function BTM_RegisterForDeviceStatusNotif -** -** Description This function is called to register for device status -** change notifications. -** -** Returns pointer to previous caller's callback function or NULL if first -** registration. -** -*******************************************************************************/ -//extern -tBTM_DEV_STATUS_CB *BTM_RegisterForDeviceStatusNotif (tBTM_DEV_STATUS_CB *p_cb); - - -/******************************************************************************* -** -** Function BTM_RegisterForVSEvents -** -** Description This function is called to register/deregister for vendor -** specific HCI events. -** -** If is_register=TRUE, then the function will be registered; -** if is_register=FALSE, then the function will be deregistered. -** -** Returns BTM_SUCCESS if successful, -** BTM_BUSY if maximum number of callbacks have already been -** registered. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_RegisterForVSEvents (tBTM_VS_EVT_CB *p_cb, BOOLEAN is_register); - - -/******************************************************************************* -** -** Function BTM_VendorSpecificCommand -** -** Description Send a vendor specific HCI command to the controller. -** -** Returns -** BTM_SUCCESS Command sent. Does not expect command complete -** event. (command cmpl callback param is NULL) -** BTM_CMD_STARTED Command sent. Waiting for command cmpl event. -** BTM_BUSY Command not sent. Waiting for cmd cmpl event for -** prior command. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_VendorSpecificCommand(UINT16 opcode, - UINT8 param_len, - UINT8 *p_param_buf, - tBTM_VSC_CMPL_CB *p_cb); - - -/******************************************************************************* -** -** Function BTM_AllocateSCN -** -** Description Look through the Server Channel Numbers for a free one to be -** used with an RFCOMM connection. -** -** Returns Allocated SCN number or 0 if none. -** -*******************************************************************************/ -//extern -#if (CLASSIC_BT_INCLUDED == TRUE) -UINT8 BTM_AllocateSCN(void); - -// btla-specific ++ -/******************************************************************************* -** -** Function BTM_TryAllocateSCN -** -** Description Try to allocate a fixed server channel -** -** Returns Returns TRUE if server channel was available -** -*******************************************************************************/ -//extern -BOOLEAN BTM_TryAllocateSCN(UINT8 scn); -// btla-specific -- - - -/******************************************************************************* -** -** Function BTM_FreeSCN -** -** Description Free the specified SCN. -** -** Returns TRUE if successful, FALSE if SCN is not in use or invalid -** -*******************************************************************************/ -//extern -BOOLEAN BTM_FreeSCN(UINT8 scn); -#endif ///CLASSIC_BT_INCLUDED == TRUE - - -/******************************************************************************* -** -** Function BTM_SetTraceLevel -** -** Description This function sets the trace level for BTM. If called with -** a value of 0xFF, it simply returns the current trace level. -** -** Returns The new or current trace level -** -*******************************************************************************/ -//extern -UINT8 BTM_SetTraceLevel (UINT8 new_level); - - -/******************************************************************************* -** -** Function BTM_WritePageTimeout -** -** Description Send HCI Wite Page Timeout. -** -** Returns -** BTM_SUCCESS Command sent. -** BTM_NO_RESOURCES If out of resources to send the command. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_WritePageTimeout(UINT16 timeout); - -/******************************************************************************* -** -** Function BTM_WriteVoiceSettings -** -** Description Send HCI Write Voice Settings command. -** See stack/hcidefs.h for settings bitmask values. -** -** Returns -** BTM_SUCCESS Command sent. -** BTM_NO_RESOURCES If out of resources to send the command. -** -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_WriteVoiceSettings(UINT16 settings); - -/******************************************************************************* -** -** Function BTM_EnableTestMode -** -** Description Send HCI the enable device under test command. -** -** Note: Controller can only be taken out of this mode by -** resetting the controller. -** -** Returns -** BTM_SUCCESS Command sent. -** BTM_NO_RESOURCES If out of resources to send the command. -** -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_EnableTestMode(void); - - -/***************************************************************************** -** DEVICE DISCOVERY FUNCTIONS - Inquiry, Remote Name, Discovery, Class of Device -*****************************************************************************/ - -/******************************************************************************* -** -** Function BTM_SetDiscoverability -** -** Description This function is called to set the device into or out of -** discoverable mode. Discoverable mode means inquiry -** scans are enabled. If a value of '0' is entered for window or -** interval, the default values are used. -** -** Returns BTM_SUCCESS if successful -** BTM_BUSY if a setting of the filter is already in progress -** BTM_NO_RESOURCES if couldn't get a memory pool buffer -** BTM_ILLEGAL_VALUE if a bad parameter was detected -** BTM_WRONG_MODE if the device is not up. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, - UINT16 interval); - - -/******************************************************************************* -** -** Function BTM_ReadDiscoverability -** -** Description This function is called to read the current discoverability -** mode of the device. -** -** Output Params: p_window - current inquiry scan duration -** p_interval - current inquiry scan interval -** -** Returns BTM_NON_DISCOVERABLE, BTM_LIMITED_DISCOVERABLE, or -** BTM_GENERAL_DISCOVERABLE -** -*******************************************************************************/ -//extern -UINT16 BTM_ReadDiscoverability (UINT16 *p_window, - UINT16 *p_interval); - - -/******************************************************************************* -** -** Function BTM_SetPeriodicInquiryMode -** -** Description This function is called to set the device periodic inquiry mode. -** If the duration is zero, the periodic inquiry mode is cancelled. -** -** Parameters: p_inqparms - pointer to the inquiry information -** mode - GENERAL or LIMITED inquiry -** duration - length in 1.28 sec intervals (If '0', the inquiry is CANCELLED) -** max_resps - maximum amount of devices to search for before ending the inquiry -** filter_cond_type - BTM_CLR_INQUIRY_FILTER, BTM_FILTER_COND_DEVICE_CLASS, or -** BTM_FILTER_COND_BD_ADDR -** filter_cond - value for the filter (based on filter_cond_type) -** -** max_delay - maximum amount of time between successive inquiries -** min_delay - minimum amount of time between successive inquiries -** p_results_cb - callback returning pointer to results (tBTM_INQ_RESULTS) -** -** Returns BTM_CMD_STARTED if successfully started -** BTM_ILLEGAL_VALUE if a bad parameter is detected -** BTM_NO_RESOURCES if could not allocate a message buffer -** BTM_SUCCESS - if cancelling the periodic inquiry -** BTM_BUSY - if an inquiry is already active -** BTM_WRONG_MODE if the device is not up. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetPeriodicInquiryMode (tBTM_INQ_PARMS *p_inqparms, - UINT16 max_delay, UINT16 min_delay, - tBTM_INQ_RESULTS_CB *p_results_cb); - - -/******************************************************************************* -** -** Function BTM_StartInquiry -** -** Description This function is called to start an inquiry. -** -** Parameters: p_inqparms - pointer to the inquiry information -** mode - GENERAL or LIMITED inquiry -** duration - length in 1.28 sec intervals (If '0', the inquiry is CANCELLED) -** max_resps - maximum amount of devices to search for before ending the inquiry -** filter_cond_type - BTM_CLR_INQUIRY_FILTER, BTM_FILTER_COND_DEVICE_CLASS, or -** BTM_FILTER_COND_BD_ADDR -** filter_cond - value for the filter (based on filter_cond_type) -** -** p_results_cb - Pointer to the callback routine which gets called -** upon receipt of an inquiry result. If this field is -** NULL, the application is not notified. -** -** p_cmpl_cb - Pointer to the callback routine which gets called -** upon completion. If this field is NULL, the -** application is not notified when completed. -** Returns tBTM_STATUS -** BTM_CMD_STARTED if successfully initiated -** BTM_BUSY if already in progress -** BTM_ILLEGAL_VALUE if parameter(s) are out of range -** BTM_NO_RESOURCES if could not allocate resources to start the command -** BTM_WRONG_MODE if the device is not up. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, - tBTM_INQ_RESULTS_CB *p_results_cb, - tBTM_CMPL_CB *p_cmpl_cb); - - -/******************************************************************************* -** -** Function BTM_IsInquiryActive -** -** Description This function returns a bit mask of the current inquiry state -** -** Returns BTM_INQUIRY_INACTIVE if inactive (0) -** BTM_LIMITED_INQUIRY_ACTIVE if a limted inquiry is active -** BTM_GENERAL_INQUIRY_ACTIVE if a general inquiry is active -** BTM_PERIODIC_INQUIRY_ACTIVE if a periodic inquiry is active -** -*******************************************************************************/ -//extern -UINT16 BTM_IsInquiryActive (void); - - -/******************************************************************************* -** -** Function BTM_CancelInquiry -** -** Description This function cancels an inquiry if active -** -** Returns BTM_SUCCESS if successful -** BTM_NO_RESOURCES if could not allocate a message buffer -** BTM_WRONG_MODE if the device is not up. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_CancelInquiry(void); - - -/******************************************************************************* -** -** Function BTM_CancelPeriodicInquiry -** -** Description This function cancels a periodic inquiry -** -** Returns -** BTM_NO_RESOURCES if could not allocate a message buffer -** BTM_SUCCESS - if cancelling the periodic inquiry -** BTM_WRONG_MODE if the device is not up. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_CancelPeriodicInquiry(void); - - -/******************************************************************************* -** -** Function BTM_SetConnectability -** -** Description This function is called to set the device into or out of -** connectable mode. Discoverable mode means page scans enabled. -** -** Returns BTM_SUCCESS if successful -** BTM_ILLEGAL_VALUE if a bad parameter is detected -** BTM_NO_RESOURCES if could not allocate a message buffer -** BTM_WRONG_MODE if the device is not up. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetConnectability (UINT16 page_mode, UINT16 window, - UINT16 interval); - - -/******************************************************************************* -** -** Function BTM_ReadConnectability -** -** Description This function is called to read the current discoverability -** mode of the device. -** Output Params p_window - current page scan duration -** p_interval - current time between page scans -** -** Returns BTM_NON_CONNECTABLE or BTM_CONNECTABLE -** -*******************************************************************************/ -//extern -UINT16 BTM_ReadConnectability (UINT16 *p_window, UINT16 *p_interval); - - -/******************************************************************************* -** -** Function BTM_SetInquiryMode -** -** Description This function is called to set standard, with RSSI -** mode or extended of the inquiry for local device. -** -** Input Params: BTM_INQ_RESULT_STANDARD, BTM_INQ_RESULT_WITH_RSSI or -** BTM_INQ_RESULT_EXTENDED -** -** Returns BTM_SUCCESS if successful -** BTM_NO_RESOURCES if couldn't get a memory pool buffer -** BTM_ILLEGAL_VALUE if a bad parameter was detected -** BTM_WRONG_MODE if the device is not up. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetInquiryMode (UINT8 mode); - -/******************************************************************************* -** -** Function BTM_SetInquiryScanType -** -** Description This function is called to set the iquiry scan-type to -** standard or interlaced. -** -** Input Params: BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED -** -** Returns BTM_SUCCESS if successful -** BTM_MODE_UNSUPPORTED if not a 1.2 device -** BTM_WRONG_MODE if the device is not up. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetInquiryScanType (UINT16 scan_type); - -/******************************************************************************* -** -** Function BTM_SetPageScanType -** -** Description This function is called to set the page scan-type to -** standard or interlaced. -** -** Input Params: BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED -** -** Returns BTM_SUCCESS if successful -** BTM_MODE_UNSUPPORTED if not a 1.2 device -** BTM_WRONG_MODE if the device is not up. -** -*******************************************************************************/ - -//extern -tBTM_STATUS BTM_SetPageScanType (UINT16 scan_type); - -/******************************************************************************* -** -** Function BTM_ReadRemoteDeviceName -** -** Description This function initiates a remote device HCI command to the -** controller and calls the callback when the process has completed. -** -** Input Params: remote_bda - device address of name to retrieve -** p_cb - callback function called when BTM_CMD_STARTED -** is returned. -** A pointer to tBTM_REMOTE_DEV_NAME is passed to the -** callback. -** -** Returns -** BTM_CMD_STARTED is returned if the request was successfully sent -** to HCI. -** BTM_BUSY if already in progress -** BTM_UNKNOWN_ADDR if device address is bad -** BTM_NO_RESOURCES if could not allocate resources to start the command -** BTM_WRONG_MODE if the device is not up. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, - tBTM_CMPL_CB *p_cb, - tBT_TRANSPORT transport); - - -/******************************************************************************* -** -** Function BTM_CancelRemoteDeviceName -** -** Description This function initiates the cancel request for the specified -** remote device. -** -** Input Params: None -** -** Returns -** BTM_CMD_STARTED is returned if the request was successfully sent -** to HCI. -** BTM_NO_RESOURCES if could not allocate resources to start the command -** BTM_WRONG_MODE if there is not an active remote name request. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_CancelRemoteDeviceName (void); - -/******************************************************************************* -** -** Function BTM_ReadRemoteVersion -** -** Description This function is called to read a remote device's version -** -** Returns BTM_SUCCESS if successful, otherwise an error -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ReadRemoteVersion (BD_ADDR addr, - UINT8 *lmp_version, - UINT16 *manufacturer, - UINT16 *lmp_sub_version); - -/******************************************************************************* -** -** Function BTM_ReadRemoteFeatures -** -** Description This function is called to read a remote device's -** supported features mask (features mask located at page 0) -** -** Note: The size of device features mask page is -** BTM_FEATURE_BYTES_PER_PAGE bytes. -** -** Returns pointer to the remote supported features mask -** -*******************************************************************************/ -//extern -UINT8 *BTM_ReadRemoteFeatures (BD_ADDR addr); - -/******************************************************************************* -** -** Function BTM_ReadRemoteExtendedFeatures -** -** Description This function is called to read a specific extended features -** page of the remote device -** -** Note1: The size of device features mask page is -** BTM_FEATURE_BYTES_PER_PAGE bytes. -** Note2: The valid device features mask page number depends on -** the remote device capabilities. It is expected to be in the -** range [0 - BTM_EXT_FEATURES_PAGE_MAX]. - -** Returns pointer to the remote extended features mask -** or NULL if page_number is not valid -** -*******************************************************************************/ -//extern -UINT8 *BTM_ReadRemoteExtendedFeatures (BD_ADDR addr, UINT8 page_number); - -/******************************************************************************* -** -** Function BTM_ReadNumberRemoteFeaturesPages -** -** Description This function is called to retrieve the number of feature pages -** read from the remote device -** -** Returns number of features pages read from the remote device -** -*******************************************************************************/ -//extern -UINT8 BTM_ReadNumberRemoteFeaturesPages (BD_ADDR addr); - -/******************************************************************************* -** -** Function BTM_ReadAllRemoteFeatures -** -** Description This function is called to read all features of the remote device -** -** Returns pointer to the byte[0] of the page[0] of the remote device -** feature mask. -** -** Note: the function returns the pointer to the array of the size -** BTM_FEATURE_BYTES_PER_PAGE * (BTM_EXT_FEATURES_PAGE_MAX + 1). -** -*******************************************************************************/ -//extern -UINT8 *BTM_ReadAllRemoteFeatures (BD_ADDR addr); - -/******************************************************************************* -** -** Function BTM_InqDbRead -** -** Description This function looks through the inquiry database for a match -** based on Bluetooth Device Address. This is the application's -** interface to get the inquiry details of a specific BD address. -** -** Returns pointer to entry, or NULL if not found -** -*******************************************************************************/ -//extern -tBTM_INQ_INFO *BTM_InqDbRead (BD_ADDR p_bda); - - -/******************************************************************************* -** -** Function BTM_InqDbFirst -** -** Description This function looks through the inquiry database for the first -** used entry, and returns that. This is used in conjunction with -** BTM_InqDbNext by applications as a way to walk through the -** inquiry database. -** -** Returns pointer to first in-use entry, or NULL if DB is empty -** -*******************************************************************************/ -//extern -tBTM_INQ_INFO *BTM_InqDbFirst (void); - - -/******************************************************************************* -** -** Function BTM_InqDbNext -** -** Description This function looks through the inquiry database for the next -** used entry, and returns that. If the input parameter is NULL, -** the first entry is returned. -** -** Returns pointer to next in-use entry, or NULL if no more found. -** -*******************************************************************************/ -//extern -tBTM_INQ_INFO *BTM_InqDbNext (tBTM_INQ_INFO *p_cur); - - -/******************************************************************************* -** -** Function BTM_ClearInqDb -** -** Description This function is called to clear out a device or all devices -** from the inquiry database. -** -** Parameter p_bda - (input) BD_ADDR -> Address of device to clear -** (NULL clears all entries) -** -** Returns BTM_BUSY if an inquiry, get remote name, or event filter -** is active, otherwise BTM_SUCCESS -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ClearInqDb (BD_ADDR p_bda); - -/******************************************************************************* -** -** Function BTM_ReadInquiryRspTxPower -** -** Description This command will read the inquiry Transmit Power level used -** to transmit the FHS and EIR data packets. -** This can be used directly in the Tx Power Level EIR data type. -** -** Returns BTM_SUCCESS if successful -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ReadInquiryRspTxPower (tBTM_CMPL_CB *p_cb); - -#if SDP_INCLUDED == TRUE -/******************************************************************************* -** -** Function BTM_StartDiscovery -** -** Description This function is called by an application (or profile) -** when it wants to trigger an service discovery using the -** BTM's discovery database. -** -** Returns tBTM_STATUS -** BTM_CMD_STARTED if the discovery was initiated -** BTM_BUSY if one is already in progress -** BTM_UNKNOWN_ADDR if no addresses are in the INQ DB -** BTM_ERR_PROCESSING if err initiating the command -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_StartDiscovery (tBTM_CMPL_CB *p_cmpl_cb, - BD_ADDR_PTR p_rem_addr); - - -/******************************************************************************* -** -** Function BTM_FindAttribute -** -** Description This function is called by an application (or profile) -** when it wants to see if an attribute exists in the BTM -** discovery database. -** -** Returns Pointer to matching record, or NULL -** -*******************************************************************************/ -//extern -tSDP_DISC_REC *BTM_FindAttribute (UINT16 attr_id, - tSDP_DISC_REC *p_start_rec); - - -/******************************************************************************* -** -** Function BTM_FindService -** -** Description This function is called by an application (or profile) -** when it wants to see if a service exists in the BTM -** discovery database. -** -** Returns Pointer to matching record, or NULL -** -*******************************************************************************/ -//extern -tSDP_DISC_REC *BTM_FindService (UINT16 service_uuid, - tSDP_DISC_REC *p_start_rec); - - -/******************************************************************************* -** -** Function BTM_SetDiscoveryParams -** -** Description This function is called to set the BTM default discovery parameters. -** These UUID and attribute filters are used during the call to -** BTM_StartDiscovery. -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_SetDiscoveryParams (UINT16 num_uuid, tSDP_UUID *p_uuid_list, - UINT16 num_attr, UINT16 *p_attr_list); -#endif /*SDP_INCLUDED*/ - -/***************************************************************************** -** ACL CHANNEL MANAGEMENT FUNCTIONS -*****************************************************************************/ -/******************************************************************************* -** -** Function BTM_SetLinkPolicy -** -** Description Create and send HCI "Write Policy Set" command -** -** Returns BTM_CMD_STARTED if successfully initiated, otherwise error -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetLinkPolicy (BD_ADDR remote_bda, - UINT16 *settings); - -/******************************************************************************* -** -** Function BTM_SetDefaultLinkPolicy -** -** Description Set the default value for HCI "Write Policy Set" command -** to use when an ACL link is created. -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_SetDefaultLinkPolicy (UINT16 settings); - - -/******************************************************************************* -** -** Function BTM_SetDefaultLinkSuperTout -** -** Description Set the default value for HCI "Write Link Supervision Timeout" -** command to use when an ACL link is created. -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_SetDefaultLinkSuperTout (UINT16 timeout); - - -/******************************************************************************* -** -** Function BTM_SetLinkSuperTout -** -** Description Create and send HCI "Write Link Supervision Timeout" command -** -** Returns BTM_CMD_STARTED if successfully initiated, otherwise error -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetLinkSuperTout (BD_ADDR remote_bda, - UINT16 timeout); -/******************************************************************************* -** -** Function BTM_GetLinkSuperTout -** -** Description Read the link supervision timeout value of the connection -** -** Returns status of the operation -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_GetLinkSuperTout (BD_ADDR remote_bda, - UINT16 *p_timeout); - -/******************************************************************************* -** -** Function BTM_IsAclConnectionUp -** -** Description This function is called to check if an ACL connection exists -** to a specific remote BD Address. -** -** Returns TRUE if connection is up, else FALSE. -** -*******************************************************************************/ -//extern -BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda, tBT_TRANSPORT transport); - - -/******************************************************************************* -** -** Function BTM_GetRole -** -** Description This function is called to get the role of the local device -** for the ACL connection with the specified remote device -** -** Returns BTM_SUCCESS if connection exists. -** BTM_UNKNOWN_ADDR if no active link with bd addr specified -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_GetRole (BD_ADDR remote_bd_addr, UINT8 *p_role); - - - -/******************************************************************************* -** -** Function BTM_SwitchRole -** -** Description This function is called to switch role between master and -** slave. If role is already set it will do nothing. If the -** command was initiated, the callback function is called upon -** completion. -** -** Returns BTM_SUCCESS if already in specified role. -** BTM_CMD_STARTED if command issued to controller. -** BTM_NO_RESOURCES if couldn't allocate memory to issue command -** BTM_UNKNOWN_ADDR if no active link with bd addr specified -** BTM_MODE_UNSUPPORTED if local device does not support role switching -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SwitchRole (BD_ADDR remote_bd_addr, - UINT8 new_role, - tBTM_CMPL_CB *p_cb); - -/******************************************************************************* -** -** Function BTM_ReadRSSI -** -** Description This function is called to read the RSSI for a particular transport. -** The RSSI of results are returned in the callback. -** (tBTM_RSSI_RESULTS) -** -** Returns BTM_CMD_STARTED if command issued to controller. -** BTM_NO_RESOURCES if couldn't allocate memory to issue command -** BTM_UNKNOWN_ADDR if no active link with bd addr specified -** BTM_BUSY if command is already in progress -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb); - - -/******************************************************************************* -** -** Function BTM_ReadTxPower -** -** Description This function is called to read the current connection -** TX power of the connection. The TX power level results -** are returned in the callback. -** (tBTM_RSSI_RESULTS) -** -** Returns BTM_CMD_STARTED if command issued to controller. -** BTM_NO_RESOURCES if couldn't allocate memory to issue command -** BTM_UNKNOWN_ADDR if no active link with bd addr specified -** BTM_BUSY if command is already in progress -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, - tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb); - -tBTM_STATUS BTM_BleReadAdvTxPower(tBTM_CMPL_CB *p_cb); - -void BTM_BleGetWhiteListSize(uint16_t *length); - - -/******************************************************************************* -** -** Function BTM_ReadLinkQuality -** -** Description This function is called to read the link quality. -** The value of the link quality is returned in the callback. -** (tBTM_LINK_QUALITY_RESULTS) -** -** Returns BTM_CMD_STARTED if command issued to controller. -** BTM_NO_RESOURCES if couldn't allocate memory to issue command -** BTM_UNKNOWN_ADDR if no active link with bd addr specified -** BTM_BUSY if command is already in progress -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ReadLinkQuality (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb); - -/******************************************************************************* -** -** Function BTM_RegBusyLevelNotif -** -** Description This function is called to register a callback to receive -** busy level change events. -** -** Returns BTM_SUCCESS if successfully registered, otherwise error -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_RegBusyLevelNotif (tBTM_BL_CHANGE_CB *p_cb, UINT8 *p_level, - tBTM_BL_EVENT_MASK evt_mask); - -/******************************************************************************* -** -** Function BTM_AclRegisterForChanges -** -** Description This function is called to register a callback to receive -** ACL database change events, i.e. new connection or removed. -** -** Returns BTM_SUCCESS if successfully initiated, otherwise error -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_AclRegisterForChanges (tBTM_ACL_DB_CHANGE_CB *p_cb); - -/******************************************************************************* -** -** Function BTM_GetNumAclLinks -** -** Description This function is called to count the number of -** ACL links that are active. -** -** Returns UINT16 Number of active ACL links -** -*******************************************************************************/ -//extern -UINT16 BTM_GetNumAclLinks (void); - -/******************************************************************************* -** -** Function BTM_SetQoS -** -** Description This function is called to setup QoS -** -** Returns BTM_CMD_STARTED if successfully initiated, otherwise error -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetQoS(BD_ADDR bd, FLOW_SPEC *p_flow, - tBTM_CMPL_CB *p_cb); - - -/***************************************************************************** -** (e)SCO CHANNEL MANAGEMENT FUNCTIONS -*****************************************************************************/ -/******************************************************************************* -** -** Function BTM_CreateSco -** -** Description This function is called to create an SCO connection. If the -** "is_orig" flag is TRUE, the connection will be originated, -** otherwise BTM will wait for the other side to connect. -** -** Returns BTM_UNKNOWN_ADDR if the ACL connection is not up -** BTM_BUSY if another SCO being set up to -** the same BD address -** BTM_NO_RESOURCES if the max SCO limit has been reached -** BTM_CMD_STARTED if the connection establishment is started. -** In this case, "*p_sco_inx" is filled in -** with the sco index used for the connection. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig, - UINT16 pkt_types, UINT16 *p_sco_inx, - tBTM_SCO_CB *p_conn_cb, - tBTM_SCO_CB *p_disc_cb); - - -/******************************************************************************* -** -** Function BTM_RemoveSco -** -** Description This function is called to remove a specific SCO connection. -** -** Returns BTM_CMD_STARTED if successfully initiated, otherwise error -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_RemoveSco (UINT16 sco_inx); - - -/******************************************************************************* -** -** Function BTM_SetScoPacketTypes -** -** Description This function is called to set the packet types used for -** a specific SCO connection, -** -** Parameters pkt_types - One or more of the following -** BTM_SCO_PKT_TYPES_MASK_HV1 -** BTM_SCO_PKT_TYPES_MASK_HV2 -** BTM_SCO_PKT_TYPES_MASK_HV3 -** BTM_SCO_PKT_TYPES_MASK_EV3 -** BTM_SCO_PKT_TYPES_MASK_EV4 -** BTM_SCO_PKT_TYPES_MASK_EV5 -** -** BTM_SCO_LINK_ALL_MASK - enables all supported types -** -** Returns BTM_CMD_STARTED if successfully initiated, otherwise error -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetScoPacketTypes (UINT16 sco_inx, UINT16 pkt_types); - - -/******************************************************************************* -** -** Function BTM_ReadScoPacketTypes -** -** Description This function is read the packet types used for a specific -** SCO connection. -** -** Returns One or more of the following (bitmask) -** BTM_SCO_PKT_TYPES_MASK_HV1 -** BTM_SCO_PKT_TYPES_MASK_HV2 -** BTM_SCO_PKT_TYPES_MASK_HV3 -** BTM_SCO_PKT_TYPES_MASK_EV3 -** BTM_SCO_PKT_TYPES_MASK_EV4 -** BTM_SCO_PKT_TYPES_MASK_EV5 -** -** Returns packet types supported for the connection -** -*******************************************************************************/ -//extern -UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx); - - -/******************************************************************************* -** -** Function BTM_ReadDeviceScoPacketTypes -** -** Description This function is read the SCO packet types that -** the device supports. -** -** Returns packet types supported by the device. -** -*******************************************************************************/ -//extern -UINT16 BTM_ReadDeviceScoPacketTypes (void); - - -/******************************************************************************* -** -** Function BTM_ReadScoHandle -** -** Description This function is used to read the HCI handle used for a specific -** SCO connection, -** -** Returns handle for the connection, or 0xFFFF if invalid SCO index. -** -*******************************************************************************/ -//extern -UINT16 BTM_ReadScoHandle (UINT16 sco_inx); - - -/******************************************************************************* -** -** Function BTM_ReadScoBdAddr -** -** Description This function is read the remote BD Address for a specific -** SCO connection, -** -** Returns pointer to BD address or NULL if not known -** -*******************************************************************************/ -//extern -UINT8 *BTM_ReadScoBdAddr (UINT16 sco_inx); - - -/******************************************************************************* -** -** Function BTM_ReadScoDiscReason -** -** Description This function is returns the reason why an (e)SCO connection -** has been removed. It contains the value until read, or until -** another (e)SCO connection has disconnected. -** -** Returns HCI reason or BTM_INVALID_SCO_DISC_REASON if not set. -** -*******************************************************************************/ -//extern -UINT16 BTM_ReadScoDiscReason (void); - - -/******************************************************************************* -** -** Function BTM_SetEScoMode -** -** Description This function sets up the negotiated parameters for SCO or -** eSCO, and sets as the default mode used for calls to -** BTM_CreateSco. It can be called only when there are no -** active (e)SCO links. -** -** Returns BTM_SUCCESS if the successful. -** BTM_BUSY if there are one or more active (e)SCO links. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, - tBTM_ESCO_PARAMS *p_parms); - -/******************************************************************************* -** -** Function BTM_SetWBSCodec -** -** Description This function sends command to the controller to setup -** WBS codec for the upcoming eSCO connection. -** -** Returns BTM_SUCCESS. -** -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type); - -/******************************************************************************* -** -** Function BTM_RegForEScoEvts -** -** Description This function registers a SCO event callback with the -** specified instance. It should be used to received -** connection indication events and change of link parameter -** events. -** -** Returns BTM_SUCCESS if the successful. -** BTM_ILLEGAL_VALUE if there is an illegal sco_inx -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_RegForEScoEvts (UINT16 sco_inx, - tBTM_ESCO_CBACK *p_esco_cback); - -/******************************************************************************* -** -** Function BTM_ReadEScoLinkParms -** -** Description This function returns the current eSCO link parameters for -** the specified handle. This can be called anytime a connection -** is active, but is typically called after receiving the SCO -** opened callback. -** -** Note: If called over a 1.1 controller, only the packet types -** field has meaning. -** Note: If the upper layer doesn't know the current sco index, -** BTM_FIRST_ACTIVE_SCO_INDEX can be used as the first parameter to -** find the first active SCO index -** -** Returns BTM_SUCCESS if returned data is valid connection. -** BTM_ILLEGAL_VALUE if no connection for specified sco_inx. -** BTM_MODE_UNSUPPORTED if local controller does not support -** 1.2 specification. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ReadEScoLinkParms (UINT16 sco_inx, - tBTM_ESCO_DATA *p_parms); - -/******************************************************************************* -** -** Function BTM_ChangeEScoLinkParms -** -** Description This function requests renegotiation of the parameters on -** the current eSCO Link. If any of the changes are accepted -** by the controllers, the BTM_ESCO_CHG_EVT event is sent in -** the tBTM_ESCO_CBACK function with the current settings of -** the link. The callback is registered through the call to -** BTM_SetEScoMode. -** -** -** Returns BTM_CMD_STARTED if command is successfully initiated. -** BTM_ILLEGAL_VALUE if no connection for specified sco_inx. -** BTM_NO_RESOURCES - not enough resources to initiate command. -** BTM_MODE_UNSUPPORTED if local controller does not support -** 1.2 specification. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ChangeEScoLinkParms (UINT16 sco_inx, - tBTM_CHG_ESCO_PARAMS *p_parms); - -/******************************************************************************* -** -** Function BTM_EScoConnRsp -** -** Description This function is called upon receipt of an (e)SCO connection -** request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject -** the request. Parameters used to negotiate eSCO links. -** If p_parms is NULL, then values set through BTM_SetEScoMode -** are used. -** If the link type of the incoming request is SCO, then only -** the tx_bw, max_latency, content format, and packet_types are -** valid. The hci_status parameter should be -** ([0x0] to accept, [0x0d..0x0f] to reject) -** -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_EScoConnRsp (UINT16 sco_inx, UINT8 hci_status, - tBTM_ESCO_PARAMS *p_parms); - -/******************************************************************************* -** -** Function BTM_GetNumScoLinks -** -** Description This function returns the number of active SCO links. -** -** Returns UINT8 -** -*******************************************************************************/ -//extern -UINT8 BTM_GetNumScoLinks (void); - -/***************************************************************************** -** SECURITY MANAGEMENT FUNCTIONS -*****************************************************************************/ -/******************************************************************************* -** -** Function BTM_SecRegister -** -** Description Application manager calls this function to register for -** security services. There can be one and only one application -** saving link keys. BTM allows only first registration. -** -** Returns TRUE if registered OK, else FALSE -** -*******************************************************************************/ -//extern -BOOLEAN BTM_SecRegister (tBTM_APPL_INFO *p_cb_info); - -/******************************************************************************* -** -** Function BTM_SecRegisterLinkKeyNotificationCallback -** -** Description Profiles can register to be notified when a new Link Key -** is generated per connection. -** -** Returns TRUE if registered OK, else FALSE -** -*******************************************************************************/ -//extern -BOOLEAN BTM_SecRegisterLinkKeyNotificationCallback( - tBTM_LINK_KEY_CALLBACK *p_callback); - -/******************************************************************************* -** -** Function BTM_SecAddRmtNameNotifyCallback -** -** Description Profiles can register to be notified when name of the -** remote device is resolved (up to BTM_SEC_MAX_RMT_NAME_CALLBACKS). -** -** Returns TRUE if registered OK, else FALSE -** -*******************************************************************************/ -//extern -BOOLEAN BTM_SecAddRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback); - - -/******************************************************************************* -** -** Function BTM_SecDeleteRmtNameNotifyCallback -** -** Description A profile can deregister notification when a new Link Key -** is generated per connection. -** -** Returns TRUE if OK, else FALSE -** -*******************************************************************************/ -//extern -BOOLEAN BTM_SecDeleteRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback); - -/******************************************************************************* -** -** Function BTM_GetSecurityFlags -** -** Description Get security flags for the device -** -** Returns BOOLEAN TRUE or FALSE is device found -** -*******************************************************************************/ -//extern -BOOLEAN BTM_GetSecurityFlags (BD_ADDR bd_addr, UINT8 *p_sec_flags); - -/******************************************************************************* -** -** Function BTM_GetSecurityFlagsByTransport -** -** Description Get security flags for the device on a particular transport -** -** Parameters bd_addr: BD address of remote device -** p_sec_flags : Out parameter to be filled with security flags for the connection -** transport : Physical transport of the connection (BR/EDR or LE) -** -** Returns BOOLEAN TRUE or FALSE is device found -** -*******************************************************************************/ -//extern -BOOLEAN BTM_GetSecurityFlagsByTransport (BD_ADDR bd_addr, - UINT8 *p_sec_flags, tBT_TRANSPORT transport); - -/******************************************************************************* -** -** Function BTM_ReadTrustedMask -** -** Description Get trusted mask for the device -** -** Returns NULL, if the device record is not found. -** otherwise, the trusted mask -** -*******************************************************************************/ -//extern -UINT32 *BTM_ReadTrustedMask (BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function BTM_SetPinType -** -** Description Set PIN type for the device. -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_SetPinType (UINT8 pin_type, PIN_CODE pin_code, UINT8 pin_code_len); - - -/******************************************************************************* -** -** Function BTM_SetPairableMode -** -** Description Enable or disable pairing -** -** Parameters allow_pairing - (TRUE or FALSE) whether or not the device -** allows pairing. -** connect_only_paired - (TRUE or FALSE) whether or not to -** only allow paired devices to connect. -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_SetPairableMode (BOOLEAN allow_pairing, BOOLEAN connect_only_paired); - -/******************************************************************************* -** -** Function BTM_SetSecureConnectionsOnly -** -** Description Enable or disable default treatment for Mode 4 Level 0 services -** -** Parameter secure_connections_only_mode - (TRUE or FALSE) -** TRUE means that the device should treat Mode 4 Level 0 services as -** services of other levels. -** FALSE means that the device should provide default treatment for -** Mode 4 Level 0 services. -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_SetSecureConnectionsOnly (BOOLEAN secure_connections_only_mode); - -/******************************************************************************* -** -** Function BTM_SetSecurityLevel -** -** Description Register service security level with Security Manager. Each -** service must register its requirements regardless of the -** security level that is used. This API is called once for originators -** nad again for acceptors of connections. -** -** Returns TRUE if registered OK, else FALSE -** -*******************************************************************************/ -//extern -BOOLEAN BTM_SetSecurityLevel (BOOLEAN is_originator, const char *p_name, - UINT8 service_id, UINT16 sec_level, - UINT16 psm, UINT32 mx_proto_id, - UINT32 mx_chan_id); - -/******************************************************************************* -** -** Function BTM_SetOutService -** -** Description This function is called to set the service for -** outgoing connection. -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_SetOutService(BD_ADDR bd_addr, UINT8 service_id, UINT32 mx_chan_id); - -/******************************************************************************* -** -** Function BTM_SecClrService -** -** Description Removes specified service record(s) from the security database. -** All service records with the specified name are removed. -** Typically used only by devices with limited RAM so that it can -** reuse an old security service record. -** records (except SDP). -** -** Returns Number of records that were freed. -** -*******************************************************************************/ -//extern -UINT8 BTM_SecClrService (UINT8 service_id); - -/******************************************************************************* -** -** Function BTM_SecAddDevice -** -** Description Add/modify device. This function will be normally called -** during host startup to restore all required information -** stored in the NVRAM. -** dev_class, bd_name, link_key, and features are NULL if unknown -** -** Returns TRUE if added OK, else FALSE -** -*******************************************************************************/ -//extern -BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, - BD_NAME bd_name, UINT8 *features, - UINT32 trusted_mask[], LINK_KEY link_key, - UINT8 key_type, tBTM_IO_CAP io_cap, UINT8 pin_length); - - -/******************************************************************************* -** -** Function BTM_SecDeleteDevice -** -** Description Free resources associated with the device. -** -** Returns TRUE if rmoved OK, FALSE if not found -** -*******************************************************************************/ -//extern -BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr, tBT_TRANSPORT transport); - -/******************************************************************************* -** -** Function BTM_SecGetDeviceLinkKey -** -** Description This function is called to obtain link key for the device -** it returns BTM_SUCCESS if link key is available, or -** BTM_UNKNOWN_ADDR if Security Manager does not know about -** the device or device record does not contain link key info -** -** Returns BTM_SUCCESS if successful, otherwise error code -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SecGetDeviceLinkKey (BD_ADDR bd_addr, - LINK_KEY link_key); - - -/******************************************************************************* -** -** Function BTM_SecGetDeviceLinkKeyType -** -** Description This function is called to obtain link key type for the -** device. -** it returns BTM_SUCCESS if link key is available, or -** BTM_UNKNOWN_ADDR if Security Manager does not know about -** the device or device record does not contain link key info -** -** Returns BTM_LKEY_TYPE_IGNORE if link key is unknown, link type -** otherwise. -** -*******************************************************************************/ -//extern -tBTM_LINK_KEY_TYPE BTM_SecGetDeviceLinkKeyType (BD_ADDR bd_addr); - - -/******************************************************************************* -** -** Function BTM_PINCodeReply -** -** Description This function is called after Security Manager submitted -** PIN code request to the UI. -** -** Parameters: bd_addr - Address of the device for which PIN was requested -** res - result of the operation BTM_SUCCESS if success -** pin_len - length in bytes of the PIN Code -** p_pin - pointer to array with the PIN Code -** trusted_mask - bitwise OR of trusted services (array of UINT32) -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_PINCodeReply (BD_ADDR bd_addr, UINT8 res, UINT8 pin_len, - UINT8 *p_pin, UINT32 trusted_mask[]); - - -/******************************************************************************* -** -** Function BTM_SecBond -** -** Description This function is called to perform bonding with peer device. -** -** Parameters: bd_addr - Address of the device to bond -** pin_len - length in bytes of the PIN Code -** p_pin - pointer to array with the PIN Code -** trusted_mask - bitwise OR of trusted services (array of UINT32) - -** Returns BTM_CMD_STARTED if successfully initiated, otherwise error -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, - UINT8 pin_len, UINT8 *p_pin, - UINT32 trusted_mask[]); - -/******************************************************************************* -** -** Function BTM_SecBondByTransport -** -** Description This function is called to perform bonding by designated transport -** -** Parameters: bd_addr - Address of the device to bond -** pin_len - length in bytes of the PIN Code -** p_pin - pointer to array with the PIN Code -** trusted_mask - bitwise OR of trusted services (array of UINT32) -** transport : Physical transport to use for bonding (BR/EDR or LE) -** -** Returns BTM_CMD_STARTED if successfully initiated, otherwise error -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SecBondByTransport (BD_ADDR bd_addr, - tBT_TRANSPORT transport, - UINT8 pin_len, UINT8 *p_pin, - UINT32 trusted_mask[]); - -/******************************************************************************* -** -** Function BTM_SecBondCancel -** -** Description This function is called to cancel ongoing bonding process -** with peer device. -** -** Returns BTM_CMD_STARTED if successfully initiated, otherwise error -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SecBondCancel (BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function BTM_SetEncryption -** -** Description This function is called to ensure that connection is -** encrypted. Should be called only on an open connection. -** Typically only needed for connections that first want to -** bring up unencrypted links, then later encrypt them. -** -** Parameters: bd_addr - Address of the peer device -** p_callback - Pointer to callback function called if -** this function returns PENDING after required -** procedures are completed. Can be set to NULL -** if status is not desired. -** p_ref_data - pointer to any data the caller wishes to receive -** in the callback function upon completion. -* can be set to NULL if not used. -** -** Returns BTM_SUCCESS - already encrypted -** BTM_PENDING - command will be returned in the callback -** BTM_WRONG_MODE- connection not up. -** BTM_BUSY - security procedures are currently active -** BTM_MODE_UNSUPPORTED - if security manager not linked in. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport, - tBTM_SEC_CBACK *p_callback, void *p_ref_data); - -/******************************************************************************* -** -** Function BTM_ConfirmReqReply -** -** Description This function is called to confirm the numeric value for -** Simple Pairing in response to BTM_SP_CFM_REQ_EVT -** -** Parameters: res - result of the operation BTM_SUCCESS if success -** bd_addr - Address of the peer device -** -*******************************************************************************/ -//extern -void BTM_ConfirmReqReply(tBTM_STATUS res, BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function BTM_PasskeyReqReply -** -** Description This function is called to provide the passkey for -** Simple Pairing in response to BTM_SP_KEY_REQ_EVT -** -** Parameters: res - result of the operation BTM_SUCCESS if success -** bd_addr - Address of the peer device -** passkey - numeric value in the range of 0 - 999999(0xF423F). -** -*******************************************************************************/ -//extern -void BTM_PasskeyReqReply(tBTM_STATUS res, BD_ADDR bd_addr, UINT32 passkey); - -/******************************************************************************* -** -** Function BTM_SendKeypressNotif -** -** Description This function is used during the passkey entry model -** by a device with KeyboardOnly IO capabilities -** (very likely to be a HID Device). -** It is called by a HID Device to inform the remote device when -** a key has been entered or erased. -** -** Parameters: bd_addr - Address of the peer device -** type - notification type -** -*******************************************************************************/ -//extern -void BTM_SendKeypressNotif(BD_ADDR bd_addr, tBTM_SP_KEY_TYPE type); - -/******************************************************************************* -** -** Function BTM_IoCapRsp -** -** Description This function is called in response to BTM_SP_IO_REQ_EVT -** When the event data io_req.oob_data is set to BTM_OOB_UNKNOWN -** by the tBTM_SP_CALLBACK implementation, this function is -** called to provide the actual response -** -** Parameters: bd_addr - Address of the peer device -** io_cap - The IO capability of local device. -** oob - BTM_OOB_NONE or BTM_OOB_PRESENT. -** auth_req- MITM protection required or not. -** -*******************************************************************************/ -//extern -void BTM_IoCapRsp(BD_ADDR bd_addr, tBTM_IO_CAP io_cap, - tBTM_OOB_DATA oob, tBTM_AUTH_REQ auth_req); - -/******************************************************************************* -** -** Function BTM_ReadLocalOobData -** -** Description This function is called to read the local OOB data from -** LM -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ReadLocalOobData(void); - -/******************************************************************************* -** -** Function BTM_RemoteOobDataReply -** -** Description This function is called to provide the remote OOB data for -** Simple Pairing in response to BTM_SP_RMT_OOB_EVT -** -** Parameters: bd_addr - Address of the peer device -** c - simple pairing Hash C. -** r - simple pairing Randomizer C. -** -*******************************************************************************/ -//extern -void BTM_RemoteOobDataReply(tBTM_STATUS res, BD_ADDR bd_addr, - BT_OCTET16 c, BT_OCTET16 r); - -/******************************************************************************* -** -** Function BTM_BuildOobData -** -** Description This function is called to build the OOB data payload to -** be sent over OOB (non-Bluetooth) link -** -** Parameters: p_data - the location for OOB data -** max_len - p_data size. -** c - simple pairing Hash C. -** r - simple pairing Randomizer C. -** name_len- 0, local device name would not be included. -** otherwise, the local device name is included for -** up to this specified length -** -** Returns Number of bytes in p_data. -** -*******************************************************************************/ -//extern -UINT16 BTM_BuildOobData(UINT8 *p_data, UINT16 max_len, BT_OCTET16 c, - BT_OCTET16 r, UINT8 name_len); - -/******************************************************************************* -** -** Function BTM_BothEndsSupportSecureConnections -** -** Description This function is called to check if both the local device and the peer device -** specified by bd_addr support BR/EDR Secure Connections. -** -** Parameters: bd_addr - address of the peer -** -** Returns TRUE if BR/EDR Secure Connections are supported by both local -** and the remote device. -** else FALSE. -** -*******************************************************************************/ -//extern -BOOLEAN BTM_BothEndsSupportSecureConnections(BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function BTM_PeerSupportsSecureConnections -** -** Description This function is called to check if the peer supports -** BR/EDR Secure Connections. -** -** Parameters: bd_addr - address of the peer -** -** Returns TRUE if BR/EDR Secure Connections are supported by the peer, -** else FALSE. -** -*******************************************************************************/ -//extern -BOOLEAN BTM_PeerSupportsSecureConnections(BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function BTM_ReadOobData -** -** Description This function is called to parse the OOB data payload -** received over OOB (non-Bluetooth) link -** -** Parameters: p_data - the location for OOB data -** eir_tag - The associated EIR tag to read the data. -** *p_len(output) - the length of the data with the given tag. -** -** Returns the beginning of the data with the given tag. -** NULL, if the tag is not found. -** -*******************************************************************************/ -//extern -UINT8 *BTM_ReadOobData(UINT8 *p_data, UINT8 eir_tag, UINT8 *p_len); - -/******************************************************************************* -** -** Function BTM_SecReadDevName -** -** Description Looks for the device name in the security database for the -** specified BD address. -** -** Returns Pointer to the name or NULL -** -*******************************************************************************/ -//extern -char *BTM_SecReadDevName (BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function BTM_SecClearSecurityFlags -** -** Description Reset the security flags (mark as not-paired) for a given -** remove device. -** -*******************************************************************************/ -extern void BTM_SecClearSecurityFlags (BD_ADDR bd_addr); - - - -/***************************************************************************** -** POWER MANAGEMENT FUNCTIONS -*****************************************************************************/ -/******************************************************************************* -** -** Function BTM_PmRegister -** -** Description register or deregister with power manager -** -** Returns BTM_SUCCESS if successful, -** BTM_NO_RESOURCES if no room to hold registration -** BTM_ILLEGAL_VALUE -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_PmRegister (UINT8 mask, UINT8 *p_pm_id, - tBTM_PM_STATUS_CBACK *p_cb); - - -/******************************************************************************* -** -** Function BTM_SetPowerMode -** -** Description store the mode in control block or -** alter ACL connection behavior. -** -** Returns BTM_SUCCESS if successful, -** BTM_UNKNOWN_ADDR if bd addr is not active or bad -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetPowerMode (UINT8 pm_id, BD_ADDR remote_bda, - tBTM_PM_PWR_MD *p_mode); - - -/******************************************************************************* -** -** Function BTM_ReadPowerMode -** -** Description This returns the current mode for a specific -** ACL connection. -** -** Input Param remote_bda - device address of desired ACL connection -** -** Output Param p_mode - address where the current mode is copied into. -** BTM_ACL_MODE_NORMAL -** BTM_ACL_MODE_HOLD -** BTM_ACL_MODE_SNIFF -** BTM_ACL_MODE_PARK -** (valid only if return code is BTM_SUCCESS) -** -** Returns BTM_SUCCESS if successful, -** BTM_UNKNOWN_ADDR if bd addr is not active or bad -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ReadPowerMode (BD_ADDR remote_bda, - tBTM_PM_MODE *p_mode); - -/******************************************************************************* -** -** Function BTM_SetSsrParams -** -** Description This sends the given SSR parameters for the given ACL -** connection if it is in ACTIVE mode. -** -** Input Param remote_bda - device address of desired ACL connection -** max_lat - maximum latency (in 0.625ms)(0-0xFFFE) -** min_rmt_to - minimum remote timeout -** min_loc_to - minimum local timeout -** -** -** Returns BTM_SUCCESS if the HCI command is issued successful, -** BTM_UNKNOWN_ADDR if bd addr is not active or bad -** BTM_CMD_STORED if the command is stored -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetSsrParams (BD_ADDR remote_bda, UINT16 max_lat, - UINT16 min_rmt_to, UINT16 min_loc_to); - -/******************************************************************************* -** -** Function BTM_GetHCIConnHandle -** -** Description This function is called to get the handle for an ACL connection -** to a specific remote BD Address. -** -** Returns the handle of the connection, or 0xFFFF if none. -** -*******************************************************************************/ -//extern -UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda, tBT_TRANSPORT transport); - -/******************************************************************************* -** -** Function BTM_DeleteStoredLinkKey -** -** Description This function is called to delete link key for the specified -** device addresses from the NVRAM storage attached to the Bluetooth -** controller. -** -** Parameters: bd_addr - Addresses of the devices -** p_cb - Call back function to be called to return -** the results -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_DeleteStoredLinkKey(BD_ADDR bd_addr, tBTM_CMPL_CB *p_cb); - -/******************************************************************************* -** -** Function BTM_WriteEIR -** -** Description This function is called to write EIR data to controller. -** -** Parameters p_buff - allocated HCI command buffer including extended -** inquriry response -** -** Returns BTM_SUCCESS - if successful -** BTM_MODE_UNSUPPORTED - if local device cannot support it -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_WriteEIR( BT_HDR *p_buff ); - -/******************************************************************************* -** -** Function BTM_CheckEirData -** -** Description This function is called to get EIR data from significant part. -** -** Parameters p_eir - pointer of EIR significant part -** type - finding EIR data type -** p_length - return the length of EIR data -** -** Returns pointer of EIR data -** -*******************************************************************************/ -//extern -UINT8 *BTM_CheckEirData( UINT8 *p_eir, UINT8 type, UINT8 *p_length ); - -/******************************************************************************* -** -** Function BTM_HasEirService -** -** Description This function is called to know if UUID in bit map of UUID. -** -** Parameters p_eir_uuid - bit map of UUID list -** uuid16 - UUID 16-bit -** -** Returns TRUE - if found -** FALSE - if not found -** -*******************************************************************************/ -//extern -BOOLEAN BTM_HasEirService( UINT32 *p_eir_uuid, UINT16 uuid16 ); - -/******************************************************************************* -** -** Function BTM_HasInquiryEirService -** -** Description This function is called to know if UUID in bit map of UUID list. -** -** Parameters p_results - inquiry results -** uuid16 - UUID 16-bit -** -** Returns BTM_EIR_FOUND - if found -** BTM_EIR_NOT_FOUND - if not found and it is complete list -** BTM_EIR_UNKNOWN - if not found and it is not complete list -** -*******************************************************************************/ -//extern -tBTM_EIR_SEARCH_RESULT BTM_HasInquiryEirService( tBTM_INQ_RESULTS *p_results, - UINT16 uuid16 ); - -/******************************************************************************* -** -** Function BTM_AddEirService -** -** Description This function is called to add a service in bit map of UUID list. -** -** Parameters p_eir_uuid - bit mask of UUID list for EIR -** uuid16 - UUID 16-bit -** -** Returns None -** -*******************************************************************************/ -//extern -void BTM_AddEirService( UINT32 *p_eir_uuid, UINT16 uuid16 ); - -/******************************************************************************* -** -** Function BTM_RemoveEirService -** -** Description This function is called to remove a service in bit map of UUID list. -** -** Parameters p_eir_uuid - bit mask of UUID list for EIR -** uuid16 - UUID 16-bit -** -** Returns None -** -*******************************************************************************/ -//extern -void BTM_RemoveEirService( UINT32 *p_eir_uuid, UINT16 uuid16 ); - -/******************************************************************************* -** -** Function BTM_GetEirSupportedServices -** -** Description This function is called to get UUID list from bit map of UUID list. -** -** Parameters p_eir_uuid - bit mask of UUID list for EIR -** p - reference of current pointer of EIR -** max_num_uuid16 - max number of UUID can be written in EIR -** num_uuid16 - number of UUID have been written in EIR -** -** Returns BTM_EIR_MORE_16BITS_UUID_TYPE, if it has more than max -** BTM_EIR_COMPLETE_16BITS_UUID_TYPE, otherwise -** -*******************************************************************************/ -//extern -UINT8 BTM_GetEirSupportedServices( UINT32 *p_eir_uuid, UINT8 **p, - UINT8 max_num_uuid16, UINT8 *p_num_uuid16); - -/******************************************************************************* -** -** Function BTM_GetEirUuidList -** -** Description This function parses EIR and returns UUID list. -** -** Parameters p_eir - EIR -** uuid_size - LEN_UUID_16, LEN_UUID_32, LEN_UUID_128 -** p_num_uuid - return number of UUID in found list -** p_uuid_list - return UUID 16-bit list -** max_num_uuid - maximum number of UUID to be returned -** -** Returns 0 - if not found -** BTM_EIR_COMPLETE_16BITS_UUID_TYPE -** BTM_EIR_MORE_16BITS_UUID_TYPE -** BTM_EIR_COMPLETE_32BITS_UUID_TYPE -** BTM_EIR_MORE_32BITS_UUID_TYPE -** BTM_EIR_COMPLETE_128BITS_UUID_TYPE -** BTM_EIR_MORE_128BITS_UUID_TYPE -** -*******************************************************************************/ -//extern -UINT8 BTM_GetEirUuidList( UINT8 *p_eir, UINT8 uuid_size, UINT8 *p_num_uuid, - UINT8 *p_uuid_list, UINT8 max_num_uuid); - -/***************************************************************************** -** SCO OVER HCI -*****************************************************************************/ -/******************************************************************************* -** -** Function BTM_ConfigScoPath -** -** Description This function enable/disable SCO over HCI and registers SCO -** data callback if SCO over HCI is enabled. -** -** Parameter path: SCO or HCI -** p_sco_data_cb: callback function or SCO data if path is set -** to transport. -** p_pcm_param: pointer to the PCM interface parameter. If a NULL -** pointer is used, PCM parameter maintained in -** the control block will be used; otherwise update -** control block value. -** err_data_rpt: Lisbon feature to enable the erronous data report -** or not. -** -** Returns BTM_SUCCESS if the successful. -** BTM_NO_RESOURCES: no rsource to start the command. -** BTM_ILLEGAL_VALUE: invalid callback function pointer. -** BTM_CMD_STARTED :Command sent. Waiting for command cmpl event. -** -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ConfigScoPath (tBTM_SCO_ROUTE_TYPE path, - tBTM_SCO_DATA_CB *p_sco_data_cb, - tBTM_SCO_PCM_PARAM *p_pcm_param, - BOOLEAN err_data_rpt); - -/******************************************************************************* -** -** Function BTM_WriteScoData -** -** Description This function write SCO data to a specified instance. The data -** to be written p_buf needs to carry an offset of -** HCI_SCO_PREAMBLE_SIZE bytes, and the data length can not -** exceed BTM_SCO_DATA_SIZE_MAX bytes, whose default value is set -** to 60 and is configurable. Data longer than the maximum bytes -** will be truncated. -** -** Returns BTM_SUCCESS: data write is successful -** BTM_ILLEGAL_VALUE: SCO data contains illegal offset value. -** BTM_SCO_BAD_LENGTH: SCO data length exceeds the max SCO packet -** size. -** BTM_NO_RESOURCES: no resources. -** BTM_UNKNOWN_ADDR: unknown SCO connection handle, or SCO is not -** routed via HCI. -** -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_WriteScoData (UINT16 sco_inx, BT_HDR *p_buf); - -/******************************************************************************* -** -** Function BTM_SetARCMode -** -** Description Send Audio Routing Control command. -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_SetARCMode (UINT8 iface, UINT8 arc_mode, tBTM_VSC_CMPL_CB *p_arc_cb); - - -/******************************************************************************* -** -** Function BTM_PCM2Setup_Write -** -** Description Send PCM2_Setup write command. -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_PCM2Setup_Write (BOOLEAN clk_master, tBTM_VSC_CMPL_CB *p_arc_cb); - - -/******************************************************************************* -** -** Function BTM_PM_ReadControllerState -** -** Description This function is called to obtain the controller state -** -** Returns Controller state (BTM_CONTRL_ACTIVE, BTM_CONTRL_SCAN, and BTM_CONTRL_IDLE) -** -*******************************************************************************/ -//extern -tBTM_CONTRL_STATE BTM_PM_ReadControllerState(void); -/* -#ifdef __cplusplus -} -#endif -*/ - -#endif /* BTM_API_H */ diff --git a/tools/sdk/include/bluedroid/stack/btm_ble_api.h b/tools/sdk/include/bluedroid/stack/btm_ble_api.h deleted file mode 100644 index 0a07c643..00000000 --- a/tools/sdk/include/bluedroid/stack/btm_ble_api.h +++ /dev/null @@ -1,2059 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains the Bluetooth Manager (BTM) API function external - * definitions. - * - ******************************************************************************/ -#ifndef BTM_BLE_API_H -#define BTM_BLE_API_H - -#include "common/bt_defs.h" -#include "stack/btm_api.h" -#include "common/bt_common_types.h" - -#define CHANNEL_MAP_LEN 5 -typedef UINT8 tBTM_BLE_CHNL_MAP[CHANNEL_MAP_LEN]; - -/* 0x00-0x04 only used for set advertising parameter command */ -#define BTM_BLE_CONNECT_EVT 0x00 /* 0x00-0x04 only used for set advertising - parameter command */ -#define BTM_BLE_CONNECT_DIR_EVT 0x01 /* Connectable directed advertising */ -#define BTM_BLE_DISCOVER_EVT 0x02 /* Scannable undirected advertising */ -#define BTM_BLE_NON_CONNECT_EVT 0x03 /* Non connectable undirected advertising */ -#define BTM_BLE_CONNECT_LO_DUTY_DIR_EVT 0x04 /* Connectable low duty - cycle directed advertising */ -/* 0x00 - 0x05 can be received on adv event type */ -#define BTM_BLE_SCAN_RSP_EVT 0x04 -#define BTM_BLE_SCAN_REQ_EVT 0x05 -#define BTM_BLE_UNKNOWN_EVT 0xff - -#define BTM_BLE_UNKNOWN_EVT 0xff - -typedef UINT8 tBTM_BLE_EVT; -typedef UINT8 tBTM_BLE_CONN_MODE; - -typedef UINT32 tBTM_BLE_REF_VALUE; - -#define BTM_BLE_SCAN_MODE_PASS 0 -#define BTM_BLE_SCAN_MODE_ACTI 1 -#define BTM_BLE_SCAN_MODE_NONE 0xff -typedef UINT8 tBLE_SCAN_MODE; - -#define BTM_BLE_BATCH_SCAN_MODE_DISABLE 0 -#define BTM_BLE_BATCH_SCAN_MODE_PASS 1 -#define BTM_BLE_BATCH_SCAN_MODE_ACTI 2 -#define BTM_BLE_BATCH_SCAN_MODE_PASS_ACTI 3 - -typedef UINT8 tBTM_BLE_BATCH_SCAN_MODE; - -/* advertising channel map */ -#define BTM_BLE_ADV_CHNL_37 (0x01 << 0) -#define BTM_BLE_ADV_CHNL_38 (0x01 << 1) -#define BTM_BLE_ADV_CHNL_39 (0x01 << 2) -typedef UINT8 tBTM_BLE_ADV_CHNL_MAP; - -/*d efault advertising channel map */ -#ifndef BTM_BLE_DEFAULT_ADV_CHNL_MAP -#define BTM_BLE_DEFAULT_ADV_CHNL_MAP (BTM_BLE_ADV_CHNL_37| BTM_BLE_ADV_CHNL_38| BTM_BLE_ADV_CHNL_39) -#endif - -/* advertising filter policy */ -#define AP_SCAN_CONN_ALL 0x00 /* default */ -#define AP_SCAN_WL_CONN_ALL 0x01 -#define AP_SCAN_ALL_CONN_WL 0x02 -#define AP_SCAN_CONN_WL 0x03 -#define AP_SCAN_CONN_POLICY_MAX 0x04 -typedef UINT8 tBTM_BLE_AFP; - -/* default advertising filter policy */ -#ifndef BTM_BLE_DEFAULT_AFP -#define BTM_BLE_DEFAULT_AFP AP_SCAN_CONN_ALL -#endif - -/* scanning filter policy */ -#define SP_ADV_ALL 0x00 /* 0: accept adv packet from all, directed adv pkt not directed */ -/* to local device is ignored */ -#define SP_ADV_WL 0x01 /* 1: accept adv packet from device in white list, directed adv */ -/* packet not directed to local device is ignored */ -#define SP_ADV_ALL_RPA_DIR_ADV 0x02 /* 2: accept adv packet from all, directed adv pkt */ -/* not directed to me is ignored except direct adv with RPA */ -#define SP_ADV_WL_RPA_DIR_ADV 0x03 /* 3: accept adv packet from device in white list, directed */ -/* adv pkt not directed to me is ignored except direct adv */ -/* with RPA */ -typedef UINT8 tBTM_BLE_SFP; - -#ifndef BTM_BLE_DEFAULT_SFP -#define BTM_BLE_DEFAULT_SFP SP_ADV_ALL -#endif - -/* adv parameter boundary values */ -#define BTM_BLE_ADV_INT_MIN 0x0020 -#define BTM_BLE_ADV_INT_MAX 0x4000 - -/* Full scan boundary values */ -#define BTM_BLE_ADV_SCAN_FULL_MIN 0x00 -#define BTM_BLE_ADV_SCAN_FULL_MAX 0x64 - -/* Partial scan boundary values */ -#define BTM_BLE_ADV_SCAN_TRUNC_MIN BTM_BLE_ADV_SCAN_FULL_MIN -#define BTM_BLE_ADV_SCAN_TRUNC_MAX BTM_BLE_ADV_SCAN_FULL_MAX - -/* Threshold values */ -#define BTM_BLE_ADV_SCAN_THR_MIN BTM_BLE_ADV_SCAN_FULL_MIN -#define BTM_BLE_ADV_SCAN_THR_MAX BTM_BLE_ADV_SCAN_FULL_MAX - -/* connection parameter boundary values */ -#define BTM_BLE_SCAN_INT_MIN 0x0004 -#define BTM_BLE_SCAN_INT_MAX 0x4000 -#define BTM_BLE_SCAN_WIN_MIN 0x0004 -#define BTM_BLE_SCAN_WIN_MAX 0x4000 -#define BTM_BLE_EXT_SCAN_INT_MAX 0x00FFFFFF -#define BTM_BLE_EXT_SCAN_WIN_MAX 0xFFFF -#define BTM_BLE_CONN_INT_MIN 0x0006 -#define BTM_BLE_CONN_INT_MAX 0x0C80 -#define BTM_BLE_CONN_LATENCY_MAX 500 -#define BTM_BLE_CONN_SUP_TOUT_MIN 0x000A -#define BTM_BLE_CONN_SUP_TOUT_MAX 0x0C80 -#define BTM_BLE_CONN_PARAM_UNDEF 0xffff /* use this value when a specific value not to be overwritten */ -#define BTM_BLE_SCAN_PARAM_UNDEF 0xffffffff - -/* default connection parameters if not configured, use GAP recommend value for auto/selective connection */ -/* default scan interval */ -#ifndef BTM_BLE_SCAN_FAST_INT -#define BTM_BLE_SCAN_FAST_INT 96 /* 30 ~ 60 ms (use 60) = 96 *0.625 */ -#endif -/* default scan window for background connection, applicable for auto connection or selective conenction */ -#ifndef BTM_BLE_SCAN_FAST_WIN -#define BTM_BLE_SCAN_FAST_WIN 48 /* 30 ms = 48 *0.625 */ -#endif - -/* default scan paramter used in reduced power cycle (background scanning) */ -#ifndef BTM_BLE_SCAN_SLOW_INT_1 -#define BTM_BLE_SCAN_SLOW_INT_1 2048 /* 1.28 s = 2048 *0.625 */ -#endif -#ifndef BTM_BLE_SCAN_SLOW_WIN_1 -#define BTM_BLE_SCAN_SLOW_WIN_1 48 /* 30 ms = 48 *0.625 */ -#endif - -/* default scan paramter used in reduced power cycle (background scanning) */ -#ifndef BTM_BLE_SCAN_SLOW_INT_2 -#define BTM_BLE_SCAN_SLOW_INT_2 4096 /* 2.56 s = 4096 *0.625 */ -#endif -#ifndef BTM_BLE_SCAN_SLOW_WIN_2 -#define BTM_BLE_SCAN_SLOW_WIN_2 36 /* 22.5 ms = 36 *0.625 */ -#endif - -/* default connection interval min */ -#ifndef BTM_BLE_CONN_INT_MIN_DEF -#define BTM_BLE_CONN_INT_MIN_DEF 10 /* recommended min: 12.5 ms = 10 * 1.25 */ -#endif - -/* default connection interval max */ -#ifndef BTM_BLE_CONN_INT_MAX_DEF -#define BTM_BLE_CONN_INT_MAX_DEF 12 /* recommended max: 15 ms = 12 * 1.25 */ -#endif - -/* default slave latency */ -#ifndef BTM_BLE_CONN_SLAVE_LATENCY_DEF -#define BTM_BLE_CONN_SLAVE_LATENCY_DEF 0 /* 0 */ -#endif - -/* default supervision timeout */ -#ifndef BTM_BLE_CONN_TIMEOUT_DEF -#define BTM_BLE_CONN_TIMEOUT_DEF 600 -#endif - -/* minimum acceptable connection interval */ -#ifndef BTM_BLE_CONN_INT_MIN_LIMIT -#define BTM_BLE_CONN_INT_MIN_LIMIT 0x0009 -#endif - -#define BTM_BLE_DIR_CONN_FALLBACK_UNDIR 1 -#define BTM_BLE_DIR_CONN_FALLBACK_NO_ADV 2 - -#ifndef BTM_BLE_DIR_CONN_FALLBACK -#define BTM_BLE_DIR_CONN_FALLBACK BTM_BLE_DIR_CONN_FALLBACK_UNDIR -#endif - -#define BTM_CMAC_TLEN_SIZE 8 /* 64 bits */ -#define BTM_BLE_AUTH_SIGN_LEN 12 /* BLE data signature length 8 Bytes + 4 bytes counter*/ -typedef UINT8 BLE_SIGNATURE[BTM_BLE_AUTH_SIGN_LEN]; /* Device address */ - -#ifndef BTM_BLE_HOST_SUPPORT -#define BTM_BLE_HOST_SUPPORT 0x01 -#endif - -#ifndef BTM_BLE_SIMULTANEOUS_HOST -#define BTM_BLE_SIMULTANEOUS_HOST 0x01 -#endif - -/* Appearance Values Reported with BTM_BLE_AD_TYPE_APPEARANCE */ -#define BTM_BLE_APPEARANCE_UNKNOWN 0x0000 -#define BTM_BLE_APPEARANCE_GENERIC_PHONE 0x0040 -#define BTM_BLE_APPEARANCE_GENERIC_COMPUTER 0x0080 -#define BTM_BLE_APPEARANCE_GENERIC_WATCH 0x00C0 -#define BTM_BLE_APPEARANCE_SPORTS_WATCH 0x00C1 -#define BTM_BLE_APPEARANCE_GENERIC_CLOCK 0x0100 -#define BTM_BLE_APPEARANCE_GENERIC_DISPLAY 0x0140 -#define BTM_BLE_APPEARANCE_GENERIC_REMOTE 0x0180 -#define BTM_BLE_APPEARANCE_GENERIC_EYEGLASSES 0x01C0 -#define BTM_BLE_APPEARANCE_GENERIC_TAG 0x0200 -#define BTM_BLE_APPEARANCE_GENERIC_KEYRING 0x0240 -#define BTM_BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 0x0280 -#define BTM_BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 0x02C0 -#define BTM_BLE_APPEARANCE_GENERIC_THERMOMETER 0x0300 -#define BTM_BLE_APPEARANCE_THERMOMETER_EAR 0x0301 -#define BTM_BLE_APPEARANCE_GENERIC_HEART_RATE 0x0340 -#define BTM_BLE_APPEARANCE_HEART_RATE_BELT 0x0341 -#define BTM_BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 0x0380 -#define BTM_BLE_APPEARANCE_BLOOD_PRESSURE_ARM 0x0381 -#define BTM_BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 0x0382 -#define BTM_BLE_APPEARANCE_GENERIC_HID 0x03C0 -#define BTM_BLE_APPEARANCE_HID_KEYBOARD 0x03C1 -#define BTM_BLE_APPEARANCE_HID_MOUSE 0x03C2 -#define BTM_BLE_APPEARANCE_HID_JOYSTICK 0x03C3 -#define BTM_BLE_APPEARANCE_HID_GAMEPAD 0x03C4 -#define BTM_BLE_APPEARANCE_HID_DIGITIZER_TABLET 0x03C5 -#define BTM_BLE_APPEARANCE_HID_CARD_READER 0x03C6 -#define BTM_BLE_APPEARANCE_HID_DIGITAL_PEN 0x03C7 -#define BTM_BLE_APPEARANCE_HID_BARCODE_SCANNER 0x03C8 -#define BTM_BLE_APPEARANCE_GENERIC_GLUCOSE 0x0400 -#define BTM_BLE_APPEARANCE_GENERIC_WALKING 0x0440 -#define BTM_BLE_APPEARANCE_WALKING_IN_SHOE 0x0441 -#define BTM_BLE_APPEARANCE_WALKING_ON_SHOE 0x0442 -#define BTM_BLE_APPEARANCE_WALKING_ON_HIP 0x0443 -#define BTM_BLE_APPEARANCE_GENERIC_CYCLING 0x0480 -#define BTM_BLE_APPEARANCE_CYCLING_COMPUTER 0x0481 -#define BTM_BLE_APPEARANCE_CYCLING_SPEED 0x0482 -#define BTM_BLE_APPEARANCE_CYCLING_CADENCE 0x0483 -#define BTM_BLE_APPEARANCE_CYCLING_POWER 0x0484 -#define BTM_BLE_APPEARANCE_CYCLING_SPEED_CADENCE 0x0485 -#define BTM_BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 0x0C40 -#define BTM_BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 0x0C41 -#define BTM_BLE_APPEARANCE_PULSE_OXIMETER_WRIST 0x0C42 -#define BTM_BLE_APPEARANCE_GENERIC_WEIGHT 0x0C80 -#define BTM_BLE_APPEARANCE_GENERIC_PERSONAL_MOBILITY_DEVICE 0x0CC0 -#define BTM_BLE_APPEARANCE_POWERED_WHEELCHAIR 0x0CC1 -#define BTM_BLE_APPEARANCE_MOBILITY_SCOOTER 0x0CC2 -#define BTM_BLE_APPEARANCE_GENERIC_CONTINUOUS_GLUCOSE_MONITOR 0x0D00 -#define BTM_BLE_APPEARANCE_GENERIC_INSULIN_PUMP 0x0D40 -#define BTM_BLE_APPEARANCE_INSULIN_PUMP_DURABLE_PUMP 0x0D41 -#define BTM_BLE_APPEARANCE_INSULIN_PUMP_PATCH_PUMP 0x0D44 -#define BTM_BLE_APPEARANCE_INSULIN_PEN 0x0D48 -#define BTM_BLE_APPEARANCE_GENERIC_MEDICATION_DELIVERY 0x0D80 -#define BTM_BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS 0x1440 -#define BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION 0x1441 -#define BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_AND_NAV 0x1442 -#define BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD 0x1443 -#define BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD_AND_NAV 0x1444 - - -/* Structure returned with Rand/Encrypt complete callback */ -typedef struct { - UINT8 status; - UINT8 param_len; - UINT16 opcode; - UINT8 param_buf[BT_OCTET16_LEN]; -} tBTM_RAND_ENC; - -/* General callback function for notifying an application that a synchronous -** BTM function is complete. The pointer contains the address of any returned data. -*/ -typedef void (tBTM_RAND_ENC_CB) (tBTM_RAND_ENC *p1); - -#define BTM_BLE_FILTER_TARGET_SCANNER 0x01 -#define BTM_BLE_FILTER_TARGET_ADVR 0x00 - -#define BTM_BLE_POLICY_BLACK_ALL 0x00 /* relevant to both */ -#define BTM_BLE_POLICY_ALLOW_SCAN 0x01 /* relevant to advertiser */ -#define BTM_BLE_POLICY_ALLOW_CONN 0x02 /* relevant to advertiser */ -#define BTM_BLE_POLICY_WHITE_ALL 0x03 /* relevant to both */ - -/* ADV data flag bit definition used for BTM_BLE_AD_TYPE_FLAG */ -#define BTM_BLE_LIMIT_DISC_FLAG (0x01 << 0) -#define BTM_BLE_GEN_DISC_FLAG (0x01 << 1) -#define BTM_BLE_BREDR_NOT_SPT (0x01 << 2) -/* 4.1 spec adv flag for simultaneous BR/EDR+LE connection support */ -#define BTM_BLE_DMT_CONTROLLER_SPT (0x01 << 3) -#define BTM_BLE_DMT_HOST_SPT (0x01 << 4) -#define BTM_BLE_NON_LIMIT_DISC_FLAG (0x00 ) /* lowest bit unset */ -#define BTM_BLE_ADV_FLAG_MASK (BTM_BLE_LIMIT_DISC_FLAG | BTM_BLE_BREDR_NOT_SPT | BTM_BLE_GEN_DISC_FLAG) -#define BTM_BLE_LIMIT_DISC_MASK (BTM_BLE_LIMIT_DISC_FLAG ) - -#define BTM_BLE_AD_BIT_DEV_NAME (0x00000001 << 0) -#define BTM_BLE_AD_BIT_FLAGS (0x00000001 << 1) -#define BTM_BLE_AD_BIT_MANU (0x00000001 << 2) -#define BTM_BLE_AD_BIT_TX_PWR (0x00000001 << 3) -#define BTM_BLE_AD_BIT_INT_RANGE (0x00000001 << 5) -#define BTM_BLE_AD_BIT_SERVICE (0x00000001 << 6) -#define BTM_BLE_AD_BIT_SERVICE_SOL (0x00000001 << 7) -#define BTM_BLE_AD_BIT_SERVICE_DATA (0x00000001 << 8) -#define BTM_BLE_AD_BIT_SIGN_DATA (0x00000001 << 9) -#define BTM_BLE_AD_BIT_SERVICE_128SOL (0x00000001 << 10) -#define BTM_BLE_AD_BIT_APPEARANCE (0x00000001 << 11) -#define BTM_BLE_AD_BIT_PUBLIC_ADDR (0x00000001 << 12) -#define BTM_BLE_AD_BIT_RANDOM_ADDR (0x00000001 << 13) -#define BTM_BLE_AD_BIT_SERVICE_32 (0x00000001 << 4) -#define BTM_BLE_AD_BIT_SERVICE_32SOL (0x00000001 << 14) -#define BTM_BLE_AD_BIT_PROPRIETARY (0x00000001 << 15) -#define BTM_BLE_AD_BIT_SERVICE_128 (0x00000001 << 16) /*128-bit Service UUIDs*/ - -typedef UINT32 tBTM_BLE_AD_MASK; - -/* relate to ESP_BLE_AD_TYPE_xxx in esp_gap_ble_api.h */ -#define BTM_BLE_AD_TYPE_FLAG HCI_EIR_FLAGS_TYPE /* 0x01 */ -#define BTM_BLE_AD_TYPE_16SRV_PART HCI_EIR_MORE_16BITS_UUID_TYPE /* 0x02 */ -#define BTM_BLE_AD_TYPE_16SRV_CMPL HCI_EIR_COMPLETE_16BITS_UUID_TYPE /* 0x03 */ -#define BTM_BLE_AD_TYPE_32SRV_PART HCI_EIR_MORE_32BITS_UUID_TYPE /* 0x04 */ -#define BTM_BLE_AD_TYPE_32SRV_CMPL HCI_EIR_COMPLETE_32BITS_UUID_TYPE /* 0x05 */ -#define BTM_BLE_AD_TYPE_128SRV_PART HCI_EIR_MORE_128BITS_UUID_TYPE /* 0x06 */ -#define BTM_BLE_AD_TYPE_128SRV_CMPL HCI_EIR_COMPLETE_128BITS_UUID_TYPE /* 0x07 */ -#define BTM_BLE_AD_TYPE_NAME_SHORT HCI_EIR_SHORTENED_LOCAL_NAME_TYPE /* 0x08 */ -#define BTM_BLE_AD_TYPE_NAME_CMPL HCI_EIR_COMPLETE_LOCAL_NAME_TYPE /* 0x09 */ -#define BTM_BLE_AD_TYPE_TX_PWR HCI_EIR_TX_POWER_LEVEL_TYPE /* 0x0A */ -#define BTM_BLE_AD_TYPE_DEV_CLASS 0x0D -#define BTM_BLE_AD_TYPE_SM_TK 0x10 -#define BTM_BLE_AD_TYPE_SM_OOB_FLAG 0x11 -#define BTM_BLE_AD_TYPE_INT_RANGE 0x12 -#define BTM_BLE_AD_TYPE_SOL_SRV_UUID 0x14 -#define BTM_BLE_AD_TYPE_128SOL_SRV_UUID 0x15 -#define BTM_BLE_AD_TYPE_SERVICE_DATA 0x16 -#define BTM_BLE_AD_TYPE_PUBLIC_TARGET 0x17 -#define BTM_BLE_AD_TYPE_RANDOM_TARGET 0x18 -#define BTM_BLE_AD_TYPE_APPEARANCE 0x19 -#define BTM_BLE_AD_TYPE_ADV_INT 0x1a -#define BTM_BLE_AD_TYPE_LE_DEV_ADDR 0x1b -#define BTM_BLE_AD_TYPE_LE_ROLE 0x1c -#define BTM_BLE_AD_TYPE_SPAIR_C256 0x1d -#define BTM_BLE_AD_TYPE_SPAIR_R256 0x1e -#define BTM_BLE_AD_TYPE_32SOL_SRV_UUID 0x1f -#define BTM_BLE_AD_TYPE_32SERVICE_DATA 0x20 -#define BTM_BLE_AD_TYPE_128SERVICE_DATA 0x21 -#define BTM_BLE_AD_TYPE_LE_SECURE_CONFIRM 0x22 -#define BTM_BLE_AD_TYPE_LE_SECURE_RANDOM 0x23 -#define BTM_BLE_AD_TYPE_URI 0x24 -#define BTM_BLE_AD_TYPE_INDOOR_POSITION 0x25 -#define BTM_BLE_AD_TYPE_TRANS_DISC_DATA 0x26 -#define BTM_BLE_AD_TYPE_LE_SUPPORT_FEATURE 0x27 -#define BTM_BLE_AD_TYPE_CHAN_MAP_UPDATE 0x28 - -#define BTM_BLE_AD_TYPE_MANU HCI_EIR_MANUFACTURER_SPECIFIC_TYPE /* 0xff */ -typedef UINT8 tBTM_BLE_AD_TYPE; - -/* Security settings used with L2CAP LE COC */ -#define BTM_SEC_LE_LINK_ENCRYPTED 0x01 -#define BTM_SEC_LE_LINK_PAIRED_WITHOUT_MITM 0x02 -#define BTM_SEC_LE_LINK_PAIRED_WITH_MITM 0x04 - -/* Min/max Preferred number of payload octets that the local Controller - should include in a single Link Layer Data Channel PDU. */ -#define BTM_BLE_DATA_SIZE_MAX 0x00fb -#define BTM_BLE_DATA_SIZE_MIN 0x001b - -/* Preferred maximum number of microseconds that the local Controller - should use to transmit a single Link Layer Data Channel PDU. */ -#define BTM_BLE_DATA_TX_TIME_MIN 0x0148 -#define BTM_BLE_DATA_TX_TIME_MAX 0x0848 - -/* adv tx power level */ -#define BTM_BLE_ADV_TX_POWER_MIN 0 /* minimum tx power */ -#define BTM_BLE_ADV_TX_POWER_MAX 7 /* maximum tx power */ -typedef UINT8 tBTM_BLE_ADV_TX_POWER; - -/* adv tx power in dBm */ -typedef struct { - UINT8 adv_inst_max; /* max adv instance supported in controller */ - UINT8 rpa_offloading; - UINT16 tot_scan_results_strg; - UINT8 max_irk_list_sz; - UINT8 filter_support; - UINT8 max_filter; - UINT8 energy_support; - BOOLEAN values_read; - UINT16 version_supported; - UINT16 total_trackable_advertisers; - UINT8 extended_scan_support; - UINT8 debug_logging_supported; -} tBTM_BLE_VSC_CB; - -/* slave preferred connection interval range */ -typedef struct { - UINT16 low; - UINT16 hi; - -} tBTM_BLE_INT_RANGE; - -/* Service tag supported in the device */ -typedef struct { - UINT8 num_service; - BOOLEAN list_cmpl; - UINT16 *p_uuid; -} tBTM_BLE_SERVICE; - -/* 32 bits Service supported in the device */ -typedef struct { - UINT8 num_service; - BOOLEAN list_cmpl; - UINT32 *p_uuid; -} tBTM_BLE_32SERVICE; - -/* 128 bits Service supported in the device */ -typedef struct { - BOOLEAN list_cmpl; - UINT8 uuid128[MAX_UUID_SIZE]; -} tBTM_BLE_128SERVICE; - -typedef struct { - UINT8 len; - UINT8 *p_val; -} tBTM_BLE_MANU; - - -typedef struct { - tBT_UUID service_uuid; - UINT8 len; - UINT8 *p_val; -} tBTM_BLE_SERVICE_DATA; - -typedef struct { - UINT8 adv_type; - UINT8 len; - UINT8 *p_val; /* number of len byte */ -} tBTM_BLE_PROP_ELEM; - -typedef struct { - UINT8 num_elem; - tBTM_BLE_PROP_ELEM *p_elem; -} tBTM_BLE_PROPRIETARY; - -typedef struct { - tBTM_BLE_INT_RANGE int_range; /* slave prefered conn interval range */ - tBTM_BLE_MANU *p_manu; /* manufactuer data */ - tBTM_BLE_SERVICE *p_services; /* services */ - tBTM_BLE_128SERVICE *p_services_128b; /* 128 bits service */ - tBTM_BLE_32SERVICE *p_service_32b; /* 32 bits Service UUID */ - tBTM_BLE_SERVICE *p_sol_services; /* 16 bits services Solicitation UUIDs */ - tBTM_BLE_32SERVICE *p_sol_service_32b; /* List of 32 bit Service Solicitation UUIDs */ - tBTM_BLE_128SERVICE *p_sol_service_128b; /* List of 128 bit Service Solicitation UUIDs */ - tBTM_BLE_PROPRIETARY *p_proprietary; - tBTM_BLE_SERVICE_DATA *p_service_data; /* service data */ - UINT16 appearance; - UINT8 flag; - UINT8 tx_power; -} tBTM_BLE_ADV_DATA; - -#ifndef BTM_BLE_MULTI_ADV_MAX -#define BTM_BLE_MULTI_ADV_MAX 16 /* controller returned adv_inst_max should be less - than this number */ -#endif - -#define BTM_BLE_MULTI_ADV_INVALID 0 - -#define BTM_BLE_MULTI_ADV_ENB_EVT 1 -#define BTM_BLE_MULTI_ADV_DISABLE_EVT 2 -#define BTM_BLE_MULTI_ADV_PARAM_EVT 3 -#define BTM_BLE_MULTI_ADV_DATA_EVT 4 -typedef UINT8 tBTM_BLE_MULTI_ADV_EVT; - -#define BTM_BLE_MULTI_ADV_DEFAULT_STD 0 - -typedef struct { - UINT16 adv_int_min; - UINT16 adv_int_max; - UINT8 adv_type; - tBTM_BLE_ADV_CHNL_MAP channel_map; - tBTM_BLE_AFP adv_filter_policy; - tBTM_BLE_ADV_TX_POWER tx_power; -} tBTM_BLE_ADV_PARAMS; - -typedef struct { - UINT8 *p_sub_code; /* dynamic array to store sub code */ - UINT8 *p_inst_id; /* dynamic array to store instance id */ - UINT8 pending_idx; - UINT8 next_idx; -} tBTM_BLE_MULTI_ADV_OPQ; - -typedef void (tBTM_BLE_MULTI_ADV_CBACK)(tBTM_BLE_MULTI_ADV_EVT evt, UINT8 inst_id, - void *p_ref, tBTM_STATUS status); - -typedef struct { - UINT8 inst_id; - BOOLEAN in_use; - UINT8 adv_evt; - BD_ADDR rpa; - TIMER_LIST_ENT raddr_timer_ent; - tBTM_BLE_MULTI_ADV_CBACK *p_cback; - void *p_ref; - UINT8 index; -} tBTM_BLE_MULTI_ADV_INST; - -typedef struct { - UINT8 inst_index_queue[BTM_BLE_MULTI_ADV_MAX]; - int front; - int rear; -} tBTM_BLE_MULTI_ADV_INST_IDX_Q; - -typedef struct { - tBTM_BLE_MULTI_ADV_INST *p_adv_inst; /* dynamic array to store adv instance */ - tBTM_BLE_MULTI_ADV_OPQ op_q; -} tBTM_BLE_MULTI_ADV_CB; - -typedef UINT8 tGATT_IF; - -typedef void (tBTM_BLE_SCAN_THRESHOLD_CBACK)(tBTM_BLE_REF_VALUE ref_value); -typedef void (tBTM_BLE_SCAN_REP_CBACK)(tBTM_BLE_REF_VALUE ref_value, UINT8 report_format, - UINT8 num_records, UINT16 total_len, - UINT8 *p_rep_data, UINT8 status); -typedef void (tBTM_BLE_SCAN_SETUP_CBACK)(UINT8 evt, tBTM_BLE_REF_VALUE ref_value, UINT8 status); - -#ifndef BTM_BLE_BATCH_SCAN_MAX -#define BTM_BLE_BATCH_SCAN_MAX 5 -#endif - -#ifndef BTM_BLE_BATCH_REP_MAIN_Q_SIZE -#define BTM_BLE_BATCH_REP_MAIN_Q_SIZE 2 -#endif - -typedef enum { - BTM_BLE_SCAN_INVALID_STATE = 0, - BTM_BLE_SCAN_ENABLE_CALLED = 1, - BTM_BLE_SCAN_ENABLED_STATE = 2, - BTM_BLE_SCAN_DISABLE_CALLED = 3, - BTM_BLE_SCAN_DISABLED_STATE = 4 -} tBTM_BLE_BATCH_SCAN_STATE; - -enum { - BTM_BLE_DISCARD_OLD_ITEMS, - BTM_BLE_DISCARD_LOWER_RSSI_ITEMS -}; -typedef UINT8 tBTM_BLE_DISCARD_RULE; - -typedef struct { - UINT8 sub_code[BTM_BLE_BATCH_SCAN_MAX]; - tBTM_BLE_BATCH_SCAN_STATE cur_state[BTM_BLE_BATCH_SCAN_MAX]; - tBTM_BLE_REF_VALUE ref_value[BTM_BLE_BATCH_SCAN_MAX]; - UINT8 pending_idx; - UINT8 next_idx; -} tBTM_BLE_BATCH_SCAN_OPQ; - -typedef struct { - UINT8 rep_mode[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; - tBTM_BLE_REF_VALUE ref_value[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; - UINT8 num_records[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; - UINT16 data_len[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; - UINT8 *p_data[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; - UINT8 pending_idx; - UINT8 next_idx; -} tBTM_BLE_BATCH_SCAN_REP_Q; - -typedef struct { - tBTM_BLE_BATCH_SCAN_STATE cur_state; - tBTM_BLE_BATCH_SCAN_MODE scan_mode; - UINT32 scan_interval; - UINT32 scan_window; - tBLE_ADDR_TYPE addr_type; - tBTM_BLE_DISCARD_RULE discard_rule; - tBTM_BLE_BATCH_SCAN_OPQ op_q; - tBTM_BLE_BATCH_SCAN_REP_Q main_rep_q; - tBTM_BLE_SCAN_SETUP_CBACK *p_setup_cback; - tBTM_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback; - tBTM_BLE_SCAN_REP_CBACK *p_scan_rep_cback; - tBTM_BLE_REF_VALUE ref_value; -} tBTM_BLE_BATCH_SCAN_CB; - -/// Ble scan duplicate type -enum { - BTM_BLE_SCAN_DUPLICATE_DISABLE = 0x0, /*!< the Link Layer should generate advertising reports to the host for each packet received */ - BTM_BLE_SCAN_DUPLICATE_ENABLE = 0x1, /*!< the Link Layer should filter out duplicate advertising reports to the Host */ - BTM_BLE_SCAN_DUPLICATE_MAX = 0x2, /*!< 0x02 – 0xFF, Reserved for future use */ -}; -/* filter selection bit index */ -#define BTM_BLE_PF_ADDR_FILTER 0 -#define BTM_BLE_PF_SRVC_DATA 1 -#define BTM_BLE_PF_SRVC_UUID 2 -#define BTM_BLE_PF_SRVC_SOL_UUID 3 -#define BTM_BLE_PF_LOCAL_NAME 4 -#define BTM_BLE_PF_MANU_DATA 5 -#define BTM_BLE_PF_SRVC_DATA_PATTERN 6 -#define BTM_BLE_PF_TYPE_ALL 7 /* when passed in payload filter type all, only clear action is applicable */ -#define BTM_BLE_PF_TYPE_MAX 8 - -/* max number of filter spot for different filter type */ -#ifndef BTM_BLE_MAX_UUID_FILTER -#define BTM_BLE_MAX_UUID_FILTER 8 -#endif -#ifndef BTM_BLE_MAX_ADDR_FILTER -#define BTM_BLE_MAX_ADDR_FILTER 8 -#endif -#ifndef BTM_BLE_PF_STR_COND_MAX -#define BTM_BLE_PF_STR_COND_MAX 4 /* apply to manu data , or local name */ -#endif -#ifndef BTM_BLE_PF_STR_LEN_MAX -#define BTM_BLE_PF_STR_LEN_MAX 29 /* match for first 29 bytes */ -#endif - -typedef UINT8 tBTM_BLE_PF_COND_TYPE; - -#define BTM_BLE_PF_LOGIC_OR 0 -#define BTM_BLE_PF_LOGIC_AND 1 -typedef UINT8 tBTM_BLE_PF_LOGIC_TYPE; - -#define BTM_BLE_PF_ENABLE 1 -#define BTM_BLE_PF_CONFIG 2 -typedef UINT8 tBTM_BLE_PF_ACTION; - -typedef UINT8 tBTM_BLE_PF_FILT_INDEX; - -typedef UINT8 tBTM_BLE_PF_AVBL_SPACE; - -#define BTM_BLE_PF_BRDCAST_ADDR_FILT 1 -#define BTM_BLE_PF_SERV_DATA_CHG_FILT 2 -#define BTM_BLE_PF_SERV_UUID 4 -#define BTM_BLE_PF_SERV_SOLC_UUID 8 -#define BTM_BLE_PF_LOC_NAME_CHECK 16 -#define BTM_BLE_PF_MANUF_NAME_CHECK 32 -#define BTM_BLE_PF_SERV_DATA_CHECK 64 -typedef UINT16 tBTM_BLE_PF_FEAT_SEL; - -#define BTM_BLE_PF_LIST_LOGIC_OR 1 -#define BTM_BLE_PF_LIST_LOGIC_AND 2 -typedef UINT16 tBTM_BLE_PF_LIST_LOGIC_TYPE; - -#define BTM_BLE_PF_FILT_LOGIC_OR 0 -#define BTM_BLE_PF_FILT_LOGIC_AND 1 -typedef UINT16 tBTM_BLE_PF_FILT_LOGIC_TYPE; - -typedef UINT8 tBTM_BLE_PF_RSSI_THRESHOLD; -typedef UINT8 tBTM_BLE_PF_DELIVERY_MODE; -typedef UINT16 tBTM_BLE_PF_TIMEOUT; -typedef UINT8 tBTM_BLE_PF_TIMEOUT_CNT; -typedef UINT16 tBTM_BLE_PF_ADV_TRACK_ENTRIES; - -typedef struct { - tBTM_BLE_PF_FEAT_SEL feat_seln; - tBTM_BLE_PF_LIST_LOGIC_TYPE logic_type; - tBTM_BLE_PF_FILT_LOGIC_TYPE filt_logic_type; - tBTM_BLE_PF_RSSI_THRESHOLD rssi_high_thres; - tBTM_BLE_PF_RSSI_THRESHOLD rssi_low_thres; - tBTM_BLE_PF_DELIVERY_MODE dely_mode; - tBTM_BLE_PF_TIMEOUT found_timeout; - tBTM_BLE_PF_TIMEOUT lost_timeout; - tBTM_BLE_PF_TIMEOUT_CNT found_timeout_cnt; - tBTM_BLE_PF_ADV_TRACK_ENTRIES num_of_tracking_entries; -} tBTM_BLE_PF_FILT_PARAMS; - -enum { - BTM_BLE_SCAN_COND_ADD, - BTM_BLE_SCAN_COND_DELETE, - BTM_BLE_SCAN_COND_CLEAR = 2 -}; -typedef UINT8 tBTM_BLE_SCAN_COND_OP; - -enum { - BTM_BLE_FILT_ENABLE_DISABLE = 1, - BTM_BLE_FILT_CFG = 2, - BTM_BLE_FILT_ADV_PARAM = 3 -}; - -typedef UINT8 tBTM_BLE_FILT_CB_EVT; - -/* BLE adv payload filtering config complete callback */ -typedef void (tBTM_BLE_PF_CFG_CBACK)(tBTM_BLE_PF_ACTION action, tBTM_BLE_SCAN_COND_OP cfg_op, - tBTM_BLE_PF_AVBL_SPACE avbl_space, tBTM_STATUS status, - tBTM_BLE_REF_VALUE ref_value); - -typedef void (tBTM_BLE_PF_CMPL_CBACK) (tBTM_BLE_PF_CFG_CBACK); - -/* BLE adv payload filtering status setup complete callback */ -typedef void (tBTM_BLE_PF_STATUS_CBACK) (UINT8 action, tBTM_STATUS status, - tBTM_BLE_REF_VALUE ref_value); - -/* BLE adv payload filtering param setup complete callback */ -typedef void (tBTM_BLE_PF_PARAM_CBACK) (tBTM_BLE_PF_ACTION action_type, - tBTM_BLE_PF_AVBL_SPACE avbl_space, - tBTM_BLE_REF_VALUE ref_value, tBTM_STATUS status); - -typedef union { - UINT16 uuid16_mask; - UINT32 uuid32_mask; - UINT8 uuid128_mask[LEN_UUID_128]; -} tBTM_BLE_PF_COND_MASK; - -typedef struct { - tBLE_BD_ADDR *p_target_addr; /* target address, if NULL, generic UUID filter */ - tBT_UUID uuid; /* UUID condition */ - tBTM_BLE_PF_LOGIC_TYPE cond_logic; /* AND/OR */ - tBTM_BLE_PF_COND_MASK *p_uuid_mask; /* UUID mask */ -} tBTM_BLE_PF_UUID_COND; - -typedef struct { - UINT8 data_len; /* <= 20 bytes */ - UINT8 *p_data; -} tBTM_BLE_PF_LOCAL_NAME_COND; - -typedef struct { - UINT16 company_id; /* company ID */ - UINT8 data_len; /* <= 20 bytes */ - UINT8 *p_pattern; - UINT16 company_id_mask; /* UUID value mask */ - UINT8 *p_pattern_mask; /* Manufacturer data matching mask, - same length as data pattern, - set to all 0xff, match exact data */ -} tBTM_BLE_PF_MANU_COND; - -typedef struct { - UINT16 uuid; /* service ID */ - UINT8 data_len; /* <= 20 bytes */ - UINT8 *p_pattern; - UINT8 *p_pattern_mask; /* Service data matching mask, same length as data pattern, - set to all 0xff, match exact data */ -} tBTM_BLE_PF_SRVC_PATTERN_COND; - - -typedef union { - tBLE_BD_ADDR target_addr; - tBTM_BLE_PF_LOCAL_NAME_COND local_name; /* lcoal name filtering */ - tBTM_BLE_PF_MANU_COND manu_data; /* manufactuer data filtering */ - tBTM_BLE_PF_UUID_COND srvc_uuid; /* service UUID filtering */ - tBTM_BLE_PF_UUID_COND solicitate_uuid; /* solicitated service UUID filtering */ - tBTM_BLE_PF_SRVC_PATTERN_COND srvc_data; /* service data pattern */ -} tBTM_BLE_PF_COND_PARAM; - -typedef struct { - UINT8 action_ocf[BTM_BLE_PF_TYPE_MAX]; - tBTM_BLE_REF_VALUE ref_value[BTM_BLE_PF_TYPE_MAX]; - tBTM_BLE_PF_PARAM_CBACK *p_filt_param_cback[BTM_BLE_PF_TYPE_MAX]; - tBTM_BLE_PF_CFG_CBACK *p_scan_cfg_cback[BTM_BLE_PF_TYPE_MAX]; - UINT8 cb_evt[BTM_BLE_PF_TYPE_MAX]; - UINT8 pending_idx; - UINT8 next_idx; -} tBTM_BLE_ADV_FILTER_ADV_OPQ; - -#define BTM_BLE_MAX_FILTER_COUNTER (BTM_BLE_MAX_ADDR_FILTER + 1) /* per device filter + one generic filter indexed by 0 */ - -#ifndef BTM_CS_IRK_LIST_MAX -#define BTM_CS_IRK_LIST_MAX 0x20 -#endif - -typedef struct { - BOOLEAN in_use; - BD_ADDR bd_addr; - UINT8 pf_counter[BTM_BLE_PF_TYPE_MAX]; /* number of filter indexed by tBTM_BLE_PF_COND_TYPE */ -} tBTM_BLE_PF_COUNT; - -typedef struct { - BOOLEAN enable; - UINT8 op_type; - tBTM_BLE_PF_COUNT *p_addr_filter_count; /* per BDA filter array */ - tBLE_BD_ADDR cur_filter_target; - tBTM_BLE_PF_STATUS_CBACK *p_filt_stat_cback; - tBTM_BLE_ADV_FILTER_ADV_OPQ op_q; -} tBTM_BLE_ADV_FILTER_CB; - -/* Sub codes */ -#define BTM_BLE_META_PF_ENABLE 0x00 -#define BTM_BLE_META_PF_FEAT_SEL 0x01 -#define BTM_BLE_META_PF_ADDR 0x02 -#define BTM_BLE_META_PF_UUID 0x03 -#define BTM_BLE_META_PF_SOL_UUID 0x04 -#define BTM_BLE_META_PF_LOCAL_NAME 0x05 -#define BTM_BLE_META_PF_MANU_DATA 0x06 -#define BTM_BLE_META_PF_SRVC_DATA 0x07 -#define BTM_BLE_META_PF_ALL 0x08 - -typedef UINT8 BTM_BLE_ADV_STATE; -typedef UINT8 BTM_BLE_ADV_INFO_PRESENT; -typedef UINT8 BTM_BLE_RSSI_VALUE; -typedef UINT16 BTM_BLE_ADV_INFO_TIMESTAMP; - -/* These are the fields returned in each device adv packet. It -** is returned in the results callback if registered. -*/ -typedef struct { - UINT8 conn_mode; - tBTM_BLE_AD_MASK ad_mask; /* mask of the valid adv data field */ - UINT8 flag; - UINT8 tx_power_level; - UINT8 remote_name_len; - UINT8 *p_remote_name; - tBTM_BLE_SERVICE service; -} tBTM_BLE_INQ_DATA; - -enum { - BTM_BLE_CONN_NONE, - BTM_BLE_CONN_AUTO, - BTM_BLE_CONN_SELECTIVE -}; -typedef UINT8 tBTM_BLE_CONN_TYPE; - -#define ADV_INFO_PRESENT 0x00 -#define NO_ADV_INFO_PRESENT 0x01 - -typedef btgatt_track_adv_info_t tBTM_BLE_TRACK_ADV_DATA; - -typedef void (tBTM_BLE_TRACK_ADV_CBACK)(tBTM_BLE_TRACK_ADV_DATA *p_track_adv_data); - -typedef UINT8 tBTM_BLE_TRACK_ADV_EVT; - -typedef struct { - tBTM_BLE_REF_VALUE ref_value; - tBTM_BLE_TRACK_ADV_CBACK *p_track_cback; -} tBTM_BLE_ADV_TRACK_CB; - -enum { - BTM_BLE_TRACK_ADV_ADD, - BTM_BLE_TRACK_ADV_REMOVE -}; - -typedef UINT8 tBTM_BLE_TRACK_ADV_ACTION; - -#define BTM_BLE_MULTI_ADV_INVALID 0 - -#define BTM_BLE_BATCH_SCAN_ENABLE_EVT 1 -#define BTM_BLE_BATCH_SCAN_CFG_STRG_EVT 2 -#define BTM_BLE_BATCH_SCAN_READ_REPTS_EVT 3 -#define BTM_BLE_BATCH_SCAN_THR_EVT 4 -#define BTM_BLE_BATCH_SCAN_PARAM_EVT 5 -#define BTM_BLE_BATCH_SCAN_DISABLE_EVT 6 - -typedef UINT8 tBTM_BLE_BATCH_SCAN_EVT; - -typedef UINT32 tBTM_BLE_TX_TIME_MS; -typedef UINT32 tBTM_BLE_RX_TIME_MS; -typedef UINT32 tBTM_BLE_IDLE_TIME_MS; -typedef UINT32 tBTM_BLE_ENERGY_USED; - -typedef void (tBTM_BLE_ENERGY_INFO_CBACK)(tBTM_BLE_TX_TIME_MS tx_time, tBTM_BLE_RX_TIME_MS rx_time, - tBTM_BLE_IDLE_TIME_MS idle_time, - tBTM_BLE_ENERGY_USED energy_used, - tBTM_STATUS status); - -typedef struct { - tBTM_BLE_ENERGY_INFO_CBACK *p_ener_cback; -} tBTM_BLE_ENERGY_INFO_CB; - -typedef BOOLEAN (tBTM_BLE_SEL_CBACK)(BD_ADDR random_bda, UINT8 *p_remote_name); -typedef void (tBTM_BLE_CTRL_FEATURES_CBACK)(tBTM_STATUS status); - -/* callback function for SMP signing algorithm, signed data in little endian order with tlen bits long */ -typedef void (tBTM_BLE_SIGN_CBACK)(void *p_ref_data, UINT8 *p_signing_data); -typedef void (tBTM_BLE_VERIFY_CBACK)(void *p_ref_data, BOOLEAN match); -/* random address set complete callback */ -typedef void (tBTM_BLE_RANDOM_SET_CBACK) (BD_ADDR random_bda); - -typedef void (tBTM_BLE_SCAN_REQ_CBACK)(BD_ADDR remote_bda, tBLE_ADDR_TYPE addr_type, UINT8 adv_evt); -typedef void (*tBLE_SCAN_PARAM_SETUP_CBACK)(tGATT_IF client_if, tBTM_STATUS status); - -tBTM_BLE_SCAN_SETUP_CBACK bta_ble_scan_setup_cb; - -typedef void (tBTM_START_ADV_CMPL_CBACK) (UINT8 status); -typedef void (tBTM_START_STOP_ADV_CMPL_CBACK) (UINT8 status); - - - -/***************************************************************************** -** EXTERNAL FUNCTION DECLARATIONS -*****************************************************************************/ -/* -#ifdef __cplusplus -extern "C" { -#endif -*/ - -/******************************************************************************* -** -** Function BTM_BleRegiseterConnParamCallback -** -** Description register connection parameters update callback func -** -** Parameters: update_conn_param_cb -** -** Returns void -** -*******************************************************************************/ -void BTM_BleRegiseterConnParamCallback(tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb); - -/******************************************************************************* -** -** Function BTM_SecAddBleDevice -** -** Description Add/modify device. This function will be normally called -** during host startup to restore all required information -** for a LE device stored in the NVRAM. -** -** Parameters: bd_addr - BD address of the peer -** bd_name - Name of the peer device. NULL if unknown. -** dev_type - Remote device's device type. -** addr_type - LE device address type. -** -** Returns TRUE if added OK, else FALSE -** -*******************************************************************************/ -//extern -BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, - tBT_DEVICE_TYPE dev_type, tBLE_ADDR_TYPE addr_type); - -/******************************************************************************* -** -** Function BTM_SecAddBleKey -** -** Description Add/modify LE device information. This function will be -** normally called during host startup to restore all required -** information stored in the NVRAM. -** -** Parameters: bd_addr - BD address of the peer -** p_le_key - LE key values. -** key_type - LE SMP key type. -* -** Returns TRUE if added OK, else FALSE -** -*******************************************************************************/ -//extern -BOOLEAN BTM_SecAddBleKey (BD_ADDR bd_addr, tBTM_LE_KEY_VALUE *p_le_key, - tBTM_LE_KEY_TYPE key_type); - -/******************************************************************************* -** -** Function BTM_BleSetAdvParams -** -** Description This function is called to set advertising parameters. -** -** Parameters: None. -** -** Returns void -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleSetAdvParams(UINT16 adv_int_min, UINT16 adv_int_max, - tBLE_BD_ADDR *p_dir_bda, tBTM_BLE_ADV_CHNL_MAP chnl_map); - - - -/******************************************************************************* -** -** Function BTM_BleSetAdvParamsStartAdv -** -** Description This function is called to set all of the advertising parameters. -** -** Parameters: None. -** -** Returns void -** -*******************************************************************************/ -tBTM_STATUS BTM_BleSetAdvParamsStartAdv(UINT16 adv_int_min, UINT16 adv_int_max, UINT8 adv_type, - tBLE_ADDR_TYPE own_bda_type, tBLE_BD_ADDR *p_dir_bda, - tBTM_BLE_ADV_CHNL_MAP chnl_map, tBTM_BLE_AFP afp, tBTM_START_ADV_CMPL_CBACK *adv_cb); - - -/******************************************************************************* -** -** Function BTM_BleWriteAdvData -** -** Description This function is called to write advertising data. -** -** Parameters: None. -** -** Returns void -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleWriteAdvData(tBTM_BLE_AD_MASK data_mask, - tBTM_BLE_ADV_DATA *p_data); - -/******************************************************************************* -** -** Function BTM_BleWriteAdvDataRaw -** -** Description This function is called to write raw advertising data. -** -** Parameters: p_raw_adv : point to raw advertising data -** raw_adv_len : raw advertising data -** -** Returns BTM_SUCCESS means success. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleWriteAdvDataRaw(UINT8 *p_raw_adv, UINT32 raw_adv_len); - - -tBTM_STATUS BTM_BleSetRandAddress(BD_ADDR rand_addr); - - -/******************************************************************************* -** -** Function BTM_BleSetAdvParams -** -** Description This function is called to set advertising parameters. -** -** Parameters adv_int_min: minimum advertising interval -** adv_int_max: maximum advertising interval -** p_dir_bda: connectable direct initiator's LE device address -** chnl_map: advertising channel map. -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleReadAdvParams (UINT16 *adv_int_min, UINT16 *adv_int_max, - tBLE_BD_ADDR *p_dir_bda, tBTM_BLE_ADV_CHNL_MAP *p_chnl_map); - -/******************************************************************************* -** -** Function BTM_BleObtainVendorCapabilities -** -** Description This function is called to obatin vendor capabilties -** -** Parameters p_cmn_vsc_cb - Returns the vednor capabilities -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleObtainVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb); - -/******************************************************************************* -** -** Function BTM_BleSetScanParams -** -** Description This function is called to set Scan parameters. -** -** Parameters client_if - Client IF value -** scan_interval - Scan interval -** scan_window - Scan window -** scan_type - Scan type -** scan_setup_status_cback - Scan setup status callback -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleSetScanParams(tGATT_IF client_if, UINT32 scan_interval, - UINT32 scan_window, tBLE_SCAN_MODE scan_type, - tBLE_SCAN_PARAM_SETUP_CBACK scan_setup_status_cback); - - - -/******************************************************************************* -** -** Function BTM_BleSetScanFilterParams -** -** Description This function is called to set Scan Filter & parameters. -** -** Parameters client_if - Client IF value -** scan_interval - Scan interval -** scan_window - Scan window -** scan_type - Scan type -** addr_type_own - owner address type -** scan_duplicate_filter - scan duplicate filter -** scan_filter_policy - scan filter policy -** scan_setup_status_cback - Scan setup status callback -** -** Returns void -** -*******************************************************************************/ -void BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, UINT32 scan_window, - tBLE_SCAN_MODE scan_mode, UINT8 addr_type_own, UINT8 scan_duplicate_filter, tBTM_BLE_SFP scan_filter_policy, - tBLE_SCAN_PARAM_SETUP_CBACK scan_setup_status_cback); - - -/******************************************************************************* -** -** Function BTM_BleGetVendorCapabilities -** -** Description This function reads local LE features -** -** Parameters p_cmn_vsc_cb : Locala LE capability structure -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleGetVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb); -/******************************************************************************* -** -** Function BTM_BleSetStorageConfig -** -** Description This function is called to setup storage configuration and setup callbacks. -** -** Parameters UINT8 batch_scan_full_max -Batch scan full maximum - UINT8 batch_scan_trunc_max - Batch scan truncated value maximum - UINT8 batch_scan_notify_threshold - Threshold value - tBTM_BLE_SCAN_SETUP_CBACK *p_setup_cback - Setup callback - tBTM_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback -Threshold callback - void *p_ref - Reference value -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleSetStorageConfig(UINT8 batch_scan_full_max, - UINT8 batch_scan_trunc_max, - UINT8 batch_scan_notify_threshold, - tBTM_BLE_SCAN_SETUP_CBACK *p_setup_cback, - tBTM_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback, - tBTM_BLE_SCAN_REP_CBACK *p_cback, - tBTM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTM_BleEnableBatchScan -** -** Description This function is called to enable batch scan -** -** Parameters tBTM_BLE_BATCH_SCAN_MODE scan_mode - Batch scan mode - UINT32 scan_interval -Scan interval - UINT32 scan_window - Scan window value - tBLE_ADDR_TYPE addr_type - Address type - tBTM_BLE_DISCARD_RULE discard_rule - Data discard rules -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode, - UINT32 scan_interval, UINT32 scan_window, - tBTM_BLE_DISCARD_RULE discard_rule, - tBLE_ADDR_TYPE addr_type, - tBTM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTM_BleDisableBatchScan -** -** Description This function is called to disable batch scanning -** -** Parameters void -** -** Returns void -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleDisableBatchScan(tBTM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTM_BleReadScanReports -** -** Description This function is called to read batch scan reports -** -** Parameters tBLE_SCAN_MODE scan_mode - Scan mode report to be read out - tBTM_BLE_SCAN_REP_CBACK* p_cback - Reports callback -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleReadScanReports(tBLE_SCAN_MODE scan_mode, - tBTM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTM_BleTrackAdvertiser -** -** Description This function is called to read batch scan reports -** -** Parameters p_track_cback - Tracking callback -** ref_value - Reference value -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK *p_track_cback, - tBTM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTM_BleWriteScanRsp -** -** Description This function is called to write LE scan response. -** -** Parameters: p_scan_rsp: scan response. -** -** Returns status -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleWriteScanRsp(tBTM_BLE_AD_MASK data_mask, - tBTM_BLE_ADV_DATA *p_data); - -/******************************************************************************* -** -** Function BTM_BleWriteScanRspRaw -** -** Description This function is called to write raw scan response data -** -** Parameters: None. -** -** Returns void -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleWriteScanRspRaw(UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_len); - -/******************************************************************************* -** -** Function BTM_BleObserve -** -** Description This procedure keep the device listening for advertising -** events from a broadcast device. -** -** Parameters start: start or stop observe. -** -** Returns void -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT32 duration, - tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb); - -/******************************************************************************* -** -** Function BTM_BleScan -** -** Description This procedure keep the device listening for advertising -** events from a broadcast device. -** -** Parameters start: start or stop scan. -** -** Returns void -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleScan(BOOLEAN start, UINT32 duration, - tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb); - - -/******************************************************************************* -** -** Function BTM_GetDeviceIDRoot -** -** Description This function is called to read the local device identity -** root. -** -** Returns void -** the local device ER is copied into er -** -*******************************************************************************/ -//extern -void BTM_GetDeviceIDRoot (BT_OCTET16 ir); - -/******************************************************************************* -** -** Function BTM_GetDeviceEncRoot -** -** Description This function is called to read the local device encryption -** root. -** -** Returns void -** the local device ER is copied into er -** -*******************************************************************************/ -//extern -void BTM_GetDeviceEncRoot (BT_OCTET16 er); - -/******************************************************************************* -** -** Function BTM_GetDeviceDHK -** -** Description This function is called to read the local device DHK. -** -** Returns void -** the local device DHK is copied into dhk -** -*******************************************************************************/ -//extern -void BTM_GetDeviceDHK (BT_OCTET16 dhk); - -/******************************************************************************* -** -** Function BTM_SecurityGrant -** -** Description This function is called to grant security process. -** -** Parameters bd_addr - peer device bd address. -** res - result of the operation BTM_SUCCESS if success. -** Otherwise, BTM_REPEATED_ATTEMPTS is too many attempts. -** -** Returns None -** -*******************************************************************************/ -//extern -void BTM_SecurityGrant(BD_ADDR bd_addr, UINT8 res); - -/******************************************************************************* -** -** Function BTM_BlePasskeyReply -** -** Description This function is called after Security Manager submitted -** passkey request to the application. -** -** Parameters: bd_addr - Address of the device for which passkey was requested -** res - result of the operation SMP_SUCCESS if success -** passkey - numeric value in the range of -** BTM_MIN_PASSKEY_VAL(0) - BTM_MAX_PASSKEY_VAL(999999(0xF423F)). -** -*******************************************************************************/ -//extern -void BTM_BlePasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey); - -/******************************************************************************* -** -** Function BTM_BleSetStaticPasskey -** -** Description This function is called to set static passkey -** -** -** Parameters: add - set static passkey when add is TRUE -** clear static passkey when add is FALSE -** passkey - static passkey -** -** -*******************************************************************************/ -void BTM_BleSetStaticPasskey(BOOLEAN add, UINT32 passkey); - -/******************************************************************************* -** -** Function BTM_BleConfirmReply -** -** Description This function is called after Security Manager submitted -** numeric comparison request to the application. -** -** Parameters: bd_addr - Address of the device with which numeric -** comparison was requested -** res - comparison result BTM_SUCCESS if success -** -*******************************************************************************/ -//extern -void BTM_BleConfirmReply (BD_ADDR bd_addr, UINT8 res); - -/******************************************************************************* -** -** Function BTM_LeOobDataReply -** -** Description This function is called to provide the OOB data for -** SMP in response to BTM_LE_OOB_REQ_EVT -** -** Parameters: bd_addr - Address of the peer device -** res - result of the operation SMP_SUCCESS if success -** p_data - simple pairing Randomizer C. -** -*******************************************************************************/ -//extern -void BTM_BleOobDataReply(BD_ADDR bd_addr, UINT8 res, UINT8 len, UINT8 *p_data); - - -/******************************************************************************* -** -** Function BTM_BleDataSignature -** -** Description This function is called to sign the data using AES128 CMAC -** algorith. -** -** Parameter bd_addr: target device the data to be signed for. -** p_text: singing data -** len: length of the signing data -** signature: output parameter where data signature is going to -** be stored. -** -** Returns TRUE if signing sucessul, otherwise FALSE. -** -*******************************************************************************/ -//extern -BOOLEAN BTM_BleDataSignature (BD_ADDR bd_addr, UINT8 *p_text, UINT16 len, - BLE_SIGNATURE signature); - -/******************************************************************************* -** -** Function BTM_BleVerifySignature -** -** Description This function is called to verify the data signature -** -** Parameter bd_addr: target device the data to be signed for. -** p_orig: original data before signature. -** len: length of the signing data -** counter: counter used when doing data signing -** p_comp: signature to be compared against. - -** Returns TRUE if signature verified correctly; otherwise FALSE. -** -*******************************************************************************/ -//extern -BOOLEAN BTM_BleVerifySignature (BD_ADDR bd_addr, UINT8 *p_orig, - UINT16 len, UINT32 counter, - UINT8 *p_comp); - -/******************************************************************************* -** -** Function BTM_ReadConnectionAddr -** -** Description This function is called to set the local device random address -** . -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_ReadConnectionAddr (BD_ADDR remote_bda, BD_ADDR local_conn_addr, - tBLE_ADDR_TYPE *p_addr_type); - - - -/******************************************************************************* -** -** Function BTM_ReadRemoteConnectionAddr -** -** Description This function is read the remote device address currently used -** . -** -** Returns void -** -*******************************************************************************/ -//extern -BOOLEAN BTM_ReadRemoteConnectionAddr(BD_ADDR pseudo_addr, - BD_ADDR conn_addr, - tBLE_ADDR_TYPE *p_addr_type); - -/******************************************************************************* -** -** Function BTM_BleLoadLocalKeys -** -** Description Local local identity key, encryption root or sign counter. -** -** Parameters: key_type: type of key, can be BTM_BLE_KEY_TYPE_ID, BTM_BLE_KEY_TYPE_ER -** or BTM_BLE_KEY_TYPE_COUNTER. -** p_key: pointer to the key. -* -** Returns non2. -** -*******************************************************************************/ -//extern -void BTM_BleLoadLocalKeys(UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key); - - -/******************************************************************************* -** -** Function BTM_BleSetBgConnType -** -** Description This function is called to set BLE background connection -** procedure type. It can be auto connection, or selective connection. -** -** Parameters conn_type: it can be auto connection, or selective connection. -** p_select_cback: callback function when selective connection procedure -** is being used. -** -** Returns void -** -*******************************************************************************/ -//extern -BOOLEAN BTM_BleSetBgConnType(tBTM_BLE_CONN_TYPE conn_type, - tBTM_BLE_SEL_CBACK *p_select_cback); - -/******************************************************************************* -** -** Function BTM_BleUpdateBgConnDev -** -** Description This function is called to add or remove a device into/from -** background connection procedure. The background connection -* procedure is decided by the background connection type, it can be -* auto connection, or selective connection. -** -** Parameters add_remove: TRUE to add; FALSE to remove. -** remote_bda: device address to add/remove. -** -** Returns void -** -*******************************************************************************/ -//extern -BOOLEAN BTM_BleUpdateBgConnDev(BOOLEAN add_remove, BD_ADDR remote_bda); - -/******************************************************************************* -** -** Function BTM_BleClearBgConnDev -** -** Description This function is called to clear the whitelist, -** end any pending whitelist connections, -* and reset the local bg device list. -** -** Parameters void -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleClearBgConnDev(void); - -/******************************************************** -** -** Function BTM_BleSetPrefConnParams -** -** Description Set a peripheral's preferred connection parameters. When -** any of the value does not want to be updated while others -** do, use BTM_BLE_CONN_PARAM_UNDEF for the ones want to -** leave untouched. -** -** Parameters: bd_addr - BD address of the peripheral -** min_conn_int - minimum preferred connection interval -** max_conn_int - maximum preferred connection interval -** slave_latency - preferred slave latency -** supervision_tout - preferred supervision timeout -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleSetPrefConnParams (BD_ADDR bd_addr, - UINT16 min_conn_int, UINT16 max_conn_int, - UINT16 slave_latency, UINT16 supervision_tout); - -/****************************************************************************** -** -** Function BTM_BleSetConnScanParams -** -** Description Set scan parameters used in BLE connection request -** -** Parameters: scan_interval - scan interval -** scan_window - scan window -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleSetConnScanParams (UINT32 scan_interval, UINT32 scan_window); - -/****************************************************************************** -** -** Function BTM_BleReadControllerFeatures -** -** Description Reads BLE specific controller features -** -** Parameters: tBTM_BLE_CTRL_FEATURES_CBACK : Callback to notify when features are read -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK *p_vsc_cback); - -/******************************************************************************* -** -** Function BTM_CheckAdvData -** -** Description This function is called to get ADV data for a specific type. -** -** Parameters p_adv - pointer of ADV data -** type - finding ADV data type -** p_length - return the length of ADV data not including type -** -** Returns pointer of ADV data -** -*******************************************************************************/ -//extern -UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length); - -/******************************************************************************* -** -** Function BTM_BleGetCurrentAddress -** -** Description This function is called to get local used BLE address. -** -** Parameters: None. -** -** Returns success or fail -** -*******************************************************************************/ -BOOLEAN BTM_BleGetCurrentAddress(BD_ADDR addr, uint8_t *addr_type); - -/******************************************************************************* -** -** Function BTM__BLEReadDiscoverability -** -** Description This function is called to read the current LE discoverability -** mode of the device. -** -** Returns BTM_BLE_NON_DISCOVERABLE ,BTM_BLE_LIMITED_DISCOVERABLE or -** BTM_BLE_GENRAL_DISCOVERABLE -** -*******************************************************************************/ -UINT16 BTM_BleReadDiscoverability(); - -/******************************************************************************* -** -** Function BTM__BLEReadConnectability -** -** Description This function is called to read the current LE connectibility -** mode of the device. -** -** Returns BTM_BLE_NON_CONNECTABLE or BTM_BLE_CONNECTABLE -** -*******************************************************************************/ -//extern -UINT16 BTM_BleReadConnectability (); - -void BTM_Recovery_Pre_State(void); - -/******************************************************************************* -** -** Function BTM_ReadDevInfo -** -** Description This function is called to read the device/address type -** of BD address. -** -** Parameter remote_bda: remote device address -** p_dev_type: output parameter to read the device type. -** p_addr_type: output parameter to read the address type. -** -*******************************************************************************/ -//extern -void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, - tBLE_ADDR_TYPE *p_addr_type); - - -/******************************************************************************* -** -** Function BTM_ReadConnectedTransportAddress -** -** Description This function is called to read the paired device/address type of other device paired -** corresponding to the BD_address -** -** Parameter remote_bda: remote device address, carry out the transport address -** transport: active transport -** -** Return TRUE if an active link is identified; FALSE otherwise -** -*******************************************************************************/ -//extern -BOOLEAN BTM_ReadConnectedTransportAddress(BD_ADDR remote_bda, - tBT_TRANSPORT transport); - -/******************************************************************************* -** -** Function BTM_BleBroadcast -** -** Description This function is to start or stop broadcasting. -** -** Parameters start: start or stop broadcasting. -** -** Returns status. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_stop_adv_cback); - -/******************************************************************************* -** -** Function BTM_BleConfigPrivacy -** -** Description This function is called to enable or disable the privacy in -** the local device. -** -** Parameters enable: TRUE to enable it; FALSE to disable it. -** -** Returns BOOLEAN privacy mode set success; otherwise failed. -** -*******************************************************************************/ -//extern -BOOLEAN BTM_BleConfigPrivacy(BOOLEAN enable, tBTM_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cabck); - -/******************************************************************************* -** -** Function BTM_BleConfigLocalIcon -** -** Description This function is called to set local icon -** -** Parameters icon: appearance value. -** -** -*******************************************************************************/ -void BTM_BleConfigLocalIcon(uint16_t icon); - -/******************************************************************************* -** -** Function BTM_BleLocalPrivacyEnabled -** -** Description Checks if local device supports private address -** -** Returns Return TRUE if local privacy is enabled else FALSE -** -*******************************************************************************/ -//extern -BOOLEAN BTM_BleLocalPrivacyEnabled(void); - -/******************************************************************************* -** -** Function BTM_BleEnableMixedPrivacyMode -** -** Description This function is called to enabled Mixed mode if privacy 1.2 -** is applicable in controller. -** -** Parameters mixed_on: mixed mode to be used or not. -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleEnableMixedPrivacyMode(BOOLEAN mixed_on); - -/******************************************************************************* -** -** Function BTM_BleMaxMultiAdvInstanceCount -** -** Description Returns max number of multi adv instances supported by controller -** -** Returns Max multi adv instance count -** -*******************************************************************************/ -//extern -UINT8 BTM_BleMaxMultiAdvInstanceCount(); - -/******************************************************************************* -** -** Function BTM_BleSetConnectableMode -** -** Description This function is called to set BLE connectable mode for a -** peripheral device. -** -** Parameters connectable_mode: directed connectable mode, or non-directed.It can -** be BTM_BLE_CONNECT_EVT, BTM_BLE_CONNECT_DIR_EVT or -** BTM_BLE_CONNECT_LO_DUTY_DIR_EVT -** -** Returns BTM_ILLEGAL_VALUE if controller does not support BLE. -** BTM_SUCCESS is status set successfully; otherwise failure. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleSetConnectableMode(tBTM_BLE_CONN_MODE connectable_mode); - -/******************************************************************************* -** -** Function BTM_BleTurnOnPrivacyOnRemote -** -** Description This function is called to enable or disable the privacy on the -** remote device. -** -** Parameters bd_addr: remote device address. -** privacy_on: TRUE to enable it; FALSE to disable it. -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleTurnOnPrivacyOnRemote(BD_ADDR bd_addr, - BOOLEAN privacy_on); - -/******************************************************************************* -** -** Function BTM_BleUpdateAdvWhitelist -** -** Description Add or remove device from advertising white list -** -** Returns void -** -*******************************************************************************/ -//extern -BOOLEAN BTM_BleUpdateAdvWhitelist(BOOLEAN add_remove, BD_ADDR emote_bda, tBTM_ADD_WHITELIST_CBACK *add_wl_cb); - -/******************************************************************************* -** -** Function BTM_BleUpdateAdvFilterPolicy -** -** Description This function update the filter policy of advertiser. -** -** Parameter adv_policy: advertising filter policy -** -** Return void -*******************************************************************************/ -//extern -void BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy); - -/******************************************************************************* -** -** Function BTM_BleReceiverTest -** -** Description This function is called to start the LE Receiver test -** -** Parameter rx_freq - Frequency Range -** p_cmd_cmpl_cback - Command Complete callback -** -*******************************************************************************/ -void BTM_BleReceiverTest(UINT8 rx_freq, tBTM_CMPL_CB *p_cmd_cmpl_cback); - - -/******************************************************************************* -** -** Function BTM_BleTransmitterTest -** -** Description This function is called to start the LE Transmitter test -** -** Parameter tx_freq - Frequency Range -** test_data_len - Length in bytes of payload data in each packet -** packet_payload - Pattern to use in the payload -** p_cmd_cmpl_cback - Command Complete callback -** -*******************************************************************************/ -void BTM_BleTransmitterTest(UINT8 tx_freq, UINT8 test_data_len, - UINT8 packet_payload, tBTM_CMPL_CB *p_cmd_cmpl_cback); - -/******************************************************************************* -** -** Function BTM_BleTestEnd -** -** Description This function is called to stop the in-progress TX or RX test -** -** Parameter p_cmd_cmpl_cback - Command complete callback -** -*******************************************************************************/ -void BTM_BleTestEnd(tBTM_CMPL_CB *p_cmd_cmpl_cback); - -/******************************************************************************* -** -** Function BTM_UseLeLink -** -** Description This function is to select the underneath physical link to use. -** -** Returns TRUE to use LE, FALSE use BR/EDR. -** -*******************************************************************************/ -//extern -BOOLEAN BTM_UseLeLink (BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function BTM_BleStackEnable -** -** Description Enable/Disable BLE functionality on stack regarless controller -** capability. -** -** Parameters: enable: TRUE to enable, FALSE to disable. -** -** Returns TRUE if added OK, else FALSE -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleStackEnable (BOOLEAN enable); - -/******************************************************************************* -** -** Function BTM_GetLeSecurityState -** -** Description This function is called to get security mode 1 flags and -** encryption key size for LE peer. -** -** Returns BOOLEAN TRUE if LE device is found, FALSE otherwise. -** -*******************************************************************************/ -//extern -BOOLEAN BTM_GetLeSecurityState (BD_ADDR bd_addr, - UINT8 *p_le_dev_sec_flags, - UINT8 *p_le_key_size); - -/******************************************************************************* -** -** Function BTM_BleSecurityProcedureIsRunning -** -** Description This function indicates if LE security procedure is -** currently running with the peer. -** -** Returns BOOLEAN TRUE if security procedure is running, FALSE otherwise. -** -*******************************************************************************/ -//extern -BOOLEAN BTM_BleSecurityProcedureIsRunning (BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function BTM_BleGetSupportedKeySize -** -** Description This function gets the maximum encryption key size in bytes -** the local device can suport. -** record. -** -** Returns the key size or 0 if the size can't be retrieved. -** -*******************************************************************************/ -//extern -UINT8 BTM_BleGetSupportedKeySize (BD_ADDR bd_addr); - -/*******************************************************************************/ -/* Multi ADV API */ -/******************************************************************************* -** -** Function BTM_BleEnableAdvInstance -** -** Description This function enable a Multi-ADV instance with the specified -** adv parameters -** -** Parameters p_params: pointer to the adv parameter structure, set as default -** adv parameter when the instance is enabled. -** p_cback: callback function for the adv instance. -** p_ref: reference data attach to the adv instance to be enabled. -** -** Returns status -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleEnableAdvInstance (tBTM_BLE_ADV_PARAMS *p_params, - tBTM_BLE_MULTI_ADV_CBACK *p_cback, - void *p_ref); - -/******************************************************************************* -** -** Function BTM_BleUpdateAdvInstParam -** -** Description This function update a Multi-ADV instance with the specififed -** adv parameters. -** -** Parameters inst_id: adv instance ID -** p_params: pointer to the adv parameter structure. -** -** Returns status -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleUpdateAdvInstParam (UINT8 inst_id, tBTM_BLE_ADV_PARAMS *p_params); - -/******************************************************************************* -** -** Function BTM_BleCfgAdvInstData -** -** Description This function configure a Multi-ADV instance with the specified -** adv data or scan response data. -** -** Parameters inst_id: adv instance ID -** is_scan_rsp: is this scacn response, if no set as adv data. -** data_mask: adv data mask. -** p_data: pointer to the adv data structure. -** -** Returns status -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp, - tBTM_BLE_AD_MASK data_mask, - tBTM_BLE_ADV_DATA *p_data); - -/******************************************************************************* -** -** Function BTM_BleDisableAdvInstance -** -** Description This function disable a Multi-ADV instance. -** -** Parameters inst_id: adv instance ID -** -** Returns status -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleDisableAdvInstance (UINT8 inst_id); - -/******************************************************************************* -** -** Function BTM_BleAdvFilterParamSetup -** -** Description This function is called to setup the adv data payload filter -** condition. -** -** Parameters p_target: enabble the filter condition on a target device; if NULL -** enable the generic scan condition. -** enable: enable or disable the filter condition -** -** Returns void -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleAdvFilterParamSetup(int action, - tBTM_BLE_PF_FILT_INDEX filt_index, - tBTM_BLE_PF_FILT_PARAMS *p_filt_params, - tBLE_BD_ADDR *p_target, tBTM_BLE_PF_PARAM_CBACK *p_cmpl_cback, - tBTM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTM_BleCfgFilterCondition -** -** Description This function is called to configure the adv data payload filter -** condition. -** -** Parameters action: to read/write/clear -** cond_type: filter condition type. -** p_cond: filter condition paramter -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleCfgFilterCondition(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_COND_TYPE cond_type, - tBTM_BLE_PF_FILT_INDEX filt_index, - tBTM_BLE_PF_COND_PARAM *p_cond, - tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback, - tBTM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTM_BleEnableDisableFilterFeature -** -** Description This function is called to enable or disable the APCF feature -** -** Parameters enable - TRUE - enables the APCF, FALSE - disables the APCF -** ref_value - Ref value -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleEnableDisableFilterFeature(UINT8 enable, - tBTM_BLE_PF_STATUS_CBACK *p_stat_cback, - tBTM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTM_BleGetEnergyInfo -** -** Description This function obtains the energy info -** -** Parameters p_ener_cback - Callback pointer -** -** Returns status -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleGetEnergyInfo(tBTM_BLE_ENERGY_INFO_CBACK *p_ener_cback); - -/******************************************************************************* -** -** Function BTM_SetBleDataLength -** -** Description This function is called to set maximum BLE transmission packet size -** -** Returns BTM_SUCCESS if success; otherwise failed. -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_SetBleDataLength(BD_ADDR bd_addr, UINT16 tx_pdu_length); - -/* -#ifdef __cplusplus -} -#endif -*/ - -#endif diff --git a/tools/sdk/include/bluedroid/stack/btu.h b/tools/sdk/include/bluedroid/stack/btu.h deleted file mode 100644 index 449b18da..00000000 --- a/tools/sdk/include/bluedroid/stack/btu.h +++ /dev/null @@ -1,285 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * this file contains the main Bluetooth Upper Layer definitions. The Broadcom - * implementations of L2CAP RFCOMM, SDP and the BTIf run as one GKI task. The - * btu_task switches between them. - * - ******************************************************************************/ - -#ifndef BTU_H -#define BTU_H - -#include "common/bt_target.h" -#include "common/bt_defs.h" - -// HACK(zachoverflow): temporary dark magic -#define BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK 0x1700 // didn't look used in bt_types...here goes nothing -typedef struct { - void (*callback)(BT_HDR *); -} post_to_task_hack_t; - -typedef struct { - void (*callback)(BT_HDR *); - BT_HDR *response; - void *context; -} command_complete_hack_t; - -typedef struct { - void (*callback)(BT_HDR *); - uint8_t status; - BT_HDR *command; - void *context; -} command_status_hack_t; - -/* callbacks -*/ -typedef void (*tBTU_TIMER_CALLBACK)(TIMER_LIST_ENT *p_tle); -typedef void (*tBTU_EVENT_CALLBACK)(BT_HDR *p_hdr); - - -/* Define the timer types maintained by BTU -*/ -#define BTU_TTYPE_BTM_DEV_CTL 1 -#define BTU_TTYPE_L2CAP_LINK 2 -#define BTU_TTYPE_L2CAP_CHNL 3 -#define BTU_TTYPE_L2CAP_HOLD 4 -#define BTU_TTYPE_SDP 5 -#define BTU_TTYPE_BTM_SCO 6 -#define BTU_TTYPE_BTM_ACL 9 -#define BTU_TTYPE_BTM_RMT_NAME 10 -#define BTU_TTYPE_RFCOMM_MFC 11 -#define BTU_TTYPE_RFCOMM_PORT 12 -#define BTU_TTYPE_TCS_L2CAP 13 -#define BTU_TTYPE_TCS_CALL 14 -#define BTU_TTYPE_TCS_WUG 15 -#define BTU_TTYPE_AUTO_SYNC 16 -#define BTU_TTYPE_CTP_RECON 17 -#define BTU_TTYPE_CTP_T100 18 -#define BTU_TTYPE_CTP_GUARD 19 -#define BTU_TTYPE_CTP_DETACH 20 - -#define BTU_TTYPE_SPP_CONN_RETRY 21 -#define BTU_TTYPE_USER_FUNC 22 - -#define BTU_TTYPE_FTP_DISC 25 -#define BTU_TTYPE_OPP_DISC 26 - -#define BTU_TTYPE_CTP_TL_DISCVY 28 -#define BTU_TTYPE_IPFRAG_TIMER 29 -#define BTU_TTYPE_HSP2_AT_CMD_TO 30 -#define BTU_TTYPE_HSP2_REPEAT_RING 31 - -#define BTU_TTYPE_CTP_GW_INIT 32 -#define BTU_TTYPE_CTP_GW_CONN 33 -#define BTU_TTYPE_CTP_GW_IDLE 35 - -#define BTU_TTYPE_ICP_L2CAP 36 -#define BTU_TTYPE_ICP_T100 37 - -#define BTU_TTYPE_HSP2_WAIT_OK 38 - -/* HCRP Timers */ -#define BTU_TTYPE_HCRP_NOTIF_REG 39 -#define BTU_TTYPE_HCRP_PROTO_RSP 40 -#define BTU_TTYPE_HCRP_CR_GRANT 41 -#define BTU_TTYPE_HCRP_CR_CHECK 42 -#define BTU_TTYPE_HCRP_W4_CLOSE 43 - -/* HCRPM Timers */ -#define BTU_TTYPE_HCRPM_NOTIF_REG 44 -#define BTU_TTYPE_HCRPM_NOTIF_KEEP 45 -#define BTU_TTYPE_HCRPM_API_RSP 46 -#define BTU_TTYPE_HCRPM_W4_OPEN 47 -#define BTU_TTYPE_HCRPM_W4_CLOSE 48 - -/* BNEP Timers */ -#define BTU_TTYPE_BNEP 50 - -#define BTU_TTYPE_HSP2_SDP_FAIL_TO 55 -#define BTU_TTYPE_HSP2_SDP_RTRY_TO 56 - -/* BTU internal */ -/* unused 60 */ - -#define BTU_TTYPE_AVDT_CCB_RET 61 -#define BTU_TTYPE_AVDT_CCB_RSP 62 -#define BTU_TTYPE_AVDT_CCB_IDLE 63 -#define BTU_TTYPE_AVDT_SCB_TC 64 - -#define BTU_TTYPE_HID_DEV_REPAGE_TO 65 -#define BTU_TTYPE_HID_HOST_REPAGE_TO 66 - -#define BTU_TTYPE_HSP2_DELAY_CKPD_RCV 67 - -#define BTU_TTYPE_SAP_TO 68 - -/* BPP Timer */ -#define BTU_TTYPE_BPP_REF_CHNL 72 - -/* LP HC idle Timer */ -#define BTU_TTYPE_LP_HC_IDLE_TO 74 - -/* Patch RAM Timer */ -#define BTU_TTYPE_PATCHRAM_TO 75 - -/* eL2CAP Info Request and other proto cmds timer */ -#define BTU_TTYPE_L2CAP_FCR_ACK 78 -#define BTU_TTYPE_L2CAP_INFO 79 -/* L2CAP update connection parameters timer */ -#define BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS 80 - -#define BTU_TTYPE_MCA_CCB_RSP 98 - -/* BTU internal timer for BLE activity */ -#define BTU_TTYPE_BLE_INQUIRY 99 -#define BTU_TTYPE_BLE_GAP_LIM_DISC 100 -#define BTU_TTYPE_ATT_WAIT_FOR_RSP 101 -#define BTU_TTYPE_SMP_PAIRING_CMD 102 -#define BTU_TTYPE_BLE_RANDOM_ADDR 103 -#define BTU_TTYPE_ATT_WAIT_FOR_APP_RSP 104 -#define BTU_TTYPE_ATT_WAIT_FOR_IND_ACK 105 - -#define BTU_TTYPE_BLE_GAP_FAST_ADV 106 -#define BTU_TTYPE_BLE_OBSERVE 107 - -#define BTU_TTYPE_UCD_TO 108 -#define BTU_TTYPE_BLE_SCAN 109 - - -/* This is the inquiry response information held by BTU, and available -** to applications. -*/ -typedef struct { - BD_ADDR remote_bd_addr; - UINT8 page_scan_rep_mode; - UINT8 page_scan_per_mode; - UINT8 page_scan_mode; - DEV_CLASS dev_class; - UINT16 clock_offset; -} tBTU_INQ_INFO; - - - -#define BTU_MAX_REG_TIMER (2) /* max # timer callbacks which may register */ -#define BTU_MAX_REG_EVENT (6) /* max # event callbacks which may register */ -#define BTU_DEFAULT_DATA_SIZE (0x2a0) - -#if (BLE_INCLUDED == TRUE) -#define BTU_DEFAULT_BLE_DATA_SIZE (27) -#endif - -/* structure to hold registered timers */ -typedef struct { - TIMER_LIST_ENT *p_tle; /* timer entry */ - tBTU_TIMER_CALLBACK timer_cb; /* callback triggered when timer expires */ -} tBTU_TIMER_REG; - -/* structure to hold registered event callbacks */ -typedef struct { - UINT16 event_range; /* start of event range */ - tBTU_EVENT_CALLBACK event_cb; /* callback triggered when event is in range */ -} tBTU_EVENT_REG; - -#define NFC_MAX_LOCAL_CTRLS 0 - -/* the index to BTU command queue array */ -#define NFC_CONTROLLER_ID (1) -#define BTU_MAX_LOCAL_CTRLS (1 + NFC_MAX_LOCAL_CTRLS) /* only BR/EDR */ - -/* Define structure holding BTU variables -*/ -typedef struct { - tBTU_TIMER_REG timer_reg[BTU_MAX_REG_TIMER]; - tBTU_EVENT_REG event_reg[BTU_MAX_REG_EVENT]; - - BOOLEAN reset_complete; /* TRUE after first ack from device received */ - UINT8 trace_level; /* Trace level for HCI layer */ -} tBTU_CB; - -/* -#ifdef __cplusplus -extern "C" { -#endif -*/ -/* Global BTU data */ -#if BTU_DYNAMIC_MEMORY == FALSE -extern tBTU_CB btu_cb; -#else -extern tBTU_CB *btu_cb_ptr; -#define btu_cb (*btu_cb_ptr) -#endif - -extern const BD_ADDR BT_BD_ANY; - -/* Functions provided by btu_task.c -************************************ -*/ -void btu_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout); -void btu_stop_timer (TIMER_LIST_ENT *p_tle); -void btu_free_timer (TIMER_LIST_ENT *p_tle); -void btu_start_timer_oneshot(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout); -void btu_stop_timer_oneshot(TIMER_LIST_ENT *p_tle); - -void btu_uipc_rx_cback(BT_HDR *p_msg); - -/* -** Quick Timer -*/ -#if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0) -void btu_start_quick_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout); -void btu_stop_quick_timer (TIMER_LIST_ENT *p_tle); -void btu_free_quick_timer (TIMER_LIST_ENT *p_tle); -void btu_process_quick_timer_evt (void); -#endif - -#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE) -void btu_check_bt_sleep (void); -#endif - -/* Functions provided by btu_hcif.c -************************************ -*/ -void btu_hcif_process_event (UINT8 controller_id, BT_HDR *p_buf); -void btu_hcif_send_cmd (UINT8 controller_id, BT_HDR *p_msg); -void btu_hcif_send_host_rdy_for_data(void); -void btu_hcif_cmd_timeout (UINT8 controller_id); - -/* Functions provided by btu_core.c -************************************ -*/ -void btu_init_core(void); -void btu_free_core(void); - -void BTU_StartUp(void); -void BTU_ShutDown(void); - -void btu_task_start_up(void); -void btu_task_shut_down(void); - -UINT16 BTU_BleAclPktSize(void); - -/* -#ifdef __cplusplus -} -#endif -*/ - -#endif diff --git a/tools/sdk/include/bluedroid/stack/dyn_mem.h b/tools/sdk/include/bluedroid/stack/dyn_mem.h deleted file mode 100644 index 223ae9f9..00000000 --- a/tools/sdk/include/bluedroid/stack/dyn_mem.h +++ /dev/null @@ -1,217 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2002-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef DYN_MEM_H -#define DYN_MEM_H - -#include "sdkconfig.h" -#if CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY -#define BTU_DYNAMIC_MEMORY TRUE -#define BTM_DYNAMIC_MEMORY TRUE -#define L2C_DYNAMIC_MEMORY TRUE -#define GATT_DYNAMIC_MEMORY TRUE -#define SMP_DYNAMIC_MEMORY TRUE -#define BTA_DYNAMIC_MEMORY TRUE -#define SDP_DYNAMIC_MEMORY TRUE -#define RFC_DYNAMIC_MEMORY TRUE -#define TCS_DYNAMIC_MEMORY TRUE -#define BNEP_DYNAMIC_MEMORY TRUE -#define AVDT_DYNAMIC_MEMORY TRUE -#define AVCT_DYNAMIC_MEMORY TRUE -#define MCA_DYNAMIC_MEMORY TRUE -#define A2D_DYNAMIC_MEMORY TRUE -#define VDP_DYNAMIC_MEMORY TRUE -#define AVRC_DYNAMIC_MEMORY TRUE -#define BIP_DYNAMIC_MEMORY TRUE -#define BPP_DYNAMIC_MEMORY TRUE -#define CTP_DYNAMIC_MEMORY TRUE -#define FTP_DYNAMIC_MEMORY TRUE -#define HCRP_DYNAMIC_MEMORY TRUE -#define HFP_DYNAMIC_MEMORY TRUE -#define HID_DYNAMIC_MEMORY TRUE -#define HSP2_DYNAMIC_MEMORY TRUE -#define ICP_DYNAMIC_MEMORY TRUE -#define OPP_DYNAMIC_MEMORY TRUE -#define PAN_DYNAMIC_MEMORY TRUE -#define SPP_DYNAMIC_MEMORY TRUE -#define SLIP_DYNAMIC_MEMORY TRUE -#define LLCP_DYNAMIC_MEMORY TRUE -#define BTC_SBC_DEC_DYNAMIC_MEMORY TRUE - -#else /* #if CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY */ - -#define SDP_DYNAMIC_MEMORY FALSE -#define RFC_DYNAMIC_MEMORY FALSE -#define TCS_DYNAMIC_MEMORY FALSE -#define BNEP_DYNAMIC_MEMORY FALSE -#define AVDT_DYNAMIC_MEMORY FALSE -#define AVCT_DYNAMIC_MEMORY FALSE -#define MCA_DYNAMIC_MEMORY FALSE -#define A2D_DYNAMIC_MEMORY FALSE -#define VDP_DYNAMIC_MEMORY FALSE -#define AVRC_DYNAMIC_MEMORY FALSE -#define BIP_DYNAMIC_MEMORY FALSE -#define BPP_DYNAMIC_MEMORY FALSE -#define CTP_DYNAMIC_MEMORY FALSE -#define FTP_DYNAMIC_MEMORY FALSE -#define HCRP_DYNAMIC_MEMORY FALSE -#define HFP_DYNAMIC_MEMORY FALSE -#define HID_DYNAMIC_MEMORY FALSE -#define HSP2_DYNAMIC_MEMORY FALSE -#define ICP_DYNAMIC_MEMORY FALSE -#define OPP_DYNAMIC_MEMORY FALSE -#define PAN_DYNAMIC_MEMORY FALSE -#define SPP_DYNAMIC_MEMORY FALSE -#define SLIP_DYNAMIC_MEMORY FALSE -#define LLCP_DYNAMIC_MEMORY FALSE -#define BTC_SBC_DEC_DYNAMIC_MEMORY FALSE - -#endif /* #if CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY */ -/**************************************************************************** -** Define memory usage for each CORE component (if not defined in bdroid_buildcfg.h) -** The default for each component is to use static memory allocations. -*/ -#ifndef BTU_DYNAMIC_MEMORY -#define BTU_DYNAMIC_MEMORY FALSE -#endif - -#ifndef BTM_DYNAMIC_MEMORY -#define BTM_DYNAMIC_MEMORY FALSE -#endif - -#ifndef SDP_DYNAMIC_MEMORY -#define SDP_DYNAMIC_MEMORY FALSE -#endif - -#ifndef L2C_DYNAMIC_MEMORY -#define L2C_DYNAMIC_MEMORY FALSE -#endif - -#ifndef RFC_DYNAMIC_MEMORY -#define RFC_DYNAMIC_MEMORY FALSE -#endif - -#ifndef TCS_DYNAMIC_MEMORY -#define TCS_DYNAMIC_MEMORY FALSE -#endif - -#ifndef BNEP_DYNAMIC_MEMORY -#define BNEP_DYNAMIC_MEMORY FALSE -#endif - -#ifndef AVDT_DYNAMIC_MEMORY -#define AVDT_DYNAMIC_MEMORY FALSE -#endif - -#ifndef AVCT_DYNAMIC_MEMORY -#define AVCT_DYNAMIC_MEMORY FALSE -#endif - -#ifndef MCA_DYNAMIC_MEMORY -#define MCA_DYNAMIC_MEMORY FALSE -#endif - -#ifndef GATT_DYNAMIC_MEMORY -#define GATT_DYNAMIC_MEMORY FALSE -#endif - -#ifndef SMP_DYNAMIC_MEMORY -#define SMP_DYNAMIC_MEMORY FALSE -#endif - -/**************************************************************************** -** Define memory usage for each PROFILE component (if not defined in bdroid_buildcfg.h) -** The default for each component is to use static memory allocations. -*/ -#ifndef A2D_DYNAMIC_MEMORY -#define A2D_DYNAMIC_MEMORY FALSE -#endif - -#ifndef VDP_DYNAMIC_MEMORY -#define VDP_DYNAMIC_MEMORY FALSE -#endif - -#ifndef AVRC_DYNAMIC_MEMORY -#define AVRC_DYNAMIC_MEMORY FALSE -#endif - -#ifndef BIP_DYNAMIC_MEMORY -#define BIP_DYNAMIC_MEMORY FALSE -#endif - -#ifndef BPP_DYNAMIC_MEMORY -#define BPP_DYNAMIC_MEMORY FALSE -#endif - -#ifndef CTP_DYNAMIC_MEMORY -#define CTP_DYNAMIC_MEMORY FALSE -#endif - -#ifndef FTP_DYNAMIC_MEMORY -#define FTP_DYNAMIC_MEMORY FALSE -#endif - -#ifndef HCRP_DYNAMIC_MEMORY -#define HCRP_DYNAMIC_MEMORY FALSE -#endif - -#ifndef HFP_DYNAMIC_MEMORY -#define HFP_DYNAMIC_MEMORY FALSE -#endif - -#ifndef HID_DYNAMIC_MEMORY -#define HID_DYNAMIC_MEMORY FALSE -#endif - -#ifndef HSP2_DYNAMIC_MEMORY -#define HSP2_DYNAMIC_MEMORY FALSE -#endif - -#ifndef ICP_DYNAMIC_MEMORY -#define ICP_DYNAMIC_MEMORY FALSE -#endif - -#ifndef OPP_DYNAMIC_MEMORY -#define OPP_DYNAMIC_MEMORY FALSE -#endif - -#ifndef PAN_DYNAMIC_MEMORY -#define PAN_DYNAMIC_MEMORY FALSE -#endif - -#ifndef SPP_DYNAMIC_MEMORY -#define SPP_DYNAMIC_MEMORY FALSE -#endif - -#ifndef SLIP_DYNAMIC_MEMORY -#define SLIP_DYNAMIC_MEMORY FALSE -#endif - -#ifndef LLCP_DYNAMIC_MEMORY -#define LLCP_DYNAMIC_MEMORY FALSE -#endif - -/**************************************************************************** -** Define memory usage for BTA (if not defined in bdroid_buildcfg.h) -** The default for each component is to use static memory allocations. -*/ -#ifndef BTA_DYNAMIC_MEMORY -#define BTA_DYNAMIC_MEMORY FALSE -#endif - -#endif /* #ifdef DYN_MEM_H */ - diff --git a/tools/sdk/include/bluedroid/stack/gap_api.h b/tools/sdk/include/bluedroid/stack/gap_api.h deleted file mode 100644 index 5d8d8764..00000000 --- a/tools/sdk/include/bluedroid/stack/gap_api.h +++ /dev/null @@ -1,391 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2009-2013 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef GAP_API_H -#define GAP_API_H - -#include "stack/sdpdefs.h" -#include "stack/profiles_api.h" -#include "stack/btm_api.h" -#include "stack/l2c_api.h" - -/***************************************************************************** -** Constants -*****************************************************************************/ -/*** GAP Error and Status Codes ***/ -#define GAP_UNSUPPORTED (GAP_ERR_GRP + 0x01) /* Unsupported call */ -#define GAP_EOINQDB (GAP_ERR_GRP + 0x02) /* End of inquiry database marker */ -#define GAP_ERR_BUSY (GAP_ERR_GRP + 0x03) /* The requested function was busy */ -#define GAP_ERR_NO_CTRL_BLK (GAP_ERR_GRP + 0x04) /* No control blocks available */ -#define GAP_ERR_STARTING_CMD (GAP_ERR_GRP + 0x05) /* Error occurred while initiating the command */ -#define GAP_NO_BDADDR_REC (GAP_ERR_GRP + 0x06) /* No Inquiry DB record for BD_ADDR */ -#define GAP_ERR_ILL_MODE (GAP_ERR_GRP + 0x07) /* An illegal mode parameter was detected */ -#define GAP_ERR_ILL_INQ_TIME (GAP_ERR_GRP + 0x08) /* An illegal time parameter was detected */ -#define GAP_ERR_ILL_PARM (GAP_ERR_GRP + 0x09) /* An illegal parameter was detected */ -#define GAP_ERR_REM_NAME (GAP_ERR_GRP + 0x0a) /* Error starting the remote device name request */ -#define GAP_CMD_INITIATED (GAP_ERR_GRP + 0x0b) /* The GAP command was started (result pending) */ -#define GAP_DEVICE_NOT_UP (GAP_ERR_GRP + 0x0c) /* The device was not up; the request was not executed */ -#define GAP_BAD_BD_ADDR (GAP_ERR_GRP + 0x0d) /* The bd addr passed in was not found or invalid */ - -#define GAP_ERR_BAD_HANDLE (GAP_ERR_GRP + 0x0e) /* Bad GAP handle */ -#define GAP_ERR_BUF_OFFSET (GAP_ERR_GRP + 0x0f) /* Buffer offset invalid */ -#define GAP_ERR_BAD_STATE (GAP_ERR_GRP + 0x10) /* Connection is in invalid state */ -#define GAP_NO_DATA_AVAIL (GAP_ERR_GRP + 0x11) /* No data available */ -#define GAP_ERR_CONGESTED (GAP_ERR_GRP + 0x12) /* BT stack is congested */ -#define GAP_ERR_SECURITY (GAP_ERR_GRP + 0x13) /* Security failed */ - -#define GAP_ERR_PROCESSING (GAP_ERR_GRP + 0x14) /* General error processing BTM request */ -#define GAP_ERR_TIMEOUT (GAP_ERR_GRP + 0x15) /* Timeout occurred while processing cmd */ -#define GAP_EVT_CONN_OPENED 0x0100 -#define GAP_EVT_CONN_CLOSED 0x0101 -#define GAP_EVT_CONN_DATA_AVAIL 0x0102 -#define GAP_EVT_CONN_CONGESTED 0x0103 -#define GAP_EVT_CONN_UNCONGESTED 0x0104 -/* Values for 'chan_mode_mask' field */ -/* GAP_ConnOpen() - optional channels to negotiate */ -#define GAP_FCR_CHAN_OPT_BASIC L2CAP_FCR_CHAN_OPT_BASIC -#define GAP_FCR_CHAN_OPT_ERTM L2CAP_FCR_CHAN_OPT_ERTM -#define GAP_FCR_CHAN_OPT_STREAM L2CAP_FCR_CHAN_OPT_STREAM -/*** used in connection variables and functions ***/ -#define GAP_INVALID_HANDLE 0xFFFF - -/* This is used to change the criteria for AMP */ -#define GAP_PROTOCOL_ID (UUID_PROTOCOL_UDP) - - -#ifndef GAP_PREFER_CONN_INT_MAX -#define GAP_PREFER_CONN_INT_MAX BTM_BLE_CONN_INT_MIN -#endif - -#ifndef GAP_PREFER_CONN_INT_MIN -#define GAP_PREFER_CONN_INT_MIN BTM_BLE_CONN_INT_MIN -#endif - -#ifndef GAP_PREFER_CONN_LATENCY -#define GAP_PREFER_CONN_LATENCY 0 -#endif - -#ifndef GAP_PREFER_CONN_SP_TOUT -#define GAP_PREFER_CONN_SP_TOUT 2000 -#endif - -/***************************************************************************** -** Type Definitions -*****************************************************************************/ -/* -** Callback function for connection services -*/ -typedef void (tGAP_CONN_CALLBACK) (UINT16 gap_handle, UINT16 event); - -/* -** Define the callback function prototypes. Parameters are specific -** to each event and are described below -*/ -typedef void (tGAP_CALLBACK) (UINT16 event, void *p_data); - - -/* Definition of the GAP_FindAddrByName results structure */ -typedef struct { - UINT16 status; - BD_ADDR bd_addr; - tBTM_BD_NAME devname; -} tGAP_FINDADDR_RESULTS; - -typedef struct { - UINT16 int_min; - UINT16 int_max; - UINT16 latency; - UINT16 sp_tout; -} tGAP_BLE_PREF_PARAM; - -typedef union { - tGAP_BLE_PREF_PARAM conn_param; - BD_ADDR reconn_bda; - UINT16 icon; - UINT8 *p_dev_name; - UINT8 addr_resolution; - -} tGAP_BLE_ATTR_VALUE; - -typedef void (tGAP_BLE_CMPL_CBACK)(BOOLEAN status, BD_ADDR addr, UINT16 length, char *p_name); - - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ - -/*** Functions for L2CAP connection interface ***/ - -/******************************************************************************* -** -** Function GAP_ConnOpen -** -** Description This function is called to open a generic L2CAP connection. -** -** Returns handle of the connection if successful, else GAP_INVALID_HANDLE -** -*******************************************************************************/ -extern UINT16 GAP_ConnOpen (const char *p_serv_name, UINT8 service_id, BOOLEAN is_server, - BD_ADDR p_rem_bda, UINT16 psm, tL2CAP_CFG_INFO *p_cfg, - tL2CAP_ERTM_INFO *ertm_info, - UINT16 security, UINT8 chan_mode_mask, tGAP_CONN_CALLBACK *p_cb); - -/******************************************************************************* -** -** Function GAP_ConnClose -** -** Description This function is called to close a connection. -** -** Returns BT_PASS - closed OK -** GAP_ERR_BAD_HANDLE - invalid handle -** -*******************************************************************************/ -extern UINT16 GAP_ConnClose (UINT16 gap_handle); - -/******************************************************************************* -** -** Function GAP_ConnReadData -** -** Description GKI buffer unaware application will call this function -** after receiving GAP_EVT_RXDATA event. A data copy is made -** into the receive buffer parameter. -** -** Returns BT_PASS - data read -** GAP_ERR_BAD_HANDLE - invalid handle -** GAP_NO_DATA_AVAIL - no data available -** -*******************************************************************************/ -extern UINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data, - UINT16 max_len, UINT16 *p_len); - -/******************************************************************************* -** -** Function GAP_GetRxQueueCnt -** -** Description This function return number of bytes on the rx queue. -** -** Parameters: handle - Handle returned in the GAP_ConnOpen -** p_rx_queue_count - Pointer to return queue count in. -** -** -*******************************************************************************/ -extern int GAP_GetRxQueueCnt (UINT16 handle, UINT32 *p_rx_queue_count); - -/******************************************************************************* -** -** Function GAP_ConnBTRead -** -** Description GKI buffer aware applications will call this function after -** receiving an GAP_EVT_RXDATA event to process the incoming -** data buffer. -** -** Returns BT_PASS - data read -** GAP_ERR_BAD_HANDLE - invalid handle -** GAP_NO_DATA_AVAIL - no data available -** -*******************************************************************************/ -extern UINT16 GAP_ConnBTRead (UINT16 gap_handle, BT_HDR **pp_buf); - -/******************************************************************************* -** -** Function GAP_ConnBTWrite -** -** Description GKI buffer aware applications can call this function to write data -** by passing a pointer to the GKI buffer of data. -** -** Returns BT_PASS - data read -** GAP_ERR_BAD_HANDLE - invalid handle -** GAP_ERR_BAD_STATE - connection not established -** GAP_INVALID_BUF_OFFSET - buffer offset is invalid -*******************************************************************************/ -extern UINT16 GAP_ConnBTWrite (UINT16 gap_handle, BT_HDR *p_buf); - -/******************************************************************************* -** -** Function GAP_ConnWriteData -** -** Description GKI buffer unaware application will call this function -** to send data to the connection. A data copy is made into a GKI -** buffer. -** -** Returns BT_PASS - data read -** GAP_ERR_BAD_HANDLE - invalid handle -** GAP_ERR_BAD_STATE - connection not established -** GAP_CONGESTION - system is congested -** -*******************************************************************************/ -extern UINT16 GAP_ConnWriteData (UINT16 gap_handle, UINT8 *p_data, - UINT16 max_len, UINT16 *p_len); - -/******************************************************************************* -** -** Function GAP_ConnReconfig -** -** Description Applications can call this function to reconfigure the connection. -** -** Returns BT_PASS - config process started -** GAP_ERR_BAD_HANDLE - invalid handle -** -*******************************************************************************/ -extern UINT16 GAP_ConnReconfig (UINT16 gap_handle, tL2CAP_CFG_INFO *p_cfg); - -/******************************************************************************* -** -** Function GAP_ConnSetIdleTimeout -** -** Description Higher layers call this function to set the idle timeout for -** a connection, or for all future connections. The "idle timeout" -** is the amount of time that a connection can remain up with -** no L2CAP channels on it. A timeout of zero means that the -** connection will be torn down immediately when the last channel -** is removed. A timeout of 0xFFFF means no timeout. Values are -** in seconds. -** -** Returns BT_PASS - config process started -** GAP_ERR_BAD_HANDLE - invalid handle -** -*******************************************************************************/ -extern UINT16 GAP_ConnSetIdleTimeout (UINT16 gap_handle, UINT16 timeout); - -/******************************************************************************* -** -** Function GAP_ConnGetRemoteAddr -** -** Description This function is called to get the remote BD address -** of a connection. -** -** Returns BT_PASS - closed OK -** GAP_ERR_BAD_HANDLE - invalid handle -** -*******************************************************************************/ -extern UINT8 *GAP_ConnGetRemoteAddr (UINT16 gap_handle); - -/******************************************************************************* -** -** Function GAP_ConnGetRemMtuSize -** -** Description Returns the remote device's MTU size. -** -** Returns UINT16 - maximum size buffer that can be transmitted to the peer -** -*******************************************************************************/ -extern UINT16 GAP_ConnGetRemMtuSize (UINT16 gap_handle); - -/******************************************************************************* -** -** Function GAP_ConnGetL2CAPCid -** -** Description Returns the L2CAP channel id -** -** Parameters: handle - Handle of the connection -** -** Returns UINT16 - The L2CAP channel id -** 0, if error -** -*******************************************************************************/ -extern UINT16 GAP_ConnGetL2CAPCid (UINT16 gap_handle); - -/******************************************************************************* -** -** Function GAP_SetTraceLevel -** -** Description This function sets the trace level for GAP. If called with -** a value of 0xFF, it simply returns the current trace level. -** -** Returns The new or current trace level -** -*******************************************************************************/ -extern UINT8 GAP_SetTraceLevel (UINT8 new_level); - -/******************************************************************************* -** -** Function GAP_Init -** -** Description Initializes the control blocks used by GAP. -** This routine should not be called except once per -** stack invocation. -** -** Returns Nothing -** -*******************************************************************************/ -extern void GAP_Init(void); - -#if (BLE_INCLUDED == TRUE) -/******************************************************************************* -** -** Function GAP_BleAttrDBUpdate -** -** Description update GAP local BLE attribute database. -** -** Returns Nothing -** -*******************************************************************************/ -extern void GAP_BleAttrDBUpdate(UINT16 attr_uuid, tGAP_BLE_ATTR_VALUE *p_value); - - -/******************************************************************************* -** -** Function GAP_BleReadPeerPrefConnParams -** -** Description Start a process to read a connected peripheral's preferred -** connection parameters -** -** Returns TRUE if read started, else FALSE if GAP is busy -** -*******************************************************************************/ -extern BOOLEAN GAP_BleReadPeerPrefConnParams (BD_ADDR peer_bda); - -/******************************************************************************* -** -** Function GAP_BleReadPeerDevName -** -** Description Start a process to read a connected peripheral's device name. -** -** Returns TRUE if request accepted -** -*******************************************************************************/ -extern BOOLEAN GAP_BleReadPeerDevName (BD_ADDR peer_bda, tGAP_BLE_CMPL_CBACK *p_cback); - - -/******************************************************************************* -** -** Function GAP_BleReadPeerAddressResolutionCap -** -** Description Start a process to read peer address resolution capability -** -** Returns TRUE if request accepted -** -*******************************************************************************/ -extern BOOLEAN GAP_BleReadPeerAddressResolutionCap (BD_ADDR peer_bda, - tGAP_BLE_CMPL_CBACK *p_cback); - -/******************************************************************************* -** -** Function GAP_BleCancelReadPeerDevName -** -** Description Cancel reading a peripheral's device name. -** -** Returns TRUE if request accepted -** -*******************************************************************************/ -extern BOOLEAN GAP_BleCancelReadPeerDevName (BD_ADDR peer_bda); - - -#endif - -#endif /* GAP_API_H */ diff --git a/tools/sdk/include/bluedroid/stack/gatt_api.h b/tools/sdk/include/bluedroid/stack/gatt_api.h deleted file mode 100644 index 24a186ae..00000000 --- a/tools/sdk/include/bluedroid/stack/gatt_api.h +++ /dev/null @@ -1,1218 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef GATT_API_H -#define GATT_API_H - -#include "common/bt_target.h" -#include "stack/gattdefs.h" -#include "stack/btm_ble_api.h" - -/***************************************************************************** -** Constants -*****************************************************************************/ -/* Success code and error codes */ -#define GATT_SUCCESS 0x00 -#define GATT_INVALID_HANDLE 0x01 -#define GATT_READ_NOT_PERMIT 0x02 -#define GATT_WRITE_NOT_PERMIT 0x03 -#define GATT_INVALID_PDU 0x04 -#define GATT_INSUF_AUTHENTICATION 0x05 -#define GATT_REQ_NOT_SUPPORTED 0x06 -#define GATT_INVALID_OFFSET 0x07 -#define GATT_INSUF_AUTHORIZATION 0x08 -#define GATT_PREPARE_Q_FULL 0x09 -#define GATT_NOT_FOUND 0x0a -#define GATT_NOT_LONG 0x0b -#define GATT_INSUF_KEY_SIZE 0x0c -#define GATT_INVALID_ATTR_LEN 0x0d -#define GATT_ERR_UNLIKELY 0x0e -#define GATT_INSUF_ENCRYPTION 0x0f -#define GATT_UNSUPPORT_GRP_TYPE 0x10 -#define GATT_INSUF_RESOURCE 0x11 - - -#define GATT_NO_RESOURCES 0x80 -#define GATT_INTERNAL_ERROR 0x81 -#define GATT_WRONG_STATE 0x82 -#define GATT_DB_FULL 0x83 -#define GATT_BUSY 0x84 -#define GATT_ERROR 0x85 -#define GATT_CMD_STARTED 0x86 -#define GATT_ILLEGAL_PARAMETER 0x87 -#define GATT_PENDING 0x88 -#define GATT_AUTH_FAIL 0x89 -#define GATT_MORE 0x8a -#define GATT_INVALID_CFG 0x8b -#define GATT_SERVICE_STARTED 0x8c -#define GATT_ENCRYPED_MITM GATT_SUCCESS -#define GATT_ENCRYPED_NO_MITM 0x8d -#define GATT_NOT_ENCRYPTED 0x8e -#define GATT_CONGESTED 0x8f - -#define GATT_DUP_REG 0x90 -#define GATT_ALREADY_OPEN 0x91 -#define GATT_CANCEL 0x92 - -/* 0xE0 ~ 0xFC reserved for future use */ -#define GATT_STACK_RSP 0xE0 -#define GATT_APP_RSP 0xE1 -//Error caused by customer application or stack bug -#define GATT_UNKNOWN_ERROR 0XEF - -#define GATT_CCC_CFG_ERR 0xFD /* Client Characteristic Configuration Descriptor Improperly Configured */ -#define GATT_PRC_IN_PROGRESS 0xFE /* Procedure Already in progress */ -#define GATT_OUT_OF_RANGE 0xFF /* Attribute value out of range */ - -typedef UINT8 tGATT_STATUS; - - -#define GATT_RSP_ERROR 0x01 -#define GATT_REQ_MTU 0x02 -#define GATT_RSP_MTU 0x03 -#define GATT_REQ_FIND_INFO 0x04 -#define GATT_RSP_FIND_INFO 0x05 -#define GATT_REQ_FIND_TYPE_VALUE 0x06 -#define GATT_RSP_FIND_TYPE_VALUE 0x07 -#define GATT_REQ_READ_BY_TYPE 0x08 -#define GATT_RSP_READ_BY_TYPE 0x09 -#define GATT_REQ_READ 0x0A -#define GATT_RSP_READ 0x0B -#define GATT_REQ_READ_BLOB 0x0C -#define GATT_RSP_READ_BLOB 0x0D -#define GATT_REQ_READ_MULTI 0x0E -#define GATT_RSP_READ_MULTI 0x0F -#define GATT_REQ_READ_BY_GRP_TYPE 0x10 -#define GATT_RSP_READ_BY_GRP_TYPE 0x11 -#define GATT_REQ_WRITE 0x12 /* 0001-0010 (write)*/ -#define GATT_RSP_WRITE 0x13 -#define GATT_CMD_WRITE 0x52 /* changed in V4.0 01001-0010(write cmd)*/ -#define GATT_REQ_PREPARE_WRITE 0x16 -#define GATT_RSP_PREPARE_WRITE 0x17 -#define GATT_REQ_EXEC_WRITE 0x18 -#define GATT_RSP_EXEC_WRITE 0x19 -#define GATT_HANDLE_VALUE_NOTIF 0x1B -#define GATT_HANDLE_VALUE_IND 0x1D -#define GATT_HANDLE_VALUE_CONF 0x1E -#define GATT_SIGN_CMD_WRITE 0xD2 /* changed in V4.0 1101-0010 (signed write) see write cmd above*/ -#define GATT_OP_CODE_MAX GATT_HANDLE_VALUE_CONF + 1 /* 0x1E = 30 + 1 = 31*/ - -#define GATT_COMMAND_FLAG 0x40 /* Command Flag: set to one means commond */ - -#define GATT_HANDLE_IS_VALID(x) ((x) != 0) - -#define GATT_CONN_UNKNOWN 0 -#define GATT_CONN_L2C_FAILURE 1 /* general L2cap failure */ -#define GATT_CONN_TIMEOUT HCI_ERR_CONNECTION_TOUT /* 0x08 connection timeout */ -#define GATT_CONN_TERMINATE_PEER_USER HCI_ERR_PEER_USER /* 0x13 connection terminate by peer user */ -#define GATT_CONN_TERMINATE_LOCAL_HOST HCI_ERR_CONN_CAUSE_LOCAL_HOST /* 0x16 connectionterminated by local host */ -#define GATT_CONN_FAIL_ESTABLISH HCI_ERR_CONN_FAILED_ESTABLISHMENT/* 0x03E connection fail to establish */ -#define GATT_CONN_LMP_TIMEOUT HCI_ERR_LMP_RESPONSE_TIMEOUT /* 0x22 connection fail for LMP response tout */ -#define GATT_CONN_CANCEL L2CAP_CONN_CANCEL /* 0x0100 L2CAP connection cancelled */ -typedef UINT16 tGATT_DISCONN_REASON; - -/* MAX GATT MTU size -*/ -#ifndef GATT_MAX_MTU_SIZE -#define GATT_MAX_MTU_SIZE 517 -#endif - -/* max legth of an attribute value -*/ -#ifndef GATT_MAX_ATTR_LEN -#define GATT_MAX_ATTR_LEN 600 -#endif - -/* default GATT MTU size over LE link -*/ -#define GATT_DEF_BLE_MTU_SIZE 23 - -/* invalid connection ID -*/ -#define GATT_INVALID_CONN_ID 0xFFFF - -#ifndef GATT_CL_MAX_LCB -#define GATT_CL_MAX_LCB 12 // 22 -#endif - -#ifndef GATT_MAX_SCCB -#define GATT_MAX_SCCB 10 -#endif - - -/* GATT notification caching timer, default to be three seconds -*/ -#ifndef GATTC_NOTIF_TIMEOUT -#define GATTC_NOTIF_TIMEOUT 3 -#endif - -/***************************************************************************** -** GATT Structure Definition -*****************************************************************************/ - -/* Attribute permissions -*/ -#define GATT_PERM_READ (1 << 0) /* bit 0 */ -#define GATT_PERM_READ_ENCRYPTED (1 << 1) /* bit 1 */ -#define GATT_PERM_READ_ENC_MITM (1 << 2) /* bit 2 */ -#define GATT_PERM_WRITE (1 << 4) /* bit 4 */ -#define GATT_PERM_WRITE_ENCRYPTED (1 << 5) /* bit 5 */ -#define GATT_PERM_WRITE_ENC_MITM (1 << 6) /* bit 6 */ -#define GATT_PERM_WRITE_SIGNED (1 << 7) /* bit 7 */ -#define GATT_PERM_WRITE_SIGNED_MITM (1 << 8) /* bit 8 */ -typedef UINT16 tGATT_PERM; - -#define GATT_ENCRYPT_KEY_SIZE_MASK (0xF000) /* the MS nibble of tGATT_PERM; key size 7=0; size 16=9 */ - -#define GATT_READ_ALLOWED (GATT_PERM_READ | GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM) -#define GATT_READ_AUTH_REQUIRED (GATT_PERM_READ_ENCRYPTED) -#define GATT_READ_MITM_REQUIRED (GATT_PERM_READ_ENC_MITM) -#define GATT_READ_ENCRYPTED_REQUIRED (GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM) - - -#define GATT_WRITE_ALLOWED (GATT_PERM_WRITE | GATT_PERM_WRITE_ENCRYPTED | GATT_PERM_WRITE_ENC_MITM | \ - GATT_PERM_WRITE_SIGNED | GATT_PERM_WRITE_SIGNED_MITM) - -#define GATT_WRITE_AUTH_REQUIRED (GATT_PERM_WRITE_ENCRYPTED | GATT_PERM_WRITE_SIGNED) - -#define GATT_WRITE_MITM_REQUIRED (GATT_PERM_WRITE_ENC_MITM | GATT_PERM_WRITE_SIGNED_MITM) - -#define GATT_WRITE_ENCRYPTED_PERM (GATT_PERM_WRITE_ENCRYPTED | GATT_PERM_WRITE_ENC_MITM) - -#define GATT_WRITE_SIGNED_PERM (GATT_PERM_WRITE_SIGNED | GATT_PERM_WRITE_SIGNED_MITM) - - -/* Characteristic properties -*/ -#define GATT_CHAR_PROP_BIT_BROADCAST (1 << 0) -#define GATT_CHAR_PROP_BIT_READ (1 << 1) -#define GATT_CHAR_PROP_BIT_WRITE_NR (1 << 2) -#define GATT_CHAR_PROP_BIT_WRITE (1 << 3) -#define GATT_CHAR_PROP_BIT_NOTIFY (1 << 4) -#define GATT_CHAR_PROP_BIT_INDICATE (1 << 5) -#define GATT_CHAR_PROP_BIT_AUTH (1 << 6) -#define GATT_CHAR_PROP_BIT_EXT_PROP (1 << 7) -typedef UINT8 tGATT_CHAR_PROP; - - -/* Format of the value of a characteristic. enumeration type -*/ -enum { - GATT_FORMAT_RES, /* rfu */ - GATT_FORMAT_BOOL, /* 0x01 boolean */ - GATT_FORMAT_2BITS, /* 0x02 2 bit */ - GATT_FORMAT_NIBBLE, /* 0x03 nibble */ - GATT_FORMAT_UINT8, /* 0x04 uint8 */ - GATT_FORMAT_UINT12, /* 0x05 uint12 */ - GATT_FORMAT_UINT16, /* 0x06 uint16 */ - GATT_FORMAT_UINT24, /* 0x07 uint24 */ - GATT_FORMAT_UINT32, /* 0x08 uint32 */ - GATT_FORMAT_UINT48, /* 0x09 uint48 */ - GATT_FORMAT_UINT64, /* 0x0a uint64 */ - GATT_FORMAT_UINT128, /* 0x0B uint128 */ - GATT_FORMAT_SINT8, /* 0x0C signed 8 bit integer */ - GATT_FORMAT_SINT12, /* 0x0D signed 12 bit integer */ - GATT_FORMAT_SINT16, /* 0x0E signed 16 bit integer */ - GATT_FORMAT_SINT24, /* 0x0F signed 24 bit integer */ - GATT_FORMAT_SINT32, /* 0x10 signed 32 bit integer */ - GATT_FORMAT_SINT48, /* 0x11 signed 48 bit integer */ - GATT_FORMAT_SINT64, /* 0x12 signed 64 bit integer */ - GATT_FORMAT_SINT128, /* 0x13 signed 128 bit integer */ - GATT_FORMAT_FLOAT32, /* 0x14 float 32 */ - GATT_FORMAT_FLOAT64, /* 0x15 float 64*/ - GATT_FORMAT_SFLOAT, /* 0x16 IEEE-11073 16 bit SFLOAT */ - GATT_FORMAT_FLOAT, /* 0x17 IEEE-11073 32 bit SFLOAT */ - GATT_FORMAT_DUINT16, /* 0x18 IEEE-20601 format */ - GATT_FORMAT_UTF8S, /* 0x19 UTF-8 string */ - GATT_FORMAT_UTF16S, /* 0x1a UTF-16 string */ - GATT_FORMAT_STRUCT, /* 0x1b Opaque structure*/ - GATT_FORMAT_MAX /* 0x1c or above reserved */ -}; -typedef UINT8 tGATT_FORMAT; - -/* Characteristic Presentation Format Descriptor value -*/ -typedef struct { - UINT16 unit; /* as UUIUD defined by SIG */ - UINT16 descr; /* as UUID as defined by SIG */ - tGATT_FORMAT format; - INT8 exp; - UINT8 name_spc; /* The name space of the description */ -} tGATT_CHAR_PRES; - -/* Characteristic Report reference Descriptor format -*/ -typedef struct { - UINT8 rpt_id; /* report ID */ - UINT8 rpt_type; /* report type */ -} tGATT_CHAR_RPT_REF; - - -#define GATT_VALID_RANGE_MAX_SIZE 16 -typedef struct { - UINT8 format; - UINT16 len; - UINT8 lower_range[GATT_VALID_RANGE_MAX_SIZE]; /* in little endian format */ - UINT8 upper_range[GATT_VALID_RANGE_MAX_SIZE]; -} tGATT_VALID_RANGE; - -/* Characteristic Aggregate Format attribute value -*/ -#define GATT_AGGR_HANDLE_NUM_MAX 10 -typedef struct { - UINT8 num_handle; - UINT16 handle_list[GATT_AGGR_HANDLE_NUM_MAX]; -} tGATT_CHAR_AGGRE; - -/* Characteristic descriptor: Extended Properties value -*/ -#define GATT_CHAR_BIT_REL_WRITE 0x0001 /* permits reliable writes of the Characteristic Value */ -#define GATT_CHAR_BIT_WRITE_AUX 0x0002 /* permits writes to the characteristic descriptor */ - - -/* characteristic descriptor: client configuration value -*/ -#define GATT_CLT_CONFIG_NONE 0x0000 -#define GATT_CLT_CONFIG_NOTIFICATION 0x0001 -#define GATT_CLT_CONFIG_INDICATION 0x0002 -typedef UINT16 tGATT_CLT_CHAR_CONFIG; - - -/* characteristic descriptor: server configuration value -*/ -#define GATT_SVR_CONFIG_NONE 0x0000 -#define GATT_SVR_CONFIG_BROADCAST 0x0001 -typedef UINT16 tGATT_SVR_CHAR_CONFIG; - -/* Characteristic descriptor: Extended Properties value -*/ -#define GATT_CHAR_BIT_REL_WRITE 0x0001 /* permits reliable writes of the Characteristic Value */ -#define GATT_CHAR_BIT_WRITE_AUX 0x0002 /* permits writes to the characteristic descriptor */ - -/* authentication requirement -*/ -#define GATT_AUTH_REQ_NONE 0 -#define GATT_AUTH_REQ_NO_MITM 1 /* unauthenticated encryption */ -#define GATT_AUTH_REQ_MITM 2 /* authenticated encryption */ -#define GATT_AUTH_REQ_SIGNED_NO_MITM 3 -#define GATT_AUTH_REQ_SIGNED_MITM 4 -typedef UINT8 tGATT_AUTH_REQ; - -/* Attribute Value structure -*/ -typedef struct { - UINT16 conn_id; - UINT16 handle; /* attribute handle */ - UINT16 offset; /* attribute value offset, if no offfset is needed for the command, ignore it */ - UINT16 len; /* length of attribute value */ - tGATT_AUTH_REQ auth_req; /* authentication request */ - UINT8 value[GATT_MAX_ATTR_LEN]; /* the actual attribute value */ -} tGATT_VALUE; - -typedef struct{ - UINT16 attr_max_len; - UINT16 attr_len; - UINT8 *attr_val; -}tGATT_ATTR_VAL; - -typedef struct{ - uint8_t auto_rsp; -}tGATTS_ATTR_CONTROL; - -/* Mask for gatt server attribute */ -#define GATT_ATTR_VALUE_ALLOCATED 0x01 -typedef UINT8 tGATT_ATTR_MASK; - -/* Union of the event data which is used in the server respond API to carry the server response information -*/ -typedef union { - /* data type member event */ - tGATT_VALUE attr_value; /* READ, HANDLE_VALUE_IND, PREPARE_WRITE */ - /* READ_BLOB, READ_BY_TYPE */ - UINT16 handle; /* WRITE, WRITE_BLOB */ - -} tGATTS_RSP; - -/* Transports for the primary service */ -#define GATT_TRANSPORT_LE BT_TRANSPORT_LE -#define GATT_TRANSPORT_BR_EDR BT_TRANSPORT_BR_EDR -#define GATT_TRANSPORT_LE_BR_EDR (BT_TRANSPORT_LE|BT_TRANSPORT_BR_EDR) -typedef UINT8 tGATT_TRANSPORT; - -#define GATT_PREP_WRITE_CANCEL 0x00 -#define GATT_PREP_WRITE_EXEC 0x01 -typedef UINT8 tGATT_EXEC_FLAG; - -/* read request always based on UUID */ -typedef struct { - UINT16 handle; - UINT16 offset; - BOOLEAN is_long; - BOOLEAN need_rsp; -} tGATT_READ_REQ; - -/* write request data */ -typedef struct { - UINT16 handle; /* attribute handle */ - UINT16 offset; /* attribute value offset, if no offfset is needed for the command, ignore it */ - UINT16 len; /* length of attribute value */ - UINT8 value[GATT_MAX_ATTR_LEN]; /* the actual attribute value */ - BOOLEAN need_rsp; /* need write response */ - BOOLEAN is_prep; /* is prepare write */ -} tGATT_WRITE_REQ; - -/* callback data for server access request from client */ -typedef union { - tGATT_READ_REQ read_req; /* read request, read by Type, read blob */ - - tGATT_WRITE_REQ write_req; /* write */ - /* prepare write */ - /* write blob */ - UINT16 handle; /* handle value confirmation */ - UINT16 mtu; /* MTU exchange request */ - tGATT_EXEC_FLAG exec_write; /* execute write */ -} tGATTS_DATA; - -typedef UINT8 tGATT_SERV_IF; /* GATT Service Interface */ - -enum { - GATTS_REQ_TYPE_READ = 1, /* Attribute read request */ - GATTS_REQ_TYPE_WRITE, /* Attribute write request */ - GATTS_REQ_TYPE_WRITE_EXEC, /* Execute write */ - GATTS_REQ_TYPE_MTU, /* MTU exchange information */ - GATTS_REQ_TYPE_CONF /* handle value confirmation */ -}; -typedef UINT8 tGATTS_REQ_TYPE; - - - -/* Client Used Data Structure -*/ -/* definition of different discovery types */ -enum { - GATT_DISC_SRVC_ALL = 1, /* discover all services */ - GATT_DISC_SRVC_BY_UUID, /* discover service of a special type */ - GATT_DISC_INC_SRVC, /* discover the included service within a service */ - GATT_DISC_CHAR, /* discover characteristics of a service with/without type requirement */ - GATT_DISC_CHAR_DSCPT, /* discover characteristic descriptors of a character */ - GATT_DISC_MAX /* maximnun discover type */ -}; -typedef UINT8 tGATT_DISC_TYPE; - -/* Discover parameters of different discovery types -*/ -typedef struct { - tBT_UUID service; - UINT16 s_handle; - UINT16 e_handle; -} tGATT_DISC_PARAM; - -/* GATT read type enumeration -*/ -enum { - GATT_READ_BY_TYPE = 1, - GATT_READ_BY_HANDLE, - GATT_READ_MULTIPLE, - GATT_READ_CHAR_VALUE, - GATT_READ_PARTIAL, - GATT_READ_MAX -}; -typedef UINT8 tGATT_READ_TYPE; - -/* Read By Type Request (GATT_READ_BY_TYPE) Data -*/ -typedef struct { - tGATT_AUTH_REQ auth_req; - UINT16 s_handle; - UINT16 e_handle; - tBT_UUID uuid; -} tGATT_READ_BY_TYPE; - -/* GATT_READ_MULTIPLE request data -*/ -#define GATT_MAX_READ_MULTI_HANDLES 10 /* Max attributes to read in one request */ -typedef struct { - tGATT_AUTH_REQ auth_req; - UINT16 num_handles; /* number of handles to read */ - UINT16 handles[GATT_MAX_READ_MULTI_HANDLES]; /* handles list to be read */ -} tGATT_READ_MULTI; - -/* Read By Handle Request (GATT_READ_BY_HANDLE) data */ -typedef struct { - tGATT_AUTH_REQ auth_req; - UINT16 handle; -} tGATT_READ_BY_HANDLE; - -/* READ_BT_HANDLE_Request data */ -typedef struct { - tGATT_AUTH_REQ auth_req; - UINT16 handle; - UINT16 offset; -} tGATT_READ_PARTIAL; - -/* Read Request Data -*/ -typedef union { - tGATT_READ_BY_TYPE service; - tGATT_READ_BY_TYPE char_type; /* characterisitc type */ - tGATT_READ_MULTI read_multiple; - tGATT_READ_BY_HANDLE by_handle; - tGATT_READ_PARTIAL partial; -} tGATT_READ_PARAM; - -/* GATT write type enumeration */ -enum { - GATT_WRITE_NO_RSP = 1, - GATT_WRITE , - GATT_WRITE_PREPARE -}; -typedef UINT8 tGATT_WRITE_TYPE; - -/* Client Operation Complete Callback Data -*/ -typedef union { - tGATT_VALUE att_value; - UINT16 mtu; - UINT16 handle; -} tGATT_CL_COMPLETE; - -/* GATT client operation type, used in client callback function -*/ -#define GATTC_OPTYPE_NONE 0 -#define GATTC_OPTYPE_DISCOVERY 1 -#define GATTC_OPTYPE_READ 2 -#define GATTC_OPTYPE_WRITE 3 -#define GATTC_OPTYPE_EXE_WRITE 4 -#define GATTC_OPTYPE_CONFIG 5 -#define GATTC_OPTYPE_NOTIFICATION 6 -#define GATTC_OPTYPE_INDICATION 7 -typedef UINT8 tGATTC_OPTYPE; - -/* characteristic declaration -*/ -typedef struct { - tGATT_CHAR_PROP char_prop; /* characterisitc properties */ - UINT16 val_handle; /* characteristic value attribute handle */ - tBT_UUID char_uuid; /* characteristic UUID type */ -} tGATT_CHAR_DCLR_VAL; - -/* primary service group data -*/ -typedef struct { - UINT16 e_handle; /* ending handle of the group */ - tBT_UUID service_type; /* group type */ -} tGATT_GROUP_VALUE; - - -/* included service attribute value -*/ -typedef struct { - tBT_UUID service_type; /* included service UUID */ - UINT16 s_handle; /* starting handle */ - UINT16 e_handle; /* ending handle */ -} tGATT_INCL_SRVC; - -typedef union { - tGATT_INCL_SRVC incl_service; /* include service value */ - tGATT_GROUP_VALUE group_value; /* Service UUID type. - This field is used with GATT_DISC_SRVC_ALL - or GATT_DISC_SRVC_BY_UUID - type of discovery result callback. */ - - UINT16 handle; /* When used with GATT_DISC_INC_SRVC type discovery result, - it is the included service starting handle.*/ - - tGATT_CHAR_DCLR_VAL dclr_value; /* Characteristic declaration value. - This field is used with GATT_DISC_CHAR type discovery.*/ -} tGATT_DISC_VALUE; - -/* discover result record -*/ -typedef struct { - tBT_UUID type; - UINT16 handle; - tGATT_DISC_VALUE value; -} tGATT_DISC_RES; - - -#define GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP 0 /* start a idle timer for this duration - when no application need to use the link */ - -#define GATT_LINK_NO_IDLE_TIMEOUT 0xFFFF - -#define GATT_INVALID_ACL_HANDLE 0xFFFF -/* discover result callback function */ -typedef void (tGATT_DISC_RES_CB) (UINT16 conn_id, tGATT_DISC_TYPE disc_type, - tGATT_DISC_RES *p_data); - -/* discover complete callback function */ -typedef void (tGATT_DISC_CMPL_CB) (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_STATUS status); - -/* Define a callback function for when read/write/disc/config operation is completed. */ -typedef void (tGATT_CMPL_CBACK) (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, - tGATT_CL_COMPLETE *p_data); - -/* Define a callback function when an initialized connection is established. */ -typedef void (tGATT_CONN_CBACK) (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, - tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport); - -/* attribute request callback for ATT server */ -typedef void (tGATT_REQ_CBACK )(UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, - tGATTS_DATA *p_data); - -/* channel congestion/uncongestion callback */ -typedef void (tGATT_CONGESTION_CBACK )(UINT16 conn_id, BOOLEAN congested); - -/* Define a callback function when encryption is established. */ -typedef void (tGATT_ENC_CMPL_CB)(tGATT_IF gatt_if, BD_ADDR bda); - - -/* Define the structure that applications use to register with -** GATT. This structure includes callback functions. All functions -** MUST be provided. -*/ -typedef struct { - tGATT_CONN_CBACK *p_conn_cb; - tGATT_CMPL_CBACK *p_cmpl_cb; - tGATT_DISC_RES_CB *p_disc_res_cb; - tGATT_DISC_CMPL_CB *p_disc_cmpl_cb; - tGATT_REQ_CBACK *p_req_cb; - tGATT_ENC_CMPL_CB *p_enc_cmpl_cb; - tGATT_CONGESTION_CBACK *p_congestion_cb; -} tGATT_CBACK; - -/*********************** Start Handle Management Definitions ********************** -*/ - - -typedef struct { - tBT_UUID app_uuid128; - tBT_UUID svc_uuid; - UINT16 svc_inst; - UINT16 s_handle; - UINT16 e_handle; - BOOLEAN is_primary; /* primary service or secondary */ -} tGATTS_HNDL_RANGE; - - - -#define GATTS_SRV_CHG_CMD_ADD_CLIENT 1 -#define GATTS_SRV_CHG_CMD_UPDATE_CLIENT 2 -#define GATTS_SRV_CHG_CMD_REMOVE_CLIENT 3 -#define GATTS_SRV_CHG_CMD_READ_NUM_CLENTS 4 -#define GATTS_SRV_CHG_CMD_READ_CLENT 5 -typedef UINT8 tGATTS_SRV_CHG_CMD; - -typedef struct { - BD_ADDR bda; - BOOLEAN srv_changed; -} tGATTS_SRV_CHG; - - -typedef union { - tGATTS_SRV_CHG srv_chg; - UINT8 client_read_index; /* only used for sequential reading client srv chg info */ -} tGATTS_SRV_CHG_REQ; - -typedef union { - tGATTS_SRV_CHG srv_chg; - UINT8 num_clients; -} tGATTS_SRV_CHG_RSP; - - - -typedef struct { - tGATTS_HNDL_RANGE *p_new_srv_start; -} tGATTS_PENDING_NEW_SRV_START; - -/* Attibute server handle ranges NV storage callback functions -*/ -typedef void (tGATTS_NV_SAVE_CBACK)(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range); -typedef BOOLEAN (tGATTS_NV_SRV_CHG_CBACK)(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, - tGATTS_SRV_CHG_RSP *p_rsp); - -typedef struct { - tGATTS_NV_SAVE_CBACK *p_nv_save_callback; - tGATTS_NV_SRV_CHG_CBACK *p_srv_chg_callback; -} tGATT_APPL_INFO; - -/* -*********************** End Handle Management Definitions **********************/ - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/******************************************************************************* -** -** Function GATT_SetTraceLevel -** -** Description This function sets the trace level. If called with -** a value of 0xFF, it simply returns the current trace level. -** -** Returns The new or current trace level -** -*******************************************************************************/ -extern UINT8 GATT_SetTraceLevel (UINT8 new_level); - - -/*******************************************************************************/ -/* GATT Profile API Functions */ -/*******************************************************************************/ -/* GATT Profile Server Functions */ -/*******************************************************************************/ -/******************************************************************************* -** -** Function GATTS_AddHandleRange -** -** Description This function add the allocated handles range for the specifed -** application UUID, service UUID and service instance -** -** Parameter p_hndl_range: pointer to allocated handles information -** -** Returns TRUE if handle range is added sucessfully; otherwise FALSE. -** -*******************************************************************************/ - -extern BOOLEAN GATTS_AddHandleRange(tGATTS_HNDL_RANGE *p_hndl_range); - -/******************************************************************************* -** -** Function GATTS_NVRegister -** -** Description Application manager calls this function to register for -** NV save callback function. There can be one and only one -** NV save callback function. -** -** Parameter p_cb_info : callback informaiton -** -** Returns TRUE if registered OK, else FALSE -** -*******************************************************************************/ -extern BOOLEAN GATTS_NVRegister (tGATT_APPL_INFO *p_cb_info); - - -/******************************************************************************* -** -** Function GATTS_CreateService -** -** Description This function is called to reserve a block of handles for a service. -** -** *** It should be called only once per service instance *** -** -** Parameter gatt_if : application if -** p_svc_uuid : service UUID -** svc_inst : instance of the service inside the application -** num_handles : number of handles needed by the service. -** is_pri : is a primary service or not. -** -** Returns service handle if sucessful, otherwise 0. -** -*******************************************************************************/ -extern UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, - UINT16 svc_inst, UINT16 num_handles, BOOLEAN is_pri); - - -/******************************************************************************* -** -** Function GATTS_AddIncludeService -** -** Description This function is called to add an included service. -** -** Parameter service_handle : To which service this included service is added to. -** include_svc_handle : included service handle. -** -** Returns included service attribute handle. If 0, add included service -** fail. -** -*******************************************************************************/ -extern UINT16 GATTS_AddIncludeService (UINT16 service_handle, - UINT16 include_svc_handle); - - -/******************************************************************************* -** -** Function GATTS_AddCharacteristic -** -** Description This function is called to add a characteristic into a service. -** It will add a characteristic declaration and characteristic -** value declaration into the service database identified by the -** service handle. -** -** Parameter service_handle : To which service this included service is added to. -** char_uuid : Characteristic UUID. -** perm : Characteristic value declaration attribute permission. -** property : Characteristic Properties -** -** Returns Characteristic value declaration attribute handle. 0 if add -** characteristic failed. -** -*******************************************************************************/ -extern UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *p_char_uuid, - tGATT_PERM perm, tGATT_CHAR_PROP property, - tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control); - -/******************************************************************************* -** -** Function GATTS_AddCharDescriptor -** -** Description This function is called to add a characteristic descriptor -** into a service database. Add descriptor should follow add char -** to which it belongs, and next add char should be done only -** after all add descriptors for the previous char. -** -** Parameter service_handle : To which service this characteristic descriptor -** is added to. -** perm : Characteristic value declaration attribute -** permission. -** p_descr_uuid : Characteristic descriptor UUID. -** -** Returns Characteristic descriptor attribute handle. 0 if add -** characteristic descriptor failed. -** -*******************************************************************************/ -extern UINT16 GATTS_AddCharDescriptor (UINT16 service_handle, tGATT_PERM perm, - tBT_UUID *p_descr_uuid, tGATT_ATTR_VAL *attr_val, - tGATTS_ATTR_CONTROL *control); - -/******************************************************************************* -** -** Function GATTS_DeleteService -** -** Description This function is called to delete a service. -** -** Parameter gatt_if : application interface -** p_svc_uuid : service UUID -** svc_inst : instance of the service inside the application -** -** Returns TRUE if operation succeed, FALSE if handle block was not found. -** -*******************************************************************************/ -extern BOOLEAN GATTS_DeleteService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, - UINT16 svc_inst); - -/******************************************************************************* -** -** Function GATTS_StartService -** -** Description This function is called to start a service with GATT -** -** Parameter gatt_if : service handle. -** p_cback : application service callback functions. -** sup_transport : supported transport(s) for this primary service -** -** return GATT_SUCCESS if sucessfully started; otherwise error code. -** -*******************************************************************************/ -extern tGATT_STATUS GATTS_StartService (tGATT_IF gatt_if, UINT16 service_handle, - tGATT_TRANSPORT sup_transport); - - -/******************************************************************************* -** -** Function GATTS_StopService -** -** Description This function is called to stop a service -** -** Parameter service_handle : this is the start handle of a service -** -** Returns None. -** -*******************************************************************************/ -extern void GATTS_StopService (UINT16 service_handle); - - -/******************************************************************************* -** -** Function GATTs_HandleValueIndication -** -** Description This function sends a handle value indication to a client. -** -** Parameter conn_id: connection identifier. -** attr_handle: Attribute handle of this handle value indication. -** val_len: Length of the indicated attribute value. -** p_val: Pointer to the indicated attribute value data. -** -** Returns GATT_SUCCESS if sucessfully sent or queued; otherwise error code. -** -*******************************************************************************/ -extern tGATT_STATUS GATTS_HandleValueIndication (UINT16 conn_id, - UINT16 attr_handle, - UINT16 val_len, UINT8 *p_val); - -/******************************************************************************* -** -** Function GATTS_HandleValueNotification -** -** Description This function sends a handle value notification to a client. -** -** Parameter conn_id: connection identifier. -** attr_handle: Attribute handle of this handle value indication. -** val_len: Length of the indicated attribute value. -** p_val: Pointer to the indicated attribute value data. -** -** Returns GATT_SUCCESS if sucessfully sent; otherwise error code. -** -*******************************************************************************/ -extern tGATT_STATUS GATTS_HandleValueNotification (UINT16 conn_id, UINT16 attr_handle, - UINT16 val_len, UINT8 *p_val); - - -/******************************************************************************* -** -** Function GATTS_SendRsp -** -** Description This function sends the server response to client. -** -** Parameter conn_id: connection identifier. -** trans_id: transaction id -** status: response status -** p_msg: pointer to message parameters structure. -** -** Returns GATT_SUCCESS if sucessfully sent; otherwise error code. -** -*******************************************************************************/ -extern tGATT_STATUS GATTS_SendRsp (UINT16 conn_id, UINT32 trans_id, - tGATT_STATUS status, tGATTS_RSP *p_msg); - - -/******************************************************************************* -** -** Function GATTS_SetAttributeValue -** -** Description This function sends to set the attribute value . -** -** Parameter attr_handle:the attribute handle -** length: the attribute length -** value: the value to be set to the attribute in the database -** -** Returns GATT_SUCCESS if sucessfully sent; otherwise error code. -** -*******************************************************************************/ -tGATT_STATUS GATTS_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value); - - -/******************************************************************************* -** -** Function GATTS_GetAttributeValue -** -** Description This function sends to set the attribute value . -** -** Parameter attr_handle: the attribute handle -** length:the attribute value length in the database -** value: the attribute value out put -** -** Returns GATT_SUCCESS if sucessfully sent; otherwise error code. -** -*******************************************************************************/ -tGATT_STATUS GATTS_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value); - - - -/*******************************************************************************/ -/* GATT Profile Client Functions */ -/*******************************************************************************/ - -/******************************************************************************* -** -** Function GATTC_ConfigureMTU -** -** Description This function is called to configure the ATT MTU size for -** a connection on an LE transport. -** -** Parameters conn_id: connection identifier. -** mtu - attribute MTU size.. -** -** Returns GATT_SUCCESS if command started successfully. -** -*******************************************************************************/ -extern tGATT_STATUS GATTC_ConfigureMTU (UINT16 conn_id); - -/******************************************************************************* -** -** Function GATTC_Discover -** -** Description This function is called to do a discovery procedure on ATT server. -** -** Parameters conn_id: connection identifier. -** disc_type:discovery type. -** p_param: parameters of discovery requirement. -** -** Returns GATT_SUCCESS if command received/sent successfully. -** -*******************************************************************************/ -extern tGATT_STATUS GATTC_Discover (UINT16 conn_id, - tGATT_DISC_TYPE disc_type, - tGATT_DISC_PARAM *p_param ); -/******************************************************************************* -** -** Function GATTC_Read -** -** Description This function is called to read the value of an attribute from -** the server. -** -** Parameters conn_id: connection identifier. -** type - attribute read type. -** p_read - read operation parameters. -** -** Returns GATT_SUCCESS if command started successfully. -** -*******************************************************************************/ -extern tGATT_STATUS GATTC_Read (UINT16 conn_id, tGATT_READ_TYPE type, - tGATT_READ_PARAM *p_read); - -/******************************************************************************* -** -** Function GATTC_Write -** -** Description This function is called to read the value of an attribute from -** the server. -** -** Parameters conn_id: connection identifier. -** type - attribute write type. -** p_write - write operation parameters. -** -** Returns GATT_SUCCESS if command started successfully. -** -*******************************************************************************/ -extern tGATT_STATUS GATTC_Write (UINT16 conn_id, tGATT_WRITE_TYPE type, - tGATT_VALUE *p_write); - - -/******************************************************************************* -** -** Function GATTC_ExecuteWrite -** -** Description This function is called to send an Execute write request to -** the server. -** -** Parameters conn_id: connection identifier. -** is_execute - to execute or cancel the prepare write requet(s) -** -** Returns GATT_SUCCESS if command started successfully. -** -*******************************************************************************/ -extern tGATT_STATUS GATTC_ExecuteWrite (UINT16 conn_id, BOOLEAN is_execute); - -/******************************************************************************* -** -** Function GATTC_SendHandleValueConfirm -** -** Description This function is called to send a handle value confirmation -** as response to a handle value notification from server. -** -** Parameters conn_id: connection identifier. -** handle: the handle of the attribute confirmation. -** -** Returns GATT_SUCCESS if command started successfully. -** -*******************************************************************************/ -extern tGATT_STATUS GATTC_SendHandleValueConfirm (UINT16 conn_id, UINT16 handle); - - -/******************************************************************************* -** -** Function GATT_SetIdleTimeout -** -** Description This function (common to both client and server) sets the idle -** timeout for a tansport connection -** -** Parameter bd_addr: target device bd address. -** idle_tout: timeout value in seconds. -** transport: trasnport option. -** -** Returns void -** -*******************************************************************************/ -extern void GATT_SetIdleTimeout (BD_ADDR bd_addr, UINT16 idle_tout, - tGATT_TRANSPORT transport); - - -/******************************************************************************* -** -** Function GATT_Register -** -** Description This function is called to register an application -** with GATT -** -** Parameter p_app_uuid128: Application UUID -** p_cb_info: callback functions. -** -** Returns 0 for error, otherwise the index of the client registered with GATT -** -*******************************************************************************/ -extern tGATT_IF GATT_Register (tBT_UUID *p_app_uuid128, tGATT_CBACK *p_cb_info); - -/******************************************************************************* -** -** Function GATT_Deregister -** -** Description This function deregistered the application from GATT. -** -** Parameters gatt_if: applicaiton interface. -** -** Returns None. -** -*******************************************************************************/ -extern void GATT_Deregister (tGATT_IF gatt_if); - -/******************************************************************************* -** -** Function GATT_StartIf -** -** Description This function is called after registration to start receiving -** callbacks for registered interface. Function may call back -** with connection status and queued notifications -** -** Parameter gatt_if: applicaiton interface. -** -** Returns None -** -*******************************************************************************/ -extern void GATT_StartIf (tGATT_IF gatt_if); - -/******************************************************************************* -** -** Function GATT_Connect -** -** Description This function initiate a connecttion to a remote device on GATT -** channel. -** -** Parameters gatt_if: applicaiton interface -** bd_addr: peer device address. -** bd_addr_type: peer device address type. -** is_direct: is a direct conenection or a background auto connection -** transport : Physical transport for GATT connection (BR/EDR or LE) -** -** Returns TRUE if connection started; FALSE if connection start failure. -** -*******************************************************************************/ -extern BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_type, - BOOLEAN is_direct, tBT_TRANSPORT transport); - - -/******************************************************************************* -** -** Function GATT_CancelConnect -** -** Description This function terminate the connection initaition to a remote -** device on GATT channel. -** -** Parameters gatt_if: client interface. If 0 used as unconditionally disconnect, -** typically used for direct connection cancellation. -** bd_addr: peer device address. -** is_direct: is a direct conenection or a background auto connection -** -** Returns TRUE if connection started; FALSE if connection start failure. -** -*******************************************************************************/ -extern BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr, - BOOLEAN is_direct); - -/******************************************************************************* -** -** Function GATT_Disconnect -** -** Description This function disconnect the GATT channel for this registered -** application. -** -** Parameters conn_id: connection identifier. -** -** Returns GATT_SUCCESS if disconnected. -** -*******************************************************************************/ -extern tGATT_STATUS GATT_Disconnect (UINT16 conn_id); - - - -/******************************************************************************* -** -** Function GATT_GetConnectionInfor -** -** Description This function use conn_id to find its associated BD address and applciation -** interface -** -** Parameters conn_id: connection id (input) -** p_gatt_if: applicaiton interface (output) -** bd_addr: peer device address. (output) -** transport : physical transport of the GATT connection (BR/EDR or LE) -** -** Returns TRUE the ligical link information is found for conn_id -** -*******************************************************************************/ -extern BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, - BD_ADDR bd_addr, tBT_TRANSPORT *p_transport); - - -/******************************************************************************* -** -** Function GATT_GetConnIdIfConnected -** -** Description This function find the conn_id if the logical link for BD address -** and applciation interface is connected -** -** Parameters gatt_if: applicaiton interface (input) -** bd_addr: peer device address. (input) -** p_conn_id: connection id (output) -** transport : physical transport of the GATT connection (BR/EDR or LE) -** -** Returns TRUE the ligical link is connected -** -*******************************************************************************/ -extern BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, - UINT16 *p_conn_id, tBT_TRANSPORT transport); - - -/******************************************************************************* -** -** Function GATT_Listen -** -** Description This function start or stop LE advertisement and listen for -** connection. -** -** Parameters gatt_if: applicaiton interface -** p_bd_addr: listen for specific address connection, or NULL for -** listen to all device connection. -** start: is a direct conenection or a background auto connection -** -** Returns TRUE if advertisement is started; FALSE if adv start failure. -** -*******************************************************************************/ -extern BOOLEAN GATT_Listen (tGATT_IF gatt_if, BOOLEAN start, BD_ADDR_PTR bd_addr); - -/******************************************************************************* -** -** Function GATT_ConfigServiceChangeCCC -** -** Description Configure service change indication on remote device -** -** Returns None. -** -*******************************************************************************/ -extern void GATT_ConfigServiceChangeCCC (BD_ADDR remote_bda, BOOLEAN enable, - tBT_TRANSPORT transport); - -#ifdef __cplusplus - -} -#endif - -#endif /* GATT_API_H */ diff --git a/tools/sdk/include/bluedroid/stack/gattdefs.h b/tools/sdk/include/bluedroid/stack/gattdefs.h deleted file mode 100644 index 9380e2e9..00000000 --- a/tools/sdk/include/bluedroid/stack/gattdefs.h +++ /dev/null @@ -1,124 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains internally used ATT definitions - * - ******************************************************************************/ - -#ifndef _GATTDEFS_H -#define _GATTDEFS_H - -#define GATT_ILLEGAL_UUID 0 - -/* GATT attribute types -*/ -#define GATT_UUID_PRI_SERVICE 0x2800 -#define GATT_UUID_SEC_SERVICE 0x2801 -#define GATT_UUID_INCLUDE_SERVICE 0x2802 -#define GATT_UUID_CHAR_DECLARE 0x2803 /* Characteristic Declaration*/ - -#define GATT_UUID_CHAR_EXT_PROP 0x2900 /* Characteristic Extended Properties */ -#define GATT_UUID_CHAR_DESCRIPTION 0x2901 /* Characteristic User Description*/ -#define GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 /* Client Characteristic Configuration */ -#define GATT_UUID_CHAR_SRVR_CONFIG 0x2903 /* Server Characteristic Configuration */ -#define GATT_UUID_CHAR_PRESENT_FORMAT 0x2904 /* Characteristic Presentation Format*/ -#define GATT_UUID_CHAR_AGG_FORMAT 0x2905 /* Characteristic Aggregate Format*/ -#define GATT_UUID_CHAR_VALID_RANGE 0x2906 /* Characteristic Valid Range */ -#define GATT_UUID_EXT_RPT_REF_DESCR 0x2907 -#define GATT_UUID_RPT_REF_DESCR 0x2908 - - -/* GAP Profile Attributes -*/ -#define GATT_UUID_GAP_DEVICE_NAME 0x2A00 -#define GATT_UUID_GAP_ICON 0x2A01 -#define GATT_UUID_GAP_PREF_CONN_PARAM 0x2A04 -#define GATT_UUID_GAP_CENTRAL_ADDR_RESOL 0x2AA6 - -/* Attribute Profile Attribute UUID */ -#define GATT_UUID_GATT_SRV_CHGD 0x2A05 -/* Attribute Protocol Test */ - -/* Link Loss Service */ -#define GATT_UUID_ALERT_LEVEL 0x2A06 /* Alert Level */ -#define GATT_UUID_TX_POWER_LEVEL 0x2A07 /* TX power level */ - -/* Time Profile */ -/* Current Time Service */ -#define GATT_UUID_CURRENT_TIME 0x2A2B /* Current Time */ -#define GATT_UUID_LOCAL_TIME_INFO 0x2A0F /* Local time info */ -#define GATT_UUID_REF_TIME_INFO 0x2A14 /* reference time information */ - -/* NwA Profile */ -#define GATT_UUID_NW_STATUS 0x2A18 /* network availability status */ -#define GATT_UUID_NW_TRIGGER 0x2A1A /* Network availability trigger */ - -/* phone alert */ -#define GATT_UUID_ALERT_STATUS 0x2A3F /* alert status */ -#define GATT_UUID_RINGER_CP 0x2A40 /* ringer control point */ -#define GATT_UUID_RINGER_SETTING 0x2A41 /* ringer setting */ - -/* Glucose Service */ -#define GATT_UUID_GM_MEASUREMENT 0x2A18 -#define GATT_UUID_GM_CONTEXT 0x2A34 -#define GATT_UUID_GM_CONTROL_POINT 0x2A52 -#define GATT_UUID_GM_FEATURE 0x2A51 - -/* device infor characteristic */ -#define GATT_UUID_SYSTEM_ID 0x2A23 -#define GATT_UUID_MODEL_NUMBER_STR 0x2A24 -#define GATT_UUID_SERIAL_NUMBER_STR 0x2A25 -#define GATT_UUID_FW_VERSION_STR 0x2A26 -#define GATT_UUID_HW_VERSION_STR 0x2A27 -#define GATT_UUID_SW_VERSION_STR 0x2A28 -#define GATT_UUID_MANU_NAME 0x2A29 -#define GATT_UUID_IEEE_DATA 0x2A2A -#define GATT_UUID_PNP_ID 0x2A50 - -/* HID characteristics */ -#define GATT_UUID_HID_INFORMATION 0x2A4A -#define GATT_UUID_HID_REPORT_MAP 0x2A4B -#define GATT_UUID_HID_CONTROL_POINT 0x2A4C -#define GATT_UUID_HID_REPORT 0x2A4D -#define GATT_UUID_HID_PROTO_MODE 0x2A4E -#define GATT_UUID_HID_BT_KB_INPUT 0x2A22 -#define GATT_UUID_HID_BT_KB_OUTPUT 0x2A32 -#define GATT_UUID_HID_BT_MOUSE_INPUT 0x2A33 - -/* Battery Service char */ -#define GATT_UUID_BATTERY_LEVEL 0x2A19 - -#define GATT_UUID_SC_CONTROL_POINT 0x2A55 -#define GATT_UUID_SENSOR_LOCATION 0x2A5D - -/* RUNNERS SPEED AND CADENCE SERVICE */ -#define GATT_UUID_RSC_MEASUREMENT 0x2A53 -#define GATT_UUID_RSC_FEATURE 0x2A54 - -/* CYCLING SPEED AND CADENCE SERVICE */ -#define GATT_UUID_CSC_MEASUREMENT 0x2A5B -#define GATT_UUID_CSC_FEATURE 0x2A5C - - -/* Scan Parameter charatceristics */ -#define GATT_UUID_SCAN_INT_WINDOW 0x2A4F -#define GATT_UUID_SCAN_REFRESH 0x2A31 - -#endif diff --git a/tools/sdk/include/bluedroid/stack/hcidefs.h b/tools/sdk/include/bluedroid/stack/hcidefs.h deleted file mode 100644 index 0169ba8c..00000000 --- a/tools/sdk/include/bluedroid/stack/hcidefs.h +++ /dev/null @@ -1,2609 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2014 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef HCIDEFS_H -#define HCIDEFS_H - -#include "common/bt_target.h" - -#include "stack/bt_types.h" - -#define HCI_PROTO_VERSION 0x01 /* Version for BT spec 1.1 */ -#define HCI_PROTO_VERSION_1_2 0x02 /* Version for BT spec 1.2 */ -#define HCI_PROTO_VERSION_2_0 0x03 /* Version for BT spec 2.0 */ -#define HCI_PROTO_VERSION_2_1 0x04 /* Version for BT spec 2.1 [Lisbon] */ -#define HCI_PROTO_VERSION_3_0 0x05 /* Version for BT spec 3.0 */ -#define HCI_PROTO_VERSION_4_0 0x06 /* Version for BT spec 4.0 */ -#define HCI_PROTO_VERSION_4_1 0x07 /* Version for BT spec 4.1 */ -#define HCI_PROTO_VERSION_4_2 0x08 /* Version for BT spec 4.2 */ -#define HCI_PROTO_REVISION 0x000C /* Current implementation version */ -/* -** Definitions for HCI groups -*/ -#define HCI_GRP_LINK_CONTROL_CMDS (0x01 << 10) /* 0x0400 */ -#define HCI_GRP_LINK_POLICY_CMDS (0x02 << 10) /* 0x0800 */ -#define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10) /* 0x0C00 */ -#define HCI_GRP_INFORMATIONAL_PARAMS (0x04 << 10) /* 0x1000 */ -#define HCI_GRP_STATUS_PARAMS (0x05 << 10) /* 0x1400 */ -#define HCI_GRP_TESTING_CMDS (0x06 << 10) /* 0x1800 */ - -#define HCI_GRP_VENDOR_SPECIFIC (0x3F << 10) /* 0xFC00 */ - -/* Group occupies high 6 bits of the HCI command rest is opcode itself */ -#define HCI_OGF(p) (UINT8)((0xFC00 & (p)) >> 10) -#define HCI_OCF(p) ( 0x3FF & (p)) - -/* -** Definitions for Link Control Commands -*/ -/* Following opcode is used only in command complete event for flow control */ -#define HCI_COMMAND_NONE 0x0000 - -/* Commands of HCI_GRP_LINK_CONTROL_CMDS group */ -#define HCI_INQUIRY (0x0001 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_INQUIRY_CANCEL (0x0002 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_PERIODIC_INQUIRY_MODE (0x0003 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_EXIT_PERIODIC_INQUIRY_MODE (0x0004 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_CREATE_CONNECTION (0x0005 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_DISCONNECT (0x0006 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_ADD_SCO_CONNECTION (0x0007 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_CREATE_CONNECTION_CANCEL (0x0008 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_ACCEPT_CONNECTION_REQUEST (0x0009 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_REJECT_CONNECTION_REQUEST (0x000A | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_LINK_KEY_REQUEST_REPLY (0x000B | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_LINK_KEY_REQUEST_NEG_REPLY (0x000C | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_PIN_CODE_REQUEST_REPLY (0x000D | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_PIN_CODE_REQUEST_NEG_REPLY (0x000E | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_CHANGE_CONN_PACKET_TYPE (0x000F | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_AUTHENTICATION_REQUESTED (0x0011 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_SET_CONN_ENCRYPTION (0x0013 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_CHANGE_CONN_LINK_KEY (0x0015 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_MASTER_LINK_KEY (0x0017 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_RMT_NAME_REQUEST (0x0019 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_RMT_NAME_REQUEST_CANCEL (0x001A | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_READ_RMT_FEATURES (0x001B | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_READ_RMT_EXT_FEATURES (0x001C | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_READ_RMT_VERSION_INFO (0x001D | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_READ_RMT_CLOCK_OFFSET (0x001F | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_READ_LMP_HANDLE (0x0020 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_SETUP_ESCO_CONNECTION (0x0028 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_ACCEPT_ESCO_CONNECTION (0x0029 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_REJECT_ESCO_CONNECTION (0x002A | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_IO_CAPABILITY_REQUEST_REPLY (0x002B | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_USER_CONF_REQUEST_REPLY (0x002C | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_USER_CONF_VALUE_NEG_REPLY (0x002D | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_USER_PASSKEY_REQ_REPLY (0x002E | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_USER_PASSKEY_REQ_NEG_REPLY (0x002F | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_REM_OOB_DATA_REQ_REPLY (0x0030 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_REM_OOB_DATA_REQ_NEG_REPLY (0x0033 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_IO_CAP_REQ_NEG_REPLY (0x0034 | HCI_GRP_LINK_CONTROL_CMDS) - -/* AMP HCI */ -#define HCI_CREATE_PHYSICAL_LINK (0x0035 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_ACCEPT_PHYSICAL_LINK (0x0036 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_DISCONNECT_PHYSICAL_LINK (0x0037 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_CREATE_LOGICAL_LINK (0x0038 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_ACCEPT_LOGICAL_LINK (0x0039 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_DISCONNECT_LOGICAL_LINK (0x003A | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_LOGICAL_LINK_CANCEL (0x003B | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_FLOW_SPEC_MODIFY (0x003C | HCI_GRP_LINK_CONTROL_CMDS) - -#define HCI_ENH_SETUP_ESCO_CONNECTION (0x003D | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_ENH_ACCEPT_ESCO_CONNECTION (0x003E | HCI_GRP_LINK_CONTROL_CMDS) - -/* ConnectionLess Broadcast */ -#define HCI_TRUNCATED_PAGE (0x003F | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_TRUNCATED_PAGE_CANCEL (0x0040 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_SET_CLB (0x0041 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_RECEIVE_CLB (0x0042 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_START_SYNC_TRAIN (0x0043 | HCI_GRP_LINK_CONTROL_CMDS) -#define HCI_RECEIVE_SYNC_TRAIN (0x0044 | HCI_GRP_LINK_CONTROL_CMDS) - -#define HCI_LINK_CTRL_CMDS_FIRST HCI_INQUIRY -#define HCI_LINK_CTRL_CMDS_LAST HCI_RECEIVE_SYNC_TRAIN - -/* Commands of HCI_GRP_LINK_POLICY_CMDS */ -#define HCI_HOLD_MODE (0x0001 | HCI_GRP_LINK_POLICY_CMDS) -#define HCI_SNIFF_MODE (0x0003 | HCI_GRP_LINK_POLICY_CMDS) -#define HCI_EXIT_SNIFF_MODE (0x0004 | HCI_GRP_LINK_POLICY_CMDS) -#define HCI_PARK_MODE (0x0005 | HCI_GRP_LINK_POLICY_CMDS) -#define HCI_EXIT_PARK_MODE (0x0006 | HCI_GRP_LINK_POLICY_CMDS) -#define HCI_QOS_SETUP (0x0007 | HCI_GRP_LINK_POLICY_CMDS) -#define HCI_ROLE_DISCOVERY (0x0009 | HCI_GRP_LINK_POLICY_CMDS) -#define HCI_SWITCH_ROLE (0x000B | HCI_GRP_LINK_POLICY_CMDS) -#define HCI_READ_POLICY_SETTINGS (0x000C | HCI_GRP_LINK_POLICY_CMDS) -#define HCI_WRITE_POLICY_SETTINGS (0x000D | HCI_GRP_LINK_POLICY_CMDS) -#define HCI_READ_DEF_POLICY_SETTINGS (0x000E | HCI_GRP_LINK_POLICY_CMDS) -#define HCI_WRITE_DEF_POLICY_SETTINGS (0x000F | HCI_GRP_LINK_POLICY_CMDS) -#define HCI_FLOW_SPECIFICATION (0x0010 | HCI_GRP_LINK_POLICY_CMDS) -#define HCI_SNIFF_SUB_RATE (0x0011 | HCI_GRP_LINK_POLICY_CMDS) - -#define HCI_LINK_POLICY_CMDS_FIRST HCI_HOLD_MODE -#define HCI_LINK_POLICY_CMDS_LAST HCI_SNIFF_SUB_RATE - - -/* Commands of HCI_GRP_HOST_CONT_BASEBAND_CMDS */ -#define HCI_SET_EVENT_MASK (0x0001 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_SET_EVENT_FILTER (0x0005 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_FLUSH (0x0008 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_PIN_TYPE (0x0009 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_PIN_TYPE (0x000A | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_CREATE_NEW_UNIT_KEY (0x000B | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_GET_MWS_TRANS_LAYER_CFG (0x000C | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_STORED_LINK_KEY (0x000D | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_STORED_LINK_KEY (0x0011 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_DELETE_STORED_LINK_KEY (0x0012 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_CHANGE_LOCAL_NAME (0x0013 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_LOCAL_NAME (0x0014 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_CONN_ACCEPT_TOUT (0x0015 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_CONN_ACCEPT_TOUT (0x0016 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_PAGE_TOUT (0x0017 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_PAGE_TOUT (0x0018 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_SCAN_ENABLE (0x0019 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_SCAN_ENABLE (0x001A | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_PAGESCAN_CFG (0x001B | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_PAGESCAN_CFG (0x001C | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_INQUIRYSCAN_CFG (0x001D | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_INQUIRYSCAN_CFG (0x001E | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_AUTHENTICATION_ENABLE (0x001F | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_AUTHENTICATION_ENABLE (0x0020 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_ENCRYPTION_MODE (0x0021 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_ENCRYPTION_MODE (0x0022 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_CLASS_OF_DEVICE (0x0023 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_CLASS_OF_DEVICE (0x0024 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_VOICE_SETTINGS (0x0025 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_VOICE_SETTINGS (0x0026 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_AUTO_FLUSH_TOUT (0x0027 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_AUTO_FLUSH_TOUT (0x0028 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_NUM_BCAST_REXMITS (0x0029 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_NUM_BCAST_REXMITS (0x002A | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_HOLD_MODE_ACTIVITY (0x002B | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_HOLD_MODE_ACTIVITY (0x002C | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_TRANSMIT_POWER_LEVEL (0x002D | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_SCO_FLOW_CTRL_ENABLE (0x002E | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_SCO_FLOW_CTRL_ENABLE (0x002F | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_SET_HC_TO_HOST_FLOW_CTRL (0x0031 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_HOST_BUFFER_SIZE (0x0033 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_HOST_NUM_PACKETS_DONE (0x0035 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_LINK_SUPER_TOUT (0x0036 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_LINK_SUPER_TOUT (0x0037 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_NUM_SUPPORTED_IAC (0x0038 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_CURRENT_IAC_LAP (0x0039 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_CURRENT_IAC_LAP (0x003A | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_PAGESCAN_PERIOD_MODE (0x003B | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_PAGESCAN_PERIOD_MODE (0x003C | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_PAGESCAN_MODE (0x003D | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_PAGESCAN_MODE (0x003E | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_SET_AFH_CHANNELS (0x003F | HCI_GRP_HOST_CONT_BASEBAND_CMDS) - -#define HCI_READ_INQSCAN_TYPE (0x0042 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_INQSCAN_TYPE (0x0043 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_INQUIRY_MODE (0x0044 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_INQUIRY_MODE (0x0045 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_PAGESCAN_TYPE (0x0046 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_PAGESCAN_TYPE (0x0047 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_AFH_ASSESSMENT_MODE (0x0048 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_AFH_ASSESSMENT_MODE (0x0049 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_EXT_INQ_RESPONSE (0x0051 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_EXT_INQ_RESPONSE (0x0052 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_REFRESH_ENCRYPTION_KEY (0x0053 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_SIMPLE_PAIRING_MODE (0x0055 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_SIMPLE_PAIRING_MODE (0x0056 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_LOCAL_OOB_DATA (0x0057 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_INQ_TX_POWER_LEVEL (0x0058 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_INQ_TX_POWER_LEVEL (0x0059 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_ERRONEOUS_DATA_RPT (0x005A | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_ERRONEOUS_DATA_RPT (0x005B | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_ENHANCED_FLUSH (0x005F | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_SEND_KEYPRESS_NOTIF (0x0060 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) - - -/* AMP HCI */ -#define HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT (0x0061 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT (0x0062 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_SET_EVENT_MASK_PAGE_2 (0x0063 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_LOCATION_DATA (0x0064 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_LOCATION_DATA (0x0065 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_FLOW_CONTROL_MODE (0x0066 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_FLOW_CONTROL_MODE (0x0067 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_BE_FLUSH_TOUT (0x0069 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_BE_FLUSH_TOUT (0x006A | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_SHORT_RANGE_MODE (0x006B | HCI_GRP_HOST_CONT_BASEBAND_CMDS) /* 802.11 only */ -#define HCI_READ_LE_HOST_SUPPORT (0x006C | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_LE_HOST_SUPPORT (0x006D | HCI_GRP_HOST_CONT_BASEBAND_CMDS) - - -/* MWS coexistence */ -#define HCI_SET_MWS_CHANNEL_PARAMETERS (0x006E | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_SET_EXTERNAL_FRAME_CONFIGURATION (0x006F | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_SET_MWS_SIGNALING (0x0070 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_SET_MWS_TRANSPORT_LAYER (0x0071 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_SET_MWS_SCAN_FREQUENCY_TABLE (0x0072 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_SET_MWS_PATTERN_CONFIGURATION (0x0073 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) - -/* Connectionless Broadcast */ -#define HCI_SET_RESERVED_LT_ADDR (0x0074 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_DELETE_RESERVED_LT_ADDR (0x0075 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_CLB_DATA (0x0076 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_SYNC_TRAIN_PARAM (0x0077 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_SYNC_TRAIN_PARAM (0x0078 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) - -#define HCI_READ_SECURE_CONNS_SUPPORT (0x0079 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_SECURE_CONNS_SUPPORT (0x007A | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_CONT_BASEBAND_CMDS_FIRST HCI_SET_EVENT_MASK -#define HCI_CONT_BASEBAND_CMDS_LAST HCI_READ_SYNC_TRAIN_PARAM - - -/* Commands of HCI_GRP_INFORMATIONAL_PARAMS group */ -#define HCI_READ_LOCAL_VERSION_INFO (0x0001 | HCI_GRP_INFORMATIONAL_PARAMS) -#define HCI_READ_LOCAL_SUPPORTED_CMDS (0x0002 | HCI_GRP_INFORMATIONAL_PARAMS) -#define HCI_READ_LOCAL_FEATURES (0x0003 | HCI_GRP_INFORMATIONAL_PARAMS) -#define HCI_READ_LOCAL_EXT_FEATURES (0x0004 | HCI_GRP_INFORMATIONAL_PARAMS) -#define HCI_READ_BUFFER_SIZE (0x0005 | HCI_GRP_INFORMATIONAL_PARAMS) -#define HCI_READ_COUNTRY_CODE (0x0007 | HCI_GRP_INFORMATIONAL_PARAMS) -#define HCI_READ_BD_ADDR (0x0009 | HCI_GRP_INFORMATIONAL_PARAMS) -#define HCI_READ_DATA_BLOCK_SIZE (0x000A | HCI_GRP_INFORMATIONAL_PARAMS) -#define HCI_READ_LOCAL_SUPPORTED_CODECS (0x000B | HCI_GRP_INFORMATIONAL_PARAMS) - -#define HCI_INFORMATIONAL_CMDS_FIRST HCI_READ_LOCAL_VERSION_INFO -#define HCI_INFORMATIONAL_CMDS_LAST HCI_READ_LOCAL_SUPPORTED_CODECS - - -/* Commands of HCI_GRP_STATUS_PARAMS group */ -#define HCI_READ_FAILED_CONTACT_COUNT (0x0001 | HCI_GRP_STATUS_PARAMS) -#define HCI_RESET_FAILED_CONTACT_COUNT (0x0002 | HCI_GRP_STATUS_PARAMS) -#define HCI_GET_LINK_QUALITY (0x0003 | HCI_GRP_STATUS_PARAMS) -#define HCI_READ_RSSI (0x0005 | HCI_GRP_STATUS_PARAMS) -#define HCI_READ_AFH_CH_MAP (0x0006 | HCI_GRP_STATUS_PARAMS) -#define HCI_READ_CLOCK (0x0007 | HCI_GRP_STATUS_PARAMS) -#define HCI_READ_ENCR_KEY_SIZE (0x0008 | HCI_GRP_STATUS_PARAMS) - -/* AMP HCI */ -#define HCI_READ_LOCAL_AMP_INFO (0x0009 | HCI_GRP_STATUS_PARAMS) -#define HCI_READ_LOCAL_AMP_ASSOC (0x000A | HCI_GRP_STATUS_PARAMS) -#define HCI_WRITE_REMOTE_AMP_ASSOC (0x000B | HCI_GRP_STATUS_PARAMS) - -#define HCI_STATUS_PARAMS_CMDS_FIRST HCI_READ_FAILED_CONTACT_COUNT -#define HCI_STATUS_PARAMS_CMDS_LAST HCI_WRITE_REMOTE_AMP_ASSOC - -/* Commands of HCI_GRP_TESTING_CMDS group */ -#define HCI_READ_LOOPBACK_MODE (0x0001 | HCI_GRP_TESTING_CMDS) -#define HCI_WRITE_LOOPBACK_MODE (0x0002 | HCI_GRP_TESTING_CMDS) -#define HCI_ENABLE_DEV_UNDER_TEST_MODE (0x0003 | HCI_GRP_TESTING_CMDS) -#define HCI_WRITE_SIMP_PAIR_DEBUG_MODE (0x0004 | HCI_GRP_TESTING_CMDS) - -/* AMP HCI */ -#define HCI_ENABLE_AMP_RCVR_REPORTS (0x0007 | HCI_GRP_TESTING_CMDS) -#define HCI_AMP_TEST_END (0x0008 | HCI_GRP_TESTING_CMDS) -#define HCI_AMP_TEST (0x0009 | HCI_GRP_TESTING_CMDS) - -#define HCI_TESTING_CMDS_FIRST HCI_READ_LOOPBACK_MODE -#define HCI_TESTING_CMDS_LAST HCI_AMP_TEST - -#define HCI_VENDOR_CMDS_FIRST 0x0001 -#define HCI_VENDOR_CMDS_LAST 0xFFFF -#define HCI_VSC_MULTI_AV_HANDLE 0x0AAA -#define HCI_VSC_BURST_MODE_HANDLE 0x0BBB - -/* BLE HCI */ -#define HCI_GRP_BLE_CMDS (0x08 << 10) -/* Commands of BLE Controller setup and configuration */ -#define HCI_BLE_SET_EVENT_MASK (0x0001 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_READ_BUFFER_SIZE (0x0002 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_READ_LOCAL_SPT_FEAT (0x0003 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_WRITE_LOCAL_SPT_FEAT (0x0004 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_WRITE_RANDOM_ADDR (0x0005 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_WRITE_ADV_PARAMS (0x0006 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_READ_ADV_CHNL_TX_POWER (0x0007 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_WRITE_ADV_DATA (0x0008 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_WRITE_SCAN_RSP_DATA (0x0009 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_WRITE_ADV_ENABLE (0x000A | HCI_GRP_BLE_CMDS) -#define HCI_BLE_WRITE_SCAN_PARAMS (0x000B | HCI_GRP_BLE_CMDS) -#define HCI_BLE_WRITE_SCAN_ENABLE (0x000C | HCI_GRP_BLE_CMDS) -#define HCI_BLE_CREATE_LL_CONN (0x000D | HCI_GRP_BLE_CMDS) -#define HCI_BLE_CREATE_CONN_CANCEL (0x000E | HCI_GRP_BLE_CMDS) -#define HCI_BLE_READ_WHITE_LIST_SIZE (0x000F | HCI_GRP_BLE_CMDS) -#define HCI_BLE_CLEAR_WHITE_LIST (0x0010 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_ADD_WHITE_LIST (0x0011 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_REMOVE_WHITE_LIST (0x0012 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_UPD_LL_CONN_PARAMS (0x0013 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_SET_HOST_CHNL_CLASS (0x0014 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_READ_CHNL_MAP (0x0015 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_READ_REMOTE_FEAT (0x0016 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_ENCRYPT (0x0017 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_RAND (0x0018 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_START_ENC (0x0019 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_LTK_REQ_REPLY (0x001A | HCI_GRP_BLE_CMDS) -#define HCI_BLE_LTK_REQ_NEG_REPLY (0x001B | HCI_GRP_BLE_CMDS) -#define HCI_BLE_READ_SUPPORTED_STATES (0x001C | HCI_GRP_BLE_CMDS) -/*0x001D, 0x001E and 0x001F are reserved*/ -#define HCI_BLE_RECEIVER_TEST (0x001D | HCI_GRP_BLE_CMDS) -#define HCI_BLE_TRANSMITTER_TEST (0x001E | HCI_GRP_BLE_CMDS) -/* BLE TEST COMMANDS */ -#define HCI_BLE_TEST_END (0x001F | HCI_GRP_BLE_CMDS) -#define HCI_BLE_RC_PARAM_REQ_REPLY (0x0020 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_RC_PARAM_REQ_NEG_REPLY (0x0021 | HCI_GRP_BLE_CMDS) - -#define HCI_BLE_SET_DATA_LENGTH (0x0022 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_READ_DEFAULT_DATA_LENGTH (0x0023 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_WRITE_DEFAULT_DATA_LENGTH (0x0024 | HCI_GRP_BLE_CMDS) - -#define HCI_BLE_ADD_DEV_RESOLVING_LIST (0x0027 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_RM_DEV_RESOLVING_LIST (0x0028 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_CLEAR_RESOLVING_LIST (0x0029 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_READ_RESOLVING_LIST_SIZE (0x002A | HCI_GRP_BLE_CMDS) -#define HCI_BLE_READ_RESOLVABLE_ADDR_PEER (0x002B | HCI_GRP_BLE_CMDS) -#define HCI_BLE_READ_RESOLVABLE_ADDR_LOCAL (0x002C | HCI_GRP_BLE_CMDS) -#define HCI_BLE_SET_ADDR_RESOLUTION_ENABLE (0x002D | HCI_GRP_BLE_CMDS) -#define HCI_BLE_SET_RAND_PRIV_ADDR_TIMOUT (0x002E | HCI_GRP_BLE_CMDS) - -/* LE Get Vendor Capabilities Command OCF */ -#define HCI_BLE_VENDOR_CAP_OCF (0x0153 | HCI_GRP_VENDOR_SPECIFIC) - -/* Multi adv OCF */ -#define HCI_BLE_MULTI_ADV_OCF (0x0154 | HCI_GRP_VENDOR_SPECIFIC) - -/* Batch scan OCF */ -#define HCI_BLE_BATCH_SCAN_OCF (0x0156 | HCI_GRP_VENDOR_SPECIFIC) - -/* ADV filter OCF */ -#define HCI_BLE_ADV_FILTER_OCF (0x0157 | HCI_GRP_VENDOR_SPECIFIC) - -/* Tracking OCF */ -#define HCI_BLE_TRACK_ADV_OCF (0x0158 | HCI_GRP_VENDOR_SPECIFIC) - -/* Energy info OCF */ -#define HCI_BLE_ENERGY_INFO_OCF (0x0159 | HCI_GRP_VENDOR_SPECIFIC) - -/* Extended BLE Scan parameters OCF */ -#define HCI_BLE_EXTENDED_SCAN_PARAMS_OCF (0x0160 | HCI_GRP_VENDOR_SPECIFIC) - -/* subcode for multi adv feature */ -#define BTM_BLE_MULTI_ADV_SET_PARAM 0x01 -#define BTM_BLE_MULTI_ADV_WRITE_ADV_DATA 0x02 -#define BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA 0x03 -#define BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR 0x04 -#define BTM_BLE_MULTI_ADV_ENB 0x05 - -/* multi adv VSE subcode */ -#define HCI_VSE_SUBCODE_BLE_MULTI_ADV_ST_CHG 0x55 /* multi adv instance state change */ - -/* subcode for batch scan feature */ -#define BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE 0x01 -#define BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM 0x02 -#define BTM_BLE_BATCH_SCAN_SET_PARAMS 0x03 -#define BTM_BLE_BATCH_SCAN_READ_RESULTS 0x04 - -/* batch scan VSE subcode */ -#define HCI_VSE_SUBCODE_BLE_THRESHOLD_SUB_EVT 0x54 /* Threshold event */ - -/* tracking sub event */ -#define HCI_VSE_SUBCODE_BLE_TRACKING_SUB_EVT 0x56 /* Tracking event */ - -/* LE supported states definition */ -#define HCI_LE_ADV_STATE 0x00000001 -#define HCI_LE_SCAN_STATE 0x00000002 -#define HCI_LE_INIT_STATE 0x00000004 -#define HCI_LE_CONN_SL_STATE 0x00000008 -#define HCI_LE_ADV_SCAN_STATE 0x00000010 -#define HCI_LE_ADV_INIT_STATE 0x00000020 -#define HCI_LE_ADV_MA_STATE 0x00000040 -#define HCI_LE_ADV_SL_STATE 0x00000080 -#define HCI_LE_SCAN_INIT_STATE 0x00000100 -#define HCI_LE_SCAN_MA_STATE 0x00000200 -#define HCI_LE_SCAN_SL_STATE 0x00000400 -#define HCI_LE_INIT_MA_STATE 0x00000800 - -/* LE Supported States */ -/* Non Connectable Adv state is supported. 0x0000000000000001 */ -#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK 0x01 -#define HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF 0 -#define HCI_LE_STATES_NON_CONN_ADV_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK) - -/*Scanneable Connectable Adv state is supported. 0x0000000000000002 */ -#define HCI_SUPP_LE_STATES_SCAN_ADV_MASK 0x02 -#define HCI_SUPP_LE_STATESSCAN_ADV_OFF 0 -#define HCI_LE_STATES_SCAN_ADV_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATESSCAN_ADV_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_MASK) - -/* Connectable Adv state is supported. 0x0000000000000004 */ -#define HCI_SUPP_LE_STATES_CONN_ADV_MASK 0x04 -#define HCI_SUPP_LE_STATES_CONN_ADV_OFF 0 -#define HCI_LE_STATES_CONN_ADV_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_MASK) - -/* Hi duty Cycle Directed Adv state is supported. 0x0000000000000008 */ -#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK 0x08 -#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF 0 -#define HCI_LE_STATES_HI_DUTY_DIR_ADV_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK) - -/* Passive Scan state is supported. 0x0000000000000010 */ -#define HCI_SUPP_LE_STATES_PASS_SCAN_MASK 0x10 -#define HCI_SUPP_LE_STATES_PASS_SCAN_OFF 0 -#define HCI_LE_STATES_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_MASK) - -/* Active Scan state is supported. 0x0000000000000020 */ -#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASK 0x20 -#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_OFF 0 -#define HCI_LE_STATES_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASK) - -/* Initiating state is supported. 0x0000000000000040 (or connection state in master role is also supported) */ -#define HCI_SUPP_LE_STATES_INIT_MASK 0x40 -#define HCI_SUPP_LE_STATES_INIT_OFF 0 -#define HCI_LE_STATES_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_INIT_OFF] & HCI_SUPP_LE_STATES_INIT_MASK) - -/*connection state in slave role is also supported. 0x0000000000000080 */ -#define HCI_SUPP_LE_STATES_SLAVE_MASK 0x80 -#define HCI_SUPP_LE_STATES_SLAVE_OFF 0 -#define HCI_LE_STATES_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SLAVE_OFF] & HCI_SUPP_LE_STATES_SLAVE_MASK) - -/* Non Connectable Adv state and Passive Scanning State combination is supported. 0x0000000000000100 */ -#define HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK 0x01 -#define HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF 1 -#define HCI_LE_STATES_NON_CONN_ADV_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK) - -/*Scannable Adv state and Passive Scanning State combination is supported. 0x0000000000000200 */ -#define HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK 0x02 -#define HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF 1 -#define HCI_LE_STATES_SCAN_ADV_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK) - -/*Connectable Adv state and Passive Scanning State combination is supported. 0x0000000000000400 */ -#define HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK 0x04 -#define HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF 1 -#define HCI_LE_STATES_CONN_ADV_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK) - -/*High Duty Cycl Directed ADv and Passive Scanning State combination is supported. 0x0000000000000800 */ -#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK 0x08 -#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF 1 -#define HCI_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF) - -/*Non Connectable Adv state and Passive Scanning State combination is supported. 0x0000000000001000 */ -#define HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK 0x10 -#define HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF 1 -#define HCI_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK) - -/*Scannable Adv state and Active Scanning State combination is supported. 0x0000000000002000 */ -#define HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK 0x20 -#define HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF 1 -#define HCI_LE_STATES_SCAN_ADV_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK) - -/*Connectable Adv state and Active Scanning State combination is supported. 0x0000000000004000 */ -#define HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK 0x40 -#define HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF 1 -#define HCI_LE_STATES_CONN_ADV_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK) - -/*High Duty Cycl Directed ADv and ACtive Scanning State combination is supported. 0x0000000000008000 */ -#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK 0x80 -#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF 1 -#define HCI_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF) - -/*Non-Connectable Adv state and Initiating State combination is supported. 0x0000000000010000 */ -#define HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK 0x01 -#define HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF 2 -#define HCI_LE_STATES_NON_CONN_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF] & HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK) - -/* Scannable Adv state and Initiating State combination is supported. 0x0000000000020000 */ -#define HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK 0x02 -#define HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF 2 -#define HCI_LE_STATES_SCAN_ADV_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK) - -/* Non-Connectable Adv state and Master Role combination is supported. 0x0000000000040000 */ -#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK 0x04 -#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF 2 -#define HCI_LE_STATES_NON_CONN_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK) - -/*Scannable Adv state and Master Role combination is supported. 0x0000000000040000 */ -#define HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK 0x08 -#define HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF 2 -#define HCI_LE_STATES_SCAN_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK) - -/* Non-Connectable Adv and Slave Role combination is supported. 0x000000000100000 */ -#define HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK 0x10 -#define HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF 2 -#define HCI_LE_STATES_NON_CONN_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK) - -/*Scannable Adv and Slave Role combination is supported. 0x000000000200000 */ -#define HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK 0x20 -#define HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF 2 -#define HCI_LE_STATES_SCAN_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK) - -/*Passive Scan and Initiating State combination is supported. 0x000000000400000 */ -#define HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK 0x40 -#define HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF 2 -#define HCI_LE_STATES_PASS_SCAN_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK) - -/*Active Scan and Initiating State combination is supported. 0x000000000800000 */ -#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK 0x80 -#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF 2 -#define HCI_LE_STATES_ACTIVE_SCAN_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK) - -/*Passive Scan and Master Role combination is supported. 0x000000001000000 */ -#define HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK 0x01 -#define HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF 3 -#define HCI_LE_STATES_PASS_SCAN_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK) - -/*Active Scan and Master Role combination is supported. 0x000000002000000 */ -#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK 0x02 -#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF 3 -#define HCI_LE_STATES_ACTIVE_SCAN_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK) - -/*Passive Scan and Slave Role combination is supported. 0x000000004000000 */ -#define HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK 0x04 -#define HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF 3 -#define HCI_LE_STATES_PASS_SCAN_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK) - -/*Active Scan and Slave Role combination is supported. 0x000000008000000 */ -#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK 0x08 -#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF 3 -#define HCI_LE_STATES_ACTIVE_SCAN_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK) - -/*Link Layer Topology Added States Combo */ -/*Initiating State and Master Role combination supported. - Master Role and Master Role combination is also supported. 0x0000000010000000 */ -#define HCI_SUPP_LE_STATES_INIT_MASTER_MASK 0x10 -#define HCI_SUPP_LE_STATES_INIT_MASTER_OFF 3 -#define HCI_LE_STATES_INIT_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_INIT_MASTER_OFF] & HCI_SUPP_LE_STATES_INIT_MASTER_MASK) - -/*Low Duty Cycle Directed Advertising State . 0x0000000020000000 */ -#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASK 0x20 -#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_OFF 3 -#define HCI_LE_STATES_LOW_DUTY_DIR_ADV_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_LOW_DUTY_DIR_ADV_OFF] & HCI_SUPP_LE_STATES_LOW_DUTY_DIR_ADV_MASK) - -/*Low Duty Cycle Directed Advertising State and Passive scan combination. 0x0000000040000000 */ -#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_MASK 0x40 -#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_OFF 3 -#define HCI_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_MASK) - -/*Low Duty Cycle Directed Advertising State and Active scan combination . 0x0000000080000000 */ -#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_MASK 0x80 -#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_OFF 3 -#define HCI_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_MASK) - -/* Connectable Advertising State and Initiating State combination supported. 0x0000000100000000 */ -#define HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK 0x01 -#define HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF 4 -#define HCI_LE_STATES_CONN_ADV_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK) - -/* High Duty Cycle Directed Advertising State and Initiating State combination supported. */ -#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK 0x02 -#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF 4 -#define HCI_LE_STATES_HI_DUTY_DIR_ADV_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK) - -/* Low Duty Cycle Directed Advertising State and Initiating State combination supported.*/ -#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK 0x04 -#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF 4 -#define HCI_LE_STATES_LO_DUTY_DIR_ADV_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK) - -/* Connectable Advertising State and Master Role combination supported.*/ -#define HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK 0x08 -#define HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF 4 -#define HCI_LE_STATES_CONN_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK) - -/* High Duty Cycle Directed Advertising State and Master Role combination supported.*/ -#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK 0x10 -#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF 4 -#define HCI_LE_STATES_HI_DUTY_DIR_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK) - -/* Low Duty Cycle Directed Advertising State and Master Role combination supported.*/ -#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK 0x20 -#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF 4 -#define HCI_LE_STATES_LO_DUTY_DIR_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK) - -/* Connectable Advertising State and Slave Role combination supported. */ -#define HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK 0x40 -#define HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF 4 -#define HCI_LE_STATES_CONN_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK) - -/* High Duty Cycle Directed Advertising State and slave Role combination supported.*/ -#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK 0x80 -#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF 4 -#define HCI_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK) - -/* Low Duty Cycle Directed Advertising State and slave Role combination supported.*/ -#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK 0x01 -#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF 5 -#define HCI_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK) - -/* Initiating State and Slave Role combination supported. - Master Role and Slave Role combination also supported. - */ -#define HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK 0x02 -#define HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF 5 -#define HCI_LE_STATES_INIT_MASTER_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF] & HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK) - -/* -** Definitions for HCI Events -*/ -#define HCI_INQUIRY_COMP_EVT 0x01 -#define HCI_INQUIRY_RESULT_EVT 0x02 -#define HCI_CONNECTION_COMP_EVT 0x03 -#define HCI_CONNECTION_REQUEST_EVT 0x04 -#define HCI_DISCONNECTION_COMP_EVT 0x05 -#define HCI_AUTHENTICATION_COMP_EVT 0x06 -#define HCI_RMT_NAME_REQUEST_COMP_EVT 0x07 -#define HCI_ENCRYPTION_CHANGE_EVT 0x08 -#define HCI_CHANGE_CONN_LINK_KEY_EVT 0x09 -#define HCI_MASTER_LINK_KEY_COMP_EVT 0x0A -#define HCI_READ_RMT_FEATURES_COMP_EVT 0x0B -#define HCI_READ_RMT_VERSION_COMP_EVT 0x0C -#define HCI_QOS_SETUP_COMP_EVT 0x0D -#define HCI_COMMAND_COMPLETE_EVT 0x0E -#define HCI_COMMAND_STATUS_EVT 0x0F -#define HCI_HARDWARE_ERROR_EVT 0x10 -#define HCI_FLUSH_OCCURED_EVT 0x11 -#define HCI_ROLE_CHANGE_EVT 0x12 -#define HCI_NUM_COMPL_DATA_PKTS_EVT 0x13 -#define HCI_MODE_CHANGE_EVT 0x14 -#define HCI_RETURN_LINK_KEYS_EVT 0x15 -#define HCI_PIN_CODE_REQUEST_EVT 0x16 -#define HCI_LINK_KEY_REQUEST_EVT 0x17 -#define HCI_LINK_KEY_NOTIFICATION_EVT 0x18 -#define HCI_LOOPBACK_COMMAND_EVT 0x19 -#define HCI_DATA_BUF_OVERFLOW_EVT 0x1A -#define HCI_MAX_SLOTS_CHANGED_EVT 0x1B -#define HCI_READ_CLOCK_OFF_COMP_EVT 0x1C -#define HCI_CONN_PKT_TYPE_CHANGE_EVT 0x1D -#define HCI_QOS_VIOLATION_EVT 0x1E -#define HCI_PAGE_SCAN_MODE_CHANGE_EVT 0x1F -#define HCI_PAGE_SCAN_REP_MODE_CHNG_EVT 0x20 -#define HCI_FLOW_SPECIFICATION_COMP_EVT 0x21 -#define HCI_INQUIRY_RSSI_RESULT_EVT 0x22 -#define HCI_READ_RMT_EXT_FEATURES_COMP_EVT 0x23 -#define HCI_ESCO_CONNECTION_COMP_EVT 0x2C -#define HCI_ESCO_CONNECTION_CHANGED_EVT 0x2D -#define HCI_SNIFF_SUB_RATE_EVT 0x2E -#define HCI_EXTENDED_INQUIRY_RESULT_EVT 0x2F -#define HCI_ENCRYPTION_KEY_REFRESH_COMP_EVT 0x30 -#define HCI_IO_CAPABILITY_REQUEST_EVT 0x31 -#define HCI_IO_CAPABILITY_RESPONSE_EVT 0x32 -#define HCI_USER_CONFIRMATION_REQUEST_EVT 0x33 -#define HCI_USER_PASSKEY_REQUEST_EVT 0x34 -#define HCI_REMOTE_OOB_DATA_REQUEST_EVT 0x35 -#define HCI_SIMPLE_PAIRING_COMPLETE_EVT 0x36 -#define HCI_LINK_SUPER_TOUT_CHANGED_EVT 0x38 -#define HCI_ENHANCED_FLUSH_COMPLETE_EVT 0x39 -#define HCI_USER_PASSKEY_NOTIFY_EVT 0x3B -#define HCI_KEYPRESS_NOTIFY_EVT 0x3C -#define HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT 0x3D - -/*#define HCI_GENERIC_AMP_LINK_KEY_NOTIF_EVT 0x3E Removed from spec */ -#define HCI_PHYSICAL_LINK_COMP_EVT 0x40 -#define HCI_CHANNEL_SELECTED_EVT 0x41 -#define HCI_DISC_PHYSICAL_LINK_COMP_EVT 0x42 -#define HCI_PHY_LINK_LOSS_EARLY_WARNING_EVT 0x43 -#define HCI_PHY_LINK_RECOVERY_EVT 0x44 -#define HCI_LOGICAL_LINK_COMP_EVT 0x45 -#define HCI_DISC_LOGICAL_LINK_COMP_EVT 0x46 -#define HCI_FLOW_SPEC_MODIFY_COMP_EVT 0x47 -#define HCI_NUM_COMPL_DATA_BLOCKS_EVT 0x48 -#define HCI_SHORT_RANGE_MODE_COMPLETE_EVT 0x4C -#define HCI_AMP_STATUS_CHANGE_EVT 0x4D -#define HCI_SET_TRIGGERED_CLOCK_CAPTURE_EVT 0x4E - -/* ULP HCI Event */ -#define HCI_BLE_EVENT 0x3e -/* ULP Event sub code */ -#define HCI_BLE_CONN_COMPLETE_EVT 0x01 -#define HCI_BLE_ADV_PKT_RPT_EVT 0x02 -#define HCI_BLE_LL_CONN_PARAM_UPD_EVT 0x03 -#define HCI_BLE_READ_REMOTE_FEAT_CMPL_EVT 0x04 -#define HCI_BLE_LTK_REQ_EVT 0x05 -#define HCI_BLE_RC_PARAM_REQ_EVT 0x06 -#define HCI_BLE_DATA_LENGTH_CHANGE_EVT 0x07 -#define HCI_BLE_ENHANCED_CONN_COMPLETE_EVT 0x0a -#define HCI_BLE_DIRECT_ADV_EVT 0x0b - -/* Definitions for LE Channel Map */ -#define HCI_BLE_CHNL_MAP_SIZE 5 - -#define HCI_VENDOR_SPECIFIC_EVT 0xFF /* Vendor specific events */ -#define HCI_NAP_TRACE_EVT 0xFF /* was define 0xFE, 0xFD, change to 0xFF - because conflict w/ TCI_EVT and per - specification compliant */ - -/* -** Defentions for HCI Error Codes that are past in the events -*/ -#define HCI_SUCCESS 0x00 -#define HCI_PENDING 0x00 -#define HCI_ERR_ILLEGAL_COMMAND 0x01 -#define HCI_ERR_NO_CONNECTION 0x02 -#define HCI_ERR_HW_FAILURE 0x03 -#define HCI_ERR_PAGE_TIMEOUT 0x04 -#define HCI_ERR_AUTH_FAILURE 0x05 -#define HCI_ERR_KEY_MISSING 0x06 -#define HCI_ERR_MEMORY_FULL 0x07 -#define HCI_ERR_CONNECTION_TOUT 0x08 -#define HCI_ERR_MAX_NUM_OF_CONNECTIONS 0x09 -#define HCI_ERR_MAX_NUM_OF_SCOS 0x0A -#define HCI_ERR_CONNECTION_EXISTS 0x0B -#define HCI_ERR_COMMAND_DISALLOWED 0x0C -#define HCI_ERR_HOST_REJECT_RESOURCES 0x0D -#define HCI_ERR_HOST_REJECT_SECURITY 0x0E -#define HCI_ERR_HOST_REJECT_DEVICE 0x0F -#define HCI_ERR_HOST_TIMEOUT 0x10 -#define HCI_ERR_UNSUPPORTED_VALUE 0x11 -#define HCI_ERR_ILLEGAL_PARAMETER_FMT 0x12 -#define HCI_ERR_PEER_USER 0x13 -#define HCI_ERR_PEER_LOW_RESOURCES 0x14 -#define HCI_ERR_PEER_POWER_OFF 0x15 -#define HCI_ERR_CONN_CAUSE_LOCAL_HOST 0x16 -#define HCI_ERR_REPEATED_ATTEMPTS 0x17 -#define HCI_ERR_PAIRING_NOT_ALLOWED 0x18 -#define HCI_ERR_UNKNOWN_LMP_PDU 0x19 -#define HCI_ERR_UNSUPPORTED_REM_FEATURE 0x1A -#define HCI_ERR_SCO_OFFSET_REJECTED 0x1B -#define HCI_ERR_SCO_INTERVAL_REJECTED 0x1C -#define HCI_ERR_SCO_AIR_MODE 0x1D -#define HCI_ERR_INVALID_LMP_PARAM 0x1E -#define HCI_ERR_UNSPECIFIED 0x1F -#define HCI_ERR_UNSUPPORTED_LMP_FEATURE 0x20 -#define HCI_ERR_ROLE_CHANGE_NOT_ALLOWED 0x21 -#define HCI_ERR_LMP_RESPONSE_TIMEOUT 0x22 -#define HCI_ERR_LMP_ERR_TRANS_COLLISION 0x23 -#define HCI_ERR_LMP_PDU_NOT_ALLOWED 0x24 -#define HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE 0x25 -#define HCI_ERR_UNIT_KEY_USED 0x26 -#define HCI_ERR_QOS_NOT_SUPPORTED 0x27 -#define HCI_ERR_INSTANT_PASSED 0x28 -#define HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED 0x29 -#define HCI_ERR_DIFF_TRANSACTION_COLLISION 0x2A -#define HCI_ERR_UNDEFINED_0x2B 0x2B -#define HCI_ERR_QOS_UNACCEPTABLE_PARAM 0x2C -#define HCI_ERR_QOS_REJECTED 0x2D -#define HCI_ERR_CHAN_CLASSIF_NOT_SUPPORTED 0x2E -#define HCI_ERR_INSUFFCIENT_SECURITY 0x2F -#define HCI_ERR_PARAM_OUT_OF_RANGE 0x30 -#define HCI_ERR_UNDEFINED_0x31 0x31 -#define HCI_ERR_ROLE_SWITCH_PENDING 0x32 -#define HCI_ERR_UNDEFINED_0x33 0x33 -#define HCI_ERR_RESERVED_SLOT_VIOLATION 0x34 -#define HCI_ERR_ROLE_SWITCH_FAILED 0x35 -#define HCI_ERR_INQ_RSP_DATA_TOO_LARGE 0x36 -#define HCI_ERR_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 -#define HCI_ERR_HOST_BUSY_PAIRING 0x38 -#define HCI_ERR_REJ_NO_SUITABLE_CHANNEL 0x39 -#define HCI_ERR_CONTROLLER_BUSY 0x3A -#define HCI_ERR_UNACCEPT_CONN_INTERVAL 0x3B -#define HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT 0x3C -#define HCI_ERR_CONN_TOUT_DUE_TO_MIC_FAILURE 0x3D -#define HCI_ERR_CONN_FAILED_ESTABLISHMENT 0x3E -#define HCI_ERR_MAC_CONNECTION_FAILED 0x3F - -/* ConnectionLess Broadcast errors */ -#define HCI_ERR_LT_ADDR_ALREADY_IN_USE 0x40 -#define HCI_ERR_LT_ADDR_NOT_ALLOCATED 0x41 -#define HCI_ERR_CLB_NOT_ENABLED 0x42 -#define HCI_ERR_CLB_DATA_TOO_BIG 0x43 - -#define HCI_ERR_MAX_ERR 0x43 - -//ESP vendor error code -#define HCI_ERR_ESP_VENDOR_FAIL 0xE0 - -#define HCI_HINT_TO_RECREATE_AMP_PHYS_LINK 0xFF - -/* -** Definitions for HCI enable event -*/ -#define HCI_INQUIRY_COMPLETE_EV(p) (*((UINT32 *)(p)) & 0x00000001) -#define HCI_INQUIRY_RESULT_EV(p) (*((UINT32 *)(p)) & 0x00000002) -#define HCI_CONNECTION_COMPLETE_EV(p) (*((UINT32 *)(p)) & 0x00000004) -#define HCI_CONNECTION_REQUEST_EV(p) (*((UINT32 *)(p)) & 0x00000008) -#define HCI_DISCONNECTION_COMPLETE_EV(p) (*((UINT32 *)(p)) & 0x00000010) -#define HCI_AUTHENTICATION_COMPLETE_EV(p) (*((UINT32 *)(p)) & 0x00000020) -#define HCI_RMT_NAME_REQUEST_COMPL_EV(p) (*((UINT32 *)(p)) & 0x00000040) -#define HCI_CHANGE_CONN_ENCRPT_ENABLE_EV(p) (*((UINT32 *)(p)) & 0x00000080) -#define HCI_CHANGE_CONN_LINK_KEY_EV(p) (*((UINT32 *)(p)) & 0x00000100) -#define HCI_MASTER_LINK_KEY_COMPLETE_EV(p) (*((UINT32 *)(p)) & 0x00000200) -#define HCI_READ_RMT_FEATURES_COMPL_EV(p) (*((UINT32 *)(p)) & 0x00000400) -#define HCI_READ_RMT_VERSION_COMPL_EV(p) (*((UINT32 *)(p)) & 0x00000800) -#define HCI_QOS_SETUP_COMPLETE_EV(p) (*((UINT32 *)(p)) & 0x00001000) -#define HCI_COMMAND_COMPLETE_EV(p) (*((UINT32 *)(p)) & 0x00002000) -#define HCI_COMMAND_STATUS_EV(p) (*((UINT32 *)(p)) & 0x00004000) -#define HCI_HARDWARE_ERROR_EV(p) (*((UINT32 *)(p)) & 0x00008000) -#define HCI_FLASH_OCCURED_EV(p) (*((UINT32 *)(p)) & 0x00010000) -#define HCI_ROLE_CHANGE_EV(p) (*((UINT32 *)(p)) & 0x00020000) -#define HCI_NUM_COMPLETED_PKTS_EV(p) (*((UINT32 *)(p)) & 0x00040000) -#define HCI_MODE_CHANGE_EV(p) (*((UINT32 *)(p)) & 0x00080000) -#define HCI_RETURN_LINK_KEYS_EV(p) (*((UINT32 *)(p)) & 0x00100000) -#define HCI_PIN_CODE_REQUEST_EV(p) (*((UINT32 *)(p)) & 0x00200000) -#define HCI_LINK_KEY_REQUEST_EV(p) (*((UINT32 *)(p)) & 0x00400000) -#define HCI_LINK_KEY_NOTIFICATION_EV(p) (*((UINT32 *)(p)) & 0x00800000) -#define HCI_LOOPBACK_COMMAND_EV(p) (*((UINT32 *)(p)) & 0x01000000) -#define HCI_DATA_BUF_OVERFLOW_EV(p) (*((UINT32 *)(p)) & 0x02000000) -#define HCI_MAX_SLOTS_CHANGE_EV(p) (*((UINT32 *)(p)) & 0x04000000) -#define HCI_READ_CLOCK_OFFSET_COMP_EV(p) (*((UINT32 *)(p)) & 0x08000000) -#define HCI_CONN_PKT_TYPE_CHANGED_EV(p) (*((UINT32 *)(p)) & 0x10000000) -#define HCI_QOS_VIOLATION_EV(p) (*((UINT32 *)(p)) & 0x20000000) -#define HCI_PAGE_SCAN_MODE_CHANGED_EV(p) (*((UINT32 *)(p)) & 0x40000000) -#define HCI_PAGE_SCAN_REP_MODE_CHNG_EV(p) (*((UINT32 *)(p)) & 0x80000000) - -/* the default event mask for 2.1+EDR (Lisbon) does not include Lisbon events */ -#define HCI_DEFAULT_EVENT_MASK_0 0xFFFFFFFF -#define HCI_DEFAULT_EVENT_MASK_1 0x00001FFF - -/* the event mask for 2.0 + EDR and later (includes Lisbon events) */ -#define HCI_LISBON_EVENT_MASK_0 0xFFFFFFFF -#define HCI_LISBON_EVENT_MASK_1 0x1DBFFFFF -#define HCI_LISBON_EVENT_MASK "\x0D\xBF\xFF\xFF\xFF\xFF\xFF\xFF" -#define HCI_LISBON_EVENT_MASK_EXT "\x1D\xBF\xFF\xFF\xFF\xFF\xFF\xFF" -#define HCI_DUMO_EVENT_MASK_EXT "\x3D\xBF\xFF\xFF\xFF\xFF\xFF\xFF" -/* 0x00001FFF FFFFFFFF Default - no Lisbon events - 0x00000800 00000000 Synchronous Connection Complete Event - 0x00001000 00000000 Synchronous Connection Changed Event - 0x00002000 00000000 Sniff Subrate Event - 0x00004000 00000000 Extended Inquiry Result Event - 0x00008000 00000000 Encryption Key Refresh Complete Event - 0x00010000 00000000 IO Capability Request Event - 0x00020000 00000000 IO Capability Response Event - 0x00040000 00000000 User Confirmation Request Event - 0x00080000 00000000 User Passkey Request Event - 0x00100000 00000000 Remote OOB Data Request Event - 0x00200000 00000000 Simple Pairing Complete Event - 0x00400000 00000000 Generic AMP Link Key Notification Event - 0x00800000 00000000 Link Supervision Timeout Changed Event - 0x01000000 00000000 Enhanced Flush Complete Event - 0x04000000 00000000 User Passkey Notification Event - 0x08000000 00000000 Keypress Notification Event - 0x10000000 00000000 Remote Host Supported Features Notification Event - 0x20000000 00000000 LE Meta Event - */ - - -/* the event mask for AMP controllers */ -#define HCI_AMP_EVENT_MASK_3_0 "\x00\x00\x00\x00\x00\x00\x3F\xFF" - -/* 0x0000000000000000 No events specified (default) - 0x0000000000000001 Physical Link Complete Event - 0x0000000000000002 Channel Selected Event - 0x0000000000000004 Disconnection Physical Link Event - 0x0000000000000008 Physical Link Loss Early Warning Event - 0x0000000000000010 Physical Link Recovery Event - 0x0000000000000020 Logical Link Complete Event - 0x0000000000000040 Disconnection Logical Link Complete Event - 0x0000000000000080 Flow Spec Modify Complete Event - 0x0000000000000100 Number of Completed Data Blocks Event - 0x0000000000000200 AMP Start Test Event - 0x0000000000000400 AMP Test End Event - 0x0000000000000800 AMP Receiver Report Event - 0x0000000000001000 Short Range Mode Change Complete Event - 0x0000000000002000 AMP Status Change Event -*/ - -/* the event mask page 2 (CLB + CSA4) for BR/EDR controller */ -#define HCI_PAGE_2_EVENT_MASK "\x00\x00\x00\x00\x00\x7F\xC0\x00" -/* 0x0000000000004000 Triggered Clock Capture Event - 0x0000000000008000 Sync Train Complete Event - 0x0000000000010000 Sync Train Received Event - 0x0000000000020000 Connectionless Broadcast Receive Event - 0x0000000000040000 Connectionless Broadcast Timeout Event - 0x0000000000080000 Truncated Page Complete Event - 0x0000000000100000 Salve Page Response Timeout Event - 0x0000000000200000 Connectionless Broadcast Channel Map Change Event - 0x0000000000400000 Inquiry Response Notification Event -*/ -#if BLE_PRIVACY_SPT == TRUE -/* BLE event mask */ -#define HCI_BLE_EVENT_MASK_DEF "\x00\x00\x00\x00\x00\x00\x07\xff" -#else -#define HCI_BLE_EVENT_MASK_DEF "\x00\x00\x00\x00\x00\x00\x00\x7f" -#endif -/* -** Definitions for packet type masks (BT1.2 and BT2.0 definitions) -*/ -#define HCI_PKT_TYPES_MASK_NO_2_DH1 0x0002 -#define HCI_PKT_TYPES_MASK_NO_3_DH1 0x0004 -#define HCI_PKT_TYPES_MASK_DM1 0x0008 -#define HCI_PKT_TYPES_MASK_DH1 0x0010 -#define HCI_PKT_TYPES_MASK_HV1 0x0020 -#define HCI_PKT_TYPES_MASK_HV2 0x0040 -#define HCI_PKT_TYPES_MASK_HV3 0x0080 -#define HCI_PKT_TYPES_MASK_NO_2_DH3 0x0100 -#define HCI_PKT_TYPES_MASK_NO_3_DH3 0x0200 -#define HCI_PKT_TYPES_MASK_DM3 0x0400 -#define HCI_PKT_TYPES_MASK_DH3 0x0800 -#define HCI_PKT_TYPES_MASK_NO_2_DH5 0x1000 -#define HCI_PKT_TYPES_MASK_NO_3_DH5 0x2000 -#define HCI_PKT_TYPES_MASK_DM5 0x4000 -#define HCI_PKT_TYPES_MASK_DH5 0x8000 - -/* Packet type should be one of valid but at least one should be specified */ -#define HCI_VALID_SCO_PKT_TYPE(t) (((((t) & ~(HCI_PKT_TYPES_MASK_HV1 \ - | HCI_PKT_TYPES_MASK_HV2 \ - | HCI_PKT_TYPES_MASK_HV3)) == 0)) \ - && ((t) != 0)) - - - - - -/* Packet type should not be invalid and at least one should be specified */ -#define HCI_VALID_ACL_PKT_TYPE(t) (((((t) & ~(HCI_PKT_TYPES_MASK_DM1 \ - | HCI_PKT_TYPES_MASK_DH1 \ - | HCI_PKT_TYPES_MASK_DM3 \ - | HCI_PKT_TYPES_MASK_DH3 \ - | HCI_PKT_TYPES_MASK_DM5 \ - | HCI_PKT_TYPES_MASK_DH5 \ - | HCI_PKT_TYPES_MASK_NO_2_DH1 \ - | HCI_PKT_TYPES_MASK_NO_3_DH1 \ - | HCI_PKT_TYPES_MASK_NO_2_DH3 \ - | HCI_PKT_TYPES_MASK_NO_3_DH3 \ - | HCI_PKT_TYPES_MASK_NO_2_DH5 \ - | HCI_PKT_TYPES_MASK_NO_3_DH5 )) == 0)) \ - && (((t) & (HCI_PKT_TYPES_MASK_DM1 \ - | HCI_PKT_TYPES_MASK_DH1 \ - | HCI_PKT_TYPES_MASK_DM3 \ - | HCI_PKT_TYPES_MASK_DH3 \ - | HCI_PKT_TYPES_MASK_DM5 \ - | HCI_PKT_TYPES_MASK_DH5)) != 0)) - -/* -** Definitions for eSCO packet type masks (BT1.2 and BT2.0 definitions) -*/ -#define HCI_ESCO_PKT_TYPES_MASK_HV1 0x0001 -#define HCI_ESCO_PKT_TYPES_MASK_HV2 0x0002 -#define HCI_ESCO_PKT_TYPES_MASK_HV3 0x0004 -#define HCI_ESCO_PKT_TYPES_MASK_EV3 0x0008 -#define HCI_ESCO_PKT_TYPES_MASK_EV4 0x0010 -#define HCI_ESCO_PKT_TYPES_MASK_EV5 0x0020 -#define HCI_ESCO_PKT_TYPES_MASK_NO_2_EV3 0x0040 -#define HCI_ESCO_PKT_TYPES_MASK_NO_3_EV3 0x0080 -#define HCI_ESCO_PKT_TYPES_MASK_NO_2_EV5 0x0100 -#define HCI_ESCO_PKT_TYPES_MASK_NO_3_EV5 0x0200 - -/* Packet type should be one of valid but at least one should be specified for 1.2 */ -#define HCI_VALID_ESCO_PKT_TYPE(t) (((((t) & ~(HCI_ESCO_PKT_TYPES_MASK_EV3 \ - | HCI_ESCO_PKT_TYPES_MASK_EV4 \ - | HCI_ESCO_PKT_TYPES_MASK_EV5)) == 0)) \ - && ((t) != 0))/* Packet type should be one of valid but at least one should be specified */ - -#define HCI_VALID_ESCO_SCOPKT_TYPE(t) (((((t) & ~(HCI_ESCO_PKT_TYPES_MASK_HV1 \ - | HCI_ESCO_PKT_TYPES_MASK_HV2 \ - | HCI_ESCO_PKT_TYPES_MASK_HV3)) == 0)) \ - && ((t) != 0)) - -#define HCI_VALID_SCO_ALL_PKT_TYPE(t) (((((t) & ~(HCI_ESCO_PKT_TYPES_MASK_HV1 \ - | HCI_ESCO_PKT_TYPES_MASK_HV2 \ - | HCI_ESCO_PKT_TYPES_MASK_HV3 \ - | HCI_ESCO_PKT_TYPES_MASK_EV3 \ - | HCI_ESCO_PKT_TYPES_MASK_EV4 \ - | HCI_ESCO_PKT_TYPES_MASK_EV5)) == 0)) \ - && ((t) != 0)) - -/* -** Define parameters to allow role switch during create connection -*/ -#define HCI_CR_CONN_NOT_ALLOW_SWITCH 0x00 -#define HCI_CR_CONN_ALLOW_SWITCH 0x01 - -/* -** Hold Mode command destination -*/ -#define HOLD_MODE_DEST_LOCAL_DEVICE 0x00 -#define HOLD_MODE_DEST_RMT_DEVICE 0x01 - -/* -** Definitions for different HCI parameters -*/ -#define HCI_PER_INQ_MIN_MAX_PERIOD 0x0003 -#define HCI_PER_INQ_MAX_MAX_PERIOD 0xFFFF -#define HCI_PER_INQ_MIN_MIN_PERIOD 0x0002 -#define HCI_PER_INQ_MAX_MIN_PERIOD 0xFFFE - -#define HCI_MAX_INQUIRY_LENGTH 0x30 - -#define HCI_MIN_INQ_LAP 0x9E8B00 -#define HCI_MAX_INQ_LAP 0x9E8B3F - -/* HCI role defenitions */ -#define HCI_ROLE_MASTER 0x00 -#define HCI_ROLE_SLAVE 0x01 -#define HCI_ROLE_UNKNOWN 0xff - -/* HCI mode defenitions */ -#define HCI_MODE_ACTIVE 0x00 -#define HCI_MODE_HOLD 0x01 -#define HCI_MODE_SNIFF 0x02 -#define HCI_MODE_PARK 0x03 - -/* HCI Flow Control Mode defenitions */ -#define HCI_PACKET_BASED_FC_MODE 0x00 -#define HCI_BLOCK_BASED_FC_MODE 0x01 - -/* Define Packet types as requested by the Host */ -#define HCI_ACL_PKT_TYPE_NONE 0x0000 -#define HCI_ACL_PKT_TYPE_DM1 0x0008 -#define HCI_ACL_PKT_TYPE_DH1 0x0010 -#define HCI_ACL_PKT_TYPE_AUX1 0x0200 -#define HCI_ACL_PKT_TYPE_DM3 0x0400 -#define HCI_ACL_PKT_TYPE_DH3 0x0800 -#define HCI_ACL_PKT_TYPE_DM5 0x4000 -#define HCI_ACL_PKT_TYPE_DH5 0x8000 - -/* Define key type in the Master Link Key command */ -#define HCI_USE_SEMI_PERMANENT_KEY 0x00 -#define HCI_USE_TEMPORARY_KEY 0x01 - -/* Page scan period modes */ -#define HCI_PAGE_SCAN_REP_MODE_R0 0x00 -#define HCI_PAGE_SCAN_REP_MODE_R1 0x01 -#define HCI_PAGE_SCAN_REP_MODE_R2 0x02 - -/* Define limits for page scan repetition modes */ -#define HCI_PAGE_SCAN_R1_LIMIT 0x0800 -#define HCI_PAGE_SCAN_R2_LIMIT 0x1000 - -/* Page scan period modes */ -#define HCI_PAGE_SCAN_PER_MODE_P0 0x00 -#define HCI_PAGE_SCAN_PER_MODE_P1 0x01 -#define HCI_PAGE_SCAN_PER_MODE_P2 0x02 - -/* Page scan modes */ -#define HCI_MANDATARY_PAGE_SCAN_MODE 0x00 -#define HCI_OPTIONAL_PAGE_SCAN_MODE1 0x01 -#define HCI_OPTIONAL_PAGE_SCAN_MODE2 0x02 -#define HCI_OPTIONAL_PAGE_SCAN_MODE3 0x03 - -/* Page and inquiry scan types */ -#define HCI_SCAN_TYPE_STANDARD 0x00 -#define HCI_SCAN_TYPE_INTERLACED 0x01 /* 1.2 devices or later */ -#define HCI_DEF_SCAN_TYPE HCI_SCAN_TYPE_STANDARD - -/* Definitions for quality of service service types */ -#define HCI_SERVICE_NO_TRAFFIC 0x00 -#define HCI_SERVICE_BEST_EFFORT 0x01 -#define HCI_SERVICE_GUARANTEED 0x02 - -#define HCI_QOS_LATENCY_DO_NOT_CARE 0xFFFFFFFF -#define HCI_QOS_DELAY_DO_NOT_CARE 0xFFFFFFFF - -/* Definitions for Flow Specification */ -#define HCI_FLOW_SPEC_LATENCY_DO_NOT_CARE 0xFFFFFFFF - -/* Definitions for AFH Channel Map */ -#define HCI_AFH_CHANNEL_MAP_LEN 10 - -/* Definitions for Extended Inquiry Response */ -#define HCI_EXT_INQ_RESPONSE_LEN 240 -#define HCI_EIR_FLAGS_TYPE BT_EIR_FLAGS_TYPE -#define HCI_EIR_MORE_16BITS_UUID_TYPE BT_EIR_MORE_16BITS_UUID_TYPE -#define HCI_EIR_COMPLETE_16BITS_UUID_TYPE BT_EIR_COMPLETE_16BITS_UUID_TYPE -#define HCI_EIR_MORE_32BITS_UUID_TYPE BT_EIR_MORE_32BITS_UUID_TYPE -#define HCI_EIR_COMPLETE_32BITS_UUID_TYPE BT_EIR_COMPLETE_32BITS_UUID_TYPE -#define HCI_EIR_MORE_128BITS_UUID_TYPE BT_EIR_MORE_128BITS_UUID_TYPE -#define HCI_EIR_COMPLETE_128BITS_UUID_TYPE BT_EIR_COMPLETE_128BITS_UUID_TYPE -#define HCI_EIR_SHORTENED_LOCAL_NAME_TYPE BT_EIR_SHORTENED_LOCAL_NAME_TYPE -#define HCI_EIR_COMPLETE_LOCAL_NAME_TYPE BT_EIR_COMPLETE_LOCAL_NAME_TYPE -#define HCI_EIR_TX_POWER_LEVEL_TYPE BT_EIR_TX_POWER_LEVEL_TYPE -#define HCI_EIR_MANUFACTURER_SPECIFIC_TYPE BT_EIR_MANUFACTURER_SPECIFIC_TYPE -#define HCI_EIR_OOB_BD_ADDR_TYPE BT_EIR_OOB_BD_ADDR_TYPE -#define HCI_EIR_OOB_COD_TYPE BT_EIR_OOB_COD_TYPE -#define HCI_EIR_OOB_SSP_HASH_C_TYPE BT_EIR_OOB_SSP_HASH_C_TYPE -#define HCI_EIR_OOB_SSP_RAND_R_TYPE BT_EIR_OOB_SSP_RAND_R_TYPE - -/* Definitions for Write Simple Pairing Mode */ -#define HCI_SP_MODE_UNDEFINED 0x00 -#define HCI_SP_MODE_ENABLED 0x01 - -/* Definitions for Write Simple Pairing Debug Mode */ -#define HCI_SPD_MODE_DISABLED 0x00 -#define HCI_SPD_MODE_ENABLED 0x01 - -/* Definitions for Write Secure Connections Host Support */ -#define HCI_SC_MODE_DISABLED 0x00 -#define HCI_SC_MODE_ENABLED 0x01 - -/* Definitions for IO Capability Response/Command */ -#define HCI_IO_CAP_DISPLAY_ONLY 0x00 -#define HCI_IO_CAP_DISPLAY_YESNO 0x01 -#define HCI_IO_CAP_KEYBOARD_ONLY 0x02 -#define HCI_IO_CAP_NO_IO 0x03 - -#define HCI_OOB_AUTH_DATA_NOT_PRESENT 0x00 -#define HCI_OOB_REM_AUTH_DATA_PRESENT 0x01 - -#define HCI_MITM_PROTECT_NOT_REQUIRED 0x00 -#define HCI_MITM_PROTECT_REQUIRED 0x01 - - -/* Policy settings status */ -#define HCI_DISABLE_ALL_LM_MODES 0x0000 -#define HCI_ENABLE_MASTER_SLAVE_SWITCH 0x0001 -#define HCI_ENABLE_HOLD_MODE 0x0002 -#define HCI_ENABLE_SNIFF_MODE 0x0004 -#define HCI_ENABLE_PARK_MODE 0x0008 - -/* By default allow switch, because host can not allow that */ -/* that until he created the connection */ -#define HCI_DEFAULT_POLICY_SETTINGS HCI_DISABLE_ALL_LM_MODES - -/* Filters that are sent in set filter command */ -#define HCI_FILTER_TYPE_CLEAR_ALL 0x00 -#define HCI_FILTER_INQUIRY_RESULT 0x01 -#define HCI_FILTER_CONNECTION_SETUP 0x02 - -#define HCI_FILTER_COND_NEW_DEVICE 0x00 -#define HCI_FILTER_COND_DEVICE_CLASS 0x01 -#define HCI_FILTER_COND_BD_ADDR 0x02 - -#define HCI_DO_NOT_AUTO_ACCEPT_CONNECT 1 -#define HCI_DO_AUTO_ACCEPT_CONNECT 2 /* role switch disabled */ -#define HCI_DO_AUTO_ACCEPT_CONNECT_RS 3 /* role switch enabled (1.1 errata 1115) */ - -/* Auto accept flags */ -#define HCI_AUTO_ACCEPT_OFF 0x00 -#define HCI_AUTO_ACCEPT_ACL_CONNECTIONS 0x01 -#define HCI_AUTO_ACCEPT_SCO_CONNECTIONS 0x02 - -/* PIN type */ -#define HCI_PIN_TYPE_VARIABLE 0 -#define HCI_PIN_TYPE_FIXED 1 - -/* Loopback Modes */ -#define HCI_LOOPBACK_MODE_DISABLED 0 -#define HCI_LOOPBACK_MODE_LOCAL 1 -#define HCI_LOOPBACK_MODE_REMOTE 2 - -#define SLOTS_PER_10MS 16 /* 0.625 ms slots in a 10 ms tick */ - -/* Maximum connection accept timeout in 0.625msec */ -#define HCI_MAX_CONN_ACCEPT_TOUT 0xB540 /* 29 sec */ -#define HCI_DEF_CONN_ACCEPT_TOUT 0x1F40 /* 5 sec */ - -/* Page timeout is used in LC only and LC is counting down slots not using OS */ -#define HCI_DEFAULT_PAGE_TOUT 0x2000 /* 5.12 sec (in slots) */ - -/* Scan enable flags */ -#define HCI_NO_SCAN_ENABLED 0x00 -#define HCI_INQUIRY_SCAN_ENABLED 0x01 -#define HCI_PAGE_SCAN_ENABLED 0x02 - -/* Pagescan timer definitions in 0.625 ms */ -#define HCI_MIN_PAGESCAN_INTERVAL 0x12 /* 11.25 ms */ -#define HCI_MAX_PAGESCAN_INTERVAL 0x1000 /* 2.56 sec */ -#define HCI_DEF_PAGESCAN_INTERVAL 0x0800 /* 1.28 sec */ - -/* Parameter for pagescan window is passed to LC and is kept in slots */ -#define HCI_MIN_PAGESCAN_WINDOW 0x11 /* 10.625 ms */ -#define HCI_MAX_PAGESCAN_WINDOW 0x1000 /* 2.56 sec */ -#define HCI_DEF_PAGESCAN_WINDOW 0x12 /* 11.25 ms */ - -/* Inquiryscan timer definitions in 0.625 ms */ -#define HCI_MIN_INQUIRYSCAN_INTERVAL 0x12 /* 11.25 ms */ -#define HCI_MAX_INQUIRYSCAN_INTERVAL 0x1000 /* 2.56 sec */ -#define HCI_DEF_INQUIRYSCAN_INTERVAL 0x1000 /* 2.56 sec */ - -/* Parameter for inquiryscan window is passed to LC and is kept in slots */ -#define HCI_MIN_INQUIRYSCAN_WINDOW 0x11 /* 10.625 ms */ -#define HCI_MAX_INQUIRYSCAN_WINDOW 0x1000 /* 2.56 sec */ -#define HCI_DEF_INQUIRYSCAN_WINDOW 0x12 /* 11.25 ms */ - -/* Encryption modes */ -#define HCI_ENCRYPT_MODE_DISABLED 0x00 -#define HCI_ENCRYPT_MODE_POINT_TO_POINT 0x01 -#define HCI_ENCRYPT_MODE_ALL 0x02 - -/* Voice settings */ -#define HCI_INP_CODING_LINEAR 0x0000 /* 0000000000 */ -#define HCI_INP_CODING_U_LAW 0x0100 /* 0100000000 */ -#define HCI_INP_CODING_A_LAW 0x0200 /* 1000000000 */ -#define HCI_INP_CODING_MASK 0x0300 /* 1100000000 */ - -#define HCI_INP_DATA_FMT_1S_COMPLEMENT 0x0000 /* 0000000000 */ -#define HCI_INP_DATA_FMT_2S_COMPLEMENT 0x0040 /* 0001000000 */ -#define HCI_INP_DATA_FMT_SIGN_MAGNITUDE 0x0080 /* 0010000000 */ -#define HCI_INP_DATA_FMT_UNSIGNED 0x00c0 /* 0011000000 */ -#define HCI_INP_DATA_FMT_MASK 0x00c0 /* 0011000000 */ - -#define HCI_INP_SAMPLE_SIZE_8BIT 0x0000 /* 0000000000 */ -#define HCI_INP_SAMPLE_SIZE_16BIT 0x0020 /* 0000100000 */ -#define HCI_INP_SAMPLE_SIZE_MASK 0x0020 /* 0000100000 */ - -#define HCI_INP_LINEAR_PCM_BIT_POS_MASK 0x001c /* 0000011100 */ -#define HCI_INP_LINEAR_PCM_BIT_POS_OFFS 2 - -#define HCI_AIR_CODING_FORMAT_CVSD 0x0000 /* 0000000000 */ -#define HCI_AIR_CODING_FORMAT_U_LAW 0x0001 /* 0000000001 */ -#define HCI_AIR_CODING_FORMAT_A_LAW 0x0002 /* 0000000010 */ -#define HCI_AIR_CODING_FORMAT_TRANSPNT 0x0003 /* 0000000011 */ -#define HCI_AIR_CODING_FORMAT_MASK 0x0003 /* 0000000011 */ - -/* default 0001100000 */ -#define HCI_DEFAULT_VOICE_SETTINGS (HCI_INP_CODING_LINEAR \ - | HCI_INP_DATA_FMT_2S_COMPLEMENT \ - | HCI_INP_SAMPLE_SIZE_16BIT \ - | HCI_AIR_CODING_FORMAT_CVSD) - -#define HCI_CVSD_SUPPORTED(x) (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_CVSD) -#define HCI_U_LAW_SUPPORTED(x) (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_U_LAW) -#define HCI_A_LAW_SUPPORTED(x) (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_A_LAW) -#define HCI_TRANSPNT_SUPPORTED(x) (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_TRANSPNT) - -/* Retransmit timer definitions in 0.625 */ -#define HCI_MAX_AUTO_FLUSH_TOUT 0x07FF -#define HCI_DEFAULT_AUTO_FLUSH_TOUT 0 /* No auto flush */ - -/* Broadcast retransmitions */ -#define HCI_DEFAULT_NUM_BCAST_RETRAN 1 - -/* Define broadcast data types as passed in the hci data packet */ -#define HCI_DATA_POINT_TO_POINT 0x00 -#define HCI_DATA_ACTIVE_BCAST 0x01 -#define HCI_DATA_PICONET_BCAST 0x02 - -/* Hold mode activity */ -#define HCI_MAINTAIN_CUR_POWER_STATE 0x00 -#define HCI_SUSPEND_PAGE_SCAN 0x01 -#define HCI_SUSPEND_INQUIRY_SCAN 0x02 -#define HCI_SUSPEND_PERIODIC_INQUIRIES 0x04 - -/* Default Link Supervision timeoout */ -#define HCI_DEFAULT_INACT_TOUT 0x7D00 /* BR/EDR (20 seconds) */ -#define HCI_DEFAULT_AMP_INACT_TOUT 0x3E80 /* AMP (10 seconds) */ - -/* Read transmit power level parameter */ -#define HCI_READ_CURRENT 0x00 -#define HCI_READ_MAXIMUM 0x01 - -/* Link types for connection complete event */ -#define HCI_LINK_TYPE_SCO 0x00 -#define HCI_LINK_TYPE_ACL 0x01 -#define HCI_LINK_TYPE_ESCO 0x02 - -/* Link Key Notification Event (Key Type) definitions */ -#define HCI_LKEY_TYPE_COMBINATION 0x00 -#define HCI_LKEY_TYPE_LOCAL_UNIT 0x01 -#define HCI_LKEY_TYPE_REMOTE_UNIT 0x02 -#define HCI_LKEY_TYPE_DEBUG_COMB 0x03 -#define HCI_LKEY_TYPE_UNAUTH_COMB 0x04 -#define HCI_LKEY_TYPE_AUTH_COMB 0x05 -#define HCI_LKEY_TYPE_CHANGED_COMB 0x06 -#define HCI_LKEY_TYPE_UNAUTH_COMB_P_256 0x07 -#define HCI_LKEY_TYPE_AUTH_COMB_P_256 0x08 - -/* Internal definitions - not used over HCI */ -#define HCI_LKEY_TYPE_AMP_WIFI 0x80 -#define HCI_LKEY_TYPE_AMP_UWB 0x81 -#define HCI_LKEY_TYPE_UNKNOWN 0xff - -/* Read Local Version HCI Version return values (Command Complete Event) */ -#define HCI_VERSION_1_0B 0x00 -#define HCI_VERSION_1_1 0x01 - -/* Define an invalid value for a handle */ -#define HCI_INVALID_HANDLE 0xFFFF - -/* Define max ammount of data in the HCI command */ -#define HCI_COMMAND_SIZE 255 - -/* Define the preamble length for all HCI Commands. -** This is 2-bytes for opcode and 1 byte for length -*/ -#define HCIC_PREAMBLE_SIZE 3 - -/* Define the preamble length for all HCI Events -** This is 1-byte for opcode and 1 byte for length -*/ -#define HCIE_PREAMBLE_SIZE 2 -#define HCI_SCO_PREAMBLE_SIZE 3 -#define HCI_DATA_PREAMBLE_SIZE 4 - -/* local Bluetooth controller id for AMP HCI */ -#define LOCAL_BR_EDR_CONTROLLER_ID 0 - -/* controller id types for AMP HCI */ -#define HCI_CONTROLLER_TYPE_BR_EDR 0 -#define HCI_CONTROLLER_TYPE_802_11 1 -#define HCI_CONTROLLER_TYPE_ECMA 2 -#define HCI_MAX_CONTROLLER_TYPES 3 - -/* ConnectionLess Broadcast */ -#define HCI_CLB_DISABLE 0x00 -#define HCI_CLB_ENABLE 0x01 - -/* ConnectionLess Broadcast Data fragment */ -#define HCI_CLB_FRAGMENT_CONT 0x00 -#define HCI_CLB_FRAGMENT_START 0x01 -#define HCI_CLB_FRAGMENT_END 0x02 -#define HCI_CLB_FRAGMENT_SINGLE 0x03 - -/* AMP Controller Status codes -*/ -#define HCI_AMP_CTRLR_PHYSICALLY_DOWN 0 -#define HCI_AMP_CTRLR_USABLE_BY_BT 1 -#define HCI_AMP_CTRLR_UNUSABLE_FOR_BT 2 -#define HCI_AMP_CTRLR_LOW_CAP_FOR_BT 3 -#define HCI_AMP_CTRLR_MED_CAP_FOR_BT 4 -#define HCI_AMP_CTRLR_HIGH_CAP_FOR_BT 5 -#define HCI_AMP_CTRLR_FULL_CAP_FOR_BT 6 - -#define HCI_MAX_AMP_STATUS_TYPES 7 - - -/* Define the extended flow specification fields used by AMP */ -typedef struct { - UINT8 id; - UINT8 stype; - UINT16 max_sdu_size; - UINT32 sdu_inter_time; - UINT32 access_latency; - UINT32 flush_timeout; -} tHCI_EXT_FLOW_SPEC; - - -/* HCI message type definitions (for H4 messages) */ -#define HCIT_TYPE_COMMAND 1 -#define HCIT_TYPE_ACL_DATA 2 -#define HCIT_TYPE_SCO_DATA 3 -#define HCIT_TYPE_EVENT 4 -#define HCIT_TYPE_LM_DIAG 7 -#define HCIT_TYPE_NFC 16 - -#define HCIT_LM_DIAG_LENGTH 63 - -/* Parameter information for HCI_BRCM_SET_ACL_PRIORITY */ -#define HCI_BRCM_ACL_PRIORITY_PARAM_SIZE 3 -#define HCI_BRCM_ACL_PRIORITY_LOW 0x00 -#define HCI_BRCM_ACL_PRIORITY_HIGH 0xFF -#define HCI_BRCM_SET_ACL_PRIORITY (0x0057 | HCI_GRP_VENDOR_SPECIFIC) - -/* Define values for LMP Test Control parameters -** Test Scenario, Hopping Mode, Power Control Mode -*/ -#define LMP_TESTCTL_TESTSC_PAUSE 0 -#define LMP_TESTCTL_TESTSC_TXTEST_0 1 -#define LMP_TESTCTL_TESTSC_TXTEST_1 2 -#define LMP_TESTCTL_TESTSC_TXTEST_1010 3 -#define LMP_TESTCTL_TESTSC_PSRND_BITSEQ 4 -#define LMP_TESTCTL_TESTSC_CLOSEDLB_ACL 5 -#define LMP_TESTCTL_TESTSC_CLOSEDLB_SCO 6 -#define LMP_TESTCTL_TESTSC_ACL_NOWHIT 7 -#define LMP_TESTCTL_TESTSC_SCO_NOWHIT 8 -#define LMP_TESTCTL_TESTSC_TXTEST_11110000 9 -#define LMP_TESTCTL_TESTSC_EXITTESTMODE 255 - -#define LMP_TESTCTL_HOPMOD_RXTX1FREQ 0 -#define LMP_TESTCTL_HOPMOD_HOP_EURUSA 1 -#define LMP_TESTCTL_HOPMOD_HOP_JAPAN 2 -#define LMP_TESTCTL_HOPMOD_HOP_FRANCE 3 -#define LMP_TESTCTL_HOPMOD_HOP_SPAIN 4 -#define LMP_TESTCTL_HOPMOD_REDUCED_HOP 5 - -#define LMP_TESTCTL_POWCTL_FIXEDTX_OP 0 -#define LMP_TESTCTL_POWCTL_ADAPTIVE 1 - -// TODO(zachoverflow): remove this once broadcom specific hacks are removed -#define LMP_COMPID_BROADCOM 15 - -/* -** Define the packet types in the packet header, and a couple extra -*/ -#define PKT_TYPE_NULL 0x00 -#define PKT_TYPE_POLL 0x01 -#define PKT_TYPE_FHS 0x02 -#define PKT_TYPE_DM1 0x03 - -#define PKT_TYPE_DH1 0x04 -#define PKT_TYPE_HV1 0x05 -#define PKT_TYPE_HV2 0x06 -#define PKT_TYPE_HV3 0x07 -#define PKT_TYPE_DV 0x08 -#define PKT_TYPE_AUX1 0x09 - -#define PKT_TYPE_DM3 0x0a -#define PKT_TYPE_DH3 0x0b - -#define PKT_TYPE_DM5 0x0e -#define PKT_TYPE_DH5 0x0f - - -#define PKT_TYPE_ID 0x10 /* Internally used packet types */ -#define PKT_TYPE_BAD 0x11 -#define PKT_TYPE_NONE 0x12 - -/* -** Define packet size -*/ -#define HCI_DM1_PACKET_SIZE 17 -#define HCI_DH1_PACKET_SIZE 27 -#define HCI_DM3_PACKET_SIZE 121 -#define HCI_DH3_PACKET_SIZE 183 -#define HCI_DM5_PACKET_SIZE 224 -#define HCI_DH5_PACKET_SIZE 339 -#define HCI_AUX1_PACKET_SIZE 29 -#define HCI_HV1_PACKET_SIZE 10 -#define HCI_HV2_PACKET_SIZE 20 -#define HCI_HV3_PACKET_SIZE 30 -#define HCI_DV_PACKET_SIZE 9 -#define HCI_EDR2_DH1_PACKET_SIZE 54 -#define HCI_EDR2_DH3_PACKET_SIZE 367 -#define HCI_EDR2_DH5_PACKET_SIZE 679 -#define HCI_EDR3_DH1_PACKET_SIZE 83 -#define HCI_EDR3_DH3_PACKET_SIZE 552 -#define HCI_EDR3_DH5_PACKET_SIZE 1021 - -/* Feature Pages */ -#define HCI_EXT_FEATURES_PAGE_0 0 /* Extended Feature Page 0 (regular features) */ -#define HCI_EXT_FEATURES_PAGE_1 1 /* Extended Feature Page 1 */ -#define HCI_EXT_FEATURES_PAGE_2 2 /* Extended Feature Page 2 */ -#define HCI_EXT_FEATURES_PAGE_MAX HCI_EXT_FEATURES_PAGE_2 - -#define HCI_FEATURE_BYTES_PER_PAGE 8 - -#define HCI_FEATURES_KNOWN(x) ((x[0] | x[1] | x[2] | x[3] | x[4] | x[5] | x[6] | x[7]) != 0) - -/* -** LMP features encoding - page 0 -*/ -#define HCI_FEATURE_3_SLOT_PACKETS_MASK 0x01 -#define HCI_FEATURE_3_SLOT_PACKETS_OFF 0 -#define HCI_3_SLOT_PACKETS_SUPPORTED(x) ((x)[HCI_FEATURE_3_SLOT_PACKETS_OFF] & HCI_FEATURE_3_SLOT_PACKETS_MASK) - -#define HCI_FEATURE_5_SLOT_PACKETS_MASK 0x02 -#define HCI_FEATURE_5_SLOT_PACKETS_OFF 0 -#define HCI_5_SLOT_PACKETS_SUPPORTED(x) ((x)[HCI_FEATURE_5_SLOT_PACKETS_OFF] & HCI_FEATURE_5_SLOT_PACKETS_MASK) - -#define HCI_FEATURE_ENCRYPTION_MASK 0x04 -#define HCI_FEATURE_ENCRYPTION_OFF 0 -#define HCI_ENCRYPTION_SUPPORTED(x) ((x)[HCI_FEATURE_ENCRYPTION_OFF] & HCI_FEATURE_ENCRYPTION_MASK) - -#define HCI_FEATURE_SLOT_OFFSET_MASK 0x08 -#define HCI_FEATURE_SLOT_OFFSET_OFF 0 -#define HCI_SLOT_OFFSET_SUPPORTED(x) ((x)[HCI_FEATURE_SLOT_OFFSET_OFF] & HCI_FEATURE_SLOT_OFFSET_MASK) - -#define HCI_FEATURE_TIMING_ACC_MASK 0x10 -#define HCI_FEATURE_TIMING_ACC_OFF 0 -#define HCI_TIMING_ACC_SUPPORTED(x) ((x)[HCI_FEATURE_TIMING_ACC_OFF] & HCI_FEATURE_TIMING_ACC_MASK) - -#define HCI_FEATURE_SWITCH_MASK 0x20 -#define HCI_FEATURE_SWITCH_OFF 0 -// temporarily disable ROLE_SWITCH since there is an issue to be fixed -#define HCI_SWITCH_SUPPORTED(x) (0 & ((x)[HCI_FEATURE_SWITCH_OFF] & HCI_FEATURE_SWITCH_MASK)) - -#define HCI_FEATURE_HOLD_MODE_MASK 0x40 -#define HCI_FEATURE_HOLD_MODE_OFF 0 -#define HCI_HOLD_MODE_SUPPORTED(x) ((x)[HCI_FEATURE_HOLD_MODE_OFF] & HCI_FEATURE_HOLD_MODE_MASK) - -#define HCI_FEATURE_SNIFF_MODE_MASK 0x80 -#define HCI_FEATURE_SNIFF_MODE_OFF 0 -#define HCI_SNIFF_MODE_SUPPORTED(x) ((x)[HCI_FEATURE_SNIFF_MODE_OFF] & HCI_FEATURE_SNIFF_MODE_MASK) - -#define HCI_FEATURE_PARK_MODE_MASK 0x01 -#define HCI_FEATURE_PARK_MODE_OFF 1 -#define HCI_PARK_MODE_SUPPORTED(x) ((x)[HCI_FEATURE_PARK_MODE_OFF] & HCI_FEATURE_PARK_MODE_MASK) - -#define HCI_FEATURE_RSSI_MASK 0x02 -#define HCI_FEATURE_RSSI_OFF 1 -#define HCI_RSSI_SUPPORTED(x) ((x)[HCI_FEATURE_RSSI_OFF] & HCI_FEATURE_RSSI_MASK) - -#define HCI_FEATURE_CQM_DATA_RATE_MASK 0x04 -#define HCI_FEATURE_CQM_DATA_RATE_OFF 1 -#define HCI_CQM_DATA_RATE_SUPPORTED(x) ((x)[HCI_FEATURE_CQM_DATA_RATE_OFF] & HCI_FEATURE_CQM_DATA_RATE_MASK) - -#define HCI_FEATURE_SCO_LINK_MASK 0x08 -#define HCI_FEATURE_SCO_LINK_OFF 1 -#define HCI_SCO_LINK_SUPPORTED(x) ((x)[HCI_FEATURE_SCO_LINK_OFF] & HCI_FEATURE_SCO_LINK_MASK) - -#define HCI_FEATURE_HV2_PACKETS_MASK 0x10 -#define HCI_FEATURE_HV2_PACKETS_OFF 1 -#define HCI_HV2_PACKETS_SUPPORTED(x) ((x)[HCI_FEATURE_HV2_PACKETS_OFF] & HCI_FEATURE_HV2_PACKETS_MASK) - -#define HCI_FEATURE_HV3_PACKETS_MASK 0x20 -#define HCI_FEATURE_HV3_PACKETS_OFF 1 -#define HCI_HV3_PACKETS_SUPPORTED(x) ((x)[HCI_FEATURE_HV3_PACKETS_OFF] & HCI_FEATURE_HV3_PACKETS_MASK) - -#define HCI_FEATURE_U_LAW_MASK 0x40 -#define HCI_FEATURE_U_LAW_OFF 1 -#define HCI_LMP_U_LAW_SUPPORTED(x) ((x)[HCI_FEATURE_U_LAW_OFF] & HCI_FEATURE_U_LAW_MASK) - -#define HCI_FEATURE_A_LAW_MASK 0x80 -#define HCI_FEATURE_A_LAW_OFF 1 -#define HCI_LMP_A_LAW_SUPPORTED(x) ((x)[HCI_FEATURE_A_LAW_OFF] & HCI_FEATURE_A_LAW_MASK) - -#define HCI_FEATURE_CVSD_MASK 0x01 -#define HCI_FEATURE_CVSD_OFF 2 -#define HCI_LMP_CVSD_SUPPORTED(x) ((x)[HCI_FEATURE_CVSD_OFF] & HCI_FEATURE_CVSD_MASK) - -#define HCI_FEATURE_PAGING_SCHEME_MASK 0x02 -#define HCI_FEATURE_PAGING_SCHEME_OFF 2 -#define HCI_PAGING_SCHEME_SUPPORTED(x) ((x)[HCI_FEATURE_PAGING_SCHEME_OFF] & HCI_FEATURE_PAGING_SCHEME_MASK) - -#define HCI_FEATURE_POWER_CTRL_MASK 0x04 -#define HCI_FEATURE_POWER_CTRL_OFF 2 -#define HCI_POWER_CTRL_SUPPORTED(x) ((x)[HCI_FEATURE_POWER_CTRL_OFF] & HCI_FEATURE_POWER_CTRL_MASK) - -#define HCI_FEATURE_TRANSPNT_MASK 0x08 -#define HCI_FEATURE_TRANSPNT_OFF 2 -#define HCI_LMP_TRANSPNT_SUPPORTED(x) ((x)[HCI_FEATURE_TRANSPNT_OFF] & HCI_FEATURE_TRANSPNT_MASK) - -#define HCI_FEATURE_FLOW_CTRL_LAG_MASK 0x70 -#define HCI_FEATURE_FLOW_CTRL_LAG_OFF 2 -#define HCI_FLOW_CTRL_LAG_VALUE(x) (((x)[HCI_FEATURE_FLOW_CTRL_LAG_OFF] & HCI_FEATURE_FLOW_CTRL_LAG_MASK) >> 4) - -#define HCI_FEATURE_BROADCAST_ENC_MASK 0x80 -#define HCI_FEATURE_BROADCAST_ENC_OFF 2 -#define HCI_LMP_BCAST_ENC_SUPPORTED(x) ((x)[HCI_FEATURE_BROADCAST_ENC_OFF] & HCI_FEATURE_BROADCAST_ENC_MASK) - -#define HCI_FEATURE_SCATTER_MODE_MASK 0x01 -#define HCI_FEATURE_SCATTER_MODE_OFF 3 -#define HCI_LMP_SCATTER_MODE_SUPPORTED(x) ((x)[HCI_FEATURE_SCATTER_MODE_OFF] & HCI_FEATURE_SCATTER_MODE_MASK) - -#define HCI_FEATURE_EDR_ACL_2MPS_MASK 0x02 -#define HCI_FEATURE_EDR_ACL_2MPS_OFF 3 -#define HCI_EDR_ACL_2MPS_SUPPORTED(x) ((x)[HCI_FEATURE_EDR_ACL_2MPS_OFF] & HCI_FEATURE_EDR_ACL_2MPS_MASK) - -#define HCI_FEATURE_EDR_ACL_3MPS_MASK 0x04 -#define HCI_FEATURE_EDR_ACL_3MPS_OFF 3 -#define HCI_EDR_ACL_3MPS_SUPPORTED(x) ((x)[HCI_FEATURE_EDR_ACL_3MPS_OFF] & HCI_FEATURE_EDR_ACL_3MPS_MASK) - -#define HCI_FEATURE_ENHANCED_INQ_MASK 0x08 -#define HCI_FEATURE_ENHANCED_INQ_OFF 3 -#define HCI_ENHANCED_INQ_SUPPORTED(x) ((x)[HCI_FEATURE_ENHANCED_INQ_OFF] & HCI_FEATURE_ENHANCED_INQ_MASK) - -#define HCI_FEATURE_INTERLACED_INQ_SCAN_MASK 0x10 -#define HCI_FEATURE_INTERLACED_INQ_SCAN_OFF 3 -#define HCI_LMP_INTERLACED_INQ_SCAN_SUPPORTED(x) ((x)[HCI_FEATURE_INTERLACED_INQ_SCAN_OFF] & HCI_FEATURE_INTERLACED_INQ_SCAN_MASK) - -#define HCI_FEATURE_INTERLACED_PAGE_SCAN_MASK 0x20 -#define HCI_FEATURE_INTERLACED_PAGE_SCAN_OFF 3 -#define HCI_LMP_INTERLACED_PAGE_SCAN_SUPPORTED(x) ((x)[HCI_FEATURE_INTERLACED_PAGE_SCAN_OFF] & HCI_FEATURE_INTERLACED_PAGE_SCAN_MASK) - -#define HCI_FEATURE_INQ_RSSI_MASK 0x40 -#define HCI_FEATURE_INQ_RSSI_OFF 3 -#define HCI_LMP_INQ_RSSI_SUPPORTED(x) ((x)[HCI_FEATURE_INQ_RSSI_OFF] & HCI_FEATURE_INQ_RSSI_MASK) - -#define HCI_FEATURE_ESCO_EV3_MASK 0x80 -#define HCI_FEATURE_ESCO_EV3_OFF 3 -#define HCI_ESCO_EV3_SUPPORTED(x) ((x)[HCI_FEATURE_ESCO_EV3_OFF] & HCI_FEATURE_ESCO_EV3_MASK) - -#define HCI_FEATURE_ESCO_EV4_MASK 0x01 -#define HCI_FEATURE_ESCO_EV4_OFF 4 -#define HCI_ESCO_EV4_SUPPORTED(x) ((x)[HCI_FEATURE_ESCO_EV4_OFF] & HCI_FEATURE_ESCO_EV4_MASK) - -#define HCI_FEATURE_ESCO_EV5_MASK 0x02 -#define HCI_FEATURE_ESCO_EV5_OFF 4 -#define HCI_ESCO_EV5_SUPPORTED(x) ((x)[HCI_FEATURE_ESCO_EV5_OFF] & HCI_FEATURE_ESCO_EV5_MASK) - -#define HCI_FEATURE_ABSENCE_MASKS_MASK 0x04 -#define HCI_FEATURE_ABSENCE_MASKS_OFF 4 -#define HCI_LMP_ABSENCE_MASKS_SUPPORTED(x) ((x)[HCI_FEATURE_ABSENCE_MASKS_OFF] & HCI_FEATURE_ABSENCE_MASKS_MASK) - -#define HCI_FEATURE_AFH_CAP_SLAVE_MASK 0x08 -#define HCI_FEATURE_AFH_CAP_SLAVE_OFF 4 -#define HCI_LMP_AFH_CAP_SLAVE_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CAP_SLAVE_OFF] & HCI_FEATURE_AFH_CAP_SLAVE_MASK) - -#define HCI_FEATURE_AFH_CLASS_SLAVE_MASK 0x10 -#define HCI_FEATURE_AFH_CLASS_SLAVE_OFF 4 -#define HCI_LMP_AFH_CLASS_SLAVE_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CLASS_SLAVE_OFF] & HCI_FEATURE_AFH_CLASS_SLAVE_MASK) - -#if 1 -#define HCI_FEATURE_BREDR_NOT_SPT_MASK 0x20 -#define HCI_FEATURE_BREDR_NOT_SPT_OFF 4 -#define HCI_BREDR_NOT_SPT_SUPPORTED(x) ((x)[HCI_FEATURE_BREDR_NOT_SPT_OFF] & HCI_FEATURE_BREDR_NOT_SPT_MASK) - -#define HCI_FEATURE_LE_SPT_MASK 0x40 -#define HCI_FEATURE_LE_SPT_OFF 4 -#define HCI_LE_SPT_SUPPORTED(x) ((x)[HCI_FEATURE_LE_SPT_OFF] & HCI_FEATURE_LE_SPT_MASK) -#else - -#define HCI_FEATURE_ALIAS_AUTH_MASK 0x20 -#define HCI_FEATURE_ALIAS_AUTH_OFF 4 -#define HCI_LMP_ALIAS_AUTH_SUPPORTED(x) ((x)[HCI_FEATURE_ALIAS_AUTH_OFF] & HCI_FEATURE_ALIAS_AUTH_MASK) - -#define HCI_FEATURE_ANON_MODE_MASK 0x40 -#define HCI_FEATURE_ANON_MODE_OFF 4 -#define HCI_LMP_ANON_MODE_SUPPORTED(x) ((x)[HCI_FEATURE_ANON_MODE_OFF] & HCI_FEATURE_ANON_MODE_MASK) -#endif - -#define HCI_FEATURE_3_SLOT_EDR_ACL_MASK 0x80 -#define HCI_FEATURE_3_SLOT_EDR_ACL_OFF 4 -#define HCI_3_SLOT_EDR_ACL_SUPPORTED(x) ((x)[HCI_FEATURE_3_SLOT_EDR_ACL_OFF] & HCI_FEATURE_3_SLOT_EDR_ACL_MASK) - -#define HCI_FEATURE_5_SLOT_EDR_ACL_MASK 0x01 -#define HCI_FEATURE_5_SLOT_EDR_ACL_OFF 5 -#define HCI_5_SLOT_EDR_ACL_SUPPORTED(x) ((x)[HCI_FEATURE_5_SLOT_EDR_ACL_OFF] & HCI_FEATURE_5_SLOT_EDR_ACL_MASK) - -#define HCI_FEATURE_SNIFF_SUB_RATE_MASK 0x02 -#define HCI_FEATURE_SNIFF_SUB_RATE_OFF 5 -#define HCI_SNIFF_SUB_RATE_SUPPORTED(x) ((x)[HCI_FEATURE_SNIFF_SUB_RATE_OFF] & HCI_FEATURE_SNIFF_SUB_RATE_MASK) - -#define HCI_FEATURE_ATOMIC_ENCRYPT_MASK 0x04 -#define HCI_FEATURE_ATOMIC_ENCRYPT_OFF 5 -#define HCI_ATOMIC_ENCRYPT_SUPPORTED(x) ((x)[HCI_FEATURE_ATOMIC_ENCRYPT_OFF] & HCI_FEATURE_ATOMIC_ENCRYPT_MASK) - -#define HCI_FEATURE_AFH_CAP_MASTR_MASK 0x08 -#define HCI_FEATURE_AFH_CAP_MASTR_OFF 5 -#define HCI_LMP_AFH_CAP_MASTR_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CAP_MASTR_OFF] & HCI_FEATURE_AFH_CAP_MASTR_MASK) - -#define HCI_FEATURE_AFH_CLASS_MASTR_MASK 0x10 -#define HCI_FEATURE_AFH_CLASS_MASTR_OFF 5 -#define HCI_LMP_AFH_CLASS_MASTR_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CLASS_MASTR_OFF] & HCI_FEATURE_AFH_CLASS_MASTR_MASK) - -#define HCI_FEATURE_EDR_ESCO_2MPS_MASK 0x20 -#define HCI_FEATURE_EDR_ESCO_2MPS_OFF 5 -#define HCI_EDR_ESCO_2MPS_SUPPORTED(x) ((x)[HCI_FEATURE_EDR_ESCO_2MPS_OFF] & HCI_FEATURE_EDR_ESCO_2MPS_MASK) - -#define HCI_FEATURE_EDR_ESCO_3MPS_MASK 0x40 -#define HCI_FEATURE_EDR_ESCO_3MPS_OFF 5 -#define HCI_EDR_ESCO_3MPS_SUPPORTED(x) ((x)[HCI_FEATURE_EDR_ESCO_3MPS_OFF] & HCI_FEATURE_EDR_ESCO_3MPS_MASK) - -#define HCI_FEATURE_3_SLOT_EDR_ESCO_MASK 0x80 -#define HCI_FEATURE_3_SLOT_EDR_ESCO_OFF 5 -#define HCI_3_SLOT_EDR_ESCO_SUPPORTED(x) ((x)[HCI_FEATURE_3_SLOT_EDR_ESCO_OFF] & HCI_FEATURE_3_SLOT_EDR_ESCO_MASK) - -#define HCI_FEATURE_EXT_INQ_RSP_MASK 0x01 -#define HCI_FEATURE_EXT_INQ_RSP_OFF 6 -#define HCI_EXT_INQ_RSP_SUPPORTED(x) ((x)[HCI_FEATURE_EXT_INQ_RSP_OFF] & HCI_FEATURE_EXT_INQ_RSP_MASK) - -#if 1 /* TOKYO spec definition */ -#define HCI_FEATURE_SIMUL_LE_BREDR_MASK 0x02 -#define HCI_FEATURE_SIMUL_LE_BREDR_OFF 6 -#define HCI_SIMUL_LE_BREDR_SUPPORTED(x) ((x)[HCI_FEATURE_SIMUL_LE_BREDR_OFF] & HCI_FEATURE_SIMUL_LE_BREDR_MASK) - -#else -#define HCI_FEATURE_ANUM_PIN_AWARE_MASK 0x02 -#define HCI_FEATURE_ANUM_PIN_AWARE_OFF 6 -#define HCI_ANUM_PIN_AWARE_SUPPORTED(x) ((x)[HCI_FEATURE_ANUM_PIN_AWARE_OFF] & HCI_FEATURE_ANUM_PIN_AWARE_MASK) -#endif - -#define HCI_FEATURE_ANUM_PIN_CAP_MASK 0x04 -#define HCI_FEATURE_ANUM_PIN_CAP_OFF 6 -#define HCI_ANUM_PIN_CAP_SUPPORTED(x) ((x)[HCI_FEATURE_ANUM_PIN_CAP_OFF] & HCI_FEATURE_ANUM_PIN_CAP_MASK) - -#define HCI_FEATURE_SIMPLE_PAIRING_MASK 0x08 -#define HCI_FEATURE_SIMPLE_PAIRING_OFF 6 -#define HCI_SIMPLE_PAIRING_SUPPORTED(x) ((x)[HCI_FEATURE_SIMPLE_PAIRING_OFF] & HCI_FEATURE_SIMPLE_PAIRING_MASK) - -#define HCI_FEATURE_ENCAP_PDU_MASK 0x10 -#define HCI_FEATURE_ENCAP_PDU_OFF 6 -#define HCI_ENCAP_PDU_SUPPORTED(x) ((x)[HCI_FEATURE_ENCAP_PDU_OFF] & HCI_FEATURE_ENCAP_PDU_MASK) - -#define HCI_FEATURE_ERROR_DATA_MASK 0x20 -#define HCI_FEATURE_ERROR_DATA_OFF 6 -#define HCI_ERROR_DATA_SUPPORTED(x) ((x)[HCI_FEATURE_ERROR_DATA_OFF] & HCI_FEATURE_ERROR_DATA_MASK) - -#define HCI_FEATURE_NON_FLUSHABLE_PB_MASK 0x40 -#define HCI_FEATURE_NON_FLUSHABLE_PB_OFF 6 - -/* This feature is causing frequent link drops when doing call switch with certain av/hfp headsets */ -#define HCI_NON_FLUSHABLE_PB_SUPPORTED(x) (0)//((x)[HCI_FEATURE_NON_FLUSHABLE_PB_OFF] & HCI_FEATURE_NON_FLUSHABLE_PB_MASK) - -#define HCI_FEATURE_LINK_SUP_TO_EVT_MASK 0x01 -#define HCI_FEATURE_LINK_SUP_TO_EVT_OFF 7 -#define HCI_LINK_SUP_TO_EVT_SUPPORTED(x) ((x)[HCI_FEATURE_LINK_SUP_TO_EVT_OFF] & HCI_FEATURE_LINK_SUP_TO_EVT_MASK) - -#define HCI_FEATURE_INQ_RESP_TX_MASK 0x02 -#define HCI_FEATURE_INQ_RESP_TX_OFF 7 -#define HCI_INQ_RESP_TX_SUPPORTED(x) ((x)[HCI_FEATURE_INQ_RESP_TX_OFF] & HCI_FEATURE_INQ_RESP_TX_MASK) - -#define HCI_FEATURE_EXTENDED_MASK 0x80 -#define HCI_FEATURE_EXTENDED_OFF 7 -#define HCI_LMP_EXTENDED_SUPPORTED(x) ((x)[HCI_FEATURE_EXTENDED_OFF] & HCI_FEATURE_EXTENDED_MASK) - -/* -** LMP features encoding - page 1 -*/ -#define HCI_EXT_FEATURE_SSP_HOST_MASK 0x01 -#define HCI_EXT_FEATURE_SSP_HOST_OFF 0 -#define HCI_SSP_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SSP_HOST_OFF] & HCI_EXT_FEATURE_SSP_HOST_MASK) - -#define HCI_EXT_FEATURE_LE_HOST_MASK 0x02 -#define HCI_EXT_FEATURE_LE_HOST_OFF 0 -#define HCI_LE_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_LE_HOST_OFF] & HCI_EXT_FEATURE_LE_HOST_MASK) - -#define HCI_EXT_FEATURE_SIMUL_DUMO_HOST_MASK 0x04 -#define HCI_EXT_FEATURE_SIMUL_DUMO_HOST_OFF 0 -#define HCI_SIMUL_DUMO_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SIMUL_DUMO_HOST_OFF] & HCI_EXT_FEATURE_SIMUL_DUMO_HOST_MASK) - -#define HCI_EXT_FEATURE_SC_HOST_MASK 0x08 -#define HCI_EXT_FEATURE_SC_HOST_OFF 0 -#define HCI_SC_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SC_HOST_OFF] & HCI_EXT_FEATURE_SC_HOST_MASK) - -/* -** LMP features encoding - page 2 -*/ -#define HCI_EXT_FEATURE_CSB_MASTER_MASK 0x01 -#define HCI_EXT_FEATURE_CSB_MASTER_OFF 0 -#define HCI_CSB_MASTER_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_CSB_MASTER_OFF] & HCI_EXT_FEATURE_CSB_MASTER_MASK) - -#define HCI_EXT_FEATURE_CSB_SLAVE_MASK 0x02 -#define HCI_EXT_FEATURE_CSB_SLAVE_OFF 0 -#define HCI_CSB_SLAVE_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_CSB_SLAVE_OFF] & HCI_EXT_FEATURE_CSB_SLAVE_MASK) - -#define HCI_EXT_FEATURE_SYNC_TRAIN_MASTER_MASK 0x04 -#define HCI_EXT_FEATURE_SYNC_TRAIN_MASTER_OFF 0 -#define HCI_SYNC_TRAIN_MASTER_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SYNC_TRAIN_MASTER_OFF] & HCI_EXT_FEATURE_SYNC_TRAIN_MASTER_MASK) - -#define HCI_EXT_FEATURE_SYNC_SCAN_SLAVE_MASK 0x08 -#define HCI_EXT_FEATURE_SYNC_SCAN_SLAVE_OFF 0 -#define HCI_SYNC_SCAN_SLAVE_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SYNC_SCAN_SLAVE_OFF] & HCI_EXT_FEATURE_SYNC_SCAN_SLAVE_MASK) - -#define HCI_EXT_FEATURE_INQ_RESP_NOTIF_MASK 0x10 -#define HCI_EXT_FEATURE_INQ_RESP_NOTIF_OFF 0 -#define HCI_INQ_RESP_NOTIF_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_INQ_RESP_NOTIF_OFF] & HCI_EXT_FEATURE_INQ_RESP_NOTIF_MASK) - -#define HCI_EXT_FEATURE_SC_CTRLR_MASK 0x01 -#define HCI_EXT_FEATURE_SC_CTRLR_OFF 1 -#define HCI_SC_CTRLR_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SC_CTRLR_OFF] & HCI_EXT_FEATURE_SC_CTRLR_MASK) - -#define HCI_EXT_FEATURE_PING_MASK 0x02 -#define HCI_EXT_FEATURE_PING_OFF 1 -#define HCI_PING_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_PING_OFF] & HCI_EXT_FEATURE_PING_MASK) - -/* -** LE features encoding - page 0 (the only page for now) -*/ -/* LE Encryption */ -#define HCI_LE_FEATURE_LE_ENCRYPTION_MASK 0x01 -#define HCI_LE_FEATURE_LE_ENCRYPTION_OFF 0 -#define HCI_LE_ENCRYPTION_SUPPORTED(x) ((x)[HCI_LE_FEATURE_LE_ENCRYPTION_OFF] & HCI_LE_FEATURE_LE_ENCRYPTION_MASK) - -/* Connection Parameters Request Procedure */ -#define HCI_LE_FEATURE_CONN_PARAM_REQ_MASK 0x02 -#define HCI_LE_FEATURE_CONN_PARAM_REQ_OFF 0 -#define HCI_LE_CONN_PARAM_REQ_SUPPORTED(x) ((x)[HCI_LE_FEATURE_CONN_PARAM_REQ_OFF] & HCI_LE_FEATURE_CONN_PARAM_REQ_MASK) - -/* Extended Reject Indication */ -#define HCI_LE_FEATURE_EXT_REJ_IND_MASK 0x04 -#define HCI_LE_FEATURE_EXT_REJ_IND_OFF 0 -#define HCI_LE_EXT_REJ_IND_SUPPORTED(x) ((x)[HCI_LE_FEATURE_EXT_REJ_IND_OFF] & HCI_LE_FEATURE_EXT_REJ_IND_MASK) - -/* Slave-initiated Features Exchange */ -#define HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_MASK 0x08 -#define HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_OFF 0 -#define HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(x) ((x)[HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_OFF] & HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_MASK) - -/* Enhanced privacy Feature: bit 6 */ -#define HCI_LE_FEATURE_ENHANCED_PRIVACY_MASK 0x40 -#define HCI_LE_FEATURE_ENHANCED_PRIVACY_OFF 0 -#define HCI_LE_ENHANCED_PRIVACY_SUPPORTED(x) ((x)[HCI_LE_FEATURE_ENHANCED_PRIVACY_OFF] & HCI_LE_FEATURE_ENHANCED_PRIVACY_MASK) - -/* Extended scanner filter policy : 7 */ -#define HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_MASK 0x80 -#define HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_OFF 0 -#define HCI_LE_EXT_SCAN_FILTER_POLICY_SUPPORTED(x) ((x)[HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_OFF] & HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_MASK) - -/* Slave-initiated Features Exchange */ -#define HCI_LE_FEATURE_DATA_LEN_EXT_MASK 0x20 -#define HCI_LE_FEATURE_DATA_LEN_EXT_OFF 0 -#define HCI_LE_DATA_LEN_EXT_SUPPORTED(x) ((x)[HCI_LE_FEATURE_DATA_LEN_EXT_OFF] & HCI_LE_FEATURE_DATA_LEN_EXT_MASK) - -/* -** Local Supported Commands encoding -*/ -#define HCI_NUM_SUPP_COMMANDS_BYTES 64 - -/* Supported Commands Byte 0 */ -#define HCI_SUPP_COMMANDS_INQUIRY_MASK 0x01 -#define HCI_SUPP_COMMANDS_INQUIRY_OFF 0 -#define HCI_INQUIRY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_INQUIRY_OFF] & HCI_SUPP_COMMANDS_INQUIRY_MASK) - -#define HCI_SUPP_COMMANDS_INQUIRY_CANCEL_MASK 0x02 -#define HCI_SUPP_COMMANDS_INQUIRY_CANCEL_OFF 0 -#define HCI_INQUIRY_CANCEL_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_INQUIRY_CANCEL_OFF] & HCI_SUPP_COMMANDS_INQUIRY_CANCEL_MASK) - -#define HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_MASK 0x04 -#define HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_OFF 0 -#define HCI_PERIODIC_INQUIRY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_OFF] & HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_MASK) - -#define HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_MASK 0x08 -#define HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_OFF 0 -#define HCI_EXIT_PERIODIC_INQUIRY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_OFF] & HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_MASK) - -#define HCI_SUPP_COMMANDS_CREATE_CONN_MASK 0x10 -#define HCI_SUPP_COMMANDS_CREATE_CONN_OFF 0 -#define HCI_CREATE_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CREATE_CONN_OFF] & HCI_SUPP_COMMANDS_CREATE_CONN_MASK) - -#define HCI_SUPP_COMMANDS_DISCONNECT_MASK 0x20 -#define HCI_SUPP_COMMANDS_DISCONNECT_OFF 0 -#define HCI_DISCONNECT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_DISCONNECT_OFF] & HCI_SUPP_COMMANDS_DISCONNECT_MASK) - -#define HCI_SUPP_COMMANDS_ADD_SCO_CONN_MASK 0x40 -#define HCI_SUPP_COMMANDS_ADD_SCO_CONN_OFF 0 -#define HCI_ADD_SCO_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ADD_SCO_CONN_OFF] & HCI_SUPP_COMMANDS_ADD_SCO_CONN_MASK) - -#define HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_MASK 0x80 -#define HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_OFF 0 -#define HCI_CANCEL_CREATE_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_OFF] & HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_MASK) - -#define HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_MASK 0x01 -#define HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_OFF 1 -#define HCI_ACCEPT_CONN_REQUEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_OFF] & HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_MASK) - -#define HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_MASK 0x02 -#define HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_OFF 1 -#define HCI_REJECT_CONN_REQUEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_OFF] & HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_MASK) - -#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_MASK 0x04 -#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_OFF 1 -#define HCI_LINK_KEY_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_MASK) - -#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_MASK 0x08 -#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_OFF 1 -#define HCI_LINK_KEY_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_MASK) - -#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_MASK 0x10 -#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_OFF 1 -#define HCI_PIN_CODE_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_MASK) - -#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_MASK 0x20 -#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_OFF 1 -#define HCI_PIN_CODE_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_MASK) - -#define HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_MASK 0x40 -#define HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_OFF 1 -#define HCI_CHANGE_CONN_PKT_TYPE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_OFF] & HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_MASK) - -#define HCI_SUPP_COMMANDS_AUTH_REQUEST_MASK 0x80 -#define HCI_SUPP_COMMANDS_AUTH_REQUEST_OFF 1 -#define HCI_AUTH_REQUEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_AUTH_REQUEST_OFF] & HCI_SUPP_COMMANDS_AUTH_REQUEST_MASK) - -#define HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_MASK 0x01 -#define HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_OFF 2 -#define HCI_SET_CONN_ENCRYPTION_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_OFF] & HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_MASK) - -#define HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_MASK 0x02 -#define HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_OFF 2 -#define HCI_CHANGE_CONN_LINK_KEY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_MASK) - -#define HCI_SUPP_COMMANDS_MASTER_LINK_KEY_MASK 0x04 -#define HCI_SUPP_COMMANDS_MASTER_LINK_KEY_OFF 2 -#define HCI_MASTER_LINK_KEY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_MASTER_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_MASTER_LINK_KEY_MASK) - -#define HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_MASK 0x08 -#define HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_OFF 2 -#define HCI_REMOTE_NAME_REQUEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_OFF] & HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_MASK) - -#define HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_MASK 0x10 -#define HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_OFF 2 -#define HCI_CANCEL_REMOTE_NAME_REQUEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_OFF] & HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_MASK) - -#define HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_MASK 0x20 -#define HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_OFF 2 -#define HCI_READ_REMOTE_SUPP_FEATURES_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_MASK) - -#define HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_MASK 0x40 -#define HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_OFF 2 -#define HCI_READ_REMOTE_EXT_FEATURES_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_MASK) - -#define HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_MASK 0x80 -#define HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_OFF 2 -#define HCI_READ_REMOTE_VER_INFO_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_OFF] & HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_MASK) - -#define HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_MASK 0x01 -#define HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_OFF 3 -#define HCI_READ_CLOCK_OFFSET_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_OFF] & HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_MASK) - -#define HCI_SUPP_COMMANDS_READ_LMP_HANDLE_MASK 0x02 -#define HCI_SUPP_COMMANDS_READ_LMP_HANDLE_OFF 3 -#define HCI_READ_LMP_HANDLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LMP_HANDLE_OFF] & HCI_SUPP_COMMANDS_READ_LMP_HANDLE_MASK) - -#define HCI_SUPP_COMMANDS_HOLD_MODE_CMD_MASK 0x02 -#define HCI_SUPP_COMMANDS_HOLD_MODE_CMD_OFF 4 -#define HCI_HOLD_MODE_CMD_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_HOLD_MODE_CMD_OFF] & HCI_SUPP_COMMANDS_HOLD_MODE_CMD_MASK) - -#define HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_MASK 0x04 -#define HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_OFF 4 -#define HCI_SNIFF_MODE_CMD_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_OFF] & HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_MASK) - -#define HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_MASK 0x08 -#define HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_OFF 4 -#define HCI_EXIT_SNIFF_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_OFF] & HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_MASK) - -#define HCI_SUPP_COMMANDS_PARK_STATE_MASK 0x10 -#define HCI_SUPP_COMMANDS_PARK_STATE_OFF 4 -#define HCI_PARK_STATE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_PARK_STATE_OFF] & HCI_SUPP_COMMANDS_PARK_STATE_MASK) - -#define HCI_SUPP_COMMANDS_EXIT_PARK_STATE_MASK 0x20 -#define HCI_SUPP_COMMANDS_EXIT_PARK_STATE_OFF 4 -#define HCI_EXIT_PARK_STATE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_EXIT_PARK_STATE_OFF] & HCI_SUPP_COMMANDS_EXIT_PARK_STATE_MASK) - -#define HCI_SUPP_COMMANDS_QOS_SETUP_MASK 0x40 -#define HCI_SUPP_COMMANDS_QOS_SETUP_OFF 4 -#define HCI_QOS_SETUP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_QOS_SETUP_OFF] & HCI_SUPP_COMMANDS_QOS_SETUP_MASK) - -#define HCI_SUPP_COMMANDS_ROLE_DISCOVERY_MASK 0x80 -#define HCI_SUPP_COMMANDS_ROLE_DISCOVERY_OFF 4 -#define HCI_ROLE_DISCOVERY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ROLE_DISCOVERY_OFF] & HCI_SUPP_COMMANDS_ROLE_DISCOVERY_MASK) - -#define HCI_SUPP_COMMANDS_SWITCH_ROLE_MASK 0x01 -#define HCI_SUPP_COMMANDS_SWITCH_ROLE_OFF 5 -#define HCI_SWITCH_ROLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SWITCH_ROLE_OFF] & HCI_SUPP_COMMANDS_SWITCH_ROLE_MASK) - -#define HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_MASK 0x02 -#define HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_OFF 5 -#define HCI_READ_LINK_POLICY_SET_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_MASK 0x04 -#define HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_OFF 5 -#define HCI_WRITE_LINK_POLICY_SET_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_MASK) - -#define HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_MASK 0x08 -#define HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_OFF 5 -#define HCI_READ_DEF_LINK_POLICY_SET_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_MASK 0x10 -#define HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_OFF 5 -#define HCI_WRITE_DEF_LINK_POLICY_SET_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_MASK) - -#define HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_MASK 0x20 -#define HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_OFF 5 -#define HCI_FLOW_SPECIFICATION_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_OFF] & HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_MASK) - -#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_MASK 0x40 -#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_OFF 5 -#define HCI_SET_EVENT_MASK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_EVENT_MASK_OFF] & HCI_SUPP_COMMANDS_SET_EVENT_MASK_MASK) - -#define HCI_SUPP_COMMANDS_RESET_MASK 0x80 -#define HCI_SUPP_COMMANDS_RESET_OFF 5 -#define HCI_RESET_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_RESET_OFF] & HCI_SUPP_COMMANDS_RESET_MASK) - -#define HCI_SUPP_COMMANDS_SET_EVENT_FILTER_MASK 0x01 -#define HCI_SUPP_COMMANDS_SET_EVENT_FILTER_OFF 6 -#define HCI_SET_EVENT_FILTER_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_EVENT_FILTER_OFF] & HCI_SUPP_COMMANDS_SET_EVENT_FILTER_MASK) - -#define HCI_SUPP_COMMANDS_FLUSH_MASK 0x02 -#define HCI_SUPP_COMMANDS_FLUSH_OFF 6 -#define HCI_FLUSH_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_FLUSH_OFF] & HCI_SUPP_COMMANDS_FLUSH_MASK) - -#define HCI_SUPP_COMMANDS_READ_PIN_TYPE_MASK 0x04 -#define HCI_SUPP_COMMANDS_READ_PIN_TYPE_OFF 6 -#define HCI_READ_PIN_TYPE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_PIN_TYPE_OFF] & HCI_SUPP_COMMANDS_READ_PIN_TYPE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_MASK 0x08 -#define HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_OFF 6 -#define HCI_WRITE_PIN_TYPE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_OFF] & HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_MASK) - -#define HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_MASK 0x10 -#define HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_OFF 6 -#define HCI_CREATE_NEW_UNIT_KEY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_OFF] & HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_MASK) - -#define HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_MASK 0x20 -#define HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_OFF 6 -#define HCI_READ_STORED_LINK_KEY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_MASK 0x40 -#define HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_OFF 6 -#define HCI_WRITE_STORED_LINK_KEY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_MASK) - -#define HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_MASK 0x80 -#define HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_OFF 6 -#define HCI_DELETE_STORED_LINK_KEY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_MASK 0x01 -#define HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_OFF 7 -#define HCI_WRITE_LOCAL_NAME_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_OFF] & HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_MASK) - -#define HCI_SUPP_COMMANDS_READ_LOCAL_NAME_MASK 0x02 -#define HCI_SUPP_COMMANDS_READ_LOCAL_NAME_OFF 7 -#define HCI_READ_LOCAL_NAME_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_NAME_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_NAME_MASK) - -#define HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_MASK 0x04 -#define HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_OFF 7 -#define HCI_READ_CONN_ACCEPT_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_MASK 0x08 -#define HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_OFF 7 -#define HCI_WRITE_CONN_ACCEPT_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_MASK) - -#define HCI_SUPP_COMMANDS_READ_PAGE_TOUT_MASK 0x10 -#define HCI_SUPP_COMMANDS_READ_PAGE_TOUT_OFF 7 -#define HCI_READ_PAGE_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_PAGE_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_TOUT_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_MASK 0x20 -#define HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_OFF 7 -#define HCI_WRITE_PAGE_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_MASK) - -#define HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_MASK 0x40 -#define HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_OFF 7 -#define HCI_READ_SCAN_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_MASK 0x80 -#define HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_OFF 7 -#define HCI_WRITE_SCAN_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_MASK) - -#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_MASK 0x01 -#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_OFF 8 -#define HCI_READ_PAGE_SCAN_ACTIVITY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_MASK 0x02 -#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_OFF 8 -#define HCI_WRITE_PAGE_SCAN_ACTIVITY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_MASK) - -#define HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_MASK 0x04 -#define HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_OFF 8 -#define HCI_READ_INQURIY_SCAN_ACTIVITY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_MASK 0x08 -#define HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_OFF 8 -#define HCI_WRITE_INQURIY_SCAN_ACTIVITY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_MASK) - -#define HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_MASK 0x10 -#define HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_OFF 8 -#define HCI_READ_AUTH_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_MASK 0x20 -#define HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_OFF 8 -#define HCI_WRITE_AUTH_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_MASK) - -#define HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_MASK 0x40 -#define HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_OFF 8 -#define HCI_READ_ENCRYPT_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_MASK 0x80 -#define HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_OFF 8 -#define HCI_WRITE_ENCRYPT_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_MASK) - -#define HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_MASK 0x01 -#define HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_OFF 9 -#define HCI_READ_CLASS_DEVICE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_OFF] & HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_MASK 0x02 -#define HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_OFF 9 -#define HCI_WRITE_CLASS_DEVICE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_OFF] & HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_MASK) - -#define HCI_SUPP_COMMANDS_READ_VOICE_SETTING_MASK 0x04 -#define HCI_SUPP_COMMANDS_READ_VOICE_SETTING_OFF 9 -#define HCI_READ_VOICE_SETTING_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_VOICE_SETTING_OFF] & HCI_SUPP_COMMANDS_READ_VOICE_SETTING_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_MASK 0x08 -#define HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_OFF 9 -#define HCI_WRITE_VOICE_SETTING_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_OFF] & HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_MASK) - -#define HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_MASK 0x10 -#define HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_OFF 9 -#define HCI_READ_AUTO_FLUSH_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_MASK 0x20 -#define HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_OFF 9 -#define HCI_WRITE_AUTO_FLUSH_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_MASK) - -#define HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_MASK 0x40 -#define HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_OFF 9 -#define HCI_READ_NUM_BROAD_RETRANS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_OFF] & HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_MASK 0x80 -#define HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_OFF 9 -#define HCI_WRITE_NUM_BROAD_RETRANS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_OFF] & HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_MASK) - -#define HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_MASK 0x01 -#define HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_OFF 10 -#define HCI_READ_HOLD_MODE_ACTIVITY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_MASK 0x02 -#define HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_OFF 10 -#define HCI_WRITE_HOLD_MODE_ACTIVITY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_MASK) - -#define HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_MASK 0x04 -#define HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_OFF 10 -#define HCI_READ_TRANS_PWR_LEVEL_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_OFF] & HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_MASK) - -#define HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_MASK 0x08 -#define HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_OFF 10 -#define HCI_READ_SYNCH_FLOW_CTRL_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_MASK 0x10 -#define HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_OFF 10 -#define HCI_WRITE_SYNCH_FLOW_CTRL_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_MASK) - -#define HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_MASK 0x20 -#define HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_OFF 10 -#define HCI_SET_HOST_CTRLR_TO_HOST_FC_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_OFF] & HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_MASK) - -#define HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_MASK 0x40 -#define HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_OFF 10 -#define HCI_HOST_BUFFER_SIZE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_OFF] & HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_MASK) - -#define HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_MASK 0x80 -#define HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_OFF 10 -#define HCI_HOST_NUM_COMPLETED_PKTS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_OFF] & HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_MASK) - -#define HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_MASK 0x01 -#define HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_OFF 11 -#define HCI_READ_LINK_SUP_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_MASK 0x02 -#define HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_OFF 11 -#define HCI_WRITE_LINK_SUP_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_MASK) - -#define HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_MASK 0x04 -#define HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_OFF 11 -#define HCI_READ_NUM_SUPP_IAC_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_OFF] & HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_MASK) - -#define HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_MASK 0x08 -#define HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_OFF 11 -#define HCI_READ_CURRENT_IAC_LAP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_OFF] & HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_MASK 0x10 -#define HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_OFF 11 -#define HCI_WRITE_CURRENT_IAC_LAP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_OFF] & HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_MASK) - -#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_MASK 0x20 -#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_OFF 11 -#define HCI_READ_PAGE_SCAN_PER_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_MASK 0x40 -#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_OFF 11 -#define HCI_WRITE_PAGE_SCAN_PER_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_MASK) - -#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_MASK 0x80 -#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_OFF 11 -#define HCI_READ_PAGE_SCAN_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_MASK 0x01 -#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_OFF 12 -#define HCI_WRITE_PAGE_SCAN_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_MASK) - -#define HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_MASK 0x02 -#define HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_OFF 12 -#define HCI_SET_AFH_CHNL_CLASS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_OFF] & HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_MASK) - -#define HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_MASK 0x10 -#define HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_OFF 12 -#define HCI_READ_INQUIRY_SCAN_TYPE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_MASK 0x20 -#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_OFF 12 -#define HCI_WRITE_INQUIRY_SCAN_TYPE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_MASK) - -#define HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_MASK 0x40 -#define HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_OFF 12 -#define HCI_READ_INQUIRY_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_OFF] & HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_MASK 0x80 -#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_OFF 12 -#define HCI_WRITE_INQUIRY_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_MASK) - -#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_MASK 0x01 -#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_OFF 13 -#define HCI_READ_PAGE_SCAN_TYPE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_MASK 0x02 -#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_OFF 13 -#define HCI_WRITE_PAGE_SCAN_TYPE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_MASK) - -#define HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_MASK 0x04 -#define HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_OFF 13 -#define HCI_READ_AFH_CHNL_ASSESS_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_OFF] & HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_MASK 0x08 -#define HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_OFF 13 -#define HCI_WRITE_AFH_CHNL_ASSESS_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_MASK) - -#define HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_MASK 0x08 -#define HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_OFF 14 -#define HCI_READ_LOCAL_VER_INFO_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_MASK) - -#define HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_MASK 0x10 -#define HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_OFF 14 -#define HCI_READ_LOCAL_SUP_CMDS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_MASK) - -#define HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_MASK 0x20 -#define HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_OFF 14 -#define HCI_READ_LOCAL_SUPP_FEATURES_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_MASK) - -#define HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_MASK 0x40 -#define HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_OFF 14 -#define HCI_READ_LOCAL_EXT_FEATURES_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_MASK) - -#define HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_MASK 0x80 -#define HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_OFF 14 -#define HCI_READ_BUFFER_SIZE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_OFF] & HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_MASK) - -#define HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_MASK 0x01 -#define HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_OFF 15 -#define HCI_READ_COUNTRY_CODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_OFF] & HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_MASK) - -#define HCI_SUPP_COMMANDS_READ_BD_ADDR_MASK 0x02 -#define HCI_SUPP_COMMANDS_READ_BD_ADDR_OFF 15 -#define HCI_READ_BD_ADDR_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_BD_ADDR_OFF] & HCI_SUPP_COMMANDS_READ_BD_ADDR_MASK) - -#define HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_MASK 0x04 -#define HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_OFF 15 -#define HCI_READ_FAIL_CONTACT_CNTR_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_OFF] & HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_MASK) - -#define HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_MASK 0x08 -#define HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_OFF 15 -#define HCI_RESET_FAIL_CONTACT_CNTR_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_OFF] & HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_MASK) - -#define HCI_SUPP_COMMANDS_GET_LINK_QUALITY_MASK 0x10 -#define HCI_SUPP_COMMANDS_GET_LINK_QUALITY_OFF 15 -#define HCI_GET_LINK_QUALITY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_GET_LINK_QUALITY_OFF] & HCI_SUPP_COMMANDS_GET_LINK_QUALITY_MASK) - -#define HCI_SUPP_COMMANDS_READ_RSSI_MASK 0x20 -#define HCI_SUPP_COMMANDS_READ_RSSI_OFF 15 -#define HCI_READ_RSSI_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_RSSI_OFF] & HCI_SUPP_COMMANDS_READ_RSSI_MASK) - -#define HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_MASK 0x40 -#define HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_OFF 15 -#define HCI_READ_AFH_CH_MAP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_OFF] & HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_MASK) - -#define HCI_SUPP_COMMANDS_READ_BD_CLOCK_MASK 0x80 -#define HCI_SUPP_COMMANDS_READ_BD_CLOCK_OFF 15 -#define HCI_READ_BD_CLOCK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_BD_CLOCK_OFF] & HCI_SUPP_COMMANDS_READ_BD_CLOCK_MASK) - -#define HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_MASK 0x01 -#define HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_OFF 16 -#define HCI_READ_LOOPBACK_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_OFF] & HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_MASK 0x02 -#define HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_OFF 16 -#define HCI_WRITE_LOOPBACK_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_MASK) - -#define HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_MASK 0x04 -#define HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_OFF 16 -#define HCI_ENABLE_DEV_UNDER_TEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_OFF] & HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_MASK) - -#define HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_MASK 0x08 -#define HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_OFF 16 -#define HCI_SETUP_SYNCH_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_MASK) - -#define HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_MASK 0x10 -#define HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_OFF 16 -#define HCI_ACCEPT_SYNCH_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_MASK) - -#define HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_MASK 0x20 -#define HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_OFF 16 -#define HCI_REJECT_SYNCH_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_MASK) - -#define HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_MASK 0x01 -#define HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_OFF 17 -#define HCI_READ_EXT_INQUIRY_RESP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_OFF] & HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_MASK 0x02 -#define HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_OFF 17 -#define HCI_WRITE_EXT_INQUIRY_RESP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_OFF] & HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_MASK) - -#define HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_MASK 0x04 -#define HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_OFF 17 -#define HCI_REFRESH_ENCRYPTION_KEY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_OFF] & HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_MASK) - -/* Octet 17, bit 3 is reserved */ - -#define HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_MASK 0x10 -#define HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_OFF 17 -#define HCI_SNIFF_SUB_RATE_CMD_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_OFF] & HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_MASK) - -#define HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_MASK 0x20 -#define HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_OFF 17 -#define HCI_READ_SIMPLE_PAIRING_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_OFF] & HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_MASK 0x40 -#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_OFF 17 -#define HCI_WRITE_SIMPLE_PAIRING_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_MASK) - -#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_MASK 0x80 -#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_OFF 17 -#define HCI_READ_LOCAL_OOB_DATA_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_MASK) - -#define HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_MASK 0x01 -#define HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_OFF 18 -#define HCI_READ_INQUIRY_RESPONSE_TX_POWER_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_OFF] & HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_MASK 0x02 -#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_OFF 18 -#define HCI_WRITE_INQUIRY_RESPONSE_TX_POWER_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_OFF] & HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_MASK) - -#define HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK 0x04 -#define HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF 18 -#define HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF] & HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK 0x08 -#define HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF 18 -#define HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF] & HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK) - -#define HCI_SUPP_COMMANDS_IO_CAPABILITY_REQUEST_REPLY_MASK 0x80 -#define HCI_SUPP_COMMANDS_IO_CAPABILITY_REQUEST_REPLY_OFF 18 -#define HCI_IO_CAPABILITY_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_IO_CAPABILITY_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_IO_CAPABILITY_REQUEST_REPLY_MASK) - -#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_MASK 0x01 -#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_OFF 19 -#define HCI_USER_CONFIRMATION_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_MASK) - -#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_MASK 0x02 -#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_OFF 19 -#define HCI_USER_CONFIRMATION_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_MASK) - -#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_MASK 0x04 -#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_OFF 19 -#define HCI_USER_PASSKEY_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_MASK) - -#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_MASK 0x08 -#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_OFF 19 -#define HCI_USER_PASSKEY_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_MASK) - -#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_MASK 0x10 -#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_OFF 19 -#define HCI_REMOTE_OOB_DATA_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_MASK 0x20 -#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_OFF 19 -#define HCI_WRITE_SIMPLE_PAIRING_DBG_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_MASK) - -#define HCI_SUPP_COMMANDS_ENHANCED_FLUSH_MASK 0x40 -#define HCI_SUPP_COMMANDS_ENHANCED_FLUSH_OFF 19 -#define HCI_ENHANCED_FLUSH_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ENHANCED_FLUSH_OFF] & HCI_SUPP_COMMANDS_ENHANCED_FLUSH_MASK) - -#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_MASK 0x80 -#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_OFF 19 -#define HCI_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_MASK) - -/* Supported Commands (Byte 20) */ -#define HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_MASK 0x04 -#define HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_OFF 20 -#define HCI_SEND_NOTIF_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_OFF] & HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_MASK) - -#define HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_MASK 0x08 -#define HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_OFF 20 -#define HCI_IO_CAP_REQ_NEG_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_MASK) - -#define HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_MASK 0x10 -#define HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_OFF 20 -#define HCI_READ_ENCR_KEY_SIZE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_OFF] & HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_MASK) - -/* Supported Commands (Byte 21) */ -#define HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_MASK 0x01 -#define HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_OFF 21 -#define HCI_CREATE_PHYSICAL_LINK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_OFF] & HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_MASK) - -#define HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_MASK 0x02 -#define HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_OFF 21 -#define HCI_ACCEPT_PHYSICAL_LINK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_OFF] & HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_MASK) - -#define HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_MASK 0x04 -#define HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_OFF 21 -#define HCI_DISCONNECT_PHYSICAL_LINK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_OFF] & HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_MASK) - -#define HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_MASK 0x08 -#define HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_OFF 21 -#define HCI_CREATE_LOGICAL_LINK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_OFF] & HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_MASK) - -#define HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_MASK 0x10 -#define HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_OFF 21 -#define HCI_ACCEPT_LOGICAL_LINK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_OFF] & HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_MASK) - -#define HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_MASK 0x20 -#define HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_OFF 21 -#define HCI_DISCONNECT_LOGICAL_LINK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_OFF] & HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_MASK) - -#define HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_MASK 0x40 -#define HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_OFF 21 -#define HCI_LOGICAL_LINK_CANCEL_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_OFF] & HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_MASK) - -#define HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_MASK 0x80 -#define HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_OFF 21 -#define HCI_FLOW_SPEC_MODIFY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_OFF] & HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_MASK) - -/* Supported Commands (Byte 22) */ -#define HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK 0x01 -#define HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF 22 -#define HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF] & HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK 0x02 -#define HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF 22 -#define HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK) - -#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_MASK 0x04 -#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_OFF 22 -#define HCI_SET_EVENT_MASK_PAGE_2_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_OFF] & HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_MASK) - -#define HCI_SUPP_COMMANDS_READ_LOCATION_DATA_MASK 0x08 -#define HCI_SUPP_COMMANDS_READ_LOCATION_DATA_OFF 22 -#define HCI_READ_LOCATION_DATA_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCATION_DATA_OFF] & HCI_SUPP_COMMANDS_READ_LOCATION_DATA_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_MASK 0x10 -#define HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_OFF 22 -#define HCI_WRITE_LOCATION_DATA_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_OFF] & HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_MASK) - -#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_MASK 0x20 -#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_OFF 22 -#define HCI_READ_LOCAL_AMP_INFO_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_MASK) - -#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_MASK 0x40 -#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_OFF 22 -#define HCI_READ_LOCAL_AMP_ASSOC_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_MASK 0x80 -#define HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_OFF 22 -#define HCI_WRITE_REMOTE_AMP_ASSOC_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_OFF] & HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_MASK) - -/* Supported Commands (Byte 23) */ -#define HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_MASK 0x01 -#define HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_OFF 23 -#define HCI_READ_FLOW_CONTROL_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_OFF] & HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_MASK 0x02 -#define HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_OFF 23 -#define HCI_WRITE_FLOW_CONTROL_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_MASK) - -#define HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_MASK 0x04 -#define HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_OFF 23 -#define HCI_READ_DATA_BLOCK_SIZE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_OFF] & HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_MASK) - -#define HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_MASK 0x20 -#define HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_OFF 23 -#define HCI_ENABLE_AMP_RCVR_REPORTS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_OFF] & HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_MASK) - -#define HCI_SUPP_COMMANDS_AMP_TEST_END_MASK 0x40 -#define HCI_SUPP_COMMANDS_AMP_TEST_END_OFF 23 -#define HCI_AMP_TEST_END_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_AMP_TEST_END_OFF] & HCI_SUPP_COMMANDS_AMP_TEST_END_MASK) - -#define HCI_SUPP_COMMANDS_AMP_TEST_MASK 0x80 -#define HCI_SUPP_COMMANDS_AMP_TEST_OFF 23 -#define HCI_AMP_TEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_AMP_TEST_OFF] & HCI_SUPP_COMMANDS_AMP_TEST_MASK) - -/* Supported Commands (Byte 24) */ -#define HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_MASK 0x01 -#define HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_OFF 24 -#define HCI_READ_TRANSMIT_POWER_LEVEL_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_OFF] & HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_MASK) - -#define HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_MASK 0x04 -#define HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_OFF 24 -#define HCI_READ_BE_FLUSH_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_MASK 0x08 -#define HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_OFF 24 -#define HCI_WRITE_BE_FLUSH_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_MASK) - -#define HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_MASK 0x10 -#define HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_OFF 24 -#define HCI_SHORT_RANGE_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_OFF] & HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_MASK) - -/* LE commands TBD -** Supported Commands (Byte 24 continued) -** Supported Commands (Byte 25) -** Supported Commands (Byte 26) -** Supported Commands (Byte 27) -** Supported Commands (Byte 28) -*/ - -/* Supported Commands (Byte 29) */ -#define HCI_SUPP_COMMANDS_ENH_SETUP_SYNCH_CONN_MASK 0x08 -#define HCI_SUPP_COMMANDS_ENH_SETUP_SYNCH_CONN_OFF 29 -#define HCI_READ_ENH_SETUP_SYNCH_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ENH_SETUP_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_ENH_SETUP_SYNCH_CONN_MASK) - -#define HCI_SUPP_COMMANDS_ENH_ACCEPT_SYNCH_CONN_MASK 0x10 -#define HCI_SUPP_COMMANDS_ENH_ACCEPT_SYNCH_CONN_OFF 29 -#define HCI_READ_ENH_ACCEPT_SYNCH_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ENH_ACCEPT_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_ENH_ACCEPT_SYNCH_CONN_MASK) - -#define HCI_SUPP_COMMANDS_READ_LOCAL_CODECS_MASK 0x20 -#define HCI_SUPP_COMMANDS_READ_LOCAL_CODECS_OFF 29 -#define HCI_READ_LOCAL_CODECS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_CODECS_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_CODECS_MASK) - -#define HCI_SUPP_COMMANDS_SET_MWS_CHANN_PARAM_MASK 0x40 -#define HCI_SUPP_COMMANDS_SET_MWS_CHANN_PARAM_OFF 29 -#define HCI_SET_MWS_CHANNEL_PARAMETERS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_MWS_CHANN_PARAM_OFF] & HCI_SUPP_COMMANDS_SET_MWS_CHANN_PARAM_MASK) - -#define HCI_SUPP_COMMANDS_SET_EXT_FRAME_CONF_MASK 0x80 -#define HCI_SUPP_COMMANDS_SET_EXT_FRAME_CONF_OFF 29 -#define HCI_SET_EXTERNAL_FRAME_CONFIGURATION_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_EXT_FRAME_CONF_OFF] & HCI_SUPP_COMMANDS_SET_EXT_FRAME_CONF_MASK) - - -/* Supported Commands (Byte 30) */ -#define HCI_SUPP_COMMANDS_SET_MWS_SIGNALING_MASK 0x01 -#define HCI_SUPP_COMMANDS_SET_MWS_SIGNALING_OFF 30 -#define HCI_SET_MWS_SIGNALING_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_MWS_SIGNALING_OFF] & HCI_SUPP_COMMANDS_SET_MWS_SIGNALING_MASK) - -#define HCI_SUPP_COMMANDS_SET_MWS_TRANS_LAYER_MASK 0x02 -#define HCI_SUPP_COMMANDS_SET_MWS_TRANS_LAYER_OFF 30 -#define HCI_SET_MWS_TRANSPORT_LAYER_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_MWS_TRANS_LAYER_OFF] & HCI_SUPP_COMMANDS_SET_MWS_TRANS_LAYER_MASK) - -#define HCI_SUPP_COMMANDS_SET_MWS_SCAN_FREQ_TABLE_MASK 0x04 -#define HCI_SUPP_COMMANDS_SET_MWS_SCAN_FREQ_TABLE_OFF 30 -#define HCI_SET_MWS_SCAN_FREQUENCY_TABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_MWS_SCAN_FREQ_TABLE_OFF] & HCI_SUPP_COMMANDS_SET_MWS_SCAN_FREQ_TABLE_MASK) - -#define HCI_SUPP_COMMANDS_GET_TRANS_LAYER_CONF_MASK 0x08 -#define HCI_SUPP_COMMANDS_GET_TRANS_LAYER_CONF_OFF 30 -#define HCI_GET_MWS_TRANS_LAYER_CFG_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_GET_TRANS_LAYER_CONF_OFF] & HCI_SUPP_COMMANDS_GET_TRANS_LAYER_CONF_MASK) - -#define HCI_SUPP_COMMANDS_SET_MWS_PATTERN_CONF_MASK 0x10 -#define HCI_SUPP_COMMANDS_SET_MWS_PATTERN_CONF_OFF 30 -#define HCI_SET_MWS_PATTERN_CONFIGURATION_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_MWS_PATTERN_CONF_OFF] & HCI_SUPP_COMMANDS_SET_MWS_PATTERN_CONF_MASK) - -/* Supported Commands (Byte 30 bit 5) */ -#define HCI_SUPP_COMMANDS_SET_TRIG_CLK_CAP_MASK 0x20 -#define HCI_SUPP_COMMANDS_SET_TRIG_CLK_CAP_OFF 30 -#define HCI_SET_TRIG_CLK_CAP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_TRIG_CLK_CAP_OFF] & HCI_SUPP_COMMANDS_SET_TRIG_CLK_CAP_MASK) - - -/* Supported Commands (Byte 30 bit 6-7) */ -#define HCI_SUPP_COMMANDS_TRUNCATED_PAGE 0x06 -#define HCI_SUPP_COMMANDS_TRUNCATED_PAGE_OFF 30 -#define HCI_TRUNCATED_PAGE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_TRUNCATED_PAGE_OFF] & HCI_SUPP_COMMANDS_TRUNCATED_PAGE) - -#define HCI_SUPP_COMMANDS_TRUNCATED_PAGE_CANCEL 0x07 -#define HCI_SUPP_COMMANDS_TRUNCATED_PAGE_CANCEL_OFF 30 -#define HCI_TRUNCATED_PAGE_CANCEL_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_TRUNCATED_PAGE_CANCEL_OFF] & HCI_SUPP_COMMANDS_TRUNCATED_PAGE_CANCEL) - -/* Supported Commands (Byte 31 bit 6-7) */ -#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST 0x00 -#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_OFF 31 -#define HCI_SET_CONLESS_SLAVE_BRCST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_OFF] & HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST) - -#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_RECEIVE 0x01 -#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_RECEIVE_OFF 31 -#define HCI_SET_CONLESS_SLAVE_BRCST_RECEIVE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_RECEIVE_OFF] & HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_RECEIVE) - -#define HCI_SUPP_COMMANDS_START_SYNC_TRAIN 0x02 -#define HCI_SUPP_COMMANDS_START_SYNC_TRAIN_OFF 31 -#define HCI_START_SYNC_TRAIN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_START_SYNC_TRAIN_OFF] & HCI_SUPP_COMMANDS_START_SYNC_TRAIN) - -#define HCI_SUPP_COMMANDS_RECEIVE_SYNC_TRAIN 0x03 -#define HCI_SUPP_COMMANDS_RECEIVE_SYNC_TRAIN_OFF 31 -#define HCI_RECEIVE_SYNC_TRAIN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_RECEIVE_SYNC_TRAIN_OFF] & HCI_SUPP_COMMANDS_RECEIVE_SYNC_TRAIN) - -#define HCI_SUPP_COMMANDS_SET_RESERVED_LT_ADDR 0x04 -#define HCI_SUPP_COMMANDS_SET_RESERVED_LT_ADDR_OFF 31 -#define HCI_SET_RESERVED_LT_ADDR_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_RESERVED_LT_ADDR_OFF] & HCI_SUPP_COMMANDS_SET_RESERVED_LT_ADDR) - -#define HCI_SUPP_COMMANDS_DELETE_RESERVED_LT_ADDR 0x05 -#define HCI_SUPP_COMMANDS_DELETE_RESERVED_LT_ADDR_OFF 31 -#define HCI_DELETE_RESERVED_LT_ADDR_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_DELETE_RESERVED_LT_ADDR_OFF] & HCI_SUPP_COMMANDS_DELETE_RESERVED_LT_ADDR) - -#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_DATA 0x06 -#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_DATA_OFF 31 -#define HCI_SET_CONLESS_SLAVE_BRCST_DATA_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_DATA_OFF] & HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_DATA) - -#define HCI_SUPP_COMMANDS_READ_SYNC_TRAIN_PARAM 0x07 -#define HCI_SUPP_COMMANDS_READ_SYNC_TRAIN_PARAM_OFF 31 -#define HCI_READ_SYNC_TRAIN_PARAM_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_SYNC_TRAIN_PARAM_OFF] & HCI_SUPP_COMMANDS_READ_SYNC_TRAIN_PARAM) - -/* Supported Commands (Byte 32 bit 0) */ -#define HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM 0x00 -#define HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM_OFF 32 -#define HCI_WRITE_SYNC_TRAIN_PARAM_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM_OFF] & HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM) - -#define HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_MASK 0x02 -#define HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_OFF 32 -#define HCI_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_MASK) - -#define HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_MASK 0x04 -#define HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_OFF 32 -#define HCI_READ_SECURE_CONNS_SUPPORT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_OFF] & HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_MASK 0x08 -#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_OFF 32 -#define HCI_WRITE_SECURE_CONNS_SUPPORT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_OFF] & HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_MASK) - -#define HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_MASK 0x10 -#define HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_OFF 32 -#define HCI_READ_AUTHENT_PAYLOAD_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_MASK 0x20 -#define HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_OFF 32 -#define HCI_WRITE_AUTHENT_PAYLOAD_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_MASK) - -#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_MASK 0x40 -#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_OFF 32 -#define HCI_READ_LOCAL_OOB_EXTENDED_DATA_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_MASK) - -#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_MASK 0x80 -#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_OFF 32 -#define HCI_WRITE_SECURE_CONNECTIONS_TEST_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_MASK) - -/* supported LE remote control connection parameter request reply */ -#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_MASK 0x10 -#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_OFF 33 -#define HCI_LE_RC_CONN_PARAM_UPD_RPY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_OFF] & HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_MASK) - -#define HCI_SUPP_COMMANDS_RLE_RC_CONN_PARAM_UPD_NEG_RPY_MASK 0x20 -#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_NEG_RPY_OFF 33 -#define HCI_LE_RC_CONN_PARAM_UPD_NEG_RPY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_NEG_RPY_OFF] & HCI_SUPP_COMMANDS_RLE_RC_CONN_PARAM_UPD_NEG_RPY_MASK) - -#endif - diff --git a/tools/sdk/include/bluedroid/stack/hcimsgs.h b/tools/sdk/include/bluedroid/stack/hcimsgs.h deleted file mode 100644 index c2067a2f..00000000 --- a/tools/sdk/include/bluedroid/stack/hcimsgs.h +++ /dev/null @@ -1,811 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef HCIMSGS_H -#define HCIMSGS_H - -#include "common/bt_target.h" -#include "stack/hcidefs.h" -#include "stack/bt_types.h" - -void bte_main_hci_send(BT_HDR *p_msg, UINT16 event); -void bte_main_lpm_allow_bt_device_sleep(void); - -/* Message by message.... */ - -BOOLEAN btsnd_hcic_inquiry(const LAP inq_lap, UINT8 duration, - UINT8 response_cnt); - -#define HCIC_PARAM_SIZE_INQUIRY 5 - - -#define HCIC_INQ_INQ_LAP_OFF 0 -#define HCIC_INQ_DUR_OFF 3 -#define HCIC_INQ_RSP_CNT_OFF 4 -/* Inquiry */ - -/* Inquiry Cancel */ -BOOLEAN btsnd_hcic_inq_cancel(void); - -#define HCIC_PARAM_SIZE_INQ_CANCEL 0 - -/* Periodic Inquiry Mode */ -BOOLEAN btsnd_hcic_per_inq_mode(UINT16 max_period, UINT16 min_period, - const LAP inq_lap, UINT8 duration, - UINT8 response_cnt); - -#define HCIC_PARAM_SIZE_PER_INQ_MODE 9 - -#define HCI_PER_INQ_MAX_INTRVL_OFF 0 -#define HCI_PER_INQ_MIN_INTRVL_OFF 2 -#define HCI_PER_INQ_INQ_LAP_OFF 4 -#define HCI_PER_INQ_DURATION_OFF 7 -#define HCI_PER_INQ_RSP_CNT_OFF 8 -/* Periodic Inquiry Mode */ - -/* Exit Periodic Inquiry Mode */ -BOOLEAN btsnd_hcic_exit_per_inq(void); - -#define HCIC_PARAM_SIZE_EXIT_PER_INQ 0 -/* Create Connection */ -BOOLEAN btsnd_hcic_create_conn(BD_ADDR dest, UINT16 packet_types, - UINT8 page_scan_rep_mode, - UINT8 page_scan_mode, - UINT16 clock_offset, - UINT8 allow_switch); - -#define HCIC_PARAM_SIZE_CREATE_CONN 13 - -#define HCIC_CR_CONN_BD_ADDR_OFF 0 -#define HCIC_CR_CONN_PKT_TYPES_OFF 6 -#define HCIC_CR_CONN_REP_MODE_OFF 8 -#define HCIC_CR_CONN_PAGE_SCAN_MODE_OFF 9 -#define HCIC_CR_CONN_CLK_OFF_OFF 10 -#define HCIC_CR_CONN_ALLOW_SWITCH_OFF 12 -/* Create Connection */ - -/* Disconnect */ -BOOLEAN btsnd_hcic_disconnect(UINT16 handle, UINT8 reason); - -#define HCIC_PARAM_SIZE_DISCONNECT 3 - -#define HCI_DISC_HANDLE_OFF 0 -#define HCI_DISC_REASON_OFF 2 -/* Disconnect */ - -#if BTM_SCO_INCLUDED == TRUE -/* Add SCO Connection */ -BOOLEAN btsnd_hcic_add_SCO_conn (UINT16 handle, UINT16 packet_types); -#endif /* BTM_SCO_INCLUDED */ - -#define HCIC_PARAM_SIZE_ADD_SCO_CONN 4 - -#define HCI_ADD_SCO_HANDLE_OFF 0 -#define HCI_ADD_SCO_PACKET_TYPES_OFF 2 -/* Add SCO Connection */ - -/* Create Connection Cancel */ -BOOLEAN btsnd_hcic_create_conn_cancel(BD_ADDR dest); - -#define HCIC_PARAM_SIZE_CREATE_CONN_CANCEL 6 - -#define HCIC_CR_CONN_CANCEL_BD_ADDR_OFF 0 -/* Create Connection Cancel */ - -/* Accept Connection Request */ -BOOLEAN btsnd_hcic_accept_conn (BD_ADDR bd_addr, UINT8 role); - -#define HCIC_PARAM_SIZE_ACCEPT_CONN 7 - -#define HCI_ACC_CONN_BD_ADDR_OFF 0 -#define HCI_ACC_CONN_ROLE_OFF 6 -/* Accept Connection Request */ - -/* Reject Connection Request */ -BOOLEAN btsnd_hcic_reject_conn (BD_ADDR bd_addr, UINT8 reason); - -#define HCIC_PARAM_SIZE_REJECT_CONN 7 - -#define HCI_REJ_CONN_BD_ADDR_OFF 0 -#define HCI_REJ_CONN_REASON_OFF 6 -/* Reject Connection Request */ - -/* Link Key Request Reply */ -BOOLEAN btsnd_hcic_link_key_req_reply (BD_ADDR bd_addr, - LINK_KEY link_key); - -#define HCIC_PARAM_SIZE_LINK_KEY_REQ_REPLY 22 - -#define HCI_LINK_KEY_REPLY_BD_ADDR_OFF 0 -#define HCI_LINK_KEY_REPLY_LINK_KEY_OFF 6 -/* Link Key Request Reply */ - -/* Link Key Request Neg Reply */ -BOOLEAN btsnd_hcic_link_key_neg_reply (BD_ADDR bd_addr); - -#define HCIC_PARAM_SIZE_LINK_KEY_NEG_REPLY 6 - -#define HCI_LINK_KEY_NEG_REP_BD_ADR_OFF 0 -/* Link Key Request Neg Reply */ - -/* PIN Code Request Reply */ -BOOLEAN btsnd_hcic_pin_code_req_reply (BD_ADDR bd_addr, - UINT8 pin_code_len, - PIN_CODE pin_code); - -#define HCIC_PARAM_SIZE_PIN_CODE_REQ_REPLY 23 - -#define HCI_PIN_CODE_REPLY_BD_ADDR_OFF 0 -#define HCI_PIN_CODE_REPLY_PIN_LEN_OFF 6 -#define HCI_PIN_CODE_REPLY_PIN_CODE_OFF 7 -/* PIN Code Request Reply */ - -/* Link Key Request Neg Reply */ -BOOLEAN btsnd_hcic_pin_code_neg_reply (BD_ADDR bd_addr); - -#define HCIC_PARAM_SIZE_PIN_CODE_NEG_REPLY 6 - -#define HCI_PIN_CODE_NEG_REP_BD_ADR_OFF 0 -/* Link Key Request Neg Reply */ - -/* Change Connection Type */ -BOOLEAN btsnd_hcic_change_conn_type (UINT16 handle, UINT16 packet_types); - -#define HCIC_PARAM_SIZE_CHANGE_CONN_TYPE 4 - -#define HCI_CHNG_PKT_TYPE_HANDLE_OFF 0 -#define HCI_CHNG_PKT_TYPE_PKT_TYPE_OFF 2 -/* Change Connection Type */ - -#define HCIC_PARAM_SIZE_CMD_HANDLE 2 - -#define HCI_CMD_HANDLE_HANDLE_OFF 0 - -BOOLEAN btsnd_hcic_auth_request (UINT16 handle); /* Authentication Request */ - -/* Set Connection Encryption */ -BOOLEAN btsnd_hcic_set_conn_encrypt (UINT16 handle, BOOLEAN enable); -#define HCIC_PARAM_SIZE_SET_CONN_ENCRYPT 3 - - -#define HCI_SET_ENCRYPT_HANDLE_OFF 0 -#define HCI_SET_ENCRYPT_ENABLE_OFF 2 -/* Set Connection Encryption */ - -/* Remote Name Request */ -BOOLEAN btsnd_hcic_rmt_name_req (BD_ADDR bd_addr, - UINT8 page_scan_rep_mode, - UINT8 page_scan_mode, - UINT16 clock_offset); - -#define HCIC_PARAM_SIZE_RMT_NAME_REQ 10 - -#define HCI_RMT_NAME_BD_ADDR_OFF 0 -#define HCI_RMT_NAME_REP_MODE_OFF 6 -#define HCI_RMT_NAME_PAGE_SCAN_MODE_OFF 7 -#define HCI_RMT_NAME_CLK_OFF_OFF 8 -/* Remote Name Request */ - -/* Remote Name Request Cancel */ -BOOLEAN btsnd_hcic_rmt_name_req_cancel(BD_ADDR bd_addr); - -#define HCIC_PARAM_SIZE_RMT_NAME_REQ_CANCEL 6 - -#define HCI_RMT_NAME_CANCEL_BD_ADDR_OFF 0 -/* Remote Name Request Cancel */ - -BOOLEAN btsnd_hcic_rmt_features_req(UINT16 handle); /* Remote Features Request */ - -/* Remote Extended Features */ -BOOLEAN btsnd_hcic_rmt_ext_features(UINT16 handle, UINT8 page_num); - -#define HCIC_PARAM_SIZE_RMT_EXT_FEATURES 3 - -#define HCI_RMT_EXT_FEATURES_HANDLE_OFF 0 -#define HCI_RMT_EXT_FEATURES_PAGE_NUM_OFF 2 -/* Remote Extended Features */ - - -BOOLEAN btsnd_hcic_rmt_ver_req(UINT16 handle); /* Remote Version Info Request */ -BOOLEAN btsnd_hcic_read_rmt_clk_offset(UINT16 handle); /* Remote Clock Offset */ -BOOLEAN btsnd_hcic_read_lmp_handle(UINT16 handle); /* Remote LMP Handle */ - -BOOLEAN btsnd_hcic_setup_esco_conn (UINT16 handle, - UINT32 tx_bw, UINT32 rx_bw, - UINT16 max_latency, UINT16 voice, - UINT8 retrans_effort, - UINT16 packet_types); -#define HCIC_PARAM_SIZE_SETUP_ESCO 17 - -#define HCI_SETUP_ESCO_HANDLE_OFF 0 -#define HCI_SETUP_ESCO_TX_BW_OFF 2 -#define HCI_SETUP_ESCO_RX_BW_OFF 6 -#define HCI_SETUP_ESCO_MAX_LAT_OFF 10 -#define HCI_SETUP_ESCO_VOICE_OFF 12 -#define HCI_SETUP_ESCO_RETRAN_EFF_OFF 14 -#define HCI_SETUP_ESCO_PKT_TYPES_OFF 15 - - -BOOLEAN btsnd_hcic_accept_esco_conn (BD_ADDR bd_addr, - UINT32 tx_bw, UINT32 rx_bw, - UINT16 max_latency, - UINT16 content_fmt, - UINT8 retrans_effort, - UINT16 packet_types); -#define HCIC_PARAM_SIZE_ACCEPT_ESCO 21 - -#define HCI_ACCEPT_ESCO_BDADDR_OFF 0 -#define HCI_ACCEPT_ESCO_TX_BW_OFF 6 -#define HCI_ACCEPT_ESCO_RX_BW_OFF 10 -#define HCI_ACCEPT_ESCO_MAX_LAT_OFF 14 -#define HCI_ACCEPT_ESCO_VOICE_OFF 16 -#define HCI_ACCEPT_ESCO_RETRAN_EFF_OFF 18 -#define HCI_ACCEPT_ESCO_PKT_TYPES_OFF 19 - - -BOOLEAN btsnd_hcic_reject_esco_conn (BD_ADDR bd_addr, UINT8 reason); -#define HCIC_PARAM_SIZE_REJECT_ESCO 7 - -#define HCI_REJECT_ESCO_BDADDR_OFF 0 -#define HCI_REJECT_ESCO_REASON_OFF 6 - -/* Hold Mode */ -BOOLEAN btsnd_hcic_hold_mode(UINT16 handle, UINT16 max_hold_period, - UINT16 min_hold_period); - -#define HCIC_PARAM_SIZE_HOLD_MODE 6 - -#define HCI_HOLD_MODE_HANDLE_OFF 0 -#define HCI_HOLD_MODE_MAX_PER_OFF 2 -#define HCI_HOLD_MODE_MIN_PER_OFF 4 -/* Hold Mode */ - -/* Sniff Mode */ -BOOLEAN btsnd_hcic_sniff_mode(UINT16 handle, - UINT16 max_sniff_period, - UINT16 min_sniff_period, - UINT16 sniff_attempt, - UINT16 sniff_timeout); - -#define HCIC_PARAM_SIZE_SNIFF_MODE 10 - - -#define HCI_SNIFF_MODE_HANDLE_OFF 0 -#define HCI_SNIFF_MODE_MAX_PER_OFF 2 -#define HCI_SNIFF_MODE_MIN_PER_OFF 4 -#define HCI_SNIFF_MODE_ATTEMPT_OFF 6 -#define HCI_SNIFF_MODE_TIMEOUT_OFF 8 -/* Sniff Mode */ - -BOOLEAN btsnd_hcic_exit_sniff_mode(UINT16 handle); /* Exit Sniff Mode */ - -/* Park Mode */ -BOOLEAN btsnd_hcic_park_mode (UINT16 handle, - UINT16 beacon_max_interval, - UINT16 beacon_min_interval); - -#define HCIC_PARAM_SIZE_PARK_MODE 6 - -#define HCI_PARK_MODE_HANDLE_OFF 0 -#define HCI_PARK_MODE_MAX_PER_OFF 2 -#define HCI_PARK_MODE_MIN_PER_OFF 4 -/* Park Mode */ - -BOOLEAN btsnd_hcic_exit_park_mode(UINT16 handle); /* Exit Park Mode */ - -/* QoS Setup */ -BOOLEAN btsnd_hcic_qos_setup (UINT16 handle, UINT8 flags, - UINT8 service_type, - UINT32 token_rate, UINT32 peak, - UINT32 latency, UINT32 delay_var); - -#define HCIC_PARAM_SIZE_QOS_SETUP 20 - -#define HCI_QOS_HANDLE_OFF 0 -#define HCI_QOS_FLAGS_OFF 2 -#define HCI_QOS_SERVICE_TYPE_OFF 3 -#define HCI_QOS_TOKEN_RATE_OFF 4 -#define HCI_QOS_PEAK_BANDWIDTH_OFF 8 -#define HCI_QOS_LATENCY_OFF 12 -#define HCI_QOS_DELAY_VAR_OFF 16 -/* QoS Setup */ - -/* Switch Role Request */ -BOOLEAN btsnd_hcic_switch_role (BD_ADDR bd_addr, UINT8 role); - -#define HCIC_PARAM_SIZE_SWITCH_ROLE 7 - -#define HCI_SWITCH_BD_ADDR_OFF 0 -#define HCI_SWITCH_ROLE_OFF 6 -/* Switch Role Request */ - -/* Write Policy Settings */ -BOOLEAN btsnd_hcic_write_policy_set(UINT16 handle, UINT16 settings); - -#define HCIC_PARAM_SIZE_WRITE_POLICY_SET 4 - -#define HCI_WRITE_POLICY_HANDLE_OFF 0 -#define HCI_WRITE_POLICY_SETTINGS_OFF 2 -/* Write Policy Settings */ - -/* Write Default Policy Settings */ -BOOLEAN btsnd_hcic_write_def_policy_set(UINT16 settings); - -#define HCIC_PARAM_SIZE_WRITE_DEF_POLICY_SET 2 - -#define HCI_WRITE_DEF_POLICY_SETTINGS_OFF 0 -/* Write Default Policy Settings */ - -/****************************************** -** Lisbon Features -*******************************************/ -#if BTM_SSR_INCLUDED == TRUE -/* Sniff Subrating */ -BOOLEAN btsnd_hcic_sniff_sub_rate(UINT16 handle, UINT16 max_lat, - UINT16 min_remote_lat, - UINT16 min_local_lat); - -#define HCIC_PARAM_SIZE_SNIFF_SUB_RATE 8 - -#define HCI_SNIFF_SUB_RATE_HANDLE_OFF 0 -#define HCI_SNIFF_SUB_RATE_MAX_LAT_OFF 2 -#define HCI_SNIFF_SUB_RATE_MIN_REM_LAT_OFF 4 -#define HCI_SNIFF_SUB_RATE_MIN_LOC_LAT_OFF 6 -/* Sniff Subrating */ - -#else /* BTM_SSR_INCLUDED == FALSE */ - -#define btsnd_hcic_sniff_sub_rate(handle, max_lat, min_remote_lat, min_local_lat) FALSE - -#endif /* BTM_SSR_INCLUDED */ - -/* Extended Inquiry Response */ -void btsnd_hcic_write_ext_inquiry_response(void *buffer, UINT8 fec_req); - -#define HCIC_PARAM_SIZE_EXT_INQ_RESP 241 - -#define HCIC_EXT_INQ_RESP_FEC_OFF 0 -#define HCIC_EXT_INQ_RESP_RESPONSE 1 -/* IO Capabilities Response */ -BOOLEAN btsnd_hcic_io_cap_req_reply (BD_ADDR bd_addr, UINT8 capability, - UINT8 oob_present, UINT8 auth_req); - -#define HCIC_PARAM_SIZE_IO_CAP_RESP 9 - -#define HCI_IO_CAP_BD_ADDR_OFF 0 -#define HCI_IO_CAPABILITY_OFF 6 -#define HCI_IO_CAP_OOB_DATA_OFF 7 -#define HCI_IO_CAP_AUTH_REQ_OFF 8 - -/* IO Capabilities Req Neg Reply */ -BOOLEAN btsnd_hcic_io_cap_req_neg_reply (BD_ADDR bd_addr, UINT8 err_code); - -#define HCIC_PARAM_SIZE_IO_CAP_NEG_REPLY 7 - -#define HCI_IO_CAP_NR_BD_ADDR_OFF 0 -#define HCI_IO_CAP_NR_ERR_CODE 6 - -/* Read Local OOB Data */ -BOOLEAN btsnd_hcic_read_local_oob_data (void); - -#define HCIC_PARAM_SIZE_R_LOCAL_OOB 0 - - -BOOLEAN btsnd_hcic_user_conf_reply (BD_ADDR bd_addr, BOOLEAN is_yes); - -#define HCIC_PARAM_SIZE_UCONF_REPLY 6 - -#define HCI_USER_CONF_BD_ADDR_OFF 0 - - -BOOLEAN btsnd_hcic_user_passkey_reply (BD_ADDR bd_addr, UINT32 value); - -#define HCIC_PARAM_SIZE_U_PKEY_REPLY 10 - -#define HCI_USER_PASSKEY_BD_ADDR_OFF 0 -#define HCI_USER_PASSKEY_VALUE_OFF 6 - - -BOOLEAN btsnd_hcic_user_passkey_neg_reply (BD_ADDR bd_addr); - -#define HCIC_PARAM_SIZE_U_PKEY_NEG_REPLY 6 - -#define HCI_USER_PASSKEY_NEG_BD_ADDR_OFF 0 - -/* Remote OOB Data Request Reply */ -BOOLEAN btsnd_hcic_rem_oob_reply (BD_ADDR bd_addr, UINT8 *p_c, - UINT8 *p_r); - -#define HCIC_PARAM_SIZE_REM_OOB_REPLY 38 - -#define HCI_REM_OOB_DATA_BD_ADDR_OFF 0 -#define HCI_REM_OOB_DATA_C_OFF 6 -#define HCI_REM_OOB_DATA_R_OFF 22 - -/* Remote OOB Data Request Negative Reply */ -BOOLEAN btsnd_hcic_rem_oob_neg_reply (BD_ADDR bd_addr); - -#define HCIC_PARAM_SIZE_REM_OOB_NEG_REPLY 6 - -#define HCI_REM_OOB_DATA_NEG_BD_ADDR_OFF 0 - -/* Read Tx Power Level */ -BOOLEAN btsnd_hcic_read_inq_tx_power (void); - -#define HCIC_PARAM_SIZE_R_TX_POWER 0 - -/* Read Default Erroneous Data Reporting */ -BOOLEAN btsnd_hcic_read_default_erroneous_data_rpt (void); - -#define HCIC_PARAM_SIZE_R_ERR_DATA_RPT 0 - -#if L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE -BOOLEAN btsnd_hcic_enhanced_flush (UINT16 handle, UINT8 packet_type); - -#define HCIC_PARAM_SIZE_ENHANCED_FLUSH 3 -#endif - - -BOOLEAN btsnd_hcic_send_keypress_notif (BD_ADDR bd_addr, UINT8 notif); - -#define HCIC_PARAM_SIZE_SEND_KEYPRESS_NOTIF 7 - -#define HCI_SEND_KEYPRESS_NOTIF_BD_ADDR_OFF 0 -#define HCI_SEND_KEYPRESS_NOTIF_NOTIF_OFF 6 - -/**** end of Simple Pairing Commands ****/ - -/* Store Current Settings */ -#define MAX_FILT_COND (sizeof (BD_ADDR) + 1) - -BOOLEAN btsnd_hcic_set_event_filter(UINT8 filt_type, - UINT8 filt_cond_type, - UINT8 *filt_cond, - UINT8 filt_cond_len); - -#define HCIC_PARAM_SIZE_SET_EVT_FILTER 9 - -#define HCI_FILT_COND_FILT_TYPE_OFF 0 -#define HCI_FILT_COND_COND_TYPE_OFF 1 -#define HCI_FILT_COND_FILT_OFF 2 -/* Set Event Filter */ - -/* Delete Stored Key */ -BOOLEAN btsnd_hcic_delete_stored_key (BD_ADDR bd_addr, BOOLEAN delete_all_flag); - -#define HCIC_PARAM_SIZE_DELETE_STORED_KEY 7 - -#define HCI_DELETE_KEY_BD_ADDR_OFF 0 -#define HCI_DELETE_KEY_ALL_FLAG_OFF 6 -/* Delete Stored Key */ - -/* Change Local Name */ -BOOLEAN btsnd_hcic_change_name(BD_NAME name); - -#define HCIC_PARAM_SIZE_CHANGE_NAME BD_NAME_LEN - -#define HCI_CHANGE_NAME_NAME_OFF 0 -/* Change Local Name */ - - -#define HCIC_PARAM_SIZE_READ_CMD 0 - -#define HCIC_PARAM_SIZE_WRITE_PARAM1 1 - -#define HCIC_WRITE_PARAM1_PARAM_OFF 0 - -#define HCIC_PARAM_SIZE_WRITE_PARAM2 2 - -#define HCIC_WRITE_PARAM2_PARAM_OFF 0 - -#define HCIC_PARAM_SIZE_WRITE_PARAM3 3 - -#define HCIC_WRITE_PARAM3_PARAM_OFF 0 - -#define HCIC_PARAM_SIZE_SET_AFH_CHANNELS 10 - -BOOLEAN btsnd_hcic_write_pin_type(UINT8 type); /* Write PIN Type */ -BOOLEAN btsnd_hcic_write_auto_accept(UINT8 flag); /* Write Auto Accept */ -BOOLEAN btsnd_hcic_read_name (void); /* Read Local Name */ -BOOLEAN btsnd_hcic_write_page_tout(UINT16 timeout); /* Write Page Timout */ -BOOLEAN btsnd_hcic_write_scan_enable(UINT8 flag); /* Write Scan Enable */ -BOOLEAN btsnd_hcic_write_pagescan_cfg(UINT16 interval, - UINT16 window); /* Write Page Scan Activity */ - -#define HCIC_PARAM_SIZE_WRITE_PAGESCAN_CFG 4 - -#define HCI_SCAN_CFG_INTERVAL_OFF 0 -#define HCI_SCAN_CFG_WINDOW_OFF 2 -/* Write Page Scan Activity */ - -/* Write Inquiry Scan Activity */ -BOOLEAN btsnd_hcic_write_inqscan_cfg(UINT16 interval, UINT16 window); - -#define HCIC_PARAM_SIZE_WRITE_INQSCAN_CFG 4 - -#define HCI_SCAN_CFG_INTERVAL_OFF 0 -#define HCI_SCAN_CFG_WINDOW_OFF 2 -/* Write Inquiry Scan Activity */ - -BOOLEAN btsnd_hcic_write_auth_enable(UINT8 flag); /* Write Authentication Enable */ -BOOLEAN btsnd_hcic_write_dev_class(DEV_CLASS dev); /* Write Class of Device */ -BOOLEAN btsnd_hcic_write_voice_settings(UINT16 flags); /* Write Voice Settings */ - -/* Host Controller to Host flow control */ -#define HCI_HOST_FLOW_CTRL_OFF 0 -#define HCI_HOST_FLOW_CTRL_ACL_ON 1 -#define HCI_HOST_FLOW_CTRL_SCO_ON 2 -#define HCI_HOST_FLOW_CTRL_BOTH_ON 3 - -BOOLEAN btsnd_hcic_write_auto_flush_tout(UINT16 handle, - UINT16 timeout); /* Write Retransmit Timout */ - -#define HCIC_PARAM_SIZE_WRITE_AUTO_FLUSH_TOUT 4 - -#define HCI_FLUSH_TOUT_HANDLE_OFF 0 -#define HCI_FLUSH_TOUT_TOUT_OFF 2 - -BOOLEAN btsnd_hcic_read_tx_power(UINT16 handle, UINT8 type); /* Read Tx Power */ - -#define HCIC_PARAM_SIZE_READ_TX_POWER 3 - -#define HCI_READ_TX_POWER_HANDLE_OFF 0 -#define HCI_READ_TX_POWER_TYPE_OFF 2 - -/* Read transmit power level parameter */ -#define HCI_READ_CURRENT 0x00 -#define HCI_READ_MAXIMUM 0x01 - -BOOLEAN btsnd_hcic_host_num_xmitted_pkts (UINT8 num_handles, - UINT16 *handle, - UINT16 *num_pkts); /* Set Host Buffer Size */ - -#define HCIC_PARAM_SIZE_NUM_PKTS_DONE_SIZE sizeof(btmsg_hcic_num_pkts_done_t) - -#define MAX_DATA_HANDLES 10 - -#define HCI_PKTS_DONE_NUM_HANDLES_OFF 0 -#define HCI_PKTS_DONE_HANDLE_OFF 1 -#define HCI_PKTS_DONE_NUM_PKTS_OFF 3 - -/* Write Link Supervision Timeout */ -BOOLEAN btsnd_hcic_write_link_super_tout(UINT8 local_controller_id, UINT16 handle, UINT16 timeout); - -#define HCIC_PARAM_SIZE_WRITE_LINK_SUPER_TOUT 4 - -#define HCI_LINK_SUPER_TOUT_HANDLE_OFF 0 -#define HCI_LINK_SUPER_TOUT_TOUT_OFF 2 -/* Write Link Supervision Timeout */ - -BOOLEAN btsnd_hcic_write_cur_iac_lap (UINT8 num_cur_iac, - LAP *const iac_lap); /* Write Current IAC LAP */ - -#define MAX_IAC_LAPS 0x40 - -#define HCI_WRITE_IAC_LAP_NUM_OFF 0 -#define HCI_WRITE_IAC_LAP_LAP_OFF 1 -/* Write Current IAC LAP */ - -BOOLEAN btsnd_hcic_get_link_quality (UINT16 handle); /* Get Link Quality */ -BOOLEAN btsnd_hcic_read_rssi (UINT16 handle); /* Read RSSI */ -BOOLEAN btsnd_hcic_enable_test_mode (void); /* Enable Device Under Test Mode */ -BOOLEAN btsnd_hcic_write_pagescan_type(UINT8 type); /* Write Page Scan Type */ -BOOLEAN btsnd_hcic_write_inqscan_type(UINT8 type); /* Write Inquiry Scan Type */ -BOOLEAN btsnd_hcic_write_inquiry_mode(UINT8 type); /* Write Inquiry Mode */ - -#define HCI_DATA_HANDLE_MASK 0x0FFF - -#define HCID_GET_HANDLE_EVENT(p) (UINT16)((*((UINT8 *)((p) + 1) + p->offset) + \ - (*((UINT8 *)((p) + 1) + p->offset + 1) << 8))) - -#define HCID_GET_HANDLE(u16) (UINT16)((u16) & HCI_DATA_HANDLE_MASK) - -#define HCI_DATA_EVENT_MASK 3 -#define HCI_DATA_EVENT_OFFSET 12 -#define HCID_GET_EVENT(u16) (UINT8)(((u16) >> HCI_DATA_EVENT_OFFSET) & HCI_DATA_EVENT_MASK) - -#define HCI_DATA_BCAST_MASK 3 -#define HCI_DATA_BCAST_OFFSET 10 -#define HCID_GET_BCAST(u16) (UINT8)(((u16) >> HCI_DATA_BCAST_OFFSET) & HCI_DATA_BCAST_MASK) - -#define HCID_GET_ACL_LEN(p) (UINT16)((*((UINT8 *)((p) + 1) + p->offset + 2) + \ - (*((UINT8 *)((p) + 1) + p->offset + 3) << 8))) - -#define HCID_HEADER_SIZE 4 - -#define HCID_GET_SCO_LEN(p) (*((UINT8 *)((p) + 1) + p->offset + 2)) - -void btsnd_hcic_vendor_spec_cmd (void *buffer, UINT16 opcode, - UINT8 len, UINT8 *p_data, - void *p_cmd_cplt_cback); - -#if (BLE_INCLUDED == TRUE) -/******************************************************************************** -** BLE Commands -** Note: "local_controller_id" is for transport, not counted in HCI message size -*********************************************************************************/ -#define HCIC_BLE_RAND_DI_SIZE 8 -#define HCIC_BLE_ENCRYT_KEY_SIZE 16 -#define HCIC_BLE_IRK_SIZE 16 - -#define HCIC_PARAM_SIZE_SET_USED_FEAT_CMD 8 -#define HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD 6 -#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS 15 -#define HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP 31 -#define HCIC_PARAM_SIZE_WRITE_ADV_ENABLE 1 -#define HCIC_PARAM_SIZE_BLE_WRITE_SCAN_PARAM 7 -#define HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE 2 -#define HCIC_PARAM_SIZE_BLE_CREATE_LL_CONN 25 -#define HCIC_PARAM_SIZE_BLE_CREATE_CONN_CANCEL 0 -#define HCIC_PARAM_SIZE_CLEAR_WHITE_LIST 0 -#define HCIC_PARAM_SIZE_ADD_WHITE_LIST 7 -#define HCIC_PARAM_SIZE_REMOVE_WHITE_LIST 7 -#define HCIC_PARAM_SIZE_BLE_UPD_LL_CONN_PARAMS 14 -#define HCIC_PARAM_SIZE_SET_HOST_CHNL_CLASS 5 -#define HCIC_PARAM_SIZE_READ_CHNL_MAP 2 -#define HCIC_PARAM_SIZE_BLE_READ_REMOTE_FEAT 2 -#define HCIC_PARAM_SIZE_BLE_ENCRYPT 32 -#define HCIC_PARAM_SIZE_BLE_RAND 0 -#define HCIC_PARAM_SIZE_WRITE_LE_HOST_SUPPORTED 2 - -#define HCIC_BLE_RAND_DI_SIZE 8 -#define HCIC_BLE_ENCRYT_KEY_SIZE 16 -#define HCIC_PARAM_SIZE_BLE_START_ENC (4 + HCIC_BLE_RAND_DI_SIZE + HCIC_BLE_ENCRYT_KEY_SIZE) -#define HCIC_PARAM_SIZE_LTK_REQ_REPLY (2 + HCIC_BLE_ENCRYT_KEY_SIZE) -#define HCIC_PARAM_SIZE_LTK_REQ_NEG_REPLY 2 -#define HCIC_BLE_CHNL_MAP_SIZE 5 -#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA 31 - -#define HCIC_PARAM_SIZE_BLE_ADD_DEV_RESOLVING_LIST (7 + HCIC_BLE_IRK_SIZE * 2) -#define HCIC_PARAM_SIZE_BLE_RM_DEV_RESOLVING_LIST 7 -#define HCIC_PARAM_SIZE_BLE_CLEAR_RESOLVING_LIST 0 -#define HCIC_PARAM_SIZE_BLE_READ_RESOLVING_LIST_SIZE 0 -#define HCIC_PARAM_SIZE_BLE_READ_RESOLVABLE_ADDR_PEER 7 -#define HCIC_PARAM_SIZE_BLE_READ_RESOLVABLE_ADDR_LOCAL 7 -#define HCIC_PARAM_SIZE_BLE_SET_ADDR_RESOLUTION_ENABLE 1 -#define HCIC_PARAM_SIZE_BLE_SET_RAND_PRIV_ADDR_TIMOUT 2 -#define HCIC_PARAM_SIZE_BLE_SET_DATA_LENGTH 6 -#define HCIC_PARAM_SIZE_BLE_WRITE_EXTENDED_SCAN_PARAM 11 - -/* ULP HCI command */ -BOOLEAN btsnd_hcic_ble_set_evt_mask (BT_EVENT_MASK event_mask); - -BOOLEAN btsnd_hcic_ble_read_buffer_size (void); - -BOOLEAN btsnd_hcic_ble_read_local_spt_feat (void); - -BOOLEAN btsnd_hcic_ble_set_local_used_feat (UINT8 feat_set[8]); - -BOOLEAN btsnd_hcic_ble_set_random_addr (BD_ADDR random_addr); - -BOOLEAN btsnd_hcic_ble_write_adv_params (UINT16 adv_int_min, UINT16 adv_int_max, - UINT8 adv_type, UINT8 addr_type_own, - UINT8 addr_type_dir, BD_ADDR direct_bda, - UINT8 channel_map, UINT8 adv_filter_policy); - -BOOLEAN btsnd_hcic_ble_read_adv_chnl_tx_power (void); - -BOOLEAN btsnd_hcic_ble_set_adv_data (UINT8 data_len, UINT8 *p_data); - -BOOLEAN btsnd_hcic_ble_set_scan_rsp_data (UINT8 data_len, UINT8 *p_scan_rsp); - -BOOLEAN btsnd_hcic_ble_set_adv_enable (UINT8 adv_enable); - -BOOLEAN btsnd_hcic_ble_set_scan_params (UINT8 scan_type, - UINT16 scan_int, UINT16 scan_win, - UINT8 addr_type, UINT8 scan_filter_policy); - -BOOLEAN btsnd_hcic_ble_set_scan_enable (UINT8 scan_enable, UINT8 duplicate); - -BOOLEAN btsnd_hcic_ble_create_ll_conn (UINT16 scan_int, UINT16 scan_win, - UINT8 init_filter_policy, UINT8 addr_type_peer, BD_ADDR bda_peer, UINT8 addr_type_own, - UINT16 conn_int_min, UINT16 conn_int_max, UINT16 conn_latency, UINT16 conn_timeout, - UINT16 min_ce_len, UINT16 max_ce_len); - -BOOLEAN btsnd_hcic_ble_create_conn_cancel (void); - -BOOLEAN btsnd_hcic_ble_read_white_list_size (void); - -BOOLEAN btsnd_hcic_ble_clear_white_list (void); - -BOOLEAN btsnd_hcic_ble_add_white_list (UINT8 addr_type, BD_ADDR bda); - -BOOLEAN btsnd_hcic_ble_remove_from_white_list (UINT8 addr_type, BD_ADDR bda); - -BOOLEAN btsnd_hcic_ble_upd_ll_conn_params (UINT16 handle, UINT16 conn_int_min, UINT16 conn_int_max, - UINT16 conn_latency, UINT16 conn_timeout, UINT16 min_len, UINT16 max_len); - -BOOLEAN btsnd_hcic_ble_set_host_chnl_class (UINT8 chnl_map[HCIC_BLE_CHNL_MAP_SIZE]); - -BOOLEAN btsnd_hcic_ble_read_chnl_map (UINT16 handle); - -BOOLEAN btsnd_hcic_ble_read_remote_feat ( UINT16 handle); - -BOOLEAN btsnd_hcic_ble_encrypt (UINT8 *key, UINT8 key_len, UINT8 *plain_text, UINT8 pt_len, void *p_cmd_cplt_cback); - -BOOLEAN btsnd_hcic_ble_rand (void *p_cmd_cplt_cback); - -BOOLEAN btsnd_hcic_ble_start_enc ( UINT16 handle, - UINT8 rand[HCIC_BLE_RAND_DI_SIZE], - UINT16 ediv, UINT8 ltk[HCIC_BLE_ENCRYT_KEY_SIZE]); - -BOOLEAN btsnd_hcic_ble_ltk_req_reply (UINT16 handle, UINT8 ltk[HCIC_BLE_ENCRYT_KEY_SIZE]); - -BOOLEAN btsnd_hcic_ble_ltk_req_neg_reply (UINT16 handle); - -BOOLEAN btsnd_hcic_ble_read_supported_states (void); - -BOOLEAN btsnd_hcic_ble_write_host_supported (UINT8 le_host_spt, UINT8 simul_le_host_spt); - -BOOLEAN btsnd_hcic_ble_read_host_supported (void); - -BOOLEAN btsnd_hcic_ble_receiver_test(UINT8 rx_freq); - -BOOLEAN btsnd_hcic_ble_transmitter_test(UINT8 tx_freq, UINT8 test_data_len, - UINT8 payload); -BOOLEAN btsnd_hcic_ble_test_end(void); - -#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) - -#define HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY 14 -BOOLEAN btsnd_hcic_ble_rc_param_req_reply(UINT16 handle, - UINT16 conn_int_min, UINT16 conn_int_max, - UINT16 conn_latency, UINT16 conn_timeout, - UINT16 min_ce_len, UINT16 max_ce_len); - -#define HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY 3 -BOOLEAN btsnd_hcic_ble_rc_param_req_neg_reply(UINT16 handle, UINT8 reason); - -#endif /* BLE_LLT_INCLUDED */ - -BOOLEAN btsnd_hcic_ble_set_data_length(UINT16 conn_handle, UINT16 tx_octets, - UINT16 tx_time); - -BOOLEAN btsnd_hcic_ble_add_device_resolving_list (UINT8 addr_type_peer, - BD_ADDR bda_peer, - UINT8 irk_peer[HCIC_BLE_IRK_SIZE], - UINT8 irk_local[HCIC_BLE_IRK_SIZE]); - -BOOLEAN btsnd_hcic_ble_rm_device_resolving_list (UINT8 addr_type_peer, - BD_ADDR bda_peer); - -BOOLEAN btsnd_hcic_ble_clear_resolving_list (void); - -BOOLEAN btsnd_hcic_ble_read_resolvable_addr_peer (UINT8 addr_type_peer, - BD_ADDR bda_peer); - -BOOLEAN btsnd_hcic_ble_read_resolvable_addr_local (UINT8 addr_type_peer, - BD_ADDR bda_peer); - -BOOLEAN btsnd_hcic_ble_set_addr_resolution_enable (UINT8 addr_resolution_enable); - -BOOLEAN btsnd_hcic_ble_set_rand_priv_addr_timeout (UINT16 rpa_timout); - -#endif /* BLE_INCLUDED */ - -BOOLEAN btsnd_hcic_read_authenticated_payload_tout(UINT16 handle); - -BOOLEAN btsnd_hcic_write_authenticated_payload_tout(UINT16 handle, - UINT16 timeout); - -#define HCIC_PARAM_SIZE_WRITE_AUTHENT_PAYLOAD_TOUT 4 - -#define HCI__WRITE_AUTHENT_PAYLOAD_TOUT_HANDLE_OFF 0 -#define HCI__WRITE_AUTHENT_PAYLOAD_TOUT_TOUT_OFF 2 - -#endif diff --git a/tools/sdk/include/bluedroid/stack/hiddefs.h b/tools/sdk/include/bluedroid/stack/hiddefs.h deleted file mode 100644 index 99d2c3c1..00000000 --- a/tools/sdk/include/bluedroid/stack/hiddefs.h +++ /dev/null @@ -1,163 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2002-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains HID protocol definitions - * - ******************************************************************************/ - -#ifndef HIDDEFS_H -#define HIDDEFS_H -#include "common/bt_target.h" -#if (HID_HOST_INCLUDED == TRUE) - -#if (SDP_INCLUDED == TRUE) -#include "stack/sdp_api.h" -#endif ///SDP_INCLUDED == TRUE -/* -** tHID_STATUS: HID result codes, returned by HID and device and host functions. -*/ -enum { - HID_SUCCESS, - HID_ERR_NOT_REGISTERED, - HID_ERR_ALREADY_REGISTERED, - HID_ERR_NO_RESOURCES, - HID_ERR_NO_CONNECTION, - HID_ERR_INVALID_PARAM, - HID_ERR_UNSUPPORTED, - HID_ERR_UNKNOWN_COMMAND, - HID_ERR_CONGESTED, - HID_ERR_CONN_IN_PROCESS, - HID_ERR_ALREADY_CONN, - HID_ERR_DISCONNECTING, - HID_ERR_SET_CONNABLE_FAIL, - /* Device specific error codes */ - HID_ERR_HOST_UNKNOWN, - HID_ERR_L2CAP_FAILED, - HID_ERR_AUTH_FAILED, - HID_ERR_SDP_BUSY, - HID_ERR_GATT, - - HID_ERR_INVALID = 0xFF -}; - -typedef UINT8 tHID_STATUS; - -#define HID_L2CAP_CONN_FAIL (0x0100) /* Connection Attempt was made but failed */ -#define HID_L2CAP_REQ_FAIL (0x0200) /* L2CAP_ConnectReq API failed */ -#define HID_L2CAP_CFG_FAIL (0x0400) /* L2CAP Configuration was rejected by peer */ - - - -/* Define the HID transaction types -*/ -#define HID_TRANS_HANDSHAKE (0) -#define HID_TRANS_CONTROL (1) -#define HID_TRANS_GET_REPORT (4) -#define HID_TRANS_SET_REPORT (5) -#define HID_TRANS_GET_PROTOCOL (6) -#define HID_TRANS_SET_PROTOCOL (7) -#define HID_TRANS_GET_IDLE (8) -#define HID_TRANS_SET_IDLE (9) -#define HID_TRANS_DATA (10) -#define HID_TRANS_DATAC (11) - -#define HID_GET_TRANS_FROM_HDR(x) ((x >> 4) & 0x0f) -#define HID_GET_PARAM_FROM_HDR(x) (x & 0x0f) -#define HID_BUILD_HDR(t,p) (UINT8)((t << 4) | (p & 0x0f)) - - -/* Parameters for Handshake -*/ -#define HID_PAR_HANDSHAKE_RSP_SUCCESS (0) -#define HID_PAR_HANDSHAKE_RSP_NOT_READY (1) -#define HID_PAR_HANDSHAKE_RSP_ERR_INVALID_REP_ID (2) -#define HID_PAR_HANDSHAKE_RSP_ERR_UNSUPPORTED_REQ (3) -#define HID_PAR_HANDSHAKE_RSP_ERR_INVALID_PARAM (4) -#define HID_PAR_HANDSHAKE_RSP_ERR_UNKNOWN (14) -#define HID_PAR_HANDSHAKE_RSP_ERR_FATAL (15) - - -/* Parameters for Control -*/ -#define HID_PAR_CONTROL_NOP (0) -#define HID_PAR_CONTROL_HARD_RESET (1) -#define HID_PAR_CONTROL_SOFT_RESET (2) -#define HID_PAR_CONTROL_SUSPEND (3) -#define HID_PAR_CONTROL_EXIT_SUSPEND (4) -#define HID_PAR_CONTROL_VIRTUAL_CABLE_UNPLUG (5) - - -/* Different report types in get, set, data -*/ -#define HID_PAR_REP_TYPE_MASK (0x03) -#define HID_PAR_REP_TYPE_OTHER (0x00) -#define HID_PAR_REP_TYPE_INPUT (0x01) -#define HID_PAR_REP_TYPE_OUTPUT (0x02) -#define HID_PAR_REP_TYPE_FEATURE (0x03) - -/* Parameters for Get Report -*/ - -/* Buffer size in two bytes after Report ID */ -#define HID_PAR_GET_REP_BUFSIZE_FOLLOWS (0x08) - - -/* Parameters for Protocol Type -*/ -#define HID_PAR_PROTOCOL_MASK (0x01) -#define HID_PAR_PROTOCOL_REPORT (0x01) -#define HID_PAR_PROTOCOL_BOOT_MODE (0x00) - -#define HID_PAR_REP_TYPE_MASK (0x03) - -/* Descriptor types in the SDP record -*/ -#define HID_SDP_DESCRIPTOR_REPORT (0x22) -#define HID_SDP_DESCRIPTOR_PHYSICAL (0x23) - -typedef struct desc_info { - UINT16 dl_len; - UINT8 *dsc_list; -} tHID_DEV_DSCP_INFO; - -#define HID_SSR_PARAM_INVALID 0xffff - -typedef struct sdp_info { - char svc_name[HID_MAX_SVC_NAME_LEN]; /*Service Name */ - char svc_descr[HID_MAX_SVC_DESCR_LEN]; /*Service Description*/ - char prov_name[HID_MAX_PROV_NAME_LEN]; /*Provider Name.*/ - UINT16 rel_num; /*Release Number */ - UINT16 hpars_ver; /*HID Parser Version.*/ - UINT16 ssr_max_latency; /* HIDSSRHostMaxLatency value, if HID_SSR_PARAM_INVALID not used*/ - UINT16 ssr_min_tout; /* HIDSSRHostMinTimeout value, if HID_SSR_PARAM_INVALID not used* */ - UINT8 sub_class; /*Device Subclass.*/ - UINT8 ctry_code; /*Country Code.*/ - UINT16 sup_timeout;/* Supervisory Timeout */ - - tHID_DEV_DSCP_INFO dscp_info; /* Descriptor list and Report list to be set in the SDP record. - This parameter is used if HID_DEV_USE_GLB_SDP_REC is set to FALSE.*/ -#if(SDP_INCLUDED == TRUE) - tSDP_DISC_REC *p_sdp_layer_rec; -#endif ///SDP_INCLUDED == TRUE -} tHID_DEV_SDP_INFO; - -#endif ///HID_HOST_INCLUDED == TRUE -#endif - diff --git a/tools/sdk/include/bluedroid/stack/hidh_api.h b/tools/sdk/include/bluedroid/stack/hidh_api.h deleted file mode 100644 index 3211138c..00000000 --- a/tools/sdk/include/bluedroid/stack/hidh_api.h +++ /dev/null @@ -1,238 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2002-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef HIDH_API_H -#define HIDH_API_H - -#include "stack/hiddefs.h" -#include "stack/sdp_api.h" - -#if (HID_HOST_INCLUDED == TRUE) -/***************************************************************************** -** Constants -*****************************************************************************/ - -enum { - HID_SDP_NO_SERV_UUID = (SDP_ILLEGAL_PARAMETER + 1), - HID_SDP_MANDATORY_MISSING -}; - -/* Attributes mask values to be used in HID_HostAddDev API */ -#define HID_VIRTUAL_CABLE 0x0001 -#define HID_NORMALLY_CONNECTABLE 0x0002 -#define HID_RECONN_INIT 0x0004 -#define HID_SDP_DISABLE 0x0008 -#define HID_BATTERY_POWER 0x0010 -#define HID_REMOTE_WAKE 0x0020 -#define HID_SUP_TOUT_AVLBL 0x0040 -#define HID_SSR_MAX_LATENCY 0x0080 -#define HID_SSR_MIN_TOUT 0x0100 - -#define HID_SEC_REQUIRED 0x8000 -#define HID_ATTR_MASK_IGNORE 0 - - -/***************************************************************************** -** Type Definitions -*****************************************************************************/ - -typedef void (tHID_HOST_SDP_CALLBACK) (UINT16 result, UINT16 attr_mask, - tHID_DEV_SDP_INFO *sdp_rec ); - -/* HID-HOST returns the events in the following table to the application via tHID_HOST_DEV_CALLBACK -HID_HDEV_EVT_OPEN Connected to device with Interrupt and Control Channels in OPEN state. - Data = NA -HID_HDEV_EVT_CLOSE Connection with device is closed. Data=reason code. -HID_HDEV_EVT_RETRYING Lost connection is being re-connected. - Data=Retrial number -HID_HDEV_EVT_IN_REPORT Device sent an input report Data=Report Type pdata= pointer to BT_HDR - (GKI buffer having report data.) -HID_HDEV_EVT_HANDSHAKE Device sent SET_REPORT Data=Result-code pdata=NA. -HID_HDEV_EVT_VC_UNPLUG Device sent Virtual Unplug Data=NA. pdata=NA. -*/ - -enum { - HID_HDEV_EVT_OPEN, - HID_HDEV_EVT_CLOSE, - HID_HDEV_EVT_RETRYING, - HID_HDEV_EVT_INTR_DATA, - HID_HDEV_EVT_INTR_DATC, - HID_HDEV_EVT_CTRL_DATA, - HID_HDEV_EVT_CTRL_DATC, - HID_HDEV_EVT_HANDSHAKE, - HID_HDEV_EVT_VC_UNPLUG -}; -typedef void (tHID_HOST_DEV_CALLBACK) (UINT8 dev_handle, - BD_ADDR addr, - UINT8 event, /* Event from HID-DEVICE. */ - UINT32 data, /* Integer data corresponding to the event.*/ - BT_HDR *p_buf ); /* Pointer data corresponding to the event. */ - - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/******************************************************************************* -** -** Function HID_HostGetSDPRecord -** -** Description This function reads the device SDP record. -** -** Returns tHID_STATUS -** -*******************************************************************************/ -extern tHID_STATUS HID_HostGetSDPRecord (BD_ADDR addr, - tSDP_DISCOVERY_DB *p_db, - UINT32 db_len, - tHID_HOST_SDP_CALLBACK *sdp_cback ); - -/******************************************************************************* -** -** Function HID_HostRegister -** -** Description This function registers HID-Host with lower layers. -** -** Returns tHID_STATUS -** -*******************************************************************************/ -extern tHID_STATUS HID_HostRegister (tHID_HOST_DEV_CALLBACK *dev_cback); - -/******************************************************************************* -** -** Function HID_HostDeregister -** -** Description This function is called when the host is about power down. -** -** Returns tHID_STATUS -** -*******************************************************************************/ -extern tHID_STATUS HID_HostDeregister(void); - -/******************************************************************************* -** -** Function HID_HostAddDev -** -** Description This is called so HID-host may manage this device. -** -** Returns tHID_STATUS -** -*******************************************************************************/ -extern tHID_STATUS HID_HostAddDev (BD_ADDR addr, UINT16 attr_mask, - UINT8 *handle ); - -/******************************************************************************* -** -** Function HID_HostRemoveDev -** -** Description This removes the device from list devices that host has to manage. -** -** Returns tHID_STATUS -** -*******************************************************************************/ -extern tHID_STATUS HID_HostRemoveDev (UINT8 dev_handle ); - -/******************************************************************************* -** -** Function HID_HostOpenDev -** -** Description This function is called when the user wants to initiate a -** connection attempt to a device. -** -** Returns void -** -*******************************************************************************/ -extern tHID_STATUS HID_HostOpenDev (UINT8 dev_handle ); - -/******************************************************************************* -** -** Function HID_HostWriteDev -** -** Description This function is called when the host has a report to send. -** -** Returns void -** -*******************************************************************************/ -extern tHID_STATUS HID_HostWriteDev(UINT8 dev_handle, UINT8 t_type, - UINT8 param, UINT16 data, - UINT8 report_id, BT_HDR *pbuf); - -/******************************************************************************* -** -** Function HID_HostCloseDev -** -** Description This function disconnects the device. -** -** Returns void -** -*******************************************************************************/ -extern tHID_STATUS HID_HostCloseDev(UINT8 dev_handle ); - -/******************************************************************************* -** Function HID_HostInit -** -** Description This function initializes the control block and trace variable -** -** Returns void -*******************************************************************************/ -extern void HID_HostInit(void); - -/******************************************************************************* -** Function HID_HostSetSecurityLevel -** -** Description This function sets the security level for the devices which -** are marked by application as requiring security -** -** Returns tHID_STATUS -*******************************************************************************/ -extern tHID_STATUS HID_HostSetSecurityLevel( char serv_name[], UINT8 sec_lvl ); - -/******************************************************************************* -** -** Function hid_known_hid_device -** -** Description This function checks if this device is of type HID Device -** -** Returns TRUE if device exists else FALSE -** -*******************************************************************************/ -BOOLEAN hid_known_hid_device (BD_ADDR bd_addr); - - -/******************************************************************************* -** -** Function HID_HostSetTraceLevel -** -** Description This function sets the trace level for HID Host. If called with -** a value of 0xFF, it simply reads the current trace level. -** -** Returns the new (current) trace level -** -*******************************************************************************/ -extern UINT8 HID_HostSetTraceLevel (UINT8 new_level); - -#ifdef __cplusplus -} -#endif - -#endif ///HID_HOST_INCLUDED == TRUE - -#endif /* HIDH_API_H */ diff --git a/tools/sdk/include/bluedroid/stack/l2c_api.h b/tools/sdk/include/bluedroid/stack/l2c_api.h deleted file mode 100644 index 147ed6c7..00000000 --- a/tools/sdk/include/bluedroid/stack/l2c_api.h +++ /dev/null @@ -1,1237 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * this file contains the L2CAP API definitions - * - ******************************************************************************/ -#ifndef L2C_API_H -#define L2C_API_H - -#include - -#include "common/bt_target.h" -#include "stack/l2cdefs.h" -#include "stack/hcidefs.h" - -/***************************************************************************** -** Constants -*****************************************************************************/ - -/* Define the minimum offset that L2CAP needs in a buffer. This is made up of -** HCI type(1), len(2), handle(2), L2CAP len(2) and CID(2) => 9 -*/ -#define L2CAP_MIN_OFFSET 13 /* plus control(2), SDU length(2) */ - -/* Minimum offset for broadcast needs another two bytes for the PSM */ -#define L2CAP_BCST_MIN_OFFSET 11 - -/* ping result codes */ -#define L2CAP_PING_RESULT_OK 0 /* Ping reply received OK */ -#define L2CAP_PING_RESULT_NO_LINK 1 /* Link could not be setup */ -#define L2CAP_PING_RESULT_NO_RESP 2 /* Remote L2CAP did not reply */ - -/* result code for L2CA_DataWrite() */ -#define L2CAP_DW_FAILED FALSE -#define L2CAP_DW_SUCCESS TRUE -#define L2CAP_DW_CONGESTED 2 - -/* Values for priority parameter to L2CA_SetAclPriority */ -#define L2CAP_PRIORITY_NORMAL 0 -#define L2CAP_PRIORITY_HIGH 1 - -/* Values for priority parameter to L2CA_SetTxPriority */ -#define L2CAP_CHNL_PRIORITY_HIGH 0 -#define L2CAP_CHNL_PRIORITY_MEDIUM 1 -#define L2CAP_CHNL_PRIORITY_LOW 2 - -typedef UINT8 tL2CAP_CHNL_PRIORITY; - -/* Values for Tx/Rx data rate parameter to L2CA_SetChnlDataRate */ -#define L2CAP_CHNL_DATA_RATE_HIGH 3 -#define L2CAP_CHNL_DATA_RATE_MEDIUM 2 -#define L2CAP_CHNL_DATA_RATE_LOW 1 -#define L2CAP_CHNL_DATA_RATE_NO_TRAFFIC 0 - -typedef UINT8 tL2CAP_CHNL_DATA_RATE; - -/* Data Packet Flags (bits 2-15 are reserved) */ -/* layer specific 14-15 bits are used for FCR SAR */ -#define L2CAP_FLUSHABLE_MASK 0x0003 -#define L2CAP_FLUSHABLE_CH_BASED 0x0000 -#define L2CAP_FLUSHABLE_PKT 0x0001 -#define L2CAP_NON_FLUSHABLE_PKT 0x0002 - - -/* L2CA_FlushChannel num_to_flush definitions */ -#define L2CAP_FLUSH_CHANS_ALL 0xffff -#define L2CAP_FLUSH_CHANS_GET 0x0000 - - -/* special CID for Multi-AV for reporting congestion */ -#define L2CAP_MULTI_AV_CID 0 - -/* length of the HCI header block */ -/* HCI header(4) + SNK count(1) + FCR bits(1) + AV data length(2) */ -#define L2CAP_MULTI_AV_HCI_HDR_LEN 8 - -/* length of padding for 4 bytes align */ -#define L2CAP_MULTI_AV_PADDING_LEN 2 - -/* length of the HCI header block with padding for FCR */ -/* HCI header(4) + SNK count(1) + FCR bits(1) + AV data length(2) + padding(2) */ -#define L2CAP_MULTI_AV_HCI_HDR_LEN_WITH_PADDING 10 - -/* length of the L2CAP header block */ -/* HCI header(4) + L2CAP header(4) + padding(4) or control word(2) + FCS(2) */ -#define L2CAP_MULTI_AV_L2C_HDR_LEN 12 - -/* definition used for L2CA_SetDesireRole */ -#define L2CAP_ROLE_SLAVE HCI_ROLE_SLAVE -#define L2CAP_ROLE_MASTER HCI_ROLE_MASTER -#define L2CAP_ROLE_ALLOW_SWITCH 0x80 /* set this bit to allow switch at create conn */ -#define L2CAP_ROLE_DISALLOW_SWITCH 0x40 /* set this bit to disallow switch at create conn */ -#define L2CAP_ROLE_CHECK_SWITCH 0xC0 - - -/* Values for 'allowed_modes' field passed in structure tL2CAP_ERTM_INFO -*/ -#define L2CAP_FCR_CHAN_OPT_BASIC (1 << L2CAP_FCR_BASIC_MODE) -#define L2CAP_FCR_CHAN_OPT_ERTM (1 << L2CAP_FCR_ERTM_MODE) -#define L2CAP_FCR_CHAN_OPT_STREAM (1 << L2CAP_FCR_STREAM_MODE) - -#define L2CAP_FCR_CHAN_OPT_ALL_MASK (L2CAP_FCR_CHAN_OPT_BASIC | L2CAP_FCR_CHAN_OPT_ERTM | L2CAP_FCR_CHAN_OPT_STREAM) - -/* Validity check for PSM. PSM values must be odd. Also, all PSM values must -** be assigned such that the least significant bit of the most sigificant -** octet equals zero. -*/ -#define L2C_INVALID_PSM(psm) (((psm) & 0x0101) != 0x0001) -#define L2C_IS_VALID_PSM(psm) (((psm) & 0x0101) == 0x0001) -#define L2C_IS_VALID_LE_PSM(psm) (((psm) > 0x0000) && ((psm) < 0x0100)) - - -/***************************************************************************** -** Type Definitions -*****************************************************************************/ - -typedef struct { -#define L2CAP_FCR_BASIC_MODE 0x00 -#define L2CAP_FCR_ERTM_MODE 0x03 -#define L2CAP_FCR_STREAM_MODE 0x04 - - UINT8 mode; - - UINT8 tx_win_sz; - UINT8 max_transmit; - UINT16 rtrans_tout; - UINT16 mon_tout; - UINT16 mps; -} tL2CAP_FCR_OPTS; - -/* Define a structure to hold the configuration parameters. Since the -** parameters are optional, for each parameter there is a boolean to -** use to signify its presence or absence. -*/ -typedef struct { - UINT16 result; /* Only used in confirm messages */ - BOOLEAN mtu_present; - UINT16 mtu; - BOOLEAN qos_present; - FLOW_SPEC qos; - BOOLEAN flush_to_present; - UINT16 flush_to; - BOOLEAN fcr_present; - tL2CAP_FCR_OPTS fcr; - BOOLEAN fcs_present; /* Optionally bypasses FCS checks */ - UINT8 fcs; /* '0' if desire is to bypass FCS, otherwise '1' */ - BOOLEAN ext_flow_spec_present; - tHCI_EXT_FLOW_SPEC ext_flow_spec; - UINT16 flags; /* bit 0: 0-no continuation, 1-continuation */ -} tL2CAP_CFG_INFO; - -/* Define a structure to hold the configuration parameter for LE L2CAP connection -** oriented channels. -*/ -typedef struct -{ - UINT16 mtu; - UINT16 mps; - UINT16 credits; -} tL2CAP_LE_CFG_INFO; - - -/* L2CAP channel configured field bitmap */ -#define L2CAP_CH_CFG_MASK_MTU 0x0001 -#define L2CAP_CH_CFG_MASK_QOS 0x0002 -#define L2CAP_CH_CFG_MASK_FLUSH_TO 0x0004 -#define L2CAP_CH_CFG_MASK_FCR 0x0008 -#define L2CAP_CH_CFG_MASK_FCS 0x0010 -#define L2CAP_CH_CFG_MASK_EXT_FLOW_SPEC 0x0020 - -typedef UINT16 tL2CAP_CH_CFG_BITS; - -/********************************* -** Callback Functions Prototypes -**********************************/ - -/* Connection indication callback prototype. Parameters are -** BD Address of remote -** Local CID assigned to the connection -** PSM that the remote wants to connect to -** Identifier that the remote sent -*/ -typedef void (tL2CA_CONNECT_IND_CB) (BD_ADDR, UINT16, UINT16, UINT8); - - -/* Connection confirmation callback prototype. Parameters are -** Local CID -** Result - 0 = connected, non-zero means failure reason -*/ -typedef void (tL2CA_CONNECT_CFM_CB) (UINT16, UINT16); - - -/* Connection pending callback prototype. Parameters are -** Local CID -*/ -typedef void (tL2CA_CONNECT_PND_CB) (UINT16); - - -/* Configuration indication callback prototype. Parameters are -** Local CID assigned to the connection -** Pointer to configuration info -*/ -typedef void (tL2CA_CONFIG_IND_CB) (UINT16, tL2CAP_CFG_INFO *); - - -/* Configuration confirm callback prototype. Parameters are -** Local CID assigned to the connection -** Pointer to configuration info -*/ -typedef void (tL2CA_CONFIG_CFM_CB) (UINT16, tL2CAP_CFG_INFO *); - - -/* Disconnect indication callback prototype. Parameters are -** Local CID -** Boolean whether upper layer should ack this -*/ -typedef void (tL2CA_DISCONNECT_IND_CB) (UINT16, BOOLEAN); - - -/* Disconnect confirm callback prototype. Parameters are -** Local CID -** Result -*/ -typedef void (tL2CA_DISCONNECT_CFM_CB) (UINT16, UINT16); - - -/* QOS Violation indication callback prototype. Parameters are -** BD Address of violating device -*/ -typedef void (tL2CA_QOS_VIOLATION_IND_CB) (BD_ADDR); - - -/* Data received indication callback prototype. Parameters are -** Local CID -** Address of buffer -*/ -typedef void (tL2CA_DATA_IND_CB) (UINT16, BT_HDR *); - - -/* Echo response callback prototype. Note that this is not included in the -** registration information, but is passed to L2CAP as part of the API to -** actually send an echo request. Parameters are -** Result -*/ -typedef void (tL2CA_ECHO_RSP_CB) (UINT16); - - -/* Callback function prototype to pass broadcom specific echo response */ -/* to the upper layer */ -typedef void (tL2CA_ECHO_DATA_CB) (BD_ADDR, UINT16, UINT8 *); - - -/* Congestion status callback protype. This callback is optional. If -** an application tries to send data when the transmit queue is full, -** the data will anyways be dropped. The parameter is: -** Local CID -** TRUE if congested, FALSE if uncongested -*/ -typedef void (tL2CA_CONGESTION_STATUS_CB) (UINT16, BOOLEAN); - -/* Callback prototype for number of packets completed events. -** This callback notifies the application when Number of Completed Packets -** event has been received. -** This callback is originally designed for 3DG devices. -** The parameter is: -** peer BD_ADDR -*/ -typedef void (tL2CA_NOCP_CB) (BD_ADDR); - -/* Transmit complete callback protype. This callback is optional. If -** set, L2CAP will call it when packets are sent or flushed. If the -** count is 0xFFFF, it means all packets are sent for that CID (eRTM -** mode only). The parameters are: -** Local CID -** Number of SDUs sent or dropped -*/ -typedef void (tL2CA_TX_COMPLETE_CB) (UINT16, UINT16); - -/* Define the structure that applications use to register with -** L2CAP. This structure includes callback functions. All functions -** MUST be provided, with the exception of the "connect pending" -** callback and "congestion status" callback. -*/ -typedef struct { - tL2CA_CONNECT_IND_CB *pL2CA_ConnectInd_Cb; - tL2CA_CONNECT_CFM_CB *pL2CA_ConnectCfm_Cb; - tL2CA_CONNECT_PND_CB *pL2CA_ConnectPnd_Cb; - tL2CA_CONFIG_IND_CB *pL2CA_ConfigInd_Cb; - tL2CA_CONFIG_CFM_CB *pL2CA_ConfigCfm_Cb; - tL2CA_DISCONNECT_IND_CB *pL2CA_DisconnectInd_Cb; - tL2CA_DISCONNECT_CFM_CB *pL2CA_DisconnectCfm_Cb; - tL2CA_QOS_VIOLATION_IND_CB *pL2CA_QoSViolationInd_Cb; - tL2CA_DATA_IND_CB *pL2CA_DataInd_Cb; - tL2CA_CONGESTION_STATUS_CB *pL2CA_CongestionStatus_Cb; - tL2CA_TX_COMPLETE_CB *pL2CA_TxComplete_Cb; - -} tL2CAP_APPL_INFO; - -/* Define the structure that applications use to create or accept -** connections with enhanced retransmission mode. -*/ -typedef struct { - UINT8 preferred_mode; - UINT8 allowed_modes; - UINT16 user_rx_buf_size; - UINT16 user_tx_buf_size; - UINT16 fcr_rx_buf_size; - UINT16 fcr_tx_buf_size; - -} tL2CAP_ERTM_INFO; - -#define L2CA_REGISTER(a,b,c) L2CA_Register(a,(tL2CAP_APPL_INFO *)b) -#define L2CA_DEREGISTER(a) L2CA_Deregister(a) -#define L2CA_CONNECT_REQ(a,b,c,d) L2CA_ErtmConnectReq(a,b,c) -#define L2CA_CONNECT_RSP(a,b,c,d,e,f,g) L2CA_ErtmConnectRsp(a,b,c,d,e,f) -#define L2CA_CONFIG_REQ(a,b) L2CA_ConfigReq(a,b) -#define L2CA_CONFIG_RSP(a,b) L2CA_ConfigRsp(a,b) -#define L2CA_DISCONNECT_REQ(a) L2CA_DisconnectReq(a) -#define L2CA_DISCONNECT_RSP(a) L2CA_DisconnectRsp(a) -#define L2CA_DATA_WRITE(a, b) L2CA_DataWrite(a, b) - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -#if (CLASSIC_BT_INCLUDED == TRUE) -/******************************************************************************* -** -** Function L2CA_Register -** -** Description Other layers call this function to register for L2CAP -** services. -** -** Returns PSM to use or zero if error. Typically, the PSM returned -** is the same as was passed in, but for an outgoing-only -** connection to a dynamic PSM, a "virtual" PSM is returned -** and should be used in the calls to L2CA_ConnectReq() and -** BTM_SetSecurityLevel(). -** -*******************************************************************************/ -extern UINT16 L2CA_Register (UINT16 psm, tL2CAP_APPL_INFO *p_cb_info); - -/******************************************************************************* -** -** Function L2CA_Deregister -** -** Description Other layers call this function to deregister for L2CAP -** services. -** -** Returns void -** -*******************************************************************************/ -extern void L2CA_Deregister (UINT16 psm); - -/******************************************************************************* -** -** Function L2CA_AllocatePSM -** -** Description Other layers call this function to find an unused PSM for L2CAP -** services. -** -** Returns PSM to use. -** -*******************************************************************************/ -extern UINT16 L2CA_AllocatePSM(void); - -/******************************************************************************* -** -** Function L2CA_ConnectReq -** -** Description Higher layers call this function to create an L2CAP connection. -** Note that the connection is not established at this time, but -** connection establishment gets started. The callback function -** will be invoked when connection establishes or fails. -** -** Returns the CID of the connection, or 0 if it failed to start -** -*******************************************************************************/ -extern UINT16 L2CA_ConnectReq (UINT16 psm, BD_ADDR p_bd_addr); - -/******************************************************************************* -** -** Function L2CA_ConnectRsp -** -** Description Higher layers call this function to accept an incoming -** L2CAP connection, for which they had gotten an connect -** indication callback. -** -** Returns TRUE for success, FALSE for failure -** -*******************************************************************************/ -extern BOOLEAN L2CA_ConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, - UINT16 result, UINT16 status); - -/******************************************************************************* -** -** Function L2CA_ErtmConnectReq -** -** Description Higher layers call this function to create an L2CAP connection -** that needs to use Enhanced Retransmission Mode. -** Note that the connection is not established at this time, but -** connection establishment gets started. The callback function -** will be invoked when connection establishes or fails. -** -** Returns the CID of the connection, or 0 if it failed to start -** -*******************************************************************************/ -extern UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, - tL2CAP_ERTM_INFO *p_ertm_info); - -// This function sets the callback routines for the L2CAP connection referred to by -// |local_cid|. The callback routines can only be modified for outgoing connections -// established by |L2CA_ConnectReq| or accepted incoming connections. |callbacks| -// must not be NULL. This function returns true if the callbacks could be updated, -// false if not (e.g. |local_cid| was not found). -bool L2CA_SetConnectionCallbacks(uint16_t local_cid, const tL2CAP_APPL_INFO *callbacks); - -/******************************************************************************* -** -** Function L2CA_ErtmConnectRsp -** -** Description Higher layers call this function to accept an incoming -** L2CAP connection, for which they had gotten an connect -** indication callback, and for which the higher layer wants -** to use Enhanced Retransmission Mode. -** -** Returns TRUE for success, FALSE for failure -** -*******************************************************************************/ -extern BOOLEAN L2CA_ErtmConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, - UINT16 result, UINT16 status, - tL2CAP_ERTM_INFO *p_ertm_info); - -/******************************************************************************* -** -** Function L2CA_ConfigReq -** -** Description Higher layers call this function to send configuration. -** -** Returns TRUE if configuration sent, else FALSE -** -*******************************************************************************/ -extern BOOLEAN L2CA_ConfigReq (UINT16 cid, tL2CAP_CFG_INFO *p_cfg); - -/******************************************************************************* -** -** Function L2CA_ConfigRsp -** -** Description Higher layers call this function to send a configuration -** response. -** -** Returns TRUE if configuration response sent, else FALSE -** -*******************************************************************************/ -extern BOOLEAN L2CA_ConfigRsp (UINT16 cid, tL2CAP_CFG_INFO *p_cfg); - -/******************************************************************************* -** -** Function L2CA_DisconnectReq -** -** Description Higher layers call this function to disconnect a channel. -** -** Returns TRUE if disconnect sent, else FALSE -** -*******************************************************************************/ -extern BOOLEAN L2CA_DisconnectReq (UINT16 cid); - -/******************************************************************************* -** -** Function L2CA_DisconnectRsp -** -** Description Higher layers call this function to acknowledge the -** disconnection of a channel. -** -** Returns void -** -*******************************************************************************/ -extern BOOLEAN L2CA_DisconnectRsp (UINT16 cid); -#endif ///CLASSIC_BT_INCLUDED == TRUE - -/******************************************************************************* -** -** Function L2CA_RegisterLECoc -** -** Description Other layers call this function to register for L2CAP -** Connection Oriented Channel. -** -** Returns PSM to use or zero if error. Typically, the PSM returned -** is the same as was passed in, but for an outgoing-only -** connection to a dynamic PSM, a "virtual" PSM is returned -** and should be used in the calls to L2CA_ConnectLECocReq() -** and BTM_SetSecurityLevel(). -** -*******************************************************************************/ -extern UINT16 L2CA_RegisterLECoc (UINT16 psm, tL2CAP_APPL_INFO *p_cb_info); - -/******************************************************************************* -** -** Function L2CA_DeregisterLECoc -** -** Description Other layers call this function to deregister for L2CAP -** Connection Oriented Channel. -** -** Returns void -** -*******************************************************************************/ -extern void L2CA_DeregisterLECoc (UINT16 psm); - -/******************************************************************************* -** -** Function L2CA_ConnectLECocReq -** -** Description Higher layers call this function to create an L2CAP LE COC. -** Note that the connection is not established at this time, but -** connection establishment gets started. The callback function -** will be invoked when connection establishes or fails. -** -** Returns the CID of the connection, or 0 if it failed to start -** -*******************************************************************************/ -extern UINT16 L2CA_ConnectLECocReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_LE_CFG_INFO *p_cfg); - -/******************************************************************************* -** -** Function L2CA_ConnectLECocRsp -** -** Description Higher layers call this function to accept an incoming -** L2CAP LE COC connection, for which they had gotten an connect -** indication callback. -** -** Returns TRUE for success, FALSE for failure -** -*******************************************************************************/ -extern BOOLEAN L2CA_ConnectLECocRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 result, - UINT16 status, tL2CAP_LE_CFG_INFO *p_cfg); - -/******************************************************************************* -** -** Function L2CA_GetPeerLECocConfig -** -** Description Get peers configuration for LE Connection Oriented Channel. -** -** Return value: TRUE if peer is connected -** -*******************************************************************************/ -extern BOOLEAN L2CA_GetPeerLECocConfig (UINT16 lcid, tL2CAP_LE_CFG_INFO* peer_cfg); - -/******************************************************************************* -** -** Function L2CA_DataWrite -** -** Description Higher layers call this function to write data. -** -** Returns L2CAP_DW_SUCCESS, if data accepted, else FALSE -** L2CAP_DW_CONGESTED, if data accepted and the channel is congested -** L2CAP_DW_FAILED, if error -** -*******************************************************************************/ -extern UINT8 L2CA_DataWrite (UINT16 cid, BT_HDR *p_data); - -#if (CLASSIC_BT_INCLUDED == TRUE) - -/******************************************************************************* -** -** Function L2CA_Ping -** -** Description Higher layers call this function to send an echo request. -** -** Returns TRUE if echo request sent, else FALSE. -** -*******************************************************************************/ -extern BOOLEAN L2CA_Ping (BD_ADDR p_bd_addr, tL2CA_ECHO_RSP_CB *p_cb); - -/******************************************************************************* -** -** Function L2CA_Echo -** -** Description Higher layers call this function to send an echo request -** with application-specific data. -** -** Returns TRUE if echo request sent, else FALSE. -** -*******************************************************************************/ -extern BOOLEAN L2CA_Echo (BD_ADDR p_bd_addr, BT_HDR *p_data, tL2CA_ECHO_DATA_CB *p_callback); -#endif ///CLASSIC_BT_INCLUDED == TRUE - - -// Given a local channel identifier, |lcid|, this function returns the bound remote -// channel identifier, |rcid|, and the ACL link handle, |handle|. If |lcid| is not -// known or is invalid, this function returns false and does not modify the values -// pointed at by |rcid| and |handle|. |rcid| and |handle| may be NULL. -bool L2CA_GetIdentifiers(uint16_t lcid, uint16_t *rcid, uint16_t *handle); - -/******************************************************************************* -** -** Function L2CA_SetIdleTimeout -** -** Description Higher layers call this function to set the idle timeout for -** a connection, or for all future connections. The "idle timeout" -** is the amount of time that a connection can remain up with -** no L2CAP channels on it. A timeout of zero means that the -** connection will be torn down immediately when the last channel -** is removed. A timeout of 0xFFFF means no timeout. Values are -** in seconds. -** -** Returns TRUE if command succeeded, FALSE if failed -** -*******************************************************************************/ -extern BOOLEAN L2CA_SetIdleTimeout (UINT16 cid, UINT16 timeout, - BOOLEAN is_global); - - -/******************************************************************************* -** -** Function L2CA_SetIdleTimeoutByBdAddr -** -** Description Higher layers call this function to set the idle timeout for -** a connection. The "idle timeout" is the amount of time that -** a connection can remain up with no L2CAP channels on it. -** A timeout of zero means that the connection will be torn -** down immediately when the last channel is removed. -** A timeout of 0xFFFF means no timeout. Values are in seconds. -** A bd_addr is the remote BD address. If bd_addr = BT_BD_ANY, -** then the idle timeouts for all active l2cap links will be -** changed. -** -** Returns TRUE if command succeeded, FALSE if failed -** -** NOTE This timeout applies to all logical channels active on the -** ACL link. -*******************************************************************************/ -extern BOOLEAN L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, UINT16 timeout, - tBT_TRANSPORT transport); - - -/******************************************************************************* -** -** Function L2CA_SetTraceLevel -** -** Description This function sets the trace level for L2CAP. If called with -** a value of 0xFF, it simply reads the current trace level. -** -** Returns the new (current) trace level -** -*******************************************************************************/ -extern UINT8 L2CA_SetTraceLevel (UINT8 trace_level); - - -/******************************************************************************* -** -** Function L2CA_SetDesireRole -** -** Description This function sets the desire role for L2CAP. -** If the new role is L2CAP_ROLE_ALLOW_SWITCH, allow switch on -** HciCreateConnection. -** If the new role is L2CAP_ROLE_DISALLOW_SWITCH, do not allow switch on -** HciCreateConnection. -** -** If the new role is a valid role (HCI_ROLE_MASTER or HCI_ROLE_SLAVE), -** the desire role is set to the new value. Otherwise, it is not changed. -** -** Returns the new (current) role -** -*******************************************************************************/ -extern UINT8 L2CA_SetDesireRole (UINT8 new_role); -#if (CLASSIC_BT_INCLUDED == TRUE) -/******************************************************************************* -** -** Function L2CA_LocalLoopbackReq -** -** Description This function sets up a CID for local loopback -** -** Returns CID of 0 if none. -** -*******************************************************************************/ -extern UINT16 L2CA_LocalLoopbackReq (UINT16 psm, UINT16 handle, BD_ADDR p_bd_addr); - -/******************************************************************************* -** -** Function L2CA_FlushChannel -** -** Description This function flushes none, some or all buffers queued up -** for xmission for a particular CID. If called with -** L2CAP_FLUSH_CHANS_GET (0), it simply returns the number -** of buffers queued for that CID L2CAP_FLUSH_CHANS_ALL (0xffff) -** flushes all buffers. All other values specifies the maximum -** buffers to flush. -** -** Returns Number of buffers left queued for that CID -** -*******************************************************************************/ -extern UINT16 L2CA_FlushChannel (UINT16 lcid, UINT16 num_to_flush); - - -/******************************************************************************* -** -** Function L2CA_SetAclPriority -** -** Description Sets the transmission priority for an ACL channel. -** (For initial implementation only two values are valid. -** L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH). -** -** Returns TRUE if a valid channel, else FALSE -** -*******************************************************************************/ -extern BOOLEAN L2CA_SetAclPriority (BD_ADDR bd_addr, UINT8 priority); - -/******************************************************************************* -** -** Function L2CA_FlowControl -** -** Description Higher layers call this function to flow control a channel. -** -** data_enabled - TRUE data flows, FALSE data is stopped -** -** Returns TRUE if valid channel, else FALSE -** -*******************************************************************************/ -extern BOOLEAN L2CA_FlowControl (UINT16 cid, BOOLEAN data_enabled); - -/******************************************************************************* -** -** Function L2CA_SendTestSFrame -** -** Description Higher layers call this function to send a test S-frame. -** -** Returns TRUE if valid Channel, else FALSE -** -*******************************************************************************/ -extern BOOLEAN L2CA_SendTestSFrame (UINT16 cid, UINT8 sup_type, - UINT8 back_track); - -/******************************************************************************* -** -** Function L2CA_SetTxPriority -** -** Description Sets the transmission priority for a channel. (FCR Mode) -** -** Returns TRUE if a valid channel, else FALSE -** -*******************************************************************************/ -extern BOOLEAN L2CA_SetTxPriority (UINT16 cid, tL2CAP_CHNL_PRIORITY priority); - -/******************************************************************************* -** -** Function L2CA_RegForNoCPEvt -** -** Description Register callback for Number of Completed Packets event. -** -** Input Param p_cb - callback for Number of completed packets event -** p_bda - BT address of remote device -** -** Returns -** -*******************************************************************************/ -extern BOOLEAN L2CA_RegForNoCPEvt(tL2CA_NOCP_CB *p_cb, BD_ADDR p_bda); - -/******************************************************************************* -** -** Function L2CA_SetChnlDataRate -** -** Description Sets the tx/rx data rate for a channel. -** -** Returns TRUE if a valid channel, else FALSE -** -*******************************************************************************/ -extern BOOLEAN L2CA_SetChnlDataRate (UINT16 cid, tL2CAP_CHNL_DATA_RATE tx, tL2CAP_CHNL_DATA_RATE rx); - -typedef void (tL2CA_RESERVE_CMPL_CBACK) (void); - -/******************************************************************************* -** -** Function L2CA_SetFlushTimeout -** -** Description This function set the automatic flush time out in Baseband -** for ACL-U packets. -** BdAddr : the remote BD address of ACL link. If it is BT_DB_ANY -** then the flush time out will be applied to all ACL link. -** FlushTimeout: flush time out in ms -** 0x0000 : No automatic flush -** L2CAP_NO_RETRANSMISSION : No retransmission -** 0x0002 - 0xFFFE : flush time out, if (flush_tout*8)+3/5) -** <= HCI_MAX_AUTO_FLUSH_TOUT (in 625us slot). -** Otherwise, return FALSE. -** L2CAP_NO_AUTOMATIC_FLUSH : No automatic flush -** -** Returns TRUE if command succeeded, FALSE if failed -** -** NOTE This flush timeout applies to all logical channels active on the -** ACL link. -*******************************************************************************/ -extern BOOLEAN L2CA_SetFlushTimeout (BD_ADDR bd_addr, UINT16 flush_tout); -#endif ///CLASSIC_BT_INCLUDED == TRUE - -/******************************************************************************* -** -** Function L2CA_DataWriteEx -** -** Description Higher layers call this function to write data with extended -** flags. -** flags : L2CAP_FLUSHABLE_CH_BASED -** L2CAP_FLUSHABLE_PKT -** L2CAP_NON_FLUSHABLE_PKT -** -** Returns L2CAP_DW_SUCCESS, if data accepted, else FALSE -** L2CAP_DW_CONGESTED, if data accepted and the channel is congested -** L2CAP_DW_FAILED, if error -** -*******************************************************************************/ -extern UINT8 L2CA_DataWriteEx (UINT16 cid, BT_HDR *p_data, UINT16 flags); - -/******************************************************************************* -** -** Function L2CA_SetChnlFlushability -** -** Description Higher layers call this function to set a channels -** flushability flags -** -** Returns TRUE if CID found, else FALSE -** -*******************************************************************************/ -extern BOOLEAN L2CA_SetChnlFlushability (UINT16 cid, BOOLEAN is_flushable); - -/******************************************************************************* -** -** Function L2CA_GetPeerFeatures -** -** Description Get a peers features and fixed channel map -** -** Parameters: BD address of the peer -** Pointers to features and channel mask storage area -** -** Return value: TRUE if peer is connected -** -*******************************************************************************/ -extern BOOLEAN L2CA_GetPeerFeatures (BD_ADDR bd_addr, UINT32 *p_ext_feat, UINT8 *p_chnl_mask); - -/******************************************************************************* -** -** Function L2CA_GetBDAddrbyHandle -** -** Description Get BD address for the given HCI handle -** -** Parameters: HCI handle -** BD address of the peer -** -** Return value: TRUE if found lcb for the given handle, FALSE otherwise -** -*******************************************************************************/ -extern BOOLEAN L2CA_GetBDAddrbyHandle (UINT16 handle, BD_ADDR bd_addr); - -#if (CLASSIC_BT_INCLUDED == TRUE) - -/******************************************************************************* -** -** Function L2CA_GetChnlFcrMode -** -** Description Get the channel FCR mode -** -** Parameters: Local CID -** -** Return value: Channel mode -** -*******************************************************************************/ -extern UINT8 L2CA_GetChnlFcrMode (UINT16 lcid); -#endif ///CLASSIC_BT_INCLUDED == TRUE - - -/******************************************************************************* -** -** UCD callback prototypes -** -*******************************************************************************/ - -/* UCD discovery. Parameters are -** BD Address of remote -** Data Type -** Data -*/ -#define L2CAP_UCD_INFO_TYPE_RECEPTION 0x01 -#define L2CAP_UCD_INFO_TYPE_MTU 0x02 - -typedef void (tL2CA_UCD_DISCOVER_CB) (BD_ADDR, UINT8, UINT32); - -/* UCD data received. Parameters are -** BD Address of remote -** Pointer to buffer with data -*/ -typedef void (tL2CA_UCD_DATA_CB) (BD_ADDR, BT_HDR *); - -/* Congestion status callback protype. This callback is optional. If -** an application tries to send data when the transmit queue is full, -** the data will anyways be dropped. The parameter is: -** remote BD_ADDR -** TRUE if congested, FALSE if uncongested -*/ -typedef void (tL2CA_UCD_CONGESTION_STATUS_CB) (BD_ADDR, BOOLEAN); - -/* UCD registration info (the callback addresses and PSM) -*/ -typedef struct { - tL2CA_UCD_DISCOVER_CB *pL2CA_UCD_Discover_Cb; - tL2CA_UCD_DATA_CB *pL2CA_UCD_Data_Cb; - tL2CA_UCD_CONGESTION_STATUS_CB *pL2CA_UCD_Congestion_Status_Cb; -} tL2CAP_UCD_CB_INFO; - -/******************************************************************************* -** -** Function L2CA_UcdRegister -** -** Description Register PSM on UCD. -** -** Parameters: tL2CAP_UCD_CB_INFO -** -** Return value: TRUE if successs -** -*******************************************************************************/ -extern BOOLEAN L2CA_UcdRegister ( UINT16 psm, tL2CAP_UCD_CB_INFO *p_cb_info ); - -/******************************************************************************* -** -** Function L2CA_UcdDeregister -** -** Description Deregister PSM on UCD. -** -** Parameters: PSM -** -** Return value: TRUE if successs -** -*******************************************************************************/ -extern BOOLEAN L2CA_UcdDeregister ( UINT16 psm ); - -/******************************************************************************* -** -** Function L2CA_UcdDiscover -** -** Description Discover UCD of remote device. -** -** Parameters: PSM -** BD_ADDR of remote device -** info_type : L2CAP_UCD_INFO_TYPE_RECEPTION -** L2CAP_UCD_INFO_TYPE_MTU -** -** -** Return value: TRUE if successs -** -*******************************************************************************/ -extern BOOLEAN L2CA_UcdDiscover ( UINT16 psm, BD_ADDR rem_bda, UINT8 info_type ); - -/******************************************************************************* -** -** Function L2CA_UcdDataWrite -** -** Description Send UCD to remote device -** -** Parameters: PSM -** BD Address of remote -** Pointer to buffer of type BT_HDR -** flags : L2CAP_FLUSHABLE_CH_BASED -** L2CAP_FLUSHABLE_PKT -** L2CAP_NON_FLUSHABLE_PKT -** -** Return value L2CAP_DW_SUCCESS, if data accepted -** L2CAP_DW_FAILED, if error -** -*******************************************************************************/ -extern UINT16 L2CA_UcdDataWrite (UINT16 psm, BD_ADDR rem_bda, BT_HDR *p_buf, UINT16 flags); - -/******************************************************************************* -** -** Function L2CA_UcdSetIdleTimeout -** -** Description Set UCD Idle timeout. -** -** Parameters: BD Addr -** Timeout in second -** -** Return value: TRUE if successs -** -*******************************************************************************/ -extern BOOLEAN L2CA_UcdSetIdleTimeout ( BD_ADDR rem_bda, UINT16 timeout ); - -/******************************************************************************* -** -** Function L2CA_UCDSetTxPriority -** -** Description Sets the transmission priority for a connectionless channel. -** -** Returns TRUE if a valid channel, else FALSE -** -*******************************************************************************/ -extern BOOLEAN L2CA_UCDSetTxPriority ( BD_ADDR rem_bda, tL2CAP_CHNL_PRIORITY priority ); - - -/******************************************************************************* -** -** Fixed Channel callback prototypes -** -*******************************************************************************/ - -/* Fixed channel connected and disconnected. Parameters are -** channel -** BD Address of remote -** TRUE if channel is connected, FALSE if disconnected -** Reason for connection failure -** transport : physical transport, BR/EDR or LE -*/ -typedef void (tL2CA_FIXED_CHNL_CB) (UINT16, BD_ADDR, BOOLEAN, UINT16, tBT_TRANSPORT); - -/* Signalling data received. Parameters are -** channel -** BD Address of remote -** Pointer to buffer with data -*/ -typedef void (tL2CA_FIXED_DATA_CB) (UINT16, BD_ADDR, BT_HDR *); - -/* Congestion status callback protype. This callback is optional. If -** an application tries to send data when the transmit queue is full, -** the data will anyways be dropped. The parameter is: -** remote BD_ADDR -** TRUE if congested, FALSE if uncongested -*/ -typedef void (tL2CA_FIXED_CONGESTION_STATUS_CB) (BD_ADDR, BOOLEAN); - -/* Fixed channel registration info (the callback addresses and channel config) -*/ -typedef struct { - tL2CA_FIXED_CHNL_CB *pL2CA_FixedConn_Cb; - tL2CA_FIXED_DATA_CB *pL2CA_FixedData_Cb; - tL2CA_FIXED_CONGESTION_STATUS_CB *pL2CA_FixedCong_Cb; - tL2CAP_FCR_OPTS fixed_chnl_opts; - - UINT16 default_idle_tout; - tL2CA_TX_COMPLETE_CB *pL2CA_FixedTxComplete_Cb; /* fixed channel tx complete callback */ -} tL2CAP_FIXED_CHNL_REG; - - -#if (L2CAP_NUM_FIXED_CHNLS > 0) -/******************************************************************************* -** -** Function L2CA_RegisterFixedChannel -** -** Description Register a fixed channel. -** -** Parameters: Fixed Channel # -** Channel Callbacks and config -** -** Return value: TRUE if registered OK -** -*******************************************************************************/ -extern BOOLEAN L2CA_RegisterFixedChannel (UINT16 fixed_cid, tL2CAP_FIXED_CHNL_REG *p_freg); - -/******************************************************************************* -** -** Function L2CA_ConnectFixedChnl -** -** Description Connect an fixed signalling channel to a remote device. -** -** Parameters: Fixed CID -** BD Address of remote -** BD Address type -** -** Return value: TRUE if connection started -** -*******************************************************************************/ -extern BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_type); - -/******************************************************************************* -** -** Function L2CA_SendFixedChnlData -** -** Description Write data on a fixed signalling channel. -** -** Parameters: Fixed CID -** BD Address of remote -** Pointer to buffer of type BT_HDR -** -** Return value L2CAP_DW_SUCCESS, if data accepted -** L2CAP_DW_FAILED, if error -** -*******************************************************************************/ -extern UINT16 L2CA_SendFixedChnlData (UINT16 fixed_cid, BD_ADDR rem_bda, BT_HDR *p_buf); - -/******************************************************************************* -** -** Function L2CA_RemoveFixedChnl -** -** Description Remove a fixed channel to a remote device. -** -** Parameters: Fixed CID -** BD Address of remote -** Idle timeout to use (or 0xFFFF if don't care) -** -** Return value: TRUE if channel removed -** -*******************************************************************************/ -extern BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda); - -/******************************************************************************* -** -** Function L2CA_SetFixedChannelTout -** -** Description Higher layers call this function to set the idle timeout for -** a fixed channel. The "idle timeout" is the amount of time that -** a connection can remain up with no L2CAP channels on it. -** A timeout of zero means that the connection will be torn -** down immediately when the last channel is removed. -** A timeout of 0xFFFF means no timeout. Values are in seconds. -** A bd_addr is the remote BD address. If bd_addr = BT_BD_ANY, -** then the idle timeouts for all active l2cap links will be -** changed. -** -** Returns TRUE if command succeeded, FALSE if failed -** -*******************************************************************************/ -extern BOOLEAN L2CA_SetFixedChannelTout (BD_ADDR rem_bda, UINT16 fixed_cid, UINT16 idle_tout); - -#endif /* (L2CAP_NUM_FIXED_CHNLS > 0) */ - -#if (CLASSIC_BT_INCLUDED == TRUE) -/******************************************************************************* -** -** Function L2CA_GetCurrentConfig -** -** Description This function returns configurations of L2CAP channel -** pp_our_cfg : pointer of our saved configuration options -** p_our_cfg_bits : valid config in bitmap -** pp_peer_cfg: pointer of peer's saved configuration options -** p_peer_cfg_bits : valid config in bitmap -** -** Returns TRUE if successful -** -*******************************************************************************/ -extern BOOLEAN L2CA_GetCurrentConfig (UINT16 lcid, - tL2CAP_CFG_INFO **pp_our_cfg, tL2CAP_CH_CFG_BITS *p_our_cfg_bits, - tL2CAP_CFG_INFO **pp_peer_cfg, tL2CAP_CH_CFG_BITS *p_peer_cfg_bits); -#endif ///CLASSIC_BT_INCLUDED == TRUE - - -#if (BLE_INCLUDED == TRUE) -/******************************************************************************* -** -** Function L2CA_CancelBleConnectReq -** -** Description Cancel a pending connection attempt to a BLE device. -** -** Parameters: BD Address of remote -** -** Return value: TRUE if connection was cancelled -** -*******************************************************************************/ -extern BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda); - -/******************************************************************************* -** -** Function L2CA_UpdateBleConnParams -** -** Description Update BLE connection parameters. -** -** Parameters: BD Address of remote -** -** Return value: TRUE if update started -** -*******************************************************************************/ -extern BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bdRa, UINT16 min_int, - UINT16 max_int, UINT16 latency, UINT16 timeout); - -/******************************************************************************* -** -** Function L2CA_EnableUpdateBleConnParams -** -** Description Update BLE connection parameters. -** -** Parameters: BD Address of remote -** enable flag -** -** Return value: TRUE if update started -** -*******************************************************************************/ -extern BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable); - -/******************************************************************************* -** -** Function L2CA_GetBleConnRole -** -** Description This function returns the connection role. -** -** Returns link role. -** -*******************************************************************************/ -extern UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function L2CA_GetDisconnectReason -** -** Description This function returns the disconnect reason code. -** -** Parameters: BD Address of remote -** Physical transport for the L2CAP connection (BR/EDR or LE) -** -** Returns disconnect reason -** -*******************************************************************************/ -extern UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport); - -extern BOOLEAN L2CA_CheckIsCongest(UINT16 fixed_cid, UINT16 handle); - - -#endif /* (BLE_INCLUDED == TRUE) */ - -#ifdef __cplusplus -} -#endif - -#endif /* L2C_API_H */ diff --git a/tools/sdk/include/bluedroid/stack/l2cap_client.h b/tools/sdk/include/bluedroid/stack/l2cap_client.h deleted file mode 100644 index d18be32c..00000000 --- a/tools/sdk/include/bluedroid/stack/l2cap_client.h +++ /dev/null @@ -1,80 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2014 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef _L2CAP_CLIENT_H_ -#define _L2CAP_CLIENT_H_ -#if (defined(L2CAP_CLIENT_INCLUDED) && L2CAP_CLIENT_INCLUDED == TRUE) - -//#include -#include -#include - -typedef struct buffer_t buffer_t; -typedef struct l2cap_client_t l2cap_client_t; - -typedef struct { - void (*connected)(l2cap_client_t *client, void *context); - void (*disconnected)(l2cap_client_t *client, void *context); - void (*read_ready)(l2cap_client_t *client, buffer_t *packet, void *context); - void (*write_ready)(l2cap_client_t *client, void *context); -} l2cap_client_callbacks_t; - -// Returns a new buffer with enough space for |size| bytes of L2CAP payload. -// |size| must be greater than zero. This function returns NULL if the buffer -// could not be allocated. The returned buffer must be freed with |buffer_free| -// when it is no longer needed. -buffer_t *l2cap_buffer_new(size_t size); - -// Creates and returns a new L2CAP client object. |callbacks| must not be NULL and -// must specify a set of functions that should be called back when events occur -// on the L2CAP connection. |context| may be NULL and will be passed as the argument -// to all callbacks in |l2cap_client_callbacks_t|. The returned object must be freed -// with |l2cap_client_free|. -l2cap_client_t *l2cap_client_new(const l2cap_client_callbacks_t *callbacks, void *context); - -// Frees the L2CAP client object allocated with |l2cap_client_new|. |client| may be NULL. -void l2cap_client_free(l2cap_client_t *client); - -// Attempts to connect the |client| to a peer device specified by |remote_bdaddr| -// using the |psm| protocol specifier. This function returns true if the connect -// operation could be started and will indicate completion with either a 'connected' -// callback (success) or a 'disconnected' callback (failure). -// -// This function must not be called while a connect operation is in progress or -// while |l2cap_client_is_connected|. |client| and |remote_bdaddr| must not be NULL. -// |psm| must be greater than zero. -bool l2cap_client_connect(l2cap_client_t *client, const bt_bdaddr_t *remote_bdaddr, uint16_t psm); - -// Disconnects a connected |client|. This function is asynchronous and idempotent. It -// will indicate completion with a 'disconnected' callback. |client| must not be NULL. -void l2cap_client_disconnect(l2cap_client_t *client); - -// Returns true if |client| is connected and is ready to accept data written to it. -// |client| must not be NULL. -bool l2cap_client_is_connected(const l2cap_client_t *client); - -// Writes data contained in |packet| to a connected |client|. This function returns -// true if the packet was successfully queued for delivery, false if the client cannot -// accept more data at this time. If this function returns false, the caller must wait -// for the 'write_ready' callback to write additional data to the client. Neither -// |client| nor |packet| may be NULL. -bool l2cap_client_write(l2cap_client_t *client, buffer_t *packet); - -#endif ///(defined(L2CAP_CLIENT_INCLUDED) && L2CAP_CLIENT_INCLUDED == TRUE) - -#endif /*_L2CAP_CLIENT_H_*/ diff --git a/tools/sdk/include/bluedroid/stack/l2cdefs.h b/tools/sdk/include/bluedroid/stack/l2cdefs.h deleted file mode 100644 index 56ddfb0d..00000000 --- a/tools/sdk/include/bluedroid/stack/l2cdefs.h +++ /dev/null @@ -1,329 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef L2CDEFS_H -#define L2CDEFS_H - -/* L2CAP command codes -*/ -#define L2CAP_CMD_REJECT 0x01 -#define L2CAP_CMD_CONN_REQ 0x02 -#define L2CAP_CMD_CONN_RSP 0x03 -#define L2CAP_CMD_CONFIG_REQ 0x04 -#define L2CAP_CMD_CONFIG_RSP 0x05 -#define L2CAP_CMD_DISC_REQ 0x06 -#define L2CAP_CMD_DISC_RSP 0x07 -#define L2CAP_CMD_ECHO_REQ 0x08 -#define L2CAP_CMD_ECHO_RSP 0x09 -#define L2CAP_CMD_INFO_REQ 0x0A -#define L2CAP_CMD_INFO_RSP 0x0B -#define L2CAP_CMD_AMP_CONN_REQ 0x0C -#define L2CAP_CMD_AMP_CONN_RSP 0x0D -#define L2CAP_CMD_AMP_MOVE_REQ 0x0E -#define L2CAP_CMD_AMP_MOVE_RSP 0x0F -#define L2CAP_CMD_AMP_MOVE_CFM 0x10 -#define L2CAP_CMD_AMP_MOVE_CFM_RSP 0x11 - -#define L2CAP_CMD_BLE_UPDATE_REQ 0x12 -#define L2CAP_CMD_BLE_UPDATE_RSP 0x13 -#define L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ 0x14 -#define L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES 0x15 -#define L2CAP_CMD_BLE_FLOW_CTRL_CREDIT 0x16 - - - -/* Define some packet and header lengths -*/ -#define L2CAP_PKT_OVERHEAD 4 /* Length and CID */ -#define L2CAP_CMD_OVERHEAD 4 /* Cmd code, Id and length */ -#define L2CAP_CMD_REJECT_LEN 2 /* Reason (data is optional) */ -#define L2CAP_CONN_REQ_LEN 4 /* PSM and source CID */ -#define L2CAP_CONN_RSP_LEN 8 /* Dest CID, source CID, reason, status */ -#define L2CAP_CONFIG_REQ_LEN 4 /* Dest CID, flags (data is optional) */ -#define L2CAP_CONFIG_RSP_LEN 6 /* Dest CID, flags, result,data optional*/ -#define L2CAP_DISC_REQ_LEN 4 /* Dest CID, source CID */ -#define L2CAP_DISC_RSP_LEN 4 /* Dest CID, source CID */ -#define L2CAP_ECHO_REQ_LEN 0 /* Data is optional */ -#define L2CAP_ECHO_RSP_LEN 0 /* Data is optional */ -#define L2CAP_INFO_REQ_LEN 2 /* Info type */ -#define L2CAP_INFO_RSP_LEN 4 /* Info type, result (data is optional) */ -#define L2CAP_BCST_OVERHEAD 2 /* Additional broadcast packet overhead */ -#define L2CAP_UCD_OVERHEAD 2 /* Additional connectionless packet overhead */ - -#define L2CAP_AMP_CONN_REQ_LEN 5 /* PSM, CID, and remote controller ID */ -#define L2CAP_AMP_MOVE_REQ_LEN 3 /* CID and remote controller ID */ -#define L2CAP_AMP_MOVE_RSP_LEN 4 /* CID and result */ -#define L2CAP_AMP_MOVE_CFM_LEN 4 /* CID and result */ -#define L2CAP_AMP_MOVE_CFM_RSP_LEN 2 /* CID */ - -#define L2CAP_CMD_BLE_UPD_REQ_LEN 8 /* Min and max interval, latency, tout */ -#define L2CAP_CMD_BLE_UPD_RSP_LEN 2 /* Result */ - -#define L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ_LEN 10 /* LE_PSM, SCID, MTU, MPS, Init Credit */ -#define L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN 10 /* DCID, MTU, MPS, Init credit, Result */ -#define L2CAP_CMD_BLE_FLOW_CTRL_CREDIT_LEN 4 /* CID, Credit */ - - - -/* Define the packet boundary flags -*/ -#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) -#define L2CAP_PKT_START_FLUSHABLE 2 -#define L2CAP_PKT_START_NON_FLUSHABLE 0 -#endif -#define L2CAP_COMPLETE_AMP_PKT 3 /* complete L2CAP packet on AMP HCI */ -#define L2CAP_PKT_START 2 -#define L2CAP_PKT_CONTINUE 1 -#define L2CAP_MASK_FLAG 0x0FFF -#define L2CAP_PKT_TYPE_SHIFT 12 -#define L2CAP_PKT_TYPE_MASK 3 - - -/* Define the L2CAP connection result codes -*/ -#define L2CAP_CONN_OK 0 -#define L2CAP_CONN_PENDING 1 -#define L2CAP_CONN_NO_PSM 2 -#define L2CAP_CONN_SECURITY_BLOCK 3 -#define L2CAP_CONN_NO_RESOURCES 4 -#define L2CAP_CONN_BAD_CTLR_ID 5 /* AMP related */ -#define L2CAP_CONN_TIMEOUT 0xEEEE -#define L2CAP_CONN_AMP_FAILED 254 -#define L2CAP_CONN_NO_LINK 255 /* Add a couple of our own for internal use */ -#define L2CAP_CONN_CANCEL 256 /* L2CAP connection cancelled */ - - -/* Define L2CAP Move Channel Response result codes -*/ -#define L2CAP_MOVE_OK 0 -#define L2CAP_MOVE_PENDING 1 -#define L2CAP_MOVE_CTRL_ID_NOT_SUPPORT 2 -#define L2CAP_MOVE_SAME_CTRLR_ID 3 -#define L2CAP_MOVE_CONFIG_NOT_SUPPORTED 4 -#define L2CAP_MOVE_CHAN_COLLISION 5 -#define L2CAP_MOVE_NOT_ALLOWED 6 - - -/* Define L2CAP Move Channel Confirmation result codes -*/ -#define L2CAP_MOVE_CFM_OK 0 -#define L2CAP_MOVE_CFM_REFUSED 1 - - -/* Define the L2CAP command reject reason codes -*/ -#define L2CAP_CMD_REJ_NOT_UNDERSTOOD 0 -#define L2CAP_CMD_REJ_MTU_EXCEEDED 1 -#define L2CAP_CMD_REJ_INVALID_CID 2 - - -/* L2CAP Predefined CIDs -*/ -#define L2CAP_SIGNALLING_CID 1 -#define L2CAP_CONNECTIONLESS_CID 2 -#define L2CAP_AMP_CID 3 -#define L2CAP_ATT_CID 4 -#define L2CAP_BLE_SIGNALLING_CID 5 -#define L2CAP_SMP_CID 6 -#define L2CAP_SMP_BR_CID 7 -#define L2CAP_AMP_TEST_CID 0x003F -#define L2CAP_BASE_APPL_CID 0x0040 -#define L2CAP_BLE_CONN_MAX_CID 0x007F - -/* Fixed Channels mask bits */ - -/* Signal channel supported (Mandatory) */ -#define L2CAP_FIXED_CHNL_SIG_BIT (1 << L2CAP_SIGNALLING_CID) - -/* Connectionless reception */ -#define L2CAP_FIXED_CHNL_CNCTLESS_BIT (1 << L2CAP_CONNECTIONLESS_CID) - -/* AMP Manager supported */ -#define L2CAP_FIXED_CHNL_AMP_BIT (1 << L2CAP_AMP_CID) - -/* Attribute protocol supported */ -#define L2CAP_FIXED_CHNL_ATT_BIT (1 << L2CAP_ATT_CID) - -/* BLE Signalling supported */ -#define L2CAP_FIXED_CHNL_BLE_SIG_BIT (1 << L2CAP_BLE_SIGNALLING_CID) - -/* BLE Security Mgr supported */ -#define L2CAP_FIXED_CHNL_SMP_BIT (1 << L2CAP_SMP_CID) - -/* Security Mgr over BR supported */ -#define L2CAP_FIXED_CHNL_SMP_BR_BIT (1 << L2CAP_SMP_BR_CID) - - - -/* Define the L2CAP configuration result codes -*/ -#define L2CAP_CFG_OK 0 -#define L2CAP_CFG_UNACCEPTABLE_PARAMS 1 -#define L2CAP_CFG_FAILED_NO_REASON 2 -#define L2CAP_CFG_UNKNOWN_OPTIONS 3 -#define L2CAP_CFG_PENDING 4 -#define L2CAP_CFG_FLOW_SPEC_REJECTED 5 - - -/* Define the L2CAP configuration option types -*/ -#define L2CAP_CFG_TYPE_MTU 0x01 -#define L2CAP_CFG_TYPE_FLUSH_TOUT 0x02 -#define L2CAP_CFG_TYPE_QOS 0x03 -#define L2CAP_CFG_TYPE_FCR 0x04 -#define L2CAP_CFG_TYPE_FCS 0x05 -#define L2CAP_CFG_TYPE_EXT_FLOW 0x06 -#define L2CAP_CFG_TYPE_EXT_WIN_SIZE 0x07 - -#define L2CAP_CFG_MTU_OPTION_LEN 2 /* MTU option length */ -#define L2CAP_CFG_FLUSH_OPTION_LEN 2 /* Flush option len */ -#define L2CAP_CFG_QOS_OPTION_LEN 22 /* QOS option length */ -#define L2CAP_CFG_FCR_OPTION_LEN 9 /* FCR option length */ -#define L2CAP_CFG_FCS_OPTION_LEN 1 /* FCR option length */ -#define L2CAP_CFG_EXT_FLOW_OPTION_LEN 16 /* Extended Flow Spec */ -#define L2CAP_CFG_EXT_WIN_SIZE_LEN 2 /* Ext window size length */ -#define L2CAP_CFG_OPTION_OVERHEAD 2 /* Type and length */ - -/* Configuration Cmd/Rsp Flags mask -*/ -#define L2CAP_CFG_FLAGS_MASK_CONT 0x0001 /* Flags mask: Continuation */ - -/* FCS Check Option values -*/ -#define L2CAP_CFG_FCS_BYPASS 0 /* Bypass the FCS in streaming or ERTM modes */ -#define L2CAP_CFG_FCS_USE 1 /* Use the FCS in streaming or ERTM modes [default] */ - -/* Default values for configuration -*/ -#define L2CAP_NO_AUTOMATIC_FLUSH 0xFFFF -#define L2CAP_NO_RETRANSMISSION 0x0001 - -#define L2CAP_DEFAULT_MTU (672) -#define L2CAP_DEFAULT_FLUSH_TO L2CAP_NO_AUTOMATIC_FLUSH -#define L2CAP_DEFAULT_SERV_TYPE 1 -#define L2CAP_DEFAULT_TOKEN_RATE 0 -#define L2CAP_DEFAULT_BUCKET_SIZE 0 -#define L2CAP_DEFAULT_PEAK_BANDWIDTH 0 -#define L2CAP_DEFAULT_LATENCY 0xFFFFFFFF -#define L2CAP_DEFAULT_DELAY 0xFFFFFFFF -#define L2CAP_DEFAULT_FCS L2CAP_CFG_FCS_USE - - -/* Define the L2CAP disconnect result codes -*/ -#define L2CAP_DISC_OK 0 -#define L2CAP_DISC_TIMEOUT 0xEEEE - -/* Define the L2CAP info resp result codes -*/ -#define L2CAP_INFO_RESP_RESULT_SUCCESS 0 -#define L2CAP_INFO_RESP_RESULT_NOT_SUPPORTED 1 - -/* Define the info-type fields of information request & response -*/ -#define L2CAP_CONNLESS_MTU_INFO_TYPE 0x0001 -#define L2CAP_EXTENDED_FEATURES_INFO_TYPE 0x0002 /* Used in Information Req/Response */ -#define L2CAP_FIXED_CHANNELS_INFO_TYPE 0x0003 /* Used in AMP */ - -#define L2CAP_CONNLESS_MTU_INFO_SIZE 2 /* Connectionless MTU size */ -#define L2CAP_EXTENDED_FEATURES_ARRAY_SIZE 4 /* Extended features array size */ -#define L2CAP_FIXED_CHNL_ARRAY_SIZE 8 /* Fixed channel array size */ - -/* Extended features mask bits -*/ -#define L2CAP_EXTFEA_RTRANS 0x00000001 /* Retransmission Mode (Not Supported) */ -#define L2CAP_EXTFEA_FC 0x00000002 /* Flow Control Mode (Not Supported) */ -#define L2CAP_EXTFEA_QOS 0x00000004 -#define L2CAP_EXTFEA_ENH_RETRANS 0x00000008 /* Enhanced retransmission mode */ -#define L2CAP_EXTFEA_STREAM_MODE 0x00000010 /* Streaming Mode */ -#define L2CAP_EXTFEA_NO_CRC 0x00000020 /* Optional FCS (if set No FCS desired) */ -#define L2CAP_EXTFEA_EXT_FLOW_SPEC 0x00000040 /* Extended flow spec */ -#define L2CAP_EXTFEA_FIXED_CHNLS 0x00000080 /* Fixed channels */ -#define L2CAP_EXTFEA_EXT_WINDOW 0x00000100 /* Extended Window Size */ -#define L2CAP_EXTFEA_UCD_RECEPTION 0x00000200 /* Unicast Connectionless Data Reception */ - -/* Mask for locally supported features used in Information Response (default to none) */ -#ifndef L2CAP_EXTFEA_SUPPORTED_MASK -#define L2CAP_EXTFEA_SUPPORTED_MASK 0 -#endif - -/* Mask for LE supported features used in Information Response (default to none) */ -#ifndef L2CAP_BLE_EXTFEA_MASK -#define L2CAP_BLE_EXTFEA_MASK 0 -#endif - -/* Define a value that tells L2CAP to use the default HCI ACL buffer size */ -#define L2CAP_INVALID_ERM_BUF_SIZE 0 - -/* Define a value that tells L2CAP to use the default MPS */ -#define L2CAP_DEFAULT_ERM_MPS 0x0000 - -#define L2CAP_FCR_OVERHEAD 2 /* Control word */ -#define L2CAP_FCS_LEN 2 /* FCS takes 2 bytes */ -#define L2CAP_SDU_LEN_OVERHEAD 2 /* SDU length field is 2 bytes */ -#define L2CAP_SDU_LEN_OFFSET 2 /* SDU length offset is 2 bytes */ -#define L2CAP_EXT_CONTROL_OVERHEAD 4 /* Extended Control Field */ -#define L2CAP_MAX_HEADER_FCS (L2CAP_PKT_OVERHEAD + L2CAP_EXT_CONTROL_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN) -/* length(2), channel(2), control(4), SDU length(2) FCS(2) */ -/* To optimize this, it must be a multiplum of the L2CAP PDU length AND match the 3DH5 air - * including the l2cap headers in each packet - to match the latter - the -5 is added - */ -#define L2CAP_MAX_SDU_LENGTH (8080 + 26 - (L2CAP_MIN_OFFSET + 6)) -#define L2CAP_MAX_BUF_SIZE (10240 + 24) - -/* Part of L2CAP_MIN_OFFSET that is not part of L2CAP -*/ -#define L2CAP_OFFSET_WO_L2HDR (L2CAP_MIN_OFFSET-(L2CAP_PKT_OVERHEAD+L2CAP_FCR_OVERHEAD)) - -/* SAR bits in the control word -*/ -#define L2CAP_FCR_UNSEG_SDU 0x0000 /* Control word to begin with for unsegmented PDU*/ -#define L2CAP_FCR_START_SDU 0x4000 /* ...for Starting PDU of a semented SDU */ -#define L2CAP_FCR_END_SDU 0x8000 /* ...for ending PDU of a segmented SDU */ -#define L2CAP_FCR_CONT_SDU 0xc000 /* ...for continuation PDU of a segmented SDU */ - -/* Supervisory frame types -*/ -#define L2CAP_FCR_SUP_RR 0x0000 /* Supervisory frame - RR */ -#define L2CAP_FCR_SUP_REJ 0x0001 /* Supervisory frame - REJ */ -#define L2CAP_FCR_SUP_RNR 0x0002 /* Supervisory frame - RNR */ -#define L2CAP_FCR_SUP_SREJ 0x0003 /* Supervisory frame - SREJ */ - -#define L2CAP_FCR_SAR_BITS 0xC000 /* Mask to get the SAR bits from control word */ -#define L2CAP_FCR_SAR_BITS_SHIFT 14 /* Bits to shift right to get the SAR bits from ctrl-word */ - -#define L2CAP_FCR_S_FRAME_BIT 0x0001 /* Mask to check if a PDU is S-frame */ -#define L2CAP_FCR_REQ_SEQ_BITS 0x3F00 /* Mask to get the req-seq from control word */ -#define L2CAP_FCR_REQ_SEQ_BITS_SHIFT 8 /* Bits to shift right to get the req-seq from ctrl-word */ -#define L2CAP_FCR_TX_SEQ_BITS 0x007E /* Mask on get the tx-seq from control word */ -#define L2CAP_FCR_TX_SEQ_BITS_SHIFT 1 /* Bits to shift right to get the tx-seq from ctrl-word */ - -#define L2CAP_FCR_F_BIT 0x0080 /* F-bit in the control word (Sup and I frames) */ -#define L2CAP_FCR_P_BIT 0x0010 /* P-bit in the control word (Sup frames only) */ - -#define L2CAP_FCR_F_BIT_SHIFT 7 -#define L2CAP_FCR_P_BIT_SHIFT 4 - -#define L2CAP_FCR_SEG_BITS 0xC000 /* Mask to get the segmentation bits from ctrl-word */ -#define L2CAP_FCR_SUP_SHIFT 2 /* Bits to shift right to get the S-bits from ctrl-word */ -#define L2CAP_FCR_SUP_BITS 0x000C /* Mask to get the supervisory bits from ctrl-word */ - -#define L2CAP_FCR_INIT_CRC 0 /* Initial state of the CRC register */ -#define L2CAP_FCR_SEQ_MODULO 0x3F /* Mask for sequence numbers (range 0 - 63) */ - -#endif diff --git a/tools/sdk/include/bluedroid/stack/port_api.h b/tools/sdk/include/bluedroid/stack/port_api.h deleted file mode 100644 index 10b03786..00000000 --- a/tools/sdk/include/bluedroid/stack/port_api.h +++ /dev/null @@ -1,657 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * this file contains the PORT API definitions - * - ******************************************************************************/ -#ifndef PORT_API_H -#define PORT_API_H - -#include "common/bt_target.h" - -/***************************************************************************** -** Constants and Types -*****************************************************************************/ - -/* -** Define port settings structure send from the application in the -** set settings request, or to the application in the set settings indication. -*/ -typedef struct { - -#define PORT_BAUD_RATE_2400 0x00 -#define PORT_BAUD_RATE_4800 0x01 -#define PORT_BAUD_RATE_7200 0x02 -#define PORT_BAUD_RATE_9600 0x03 -#define PORT_BAUD_RATE_19200 0x04 -#define PORT_BAUD_RATE_38400 0x05 -#define PORT_BAUD_RATE_57600 0x06 -#define PORT_BAUD_RATE_115200 0x07 -#define PORT_BAUD_RATE_230400 0x08 - - UINT8 baud_rate; - -#define PORT_5_BITS 0x00 -#define PORT_6_BITS 0x01 -#define PORT_7_BITS 0x02 -#define PORT_8_BITS 0x03 - - UINT8 byte_size; - -#define PORT_ONESTOPBIT 0x00 -#define PORT_ONE5STOPBITS 0x01 - UINT8 stop_bits; - -#define PORT_PARITY_NO 0x00 -#define PORT_PARITY_YES 0x01 - UINT8 parity; - -#define PORT_ODD_PARITY 0x00 -#define PORT_EVEN_PARITY 0x01 -#define PORT_MARK_PARITY 0x02 -#define PORT_SPACE_PARITY 0x03 - - UINT8 parity_type; - -#define PORT_FC_OFF 0x00 -#define PORT_FC_XONXOFF_ON_INPUT 0x01 -#define PORT_FC_XONXOFF_ON_OUTPUT 0x02 -#define PORT_FC_CTS_ON_INPUT 0x04 -#define PORT_FC_CTS_ON_OUTPUT 0x08 -#define PORT_FC_DSR_ON_INPUT 0x10 -#define PORT_FC_DSR_ON_OUTPUT 0x20 - - UINT8 fc_type; - - UINT8 rx_char1; - -#define PORT_XON_DC1 0x11 - UINT8 xon_char; - -#define PORT_XOFF_DC3 0x13 - UINT8 xoff_char; - -} tPORT_STATE; - - -/* -** Define the callback function prototypes. Parameters are specific -** to each event and are described bellow -*/ -typedef int (tPORT_DATA_CALLBACK) (UINT16 port_handle, void *p_data, UINT16 len); - -#define DATA_CO_CALLBACK_TYPE_INCOMING 1 -#define DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE 2 -#define DATA_CO_CALLBACK_TYPE_OUTGOING 3 -typedef int (tPORT_DATA_CO_CALLBACK) (UINT16 port_handle, UINT8 *p_buf, UINT16 len, int type); - -typedef void (tPORT_CALLBACK) (UINT32 code, UINT16 port_handle); - -/* -** Define events that registered application can receive in the callback -*/ - -#define PORT_EV_RXCHAR 0x00000001 /* Any Character received */ -#define PORT_EV_RXFLAG 0x00000002 /* Received certain character */ -#define PORT_EV_TXEMPTY 0x00000004 /* Transmitt Queue Empty */ -#define PORT_EV_CTS 0x00000008 /* CTS changed state */ -#define PORT_EV_DSR 0x00000010 /* DSR changed state */ -#define PORT_EV_RLSD 0x00000020 /* RLSD changed state */ -#define PORT_EV_BREAK 0x00000040 /* BREAK received */ -#define PORT_EV_ERR 0x00000080 /* Line status error occurred */ -#define PORT_EV_RING 0x00000100 /* Ring signal detected */ -#define PORT_EV_CTSS 0x00000400 /* CTS state */ -#define PORT_EV_DSRS 0x00000800 /* DSR state */ -#define PORT_EV_RLSDS 0x00001000 /* RLSD state */ -#define PORT_EV_OVERRUN 0x00002000 /* receiver buffer overrun */ -#define PORT_EV_TXCHAR 0x00004000 /* Any character transmitted */ - -#define PORT_EV_CONNECTED 0x00000200 /* RFCOMM connection established */ -#define PORT_EV_CONNECT_ERR 0x00008000 /* Was not able to establish connection */ -/* or disconnected */ -#define PORT_EV_FC 0x00010000 /* data flow enabled flag changed by remote */ -#define PORT_EV_FCS 0x00020000 /* data flow enable status true = enabled */ - -/* -** To register for events application should provide bitmask with -** corresponding bit set -*/ - -#define PORT_MASK_ALL (PORT_EV_RXCHAR | PORT_EV_TXEMPTY | PORT_EV_CTS | \ - PORT_EV_DSR | PORT_EV_RLSD | PORT_EV_BREAK | \ - PORT_EV_ERR | PORT_EV_RING | PORT_EV_CONNECT_ERR | \ - PORT_EV_DSRS | PORT_EV_CTSS | PORT_EV_RLSDS | \ - PORT_EV_RXFLAG | PORT_EV_TXCHAR | PORT_EV_OVERRUN | \ - PORT_EV_FC | PORT_EV_FCS | PORT_EV_CONNECTED) - - -/* -** Define port result codes -*/ -#define PORT_SUCCESS 0 - -#define PORT_ERR_BASE 0 - -#define PORT_UNKNOWN_ERROR (PORT_ERR_BASE + 1) -#define PORT_ALREADY_OPENED (PORT_ERR_BASE + 2) -#define PORT_CMD_PENDING (PORT_ERR_BASE + 3) -#define PORT_APP_NOT_REGISTERED (PORT_ERR_BASE + 4) -#define PORT_NO_MEM (PORT_ERR_BASE + 5) -#define PORT_NO_RESOURCES (PORT_ERR_BASE + 6) -#define PORT_BAD_BD_ADDR (PORT_ERR_BASE + 7) -#define PORT_BAD_HANDLE (PORT_ERR_BASE + 9) -#define PORT_NOT_OPENED (PORT_ERR_BASE + 10) -#define PORT_LINE_ERR (PORT_ERR_BASE + 11) -#define PORT_START_FAILED (PORT_ERR_BASE + 12) -#define PORT_PAR_NEG_FAILED (PORT_ERR_BASE + 13) -#define PORT_PORT_NEG_FAILED (PORT_ERR_BASE + 14) -#define PORT_SEC_FAILED (PORT_ERR_BASE + 15) -#define PORT_PEER_CONNECTION_FAILED (PORT_ERR_BASE + 16) -#define PORT_PEER_FAILED (PORT_ERR_BASE + 17) -#define PORT_PEER_TIMEOUT (PORT_ERR_BASE + 18) -#define PORT_CLOSED (PORT_ERR_BASE + 19) -#define PORT_TX_FULL (PORT_ERR_BASE + 20) -#define PORT_LOCAL_CLOSED (PORT_ERR_BASE + 21) -#define PORT_LOCAL_TIMEOUT (PORT_ERR_BASE + 22) -#define PORT_TX_QUEUE_DISABLED (PORT_ERR_BASE + 23) -#define PORT_PAGE_TIMEOUT (PORT_ERR_BASE + 24) -#define PORT_INVALID_SCN (PORT_ERR_BASE + 25) - -#define PORT_ERR_MAX (PORT_ERR_BASE + 26) - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/******************************************************************************* -** -** Function RFCOMM_CreateConnection -** -** Description RFCOMM_CreateConnection function is used from the application -** to establish serial port connection to the peer device, -** or allow RFCOMM to accept a connection from the peer -** application. -** -** Parameters: scn - Service Channel Number as registered with -** the SDP (server) or obtained using SDP from -** the peer device (client). -** is_server - TRUE if requesting application is a server -** mtu - Maximum frame size the application can accept -** bd_addr - BD_ADDR of the peer (client) -** mask - specifies events to be enabled. A value -** of zero disables all events. -** p_handle - OUT pointer to the handle. -** p_mgmt_cb - pointer to callback function to receive -** connection up/down events. -** Notes: -** -** Server can call this function with the same scn parameter multiple times if -** it is ready to accept multiple simulteneous connections. -** -** DLCI for the connection is (scn * 2 + 1) if client originates connection on -** existing none initiator multiplexer channel. Otherwise it is (scn * 2). -** For the server DLCI can be changed later if client will be calling it using -** (scn * 2 + 1) dlci. -** -*******************************************************************************/ -extern int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, - BOOLEAN is_server, UINT16 mtu, - BD_ADDR bd_addr, UINT16 *p_handle, - tPORT_CALLBACK *p_mgmt_cb); - - -/******************************************************************************* -** -** Function RFCOMM_RemoveConnection -** -** Description This function is called to close the specified connection. -** -** Parameters: handle - Handle of the port returned in the Open -** -*******************************************************************************/ -extern int RFCOMM_RemoveConnection (UINT16 handle); - - -/******************************************************************************* -** -** Function RFCOMM_RemoveServer -** -** Description This function is called to close the server port. -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** -*******************************************************************************/ -extern int RFCOMM_RemoveServer (UINT16 handle); - - -/******************************************************************************* -** -** Function PORT_SetEventCallback -** -** Description Set event callback the specified connection. -** -** Parameters: handle - Handle of the port returned in the Open -** p_callback - address of the callback function which should -** be called from the RFCOMM when an event -** specified in the mask occurs. -** -*******************************************************************************/ -extern int PORT_SetEventCallback (UINT16 port_handle, - tPORT_CALLBACK *p_port_cb); - -/******************************************************************************* -** -** Function PORT_ClearKeepHandleFlag -** -** Description This function is called to clear the keep handle flag -** which will cause not to keep the port handle open when closed -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** -*******************************************************************************/ -int PORT_ClearKeepHandleFlag (UINT16 port_handle); - -/******************************************************************************* -** -** Function PORT_SetEventCallback -** -** Description Set event data callback the specified connection. -** -** Parameters: handle - Handle of the port returned in the Open -** p_callback - address of the callback function which should -** be called from the RFCOMM when a data -** packet is received. -** -*******************************************************************************/ -extern int PORT_SetDataCallback (UINT16 port_handle, - tPORT_DATA_CALLBACK *p_cb); - -extern int PORT_SetDataCOCallback (UINT16 port_handle, tPORT_DATA_CO_CALLBACK *p_port_cb); -/******************************************************************************* -** -** Function PORT_SetEventMask -** -** Description This function is called to close the specified connection. -** -** Parameters: handle - Handle of the port returned in the Open -** mask - specifies events to be enabled. A value -** of zero disables all events. -** -*******************************************************************************/ -extern int PORT_SetEventMask (UINT16 port_handle, UINT32 mask); - - -/******************************************************************************* -** -** Function PORT_CheckConnection -** -** Description This function returns PORT_SUCCESS if connection referenced -** by handle is up and running -** -** Parameters: handle - Handle of the port returned in the Open -** bd_addr - OUT bd_addr of the peer -** p_lcid - OUT L2CAP's LCID -** -*******************************************************************************/ -extern int PORT_CheckConnection (UINT16 handle, BD_ADDR bd_addr, - UINT16 *p_lcid); - -/******************************************************************************* -** -** Function PORT_IsOpening -** -** Description This function returns TRUE if there is any RFCOMM connection -** opening in process. -** -** Parameters: TRUE if any connection opening is found -** bd_addr - bd_addr of the peer -** -*******************************************************************************/ -extern BOOLEAN PORT_IsOpening (BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function PORT_SetState -** -** Description This function configures connection according to the -** specifications in the tPORT_STATE structure. -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** p_settings - Pointer to a tPORT_STATE structure containing -** configuration information for the connection. -** -*******************************************************************************/ -extern int PORT_SetState (UINT16 handle, tPORT_STATE *p_settings); - -/******************************************************************************* -** -** Function PORT_GetRxQueueCnt -** -** Description This function return number of buffers on the rx queue. -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** p_rx_queue_count - Pointer to return queue count in. -** -*******************************************************************************/ -extern int PORT_GetRxQueueCnt (UINT16 handle, UINT16 *p_rx_queue_count); - -/******************************************************************************* -** -** Function PORT_GetState -** -** Description This function is called to fill tPORT_STATE structure -** with the current control settings for the port -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** p_settings - Pointer to a tPORT_STATE structure in which -** configuration information is returned. -** -*******************************************************************************/ -extern int PORT_GetState (UINT16 handle, tPORT_STATE *p_settings); - - -/******************************************************************************* -** -** Function PORT_Control -** -** Description This function directs a specified connection to pass control -** control information to the peer device. -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** signal - specify the function to be passed -** -*******************************************************************************/ -#define PORT_SET_DTRDSR 0x01 -#define PORT_CLR_DTRDSR 0x02 -#define PORT_SET_CTSRTS 0x03 -#define PORT_CLR_CTSRTS 0x04 -#define PORT_SET_RI 0x05 /* DCE only */ -#define PORT_CLR_RI 0x06 /* DCE only */ -#define PORT_SET_DCD 0x07 /* DCE only */ -#define PORT_CLR_DCD 0x08 /* DCE only */ -#define PORT_BREAK 0x09 /* Break event */ - -extern int PORT_Control (UINT16 handle, UINT8 signal); - - -/******************************************************************************* -** -** Function PORT_FlowControl -** -** Description This function directs a specified connection to pass -** flow control message to the peer device. Enable flag passed -** shows if port can accept more data. -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** enable - enables data flow -** -*******************************************************************************/ -extern int PORT_FlowControl (UINT16 handle, BOOLEAN enable); - - -/******************************************************************************* -** -** Function PORT_GetModemStatus -** -** Description This function retrieves modem control signals. Normally -** application will call this function after a callback -** function is called with notification that one of signals -** has been changed. -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** callback. -** p_signal - specify the pointer to control signals info -** -*******************************************************************************/ -#define PORT_DTRDSR_ON 0x01 -#define PORT_CTSRTS_ON 0x02 -#define PORT_RING_ON 0x04 -#define PORT_DCD_ON 0x08 - -/* -** Define default initial local modem signals state set after connection established -*/ -#define PORT_OBEX_DEFAULT_SIGNAL_STATE (PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON) -#define PORT_SPP_DEFAULT_SIGNAL_STATE (PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON) -#define PORT_PPP_DEFAULT_SIGNAL_STATE (PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON) -#define PORT_DUN_DEFAULT_SIGNAL_STATE (PORT_DTRDSR_ON | PORT_CTSRTS_ON) - -extern int PORT_GetModemStatus (UINT16 handle, UINT8 *p_control_signal); - - -/******************************************************************************* -** -** Function PORT_ClearError -** -** Description This function retreives information about a communications -** error and reports current status of a connection. The -** function should be called when an error occures to clear -** the connection error flag and to enable additional read -** and write operations. -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** p_errors - pointer of the variable to receive error codes -** p_status - pointer to the tPORT_STATUS structur to receive -** connection status -** -*******************************************************************************/ - -#define PORT_ERR_BREAK 0x01 /* Break condition occured on the peer device */ -#define PORT_ERR_OVERRUN 0x02 /* Overrun is reported by peer device */ -#define PORT_ERR_FRAME 0x04 /* Framing error reported by peer device */ -#define PORT_ERR_RXOVER 0x08 /* Input queue overflow occured */ -#define PORT_ERR_TXFULL 0x10 /* Output queue overflow occured */ - -typedef struct { -#define PORT_FLAG_CTS_HOLD 0x01 /* Tx is waiting for CTS signal */ -#define PORT_FLAG_DSR_HOLD 0x02 /* Tx is waiting for DSR signal */ -#define PORT_FLAG_RLSD_HOLD 0x04 /* Tx is waiting for RLSD signal */ - - UINT16 flags; - UINT16 in_queue_size; /* Number of bytes in the input queue */ - UINT16 out_queue_size; /* Number of bytes in the output queue */ - UINT16 mtu_size; /* peer MTU size */ -} tPORT_STATUS; - - -extern int PORT_ClearError (UINT16 handle, UINT16 *p_errors, - tPORT_STATUS *p_status); - - -/******************************************************************************* -** -** Function PORT_SendError -** -** Description This function send a communications error to the peer device -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** errors - receive error codes -** -*******************************************************************************/ -extern int PORT_SendError (UINT16 handle, UINT8 errors); - - -/******************************************************************************* -** -** Function PORT_GetQueueStatus -** -** Description This function reports current status of a connection. -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** p_status - pointer to the tPORT_STATUS structur to receive -** connection status -** -*******************************************************************************/ -extern int PORT_GetQueueStatus (UINT16 handle, tPORT_STATUS *p_status); - - -/******************************************************************************* -** -** Function PORT_Purge -** -** Description This function discards all the data from the output or -** input queues of the specified connection. -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** purge_flags - specify the action to take. -** -*******************************************************************************/ -#define PORT_PURGE_TXCLEAR 0x01 -#define PORT_PURGE_RXCLEAR 0x02 - -extern int PORT_Purge (UINT16 handle, UINT8 purge_flags); - - -/******************************************************************************* -** -** Function PORT_Read -** -** Description This function returns the pointer to the buffer received -** from the peer device. Normally application will call this -** function after receiving PORT_EVT_RXCHAR event. -** Application calling this function is responsible to free -** buffer returned. -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** callback. -** pp_buf - pointer to address of buffer with data, -** -*******************************************************************************/ -extern int PORT_Read (UINT16 handle, BT_HDR **pp_buf); - - -/******************************************************************************* -** -** Function PORT_ReadData -** -** Description Normally application will call this function after receiving -** PORT_EVT_RXCHAR event. -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** callback. -** p_data - Data area -** max_len - Byte count requested -** p_len - Byte count received -** -*******************************************************************************/ -extern int PORT_ReadData (UINT16 handle, char *p_data, UINT16 max_len, - UINT16 *p_len); - - -/******************************************************************************* -** -** Function PORT_Write -** -** Description This function to send BT buffer to the peer device. -** Application should not free the buffer. -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** p_buf - pointer to the buffer with data, -** -*******************************************************************************/ -extern int PORT_Write (UINT16 handle, BT_HDR *p_buf); - - -/******************************************************************************* -** -** Function PORT_WriteData -** -** Description This function is called from the legacy application to -** send data. -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** p_data - Data area -** max_len - Byte count to write -** p_len - Bytes written -** -*******************************************************************************/ -extern int PORT_WriteData (UINT16 handle, char *p_data, UINT16 max_len, - UINT16 *p_len); - -/******************************************************************************* -** -** Function PORT_WriteDataCO -** -** Description Normally not GKI aware application will call this function -** to send data to the port by callout functions. -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** -*******************************************************************************/ -extern int PORT_WriteDataCO (UINT16 handle, int *p_len, int len, UINT8 *p_data); - -/******************************************************************************* -** -** Function PORT_Test -** -** Description Application can call this function to send RFCOMM Test frame -** -** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** p_data - Data area -** max_len - Byte count requested -** -*******************************************************************************/ -extern int PORT_Test (UINT16 handle, UINT8 *p_data, UINT16 len); - - -/******************************************************************************* -** -** Function RFCOMM_Init -** -** Description This function is called to initialize RFCOMM layer -** -*******************************************************************************/ -extern void RFCOMM_Init (void); - - -/******************************************************************************* -** -** Function PORT_SetTraceLevel -** -** Description This function sets the trace level for RFCOMM. If called with -** a value of 0xFF, it simply reads the current trace level. -** -** Returns the new (current) trace level -** -*******************************************************************************/ -extern UINT8 PORT_SetTraceLevel (UINT8 new_level); - - -/******************************************************************************* -** -** Function PORT_GetResultString -** -** Description This function returns the human-readable string for a given -** result code. -** -** Returns a pointer to the human-readable string for the given -** result. Note that the string returned must not be freed. -** -*******************************************************************************/ -extern const char *PORT_GetResultString (const uint8_t result_code); - -#ifdef __cplusplus -} -#endif - -#endif /* PORT_API_H */ diff --git a/tools/sdk/include/bluedroid/stack/port_ext.h b/tools/sdk/include/bluedroid/stack/port_ext.h deleted file mode 100644 index 40cdbfce..00000000 --- a/tools/sdk/include/bluedroid/stack/port_ext.h +++ /dev/null @@ -1,31 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains external definitions of Port Emulation entity unit - * - ******************************************************************************/ - -#ifndef PORTEXT_H -#define PORTEXT_H - - -/* Port emulation entity Entry Points */ -extern void rfcomm_process_timeout (TIMER_LIST_ENT *p_tle); -#endif diff --git a/tools/sdk/include/bluedroid/stack/profiles_api.h b/tools/sdk/include/bluedroid/stack/profiles_api.h deleted file mode 100644 index a9ad7b1e..00000000 --- a/tools/sdk/include/bluedroid/stack/profiles_api.h +++ /dev/null @@ -1,70 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2009-2013 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#ifndef PROFILES_API_H -#define PROFILES_API_H - -#include "common/bt_target.h" -#include "stack/btm_api.h" - -/***************************************************************************** -** Constants -*****************************************************************************/ -#define BT_PASS 0 /* Used for general successful function returns */ - -/*** Port entity passes back 8 bit errors; will use upper byte offset ***/ -#define PORT_ERR_GRP 0x0000 /* base offset for port entity */ -#define GAP_ERR_GRP 0x0100 /* base offset for GAP profile */ -#define SPP_ERR_GRP 0x0200 /* base offset for serial port profile */ -#define HCRP_ERR_GRP 0x0300 /* base offset for HCRP */ -#define HCRPM_ERR_GRP 0x0400 /* base offset for HCRPM */ - -/* #define HSP2_ERR_GRP 0x0F00 */ - -/* security level definitions (tBT_SECURITY) */ -#define BT_USE_DEF_SECURITY 0 -#define BT_SEC_MODE_NONE BTM_SEC_MODE_NONE -#define BT_SEC_MODE_SERVICE BTM_SEC_MODE_SERVICE -#define BT_SEC_MODE_LINK BTM_SEC_MODE_LINK - -/* security mask definitions (tBT_SECURITY) */ -/* The following definitions are OR'd together to form the security requirements */ -#define BT_SEC_IN_AUTHORIZE BTM_SEC_IN_AUTHORIZE /* Inbound call requires authorization */ -#define BT_SEC_IN_AUTHENTICATE BTM_SEC_IN_AUTHENTICATE /* Inbound call requires authentication */ -#define BT_SEC_IN_ENCRYPT BTM_SEC_IN_ENCRYPT /* Inbound call requires encryption */ -#define BT_SEC_OUT_AUTHORIZE BTM_SEC_OUT_AUTHORIZE /* Outbound call requires authorization */ -#define BT_SEC_OUT_AUTHENTICATE BTM_SEC_OUT_AUTHENTICATE /* Outbound call requires authentication */ -#define BT_SEC_OUT_ENCRYPT BTM_SEC_OUT_ENCRYPT /* Outbound call requires encryption */ - - -/***************************************************************************** -** Type Definitions -*****************************************************************************/ - -/* -** Security Definitions -** This following definitions are used to indicate the security -** requirements for a service. -*/ -typedef struct { - UINT8 level; - UINT8 mask; -} tBT_SECURITY; - -#endif /* PROFILES_API_H */ - diff --git a/tools/sdk/include/bluedroid/stack/rfcdefs.h b/tools/sdk/include/bluedroid/stack/rfcdefs.h deleted file mode 100644 index dcc37bc7..00000000 --- a/tools/sdk/include/bluedroid/stack/rfcdefs.h +++ /dev/null @@ -1,248 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/**************************************************************************** - * - * This file contains definitions for the RFCOMM protocol - * - ****************************************************************************/ - -#ifndef RFCDEFS_H -#define RFCDEFS_H - -#define PORT_MAX_RFC_PORTS 31 - -/* -** If nothing is negotiated MTU should be 127 -*/ -#define RFCOMM_DEFAULT_MTU 127 - -/* -** Define used by RFCOMM TS frame types -*/ -#define RFCOMM_SABME 0x2F -#define RFCOMM_UA 0x63 -#define RFCOMM_DM 0x0F -#define RFCOMM_DISC 0x43 -#define RFCOMM_UIH 0xEF - -/* -** Defenitions for the TS control frames -*/ -#define RFCOMM_CTRL_FRAME_LEN 3 -#define RFCOMM_MIN_OFFSET 5 /* ctrl 2 , len 1 or 2 bytes, credit 1 byte */ -#define RFCOMM_DATA_OVERHEAD (RFCOMM_MIN_OFFSET + 1) /* add 1 for checksum */ - -#define RFCOMM_EA 1 -#define RFCOMM_EA_MASK 0x01 -#define RFCOMM_CR_MASK 0x02 -#define RFCOMM_SHIFT_CR 1 -#define RFCOMM_SHIFT_DLCI 2 -#define RFCOMM_SHIFT_DLCI2 6 -#define RFCOMM_PF 0x10 -#define RFCOMM_PF_MASK 0x10 -#define RFCOMM_PF_OFFSET 4 -#define RFCOMM_SHIFT_LENGTH1 1 -#define RFCOMM_SHIFT_LENGTH2 7 -#define RFCOMM_SHIFT_MX_CTRL_TYPE 2 - -#define RFCOMM_INITIATOR_CMD 1 -#define RFCOMM_INITIATOR_RSP 0 -#define RFCOMM_RESPONDER_CMD 0 -#define RFCOMM_RESPONDER_RSP 1 - -#define RFCOMM_PARSE_CTRL_FIELD(ea, cr, dlci, p_data) \ -{ \ - ea = *p_data & RFCOMM_EA; \ - cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR; \ - dlci = *p_data++ >> RFCOMM_SHIFT_DLCI; \ - if (!ea) dlci += *p_data++ << RFCOMM_SHIFT_DLCI2; \ -} - -#define RFCOMM_FORMAT_CTRL_FIELD(p_data, ea, cr, dlci) \ - *p_data++ = ea | cr | (dlci << RFCOMM_SHIFT_DLCI) - -#define RFCOMM_PARSE_TYPE_FIELD(type, pf, p_data) \ -{ \ - type = *p_data & ~RFCOMM_PF_MASK; \ - pf = (*p_data++ & RFCOMM_PF_MASK) >> RFCOMM_PF_OFFSET;\ -} - -#define RFCOMM_FORMAT_TYPE_FIELD(p_data, type, pf) \ - *p_data++ = (type | (pf << RFCOMM_PF_OFFSET)) \ -{ \ - type = *p_data & ~RFCOMM_PF_MASK; \ - pf = (*p_data++ & RFCOMM_PF_MASK) >> RFCOMM_PF_OFFSET;\ -} - -#define RFCOMM_PARSE_LEN_FIELD(ea, length, p_data) \ -{ \ - ea = (*p_data & RFCOMM_EA); \ - length = (*p_data++ >> RFCOMM_SHIFT_LENGTH1); \ - if (!ea) length += (*p_data++ << RFCOMM_SHIFT_LENGTH2); \ -} - -#define RFCOMM_FRAME_IS_CMD(initiator, cr) \ - (( (initiator) && !(cr)) || (!(initiator) && (cr))) - -#define RFCOMM_FRAME_IS_RSP(initiator, cr) \ - (( (initiator) && (cr)) || (!(initiator) && !(cr))) - -#define RFCOMM_CR(initiator, is_command) \ - (( ( (initiator) && (is_command)) \ - || (!(initiator) && !(is_command))) << 1) - -#define RFCOMM_I_CR(is_command) ((is_command) ? 0x02 : 0x00) - -#define RFCOMM_MAX_DLCI 61 - -#define RFCOMM_VALID_DLCI(dlci) \ - (((dlci) == 0) || (((dlci) >= 2) && ((dlci) <= RFCOMM_MAX_DLCI))) - - -/* Port Negotiation (PN) */ -#define RFCOMM_PN_DLCI_MASK 0x3F - -#define RFCOMM_PN_FRAM_TYPE_UIH 0x00 -#define RFCOMM_PN_FRAME_TYPE_MASK 0x0F - -#define RFCOMM_PN_CONV_LAYER_MASK 0xF0 -#define RFCOMM_PN_CONV_LAYER_TYPE_1 0 -#define RFCOMM_PN_CONV_LAYER_CBFC_I 0xF0 -#define RFCOMM_PN_CONV_LAYER_CBFC_R 0xE0 - -#define RFCOMM_PN_PRIORITY_MASK 0x3F -#define RFCOMM_PN_PRIORITY_0 0 - -#define RFCOMM_PN_K_MASK 0x07 - -#define RFCOMM_T1_DSEC 0 /* None negotiable in RFCOMM */ -#define RFCOMM_N2 0 /* Number of retransmissions */ -#define RFCOMM_K 0 /* Window size */ -#define RFCOMM_K_MAX 7 /* Max value of K for credit based flow control */ - -#define RFCOMM_MSC_FC 0x02 /* Flow control*/ -#define RFCOMM_MSC_RTC 0x04 /* Ready to communicate*/ -#define RFCOMM_MSC_RTR 0x08 /* Ready to receive*/ -#define RFCOMM_MSC_IC 0x40 /* Incomming call indicator*/ -#define RFCOMM_MSC_DV 0x80 /* Data Valid*/ - -#define RFCOMM_MSC_SHIFT_BREAK 4 -#define RFCOMM_MSC_BREAK_MASK 0xF0 -#define RFCOMM_MSC_BREAK_PRESENT_MASK 0x02 - -#define RFCOMM_BAUD_RATE_2400 0x00 -#define RFCOMM_BAUD_RATE_4800 0x01 -#define RFCOMM_BAUD_RATE_7200 0x02 -#define RFCOMM_BAUD_RATE_9600 0x03 -#define RFCOMM_BAUD_RATE_19200 0x04 -#define RFCOMM_BAUD_RATE_38400 0x05 -#define RFCOMM_BAUD_RATE_57600 0x06 -#define RFCOMM_BAUD_RATE_115200 0x07 -#define RFCOMM_BAUD_RATE_230400 0x08 - -#define RFCOMM_5_BITS 0x00 -#define RFCOMM_6_BITS 0x01 -#define RFCOMM_7_BITS 0x02 -#define RFCOMM_8_BITS 0x03 - -#define RFCOMM_RPN_BITS_MASK 0x03 -#define RFCOMM_RPN_BITS_SHIFT 0 - -#define RFCOMM_ONESTOPBIT 0x00 -#define RFCOMM_ONE5STOPBITS 0x01 - -#define RFCOMM_RPN_STOP_BITS_MASK 0x01 -#define RFCOMM_RPN_STOP_BITS_SHIFT 2 - -#define RFCOMM_PARITY_NO 0x00 -#define RFCOMM_PARITY_YES 0x01 -#define RFCOMM_RPN_PARITY_MASK 0x01 -#define RFCOMM_RPN_PARITY_SHIFT 3 - -#define RFCOMM_ODD_PARITY 0x00 -#define RFCOMM_EVEN_PARITY 0x01 -#define RFCOMM_MARK_PARITY 0x02 -#define RFCOMM_SPACE_PARITY 0x03 - -#define RFCOMM_RPN_PARITY_TYPE_MASK 0x03 -#define RFCOMM_RPN_PARITY_TYPE_SHIFT 4 - -#define RFCOMM_FC_OFF 0x00 -#define RFCOMM_FC_XONXOFF_ON_INPUT 0x01 -#define RFCOMM_FC_XONXOFF_ON_OUTPUT 0x02 -#define RFCOMM_FC_RTR_ON_INPUT 0x04 -#define RFCOMM_FC_RTR_ON_OUTPUT 0x08 -#define RFCOMM_FC_RTC_ON_INPUT 0x10 -#define RFCOMM_FC_RTC_ON_OUTPUT 0x20 -#define RFCOMM_FC_MASK 0x3F - -#define RFCOMM_RPN_PM_BIT_RATE 0x0001 -#define RFCOMM_RPN_PM_DATA_BITS 0x0002 -#define RFCOMM_RPN_PM_STOP_BITS 0x0004 -#define RFCOMM_RPN_PM_PARITY 0x0008 -#define RFCOMM_RPN_PM_PARITY_TYPE 0x0010 -#define RFCOMM_RPN_PM_XON_CHAR 0x0020 -#define RFCOMM_RPN_PM_XOFF_CHAR 0x0040 -#define RFCOMM_RPN_PM_XONXOFF_ON_INPUT 0x0100 -#define RFCOMM_RPN_PM_XONXOFF_ON_OUTPUT 0x0200 -#define RFCOMM_RPN_PM_RTR_ON_INPUT 0x0400 -#define RFCOMM_RPN_PM_RTR_ON_OUTPUT 0x0800 -#define RFCOMM_RPN_PM_RTC_ON_INPUT 0x1000 -#define RFCOMM_RPN_PM_RTC_ON_OUTPUT 0x2000 -#define RFCOMM_RPN_PM_MASK 0x3F7F - -#define RFCOMM_RLS_ERROR 0x01 -#define RFCOMM_RLS_OVERRUN 0x02 -#define RFCOMM_RLS_PARITY 0x04 -#define RFCOMM_RLS_FRAMING 0x08 - -/* Multiplexor channel uses DLCI 0 */ -#define RFCOMM_MX_DLCI 0 - -/* -** Define RFCOMM Multiplexer message types -*/ -#define RFCOMM_MX_PN 0x80 -#define RFCOMM_MX_PN_LEN 8 - -#define RFCOMM_MX_CLD 0xC0 -#define RFCOMM_MX_CLD_LEN 0 - -#define RFCOMM_MX_TEST 0x20 - -#define RFCOMM_MX_FCON 0xA0 -#define RFCOMM_MX_FCON_LEN 0 - -#define RFCOMM_MX_FCOFF 0x60 -#define RFCOMM_MX_FCOFF_LEN 0 - -#define RFCOMM_MX_MSC 0xE0 -#define RFCOMM_MX_MSC_LEN_NO_BREAK 2 -#define RFCOMM_MX_MSC_LEN_WITH_BREAK 3 - -#define RFCOMM_MX_NSC 0x10 -#define RFCOMM_MX_NSC_LEN 1 - -#define RFCOMM_MX_RPN 0x90 -#define RFCOMM_MX_RPN_REQ_LEN 1 -#define RFCOMM_MX_RPN_LEN 8 - -#define RFCOMM_MX_RLS 0x50 -#define RFCOMM_MX_RLS_LEN 2 -#endif diff --git a/tools/sdk/include/bluedroid/stack/sdp_api.h b/tools/sdk/include/bluedroid/stack/sdp_api.h deleted file mode 100644 index a64e5f26..00000000 --- a/tools/sdk/include/bluedroid/stack/sdp_api.h +++ /dev/null @@ -1,726 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#ifndef SDP_API_H -#define SDP_API_H - -#include "common/bt_target.h" -#include "stack/sdpdefs.h" -#if (SDP_INCLUDED == TRUE) -/***************************************************************************** -** Constants -*****************************************************************************/ - -/* Success code and error codes */ -#define SDP_SUCCESS 0x0000 -#define SDP_INVALID_VERSION 0x0001 -#define SDP_INVALID_SERV_REC_HDL 0x0002 -#define SDP_INVALID_REQ_SYNTAX 0x0003 -#define SDP_INVALID_PDU_SIZE 0x0004 -#define SDP_INVALID_CONT_STATE 0x0005 -#define SDP_NO_RESOURCES 0x0006 -#define SDP_DI_REG_FAILED 0x0007 -#define SDP_DI_DISC_FAILED 0x0008 -#define SDP_NO_DI_RECORD_FOUND 0x0009 -#define SDP_ERR_ATTR_NOT_PRESENT 0x000A -#define SDP_ILLEGAL_PARAMETER 0x000B - -#define SDP_NO_RECS_MATCH 0xFFF0 -#define SDP_CONN_FAILED 0xFFF1 -#define SDP_CFG_FAILED 0xFFF2 -#define SDP_GENERIC_ERROR 0xFFF3 -#define SDP_DB_FULL 0xFFF4 -#define SDP_INVALID_PDU 0xFFF5 -#define SDP_SECURITY_ERR 0xFFF6 -#define SDP_CONN_REJECTED 0xFFF7 -#define SDP_CANCEL 0xFFF8 - -/* Define the PSM that SDP uses */ -#define SDP_PSM 0x0001 - -/* Legacy #define to avoid code changes - SDP UUID is same as BT UUID */ -#define tSDP_UUID tBT_UUID - -/* Masks for attr_value field of tSDP_DISC_ATTR */ -#define SDP_DISC_ATTR_LEN_MASK 0x0FFF -#define SDP_DISC_ATTR_TYPE(len_type) (len_type >> 12) -#define SDP_DISC_ATTR_LEN(len_type) (len_type & SDP_DISC_ATTR_LEN_MASK) - -/* Maximum number of protocol list items (list_elem in tSDP_PROTOCOL_ELEM) */ -#define SDP_MAX_LIST_ELEMS 3 - - -/***************************************************************************** -** Type Definitions -*****************************************************************************/ - -/* Define a callback function for when discovery is complete. */ -typedef void (tSDP_DISC_CMPL_CB) (UINT16 result); -typedef void (tSDP_DISC_CMPL_CB2) (UINT16 result, void *user_data); - -typedef struct { - BD_ADDR peer_addr; - UINT16 peer_mtu; -} tSDP_DR_OPEN; - -typedef struct { - UINT8 *p_data; - UINT16 data_len; -} tSDP_DR_DATA; - -typedef union { - tSDP_DR_OPEN open; - tSDP_DR_DATA data; -} tSDP_DATA; - -/* Define a callback function for when discovery result is received. */ -typedef void (tSDP_DISC_RES_CB) (UINT16 event, tSDP_DATA *p_data); - -/* Define a structure to hold the discovered service information. */ -typedef struct { - union { - UINT8 u8; /* 8-bit integer */ - UINT16 u16; /* 16-bit integer */ - UINT32 u32; /* 32-bit integer */ - UINT8 array[4]; /* Variable length field */ - struct t_sdp_disc_attr *p_sub_attr; /* Addr of first sub-attr (list)*/ - } v; - -} tSDP_DISC_ATVAL; - -typedef struct t_sdp_disc_attr { - struct t_sdp_disc_attr *p_next_attr; /* Addr of next linked attr */ - UINT16 attr_id; /* Attribute ID */ - UINT16 attr_len_type; /* Length and type fields */ - tSDP_DISC_ATVAL attr_value; /* Variable length entry data */ -} tSDP_DISC_ATTR; - -typedef struct t_sdp_disc_rec { - tSDP_DISC_ATTR *p_first_attr; /* First attribute of record */ - struct t_sdp_disc_rec *p_next_rec; /* Addr of next linked record */ - UINT32 time_read; /* The time the record was read */ - BD_ADDR remote_bd_addr; /* Remote BD address */ -} tSDP_DISC_REC; - -typedef struct { - UINT32 mem_size; /* Memory size of the DB */ - UINT32 mem_free; /* Memory still available */ - tSDP_DISC_REC *p_first_rec; /* Addr of first record in DB */ - UINT16 num_uuid_filters; /* Number of UUIds to filter */ - tSDP_UUID uuid_filters[SDP_MAX_UUID_FILTERS]; /* UUIDs to filter */ - UINT16 num_attr_filters; /* Number of attribute filters */ - UINT16 attr_filters[SDP_MAX_ATTR_FILTERS]; /* Attributes to filter */ - UINT8 *p_free_mem; /* Pointer to free memory */ -#if (SDP_RAW_DATA_INCLUDED == TRUE) - UINT8 *raw_data; /* Received record from server. allocated/released by client */ - UINT32 raw_size; /* size of raw_data */ - UINT32 raw_used; /* length of raw_data used */ -#endif -} tSDP_DISCOVERY_DB; - -/* This structure is used to add protocol lists and find protocol elements */ -typedef struct { - UINT16 protocol_uuid; - UINT16 num_params; - UINT16 params[SDP_MAX_PROTOCOL_PARAMS]; -} tSDP_PROTOCOL_ELEM; - -typedef struct { - UINT16 num_elems; - tSDP_PROTOCOL_ELEM list_elem[SDP_MAX_LIST_ELEMS]; -} tSDP_PROTO_LIST_ELEM; - -/* Device Identification (DI) data structure -*/ -/* Used to set the DI record */ -typedef struct t_sdp_di_record { - UINT16 vendor; - UINT16 vendor_id_source; - UINT16 product; - UINT16 version; - BOOLEAN primary_record; - char client_executable_url[SDP_MAX_ATTR_LEN]; /* optional */ - char service_description[SDP_MAX_ATTR_LEN]; /* optional */ - char documentation_url[SDP_MAX_ATTR_LEN]; /* optional */ -} tSDP_DI_RECORD; - -/* Used to get the DI record */ -typedef struct t_sdp_di_get_record { - UINT16 spec_id; - tSDP_DI_RECORD rec; -} tSDP_DI_GET_RECORD; - - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/* API into the SDP layer for service discovery. */ - -/******************************************************************************* -** -** Function SDP_InitDiscoveryDb -** -** Description This function is called to initialize a discovery database. -** -** Returns TRUE if successful, FALSE if one or more parameters are bad -** -*******************************************************************************/ -extern BOOLEAN SDP_InitDiscoveryDb (tSDP_DISCOVERY_DB *p_db, UINT32 len, - UINT16 num_uuid, - tSDP_UUID *p_uuid_list, - UINT16 num_attr, - UINT16 *p_attr_list); - -/******************************************************************************* -** -** Function SDP_CancelServiceSearch -** -** Description This function cancels an active query to an SDP server. -** -** Returns TRUE if discovery cancelled, FALSE if a matching activity is not found. -** -*******************************************************************************/ -extern BOOLEAN SDP_CancelServiceSearch (tSDP_DISCOVERY_DB *p_db); - -/******************************************************************************* -** -** Function SDP_ServiceSearchRequest -** -** Description This function queries an SDP server for information. -** -** Returns TRUE if discovery started, FALSE if failed. -** -*******************************************************************************/ -extern BOOLEAN SDP_ServiceSearchRequest (UINT8 *p_bd_addr, - tSDP_DISCOVERY_DB *p_db, - tSDP_DISC_CMPL_CB *p_cb); - - -/******************************************************************************* -** -** Function SDP_ServiceSearchAttributeRequest -** -** Description This function queries an SDP server for information. -** -** The difference between this API function and the function -** SDP_ServiceSearchRequest is that this one does a -** combined ServiceSearchAttributeRequest SDP function. -** -** Returns TRUE if discovery started, FALSE if failed. -** -*******************************************************************************/ -extern BOOLEAN SDP_ServiceSearchAttributeRequest (UINT8 *p_bd_addr, - tSDP_DISCOVERY_DB *p_db, - tSDP_DISC_CMPL_CB *p_cb); - -/******************************************************************************* -** -** Function SDP_ServiceSearchAttributeRequest2 -** -** Description This function queries an SDP server for information. -** -** The difference between this API function and the function -** SDP_ServiceSearchRequest is that this one does a -** combined ServiceSearchAttributeRequest SDP function with the -** user data piggyback -** -** Returns TRUE if discovery started, FALSE if failed. -** -*******************************************************************************/ -extern BOOLEAN SDP_ServiceSearchAttributeRequest2 (UINT8 *p_bd_addr, - tSDP_DISCOVERY_DB *p_db, - tSDP_DISC_CMPL_CB2 *p_cb, void *user_data); - -/* API of utilities to find data in the local discovery database */ - -/******************************************************************************* -** -** Function SDP_FindAttributeInDb -** -** Description This function queries an SDP database for a specific attribute. -** If the p_start_rec pointer is NULL, it looks from the beginning -** of the database, else it continues from the next record after -** p_start_rec. -** -** Returns Pointer to matching record, or NULL -** -*******************************************************************************/ -extern tSDP_DISC_REC *SDP_FindAttributeInDb (tSDP_DISCOVERY_DB *p_db, - UINT16 attr_id, - tSDP_DISC_REC *p_start_rec); - - -/******************************************************************************* -** -** Function SDP_FindAttributeInRec -** -** Description This function searches an SDP discovery record for a -** specific attribute. -** -** Returns Pointer to matching attribute entry, or NULL -** -*******************************************************************************/ -extern tSDP_DISC_ATTR *SDP_FindAttributeInRec (tSDP_DISC_REC *p_rec, - UINT16 attr_id); - - -/******************************************************************************* -** -** Function SDP_FindServiceInDb -** -** Description This function queries an SDP database for a specific service. -** If the p_start_rec pointer is NULL, it looks from the beginning -** of the database, else it continues from the next record after -** p_start_rec. -** -** Returns Pointer to record containing service class, or NULL -** -*******************************************************************************/ -extern tSDP_DISC_REC *SDP_FindServiceInDb (tSDP_DISCOVERY_DB *p_db, - UINT16 service_uuid, - tSDP_DISC_REC *p_start_rec); - - -/******************************************************************************* -** -** Function SDP_FindServiceUUIDInDb -** -** Description This function queries an SDP database for a specific service. -** If the p_start_rec pointer is NULL, it looks from the beginning -** of the database, else it continues from the next record after -** p_start_rec. -** -** NOTE the only difference between this function and the previous -** function "SDP_FindServiceInDb()" is that this function takes -** a tBT_UUID input. -** -** Returns Pointer to record containing service class, or NULL -** -*******************************************************************************/ -extern tSDP_DISC_REC *SDP_FindServiceUUIDInDb (tSDP_DISCOVERY_DB *p_db, - tBT_UUID *p_uuid, - tSDP_DISC_REC *p_start_rec); - -/******************************************************************************* -** -** Function SDP_FindServiceUUIDInRec_128bit -** -** Description This function is called to read the 128-bit service UUID within a record -** if there is any. -** -** Parameters: p_rec - pointer to a SDP record. -** p_uuid - output parameter to save the UUID found. -** -** Returns TRUE if found, otherwise FALSE. -** -*******************************************************************************/ -extern BOOLEAN SDP_FindServiceUUIDInRec_128bit(tSDP_DISC_REC *p_rec, tBT_UUID *p_uuid); - -/******************************************************************************* -** -** Function SDP_FindServiceInDb_128bit -** -** Description This function queries an SDP database for a specific service. -** If the p_start_rec pointer is NULL, it looks from the beginning -** of the database, else it continues from the next record after -** p_start_rec. -** -** Returns Pointer to record containing service class, or NULL -** -*******************************************************************************/ -extern tSDP_DISC_REC *SDP_FindServiceInDb_128bit(tSDP_DISCOVERY_DB *p_db, - tSDP_DISC_REC *p_start_rec); - -/******************************************************************************* -** -** Function SDP_FindProtocolListElemInRec -** -** Description This function looks at a specific discovery record for a -** protocol list element. -** -** Returns TRUE if found, FALSE if not -** If found, the passed protocol list element is filled in. -** -*******************************************************************************/ -extern BOOLEAN SDP_FindProtocolListElemInRec (tSDP_DISC_REC *p_rec, - UINT16 layer_uuid, - tSDP_PROTOCOL_ELEM *p_elem); - - -/******************************************************************************* -** -** Function SDP_FindAddProtoListsElemInRec -** -** Description This function looks at a specific discovery record for a -** protocol list element. -** -** Returns TRUE if found, FALSE if not -** If found, the passed protocol list element is filled in. -** -*******************************************************************************/ -extern BOOLEAN SDP_FindAddProtoListsElemInRec (tSDP_DISC_REC *p_rec, - UINT16 layer_uuid, - tSDP_PROTOCOL_ELEM *p_elem); - - -/******************************************************************************* -** -** Function SDP_FindProfileVersionInRec -** -** Description This function looks at a specific discovery record for the -** Profile list descriptor, and pulls out the version number. -** The version number consists of an 8-bit major version and -** an 8-bit minor version. -** -** Returns TRUE if found, FALSE if not -** If found, the major and minor version numbers that were passed -** in are filled in. -** -*******************************************************************************/ -extern BOOLEAN SDP_FindProfileVersionInRec (tSDP_DISC_REC *p_rec, - UINT16 profile_uuid, - UINT16 *p_version); - - -/* API into SDP for local service database updates */ - -/******************************************************************************* -** -** Function SDP_CreateRecord -** -** Description This function is called to create a record in the database. -** This would be through the SDP database maintenance API. The -** record is created empty, teh application should then call -** "add_attribute" to add the record's attributes. -** -** Returns Record handle if OK, else 0. -** -*******************************************************************************/ -extern UINT32 SDP_CreateRecord (void); - - -/******************************************************************************* -** -** Function SDP_DeleteRecord -** -** Description This function is called to add a record (or all records) -** from the database. This would be through the SDP database -** maintenance API. -** -** If a record handle of 0 is passed, all records are deleted. -** -** Returns TRUE if succeeded, else FALSE -** -*******************************************************************************/ -extern BOOLEAN SDP_DeleteRecord (UINT32 handle); - - -/******************************************************************************* -** -** Function SDP_ReadRecord -** -** Description This function is called to get the raw data of the record -** with the given handle from the database. -** -** Returns -1, if the record is not found. -** Otherwise, the offset (0 or 1) to start of data in p_data. -** -** The size of data copied into p_data is in *p_data_len. -** -*******************************************************************************/ -extern INT32 SDP_ReadRecord(UINT32 handle, UINT8 *p_data, INT32 *p_data_len); - -/******************************************************************************* -** -** Function SDP_AddAttribute -** -** Description This function is called to add an attribute to a record. -** This would be through the SDP database maintenance API. -** If the attribute already exists in the record, it is replaced -** with the new value. -** -** NOTE Attribute values must be passed as a Big Endian stream. -** -** Returns TRUE if added OK, else FALSE -** -*******************************************************************************/ -extern BOOLEAN SDP_AddAttribute (UINT32 handle, UINT16 attr_id, - UINT8 attr_type, UINT32 attr_len, - UINT8 *p_val); - - -/******************************************************************************* -** -** Function SDP_AddSequence -** -** Description This function is called to add a sequence to a record. -** This would be through the SDP database maintenance API. -** If the sequence already exists in the record, it is replaced -** with the new sequence. -** -** NOTE Element values must be passed as a Big Endian stream. -** -** Returns TRUE if added OK, else FALSE -** -*******************************************************************************/ -extern BOOLEAN SDP_AddSequence (UINT32 handle, UINT16 attr_id, - UINT16 num_elem, UINT8 type[], - UINT8 len[], UINT8 *p_val[]); - - -/******************************************************************************* -** -** Function SDP_AddUuidSequence -** -** Description This function is called to add a UUID sequence to a record. -** This would be through the SDP database maintenance API. -** If the sequence already exists in the record, it is replaced -** with the new sequence. -** -** Returns TRUE if added OK, else FALSE -** -*******************************************************************************/ -extern BOOLEAN SDP_AddUuidSequence (UINT32 handle, UINT16 attr_id, - UINT16 num_uuids, UINT16 *p_uuids); - - -/******************************************************************************* -** -** Function SDP_AddProtocolList -** -** Description This function is called to add a protocol descriptor list to -** a record. This would be through the SDP database maintenance API. -** If the protocol list already exists in the record, it is replaced -** with the new list. -** -** Returns TRUE if added OK, else FALSE -** -*******************************************************************************/ -extern BOOLEAN SDP_AddProtocolList (UINT32 handle, UINT16 num_elem, - tSDP_PROTOCOL_ELEM *p_elem_list); - - -/******************************************************************************* -** -** Function SDP_AddAdditionProtoLists -** -** Description This function is called to add a protocol descriptor list to -** a record. This would be through the SDP database maintenance API. -** If the protocol list already exists in the record, it is replaced -** with the new list. -** -** Returns TRUE if added OK, else FALSE -** -*******************************************************************************/ -extern BOOLEAN SDP_AddAdditionProtoLists (UINT32 handle, UINT16 num_elem, - tSDP_PROTO_LIST_ELEM *p_proto_list); - - -/******************************************************************************* -** -** Function SDP_AddProfileDescriptorList -** -** Description This function is called to add a profile descriptor list to -** a record. This would be through the SDP database maintenance API. -** If the version already exists in the record, it is replaced -** with the new one. -** -** Returns TRUE if added OK, else FALSE -** -*******************************************************************************/ -extern BOOLEAN SDP_AddProfileDescriptorList (UINT32 handle, - UINT16 profile_uuid, - UINT16 version); - - -/******************************************************************************* -** -** Function SDP_AddLanguageBaseAttrIDList -** -** Description This function is called to add a language base attr list to -** a record. This would be through the SDP database maintenance API. -** If the version already exists in the record, it is replaced -** with the new one. -** -** Returns TRUE if added OK, else FALSE -** -*******************************************************************************/ -extern BOOLEAN SDP_AddLanguageBaseAttrIDList (UINT32 handle, - UINT16 lang, UINT16 char_enc, - UINT16 base_id); - - -/******************************************************************************* -** -** Function SDP_AddServiceClassIdList -** -** Description This function is called to add a service list to a record. -** This would be through the SDP database maintenance API. -** If the service list already exists in the record, it is replaced -** with the new list. -** -** Returns TRUE if added OK, else FALSE -** -*******************************************************************************/ -extern BOOLEAN SDP_AddServiceClassIdList (UINT32 handle, - UINT16 num_services, - UINT16 *p_service_uuids); - - -/******************************************************************************* -** -** Function SDP_DeleteAttribute -** -** Description This function is called to delete an attribute from a record. -** This would be through the SDP database maintenance API. -** -** Returns TRUE if deleted OK, else FALSE if not found -** -*******************************************************************************/ -extern BOOLEAN SDP_DeleteAttribute (UINT32 handle, UINT16 attr_id); - - -/* Device Identification APIs */ - -/******************************************************************************* -** -** Function SDP_SetLocalDiRecord -** -** Description This function adds a DI record to the local SDP database. -** -** Returns Returns SDP_SUCCESS if record added successfully, else error -** -*******************************************************************************/ -extern UINT16 SDP_SetLocalDiRecord (tSDP_DI_RECORD *device_info, - UINT32 *p_handle); - -/******************************************************************************* -** -** Function SDP_DiDiscover -** -** Description This function queries a remote device for DI information. -** -** Returns SDP_SUCCESS if query started successfully, else error -** -*******************************************************************************/ -extern UINT16 SDP_DiDiscover (BD_ADDR remote_device, - tSDP_DISCOVERY_DB *p_db, UINT32 len, - tSDP_DISC_CMPL_CB *p_cb); - - -/******************************************************************************* -** -** Function SDP_GetNumDiRecords -** -** Description Searches specified database for DI records -** -** Returns number of DI records found -** -*******************************************************************************/ -extern UINT8 SDP_GetNumDiRecords (tSDP_DISCOVERY_DB *p_db); - - -/******************************************************************************* -** -** Function SDP_GetDiRecord -** -** Description This function retrieves a remote device's DI record from -** the specified database. -** -** Returns SDP_SUCCESS if record retrieved, else error -** -*******************************************************************************/ -extern UINT16 SDP_GetDiRecord (UINT8 getRecordIndex, - tSDP_DI_GET_RECORD *device_info, - tSDP_DISCOVERY_DB *p_db); - - -/******************************************************************************* -** -** Function SDP_SetTraceLevel -** -** Description This function sets the trace level for SDP. If called with -** a value of 0xFF, it simply reads the current trace level. -** -** Returns the new (current) trace level -** -*******************************************************************************/ -extern UINT8 SDP_SetTraceLevel (UINT8 new_level); - -/******************************************************************************* -** -** Function SDP_ConnOpen -** -** Description This function creates a connection to the SDP server on the -** given device. -** -** Returns 0, if failed to initiate connection. Otherwise, the handle. -** -*******************************************************************************/ -UINT32 SDP_ConnOpen (UINT8 *p_bd_addr, tSDP_DISC_RES_CB *p_rcb, - tSDP_DISC_CMPL_CB *p_cb); - -/******************************************************************************* -** -** Function SDP_WriteData -** -** Description This function sends data to the connected SDP server. -** -** Returns TRUE if data is sent, FALSE if failed. -** -*******************************************************************************/ -BOOLEAN SDP_WriteData (UINT32 handle, BT_HDR *p_msg); - -/******************************************************************************* -** -** Function SDP_ConnClose -** -** Description This function is called to close a SDP connection. -** -** Parameters: handle - Handle of the connection returned by SDP_ConnOpen -** -** Returns TRUE if connection is closed, FALSE if failed to find the handle. -** -*******************************************************************************/ -BOOLEAN SDP_ConnClose (UINT32 handle); - -/******************************************************************************* -** -** Function SDP_FindServiceUUIDInRec -** -** Description This function is called to read the service UUID within a record -** if there is any. -** -** Parameters: p_rec - pointer to a SDP record. -** -** Returns TRUE if found, otherwise FALSE. -** -*******************************************************************************/ -BOOLEAN SDP_FindServiceUUIDInRec(tSDP_DISC_REC *p_rec, tBT_UUID *p_uuid); - -#ifdef __cplusplus -} -#endif - -#endif ///SDP_INCLUDED == TRUE - -#endif /* SDP_API_H */ diff --git a/tools/sdk/include/bluedroid/stack/sdpdefs.h b/tools/sdk/include/bluedroid/stack/sdpdefs.h deleted file mode 100644 index 44d87e74..00000000 --- a/tools/sdk/include/bluedroid/stack/sdpdefs.h +++ /dev/null @@ -1,327 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains the definitions for the SDP API - * - ******************************************************************************/ - -#ifndef SDP_DEFS_H -#define SDP_DEFS_H - -/* Define the service attribute IDs. -*/ -#define ATTR_ID_SERVICE_RECORD_HDL 0x0000 -#define ATTR_ID_SERVICE_CLASS_ID_LIST 0x0001 -#define ATTR_ID_SERVICE_RECORD_STATE 0x0002 -#define ATTR_ID_SERVICE_ID 0x0003 -#define ATTR_ID_PROTOCOL_DESC_LIST 0x0004 -#define ATTR_ID_BROWSE_GROUP_LIST 0x0005 -#define ATTR_ID_LANGUAGE_BASE_ATTR_ID_LIST 0x0006 -#define ATTR_ID_SERVICE_INFO_TIME_TO_LIVE 0x0007 -#define ATTR_ID_SERVICE_AVAILABILITY 0x0008 -#define ATTR_ID_BT_PROFILE_DESC_LIST 0x0009 -#define ATTR_ID_DOCUMENTATION_URL 0x000A -#define ATTR_ID_CLIENT_EXE_URL 0x000B -#define ATTR_ID_ICON_URL 0x000C -#define ATTR_ID_ADDITION_PROTO_DESC_LISTS 0x000D - -#define LANGUAGE_BASE_ID 0x0100 -#define ATTR_ID_SERVICE_NAME LANGUAGE_BASE_ID + 0x0000 -#define ATTR_ID_SERVICE_DESCRIPTION LANGUAGE_BASE_ID + 0x0001 -#define ATTR_ID_PROVIDER_NAME LANGUAGE_BASE_ID + 0x0002 - -/* Device Identification (DI) -*/ -#define ATTR_ID_SPECIFICATION_ID 0x0200 -#define ATTR_ID_VENDOR_ID 0x0201 -#define ATTR_ID_PRODUCT_ID 0x0202 -#define ATTR_ID_PRODUCT_VERSION 0x0203 -#define ATTR_ID_PRIMARY_RECORD 0x0204 -#define ATTR_ID_VENDOR_ID_SOURCE 0x0205 - -#define BLUETOOTH_DI_SPECIFICATION 0x0103 /* 1.3 */ -#define DI_VENDOR_ID_DEFAULT 0xFFFF -#define DI_VENDOR_ID_SOURCE_BTSIG 0x0001 -#define DI_VENDOR_ID_SOURCE_USBIF 0x0002 - - -#define ATTR_ID_IP_SUBNET 0x0200 /* PAN Profile (***) */ -#define ATTR_ID_VERSION_NUMBER_LIST 0x0200 -#define ATTR_ID_GOEP_L2CAP_PSM 0x0200 -#define ATTR_ID_GROUP_ID 0x0200 -#define ATTR_ID_SERVICE_DATABASE_STATE 0x0201 -#define ATTR_ID_SERVICE_VERSION 0x0300 -#define ATTR_ID_HCRP_1284ID 0x0300 - -#define ATTR_ID_SUPPORTED_DATA_STORES 0x0301 -#define ATTR_ID_NETWORK 0x0301 -#define ATTR_ID_EXTERNAL_NETWORK 0x0301 -#define ATTR_ID_FAX_CLASS_1_SUPPORT 0x0302 -#define ATTR_ID_REMOTE_AUDIO_VOLUME_CONTROL 0x0302 -#define ATTR_ID_DEVICE_NAME 0x0302 -#define ATTR_ID_SUPPORTED_FORMATS_LIST 0x0303 -#define ATTR_ID_FAX_CLASS_2_0_SUPPORT 0x0303 -#define ATTR_ID_FAX_CLASS_2_SUPPORT 0x0304 -#define ATTR_ID_FRIENDLY_NAME 0x0304 -#define ATTR_ID_AUDIO_FEEDBACK_SUPPORT 0x0305 -#define ATTR_ID_NETWORK_ADDRESS 0x0306 -#define ATTR_ID_DEVICE_LOCATION 0x0306 -#define ATTR_ID_WAP_GATEWAY 0x0307 -#define ATTR_ID_HOME_PAGE_URL 0x0308 -#define ATTR_ID_WAP_STACK_TYPE 0x0309 -#define ATTR_ID_IMG_SUPPORTED_CAPABILITIES 0x0310 /* Imaging Profile */ -#define ATTR_ID_SUPPORTED_FEATURES 0x0311 /* HFP, BIP */ -#define ATTR_ID_IMG_SUPPORTED_FUNCTIONS 0x0312 /* Imaging Profile */ -#define ATTR_ID_IMG_TOT_DATA_CAPABILITY 0x0313 /* Imaging Profile */ -#define ATTR_ID_SUPPORTED_REPOSITORIES 0x0314 /* Phone book access Profile */ -#define ATTR_ID_MAS_INSTANCE_ID 0x0315 /* MAP profile */ -#define ATTR_ID_SUPPORTED_MSG_TYPE 0x0316 /* MAP profile */ -#define ATTR_ID_MAP_SUPPORTED_FEATURES 0x0317 /* MAP profile */ -#define ATTR_ID_PBAP_SUPPORTED_FEATURES 0x0317 /* PBAP profile */ - - -/* These values are for the BPP profile */ -#define ATTR_ID_DOCUMENT_FORMATS_SUPPORTED 0x0350 -#define ATTR_ID_CHARACTER_REPERTOIRES_SUPPORTED 0x0352 -#define ATTR_ID_XHTML_IMAGE_FORMATS_SUPPORTED 0x0354 -#define ATTR_ID_COLOR_SUPPORTED 0x0356 -#define ATTR_ID_1284ID 0x0358 -#define ATTR_ID_PRINTER_NAME 0x035A -#define ATTR_ID_PRINTER_LOCATION 0x035C -#define ATTR_ID_DUPLEX_SUPPORTED 0x035E -#define ATTR_ID_MEDIA_TYPES_SUPPORTED 0x0360 -#define ATTR_ID_MAX_MEDIA_WIDTH 0x0362 -#define ATTR_ID_MAX_MEDIA_LENGTH 0x0364 -#define ATTR_ID_ENHANCED_LAYOUT_SUPPORTED 0x0366 -#define ATTR_ID_RUI_FORMATS_SUPPORTED 0x0368 -#define ATTR_ID_RUI_REF_PRINTING_SUPPORTED 0x0370 /* Boolean */ -#define ATTR_ID_RUI_DIRECT_PRINTING_SUPPORTED 0x0372 /* Boolean */ -#define ATTR_ID_REF_PRINTING_TOP_URL 0x0374 -#define ATTR_ID_DIRECT_PRINTING_TOP_URL 0x0376 -#define ATTR_ID_PRINTER_ADMIN_RUI_TOP_URL 0x0378 -#define ATTR_ID_BPP_DEVICE_NAME 0x037A - -/* These values are for the PAN profile */ -#define ATTR_ID_SECURITY_DESCRIPTION 0x030A -#define ATTR_ID_NET_ACCESS_TYPE 0x030B -#define ATTR_ID_MAX_NET_ACCESS_RATE 0x030C -#define ATTR_ID_IPV4_SUBNET 0x030D -#define ATTR_ID_IPV6_SUBNET 0x030E -#define ATTR_ID_PAN_SECURITY 0x0400 - -/* These values are for HID profile */ -#define ATTR_ID_HID_DEVICE_RELNUM 0x0200 -#define ATTR_ID_HID_PARSER_VERSION 0x0201 -#define ATTR_ID_HID_DEVICE_SUBCLASS 0x0202 -#define ATTR_ID_HID_COUNTRY_CODE 0x0203 -#define ATTR_ID_HID_VIRTUAL_CABLE 0x0204 -#define ATTR_ID_HID_RECONNECT_INITIATE 0x0205 -#define ATTR_ID_HID_DESCRIPTOR_LIST 0x0206 -#define ATTR_ID_HID_LANGUAGE_ID_BASE 0x0207 -#define ATTR_ID_HID_SDP_DISABLE 0x0208 -#define ATTR_ID_HID_BATTERY_POWER 0x0209 -#define ATTR_ID_HID_REMOTE_WAKE 0x020A -#define ATTR_ID_HID_PROFILE_VERSION 0x020B -#define ATTR_ID_HID_LINK_SUPERVISION_TO 0x020C -#define ATTR_ID_HID_NORMALLY_CONNECTABLE 0x020D -#define ATTR_ID_HID_BOOT_DEVICE 0x020E -#define ATTR_ID_HID_SSR_HOST_MAX_LAT 0x020F -#define ATTR_ID_HID_SSR_HOST_MIN_TOUT 0x0210 - -/* These values are for the HDP profile */ -#define ATTR_ID_HDP_SUP_FEAT_LIST 0x0200 /* Supported features list */ -#define ATTR_ID_HDP_DATA_EXCH_SPEC 0x0301 /* Data exchange specification */ -#define ATTR_ID_HDP_MCAP_SUP_PROC 0x0302 /* MCAP supported procedures */ - -/* Define common 16-bit protocol UUIDs -*/ -#define UUID_PROTOCOL_SDP 0x0001 -#define UUID_PROTOCOL_UDP 0x0002 -#define UUID_PROTOCOL_RFCOMM 0x0003 -#define UUID_PROTOCOL_TCP 0x0004 -#define UUID_PROTOCOL_TCS_BIN 0x0005 -#define UUID_PROTOCOL_TCS_AT 0x0006 -#define UUID_PROTOCOL_OBEX 0x0008 -#define UUID_PROTOCOL_IP 0x0009 -#define UUID_PROTOCOL_FTP 0x000A -#define UUID_PROTOCOL_HTTP 0x000C -#define UUID_PROTOCOL_WSP 0x000E -#define UUID_PROTOCOL_BNEP 0x000F -#define UUID_PROTOCOL_UPNP 0x0010 -#define UUID_PROTOCOL_HIDP 0x0011 -#define UUID_PROTOCOL_HCRP_CTRL 0x0012 -#define UUID_PROTOCOL_HCRP_DATA 0x0014 -#define UUID_PROTOCOL_HCRP_NOTIF 0x0016 -#define UUID_PROTOCOL_AVCTP 0x0017 -#define UUID_PROTOCOL_AVDTP 0x0019 -#define UUID_PROTOCOL_CMTP 0x001B -#define UUID_PROTOCOL_UDI 0x001D -#define UUID_PROTOCOL_MCAP_CTRL 0x001E -#define UUID_PROTOCOL_MCAP_DATA 0x001F -#define UUID_PROTOCOL_L2CAP 0x0100 -#define UUID_PROTOCOL_ATT 0x0007 - -/* Define common 16-bit service class UUIDs -*/ -#define UUID_SERVCLASS_SERVICE_DISCOVERY_SERVER 0X1000 -#define UUID_SERVCLASS_BROWSE_GROUP_DESCRIPTOR 0X1001 -#define UUID_SERVCLASS_PUBLIC_BROWSE_GROUP 0X1002 -#define UUID_SERVCLASS_SERIAL_PORT 0X1101 -#define UUID_SERVCLASS_LAN_ACCESS_USING_PPP 0X1102 -#define UUID_SERVCLASS_DIALUP_NETWORKING 0X1103 -#define UUID_SERVCLASS_IRMC_SYNC 0X1104 -#define UUID_SERVCLASS_OBEX_OBJECT_PUSH 0X1105 -#define UUID_SERVCLASS_OBEX_FILE_TRANSFER 0X1106 -#define UUID_SERVCLASS_IRMC_SYNC_COMMAND 0X1107 -#define UUID_SERVCLASS_HEADSET 0X1108 -#define UUID_SERVCLASS_CORDLESS_TELEPHONY 0X1109 -#define UUID_SERVCLASS_AUDIO_SOURCE 0X110A -#define UUID_SERVCLASS_AUDIO_SINK 0X110B -#define UUID_SERVCLASS_AV_REM_CTRL_TARGET 0X110C /* Audio/Video Control profile */ -#define UUID_SERVCLASS_ADV_AUDIO_DISTRIBUTION 0X110D /* Advanced Audio Distribution profile */ -#define UUID_SERVCLASS_AV_REMOTE_CONTROL 0X110E /* Audio/Video Control profile */ -#define UUID_SERVCLASS_AV_REM_CTRL_CONTROL 0X110F /* Audio/Video Control profile */ -#define UUID_SERVCLASS_INTERCOM 0X1110 -#define UUID_SERVCLASS_FAX 0X1111 -#define UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY 0X1112 -#define UUID_SERVCLASS_WAP 0X1113 -#define UUID_SERVCLASS_WAP_CLIENT 0X1114 -#define UUID_SERVCLASS_PANU 0X1115 /* PAN profile */ -#define UUID_SERVCLASS_NAP 0X1116 /* PAN profile */ -#define UUID_SERVCLASS_GN 0X1117 /* PAN profile */ -#define UUID_SERVCLASS_DIRECT_PRINTING 0X1118 /* BPP profile */ -#define UUID_SERVCLASS_REFERENCE_PRINTING 0X1119 /* BPP profile */ -#define UUID_SERVCLASS_IMAGING 0X111A /* Imaging profile */ -#define UUID_SERVCLASS_IMAGING_RESPONDER 0X111B /* Imaging profile */ -#define UUID_SERVCLASS_IMAGING_AUTO_ARCHIVE 0X111C /* Imaging profile */ -#define UUID_SERVCLASS_IMAGING_REF_OBJECTS 0X111D /* Imaging profile */ -#define UUID_SERVCLASS_HF_HANDSFREE 0X111E /* Handsfree profile */ -#define UUID_SERVCLASS_AG_HANDSFREE 0X111F /* Handsfree profile */ -#define UUID_SERVCLASS_DIR_PRT_REF_OBJ_SERVICE 0X1120 /* BPP profile */ -#define UUID_SERVCLASS_REFLECTED_UI 0X1121 /* BPP profile */ -#define UUID_SERVCLASS_BASIC_PRINTING 0X1122 /* BPP profile */ -#define UUID_SERVCLASS_PRINTING_STATUS 0X1123 /* BPP profile */ -#define UUID_SERVCLASS_HUMAN_INTERFACE 0X1124 /* HID profile */ -#define UUID_SERVCLASS_CABLE_REPLACEMENT 0X1125 /* HCRP profile */ -#define UUID_SERVCLASS_HCRP_PRINT 0X1126 /* HCRP profile */ -#define UUID_SERVCLASS_HCRP_SCAN 0X1127 /* HCRP profile */ -#define UUID_SERVCLASS_COMMON_ISDN_ACCESS 0X1128 /* CAPI Message Transport Protocol*/ -#define UUID_SERVCLASS_VIDEO_CONFERENCING_GW 0X1129 /* Video Conferencing profile */ -#define UUID_SERVCLASS_UDI_MT 0X112A /* Unrestricted Digital Information profile */ -#define UUID_SERVCLASS_UDI_TA 0X112B /* Unrestricted Digital Information profile */ -#define UUID_SERVCLASS_VCP 0X112C /* Video Conferencing profile */ -#define UUID_SERVCLASS_SAP 0X112D /* SIM Access profile */ -#define UUID_SERVCLASS_PBAP_PCE 0X112E /* Phonebook Access - PCE */ -#define UUID_SERVCLASS_PBAP_PSE 0X112F /* Phonebook Access - PSE */ -#define UUID_SERVCLASS_PHONE_ACCESS 0x1130 -#define UUID_SERVCLASS_HEADSET_HS 0x1131 /* Headset - HS, from HSP v1.2 */ -#define UUID_SERVCLASS_PNP_INFORMATION 0X1200 /* Device Identification */ -#define UUID_SERVCLASS_GENERIC_NETWORKING 0X1201 -#define UUID_SERVCLASS_GENERIC_FILETRANSFER 0X1202 -#define UUID_SERVCLASS_GENERIC_AUDIO 0X1203 -#define UUID_SERVCLASS_GENERIC_TELEPHONY 0X1204 -#define UUID_SERVCLASS_UPNP_SERVICE 0X1205 /* UPNP_Service [ESDP] */ -#define UUID_SERVCLASS_UPNP_IP_SERVICE 0X1206 /* UPNP_IP_Service [ESDP] */ -#define UUID_SERVCLASS_ESDP_UPNP_IP_PAN 0X1300 /* UPNP_IP_PAN [ESDP] */ -#define UUID_SERVCLASS_ESDP_UPNP_IP_LAP 0X1301 /* UPNP_IP_LAP [ESDP] */ -#define UUID_SERVCLASS_ESDP_UPNP_IP_L2CAP 0X1302 /* UPNP_L2CAP [ESDP] */ -#define UUID_SERVCLASS_VIDEO_SOURCE 0X1303 /* Video Distribution Profile (VDP) */ -#define UUID_SERVCLASS_VIDEO_SINK 0X1304 /* Video Distribution Profile (VDP) */ -#define UUID_SERVCLASS_VIDEO_DISTRIBUTION 0X1305 /* Video Distribution Profile (VDP) */ -#define UUID_SERVCLASS_HDP_PROFILE 0X1400 /* Health Device profile (HDP) */ -#define UUID_SERVCLASS_HDP_SOURCE 0X1401 /* Health Device profile (HDP) */ -#define UUID_SERVCLASS_HDP_SINK 0X1402 /* Health Device profile (HDP) */ -#define UUID_SERVCLASS_MAP_PROFILE 0X1134 /* MAP profile UUID */ -#define UUID_SERVCLASS_MESSAGE_ACCESS 0X1132 /* Message Access Service UUID */ -#define UUID_SERVCLASS_MESSAGE_NOTIFICATION 0X1133 /* Message Notification Service UUID */ - -#define UUID_SERVCLASS_GAP_SERVER 0x1800 -#define UUID_SERVCLASS_GATT_SERVER 0x1801 -#define UUID_SERVCLASS_IMMEDIATE_ALERT 0x1802 /* immediate alert */ -#define UUID_SERVCLASS_LINKLOSS 0x1803 /* Link Loss Alert */ -#define UUID_SERVCLASS_TX_POWER 0x1804 /* TX power */ -#define UUID_SERVCLASS_CURRENT_TIME 0x1805 /* Link Loss Alert */ -#define UUID_SERVCLASS_DST_CHG 0x1806 /* DST Time change */ -#define UUID_SERVCLASS_REF_TIME_UPD 0x1807 /* reference time update */ -#define UUID_SERVCLASS_THERMOMETER 0x1809 /* Thermometer UUID */ -#define UUID_SERVCLASS_DEVICE_INFO 0x180A /* device info service */ -#define UUID_SERVCLASS_NWA 0x180B /* Network availability */ -#define UUID_SERVCLASS_HEART_RATE 0x180D /* Heart Rate service */ -#define UUID_SERVCLASS_PHALERT 0x180E /* phone alert service */ -#define UUID_SERVCLASS_BATTERY 0x180F /* battery service */ -#define UUID_SERVCLASS_BPM 0x1810 /* blood pressure service */ -#define UUID_SERVCLASS_ALERT_NOTIFICATION 0x1811 /* alert notification service */ -#define UUID_SERVCLASS_LE_HID 0x1812 /* HID over LE */ -#define UUID_SERVCLASS_SCAN_PARAM 0x1813 /* Scan Parameter service */ -#define UUID_SERVCLASS_GLUCOSE 0x1808 /* Glucose Meter Service */ -#define UUID_SERVCLASS_RSC 0x1814 /* RUNNERS SPEED AND CADENCE SERVICE */ -#define UUID_SERVCLASS_CSC 0x1816 /* Cycling SPEED AND CADENCE SERVICE */ - -#define UUID_SERVCLASS_TEST_SERVER 0x9000 /* Test Group UUID */ - -#if (BTM_WBS_INCLUDED == TRUE ) -#define UUID_CODEC_CVSD 0x0001 /* CVSD */ -#define UUID_CODEC_MSBC 0x0002 /* mSBC */ -#endif - -/* Define all the 'Descriptor Type' values. -*/ -#define NULL_DESC_TYPE 0 -#define UINT_DESC_TYPE 1 -#define TWO_COMP_INT_DESC_TYPE 2 -#define UUID_DESC_TYPE 3 -#define TEXT_STR_DESC_TYPE 4 -#define BOOLEAN_DESC_TYPE 5 -#define DATA_ELE_SEQ_DESC_TYPE 6 -#define DATA_ELE_ALT_DESC_TYPE 7 -#define URL_DESC_TYPE 8 - -/* Define all the "Descriptor Size" values. -*/ -#define SIZE_ONE_BYTE 0 -#define SIZE_TWO_BYTES 1 -#define SIZE_FOUR_BYTES 2 -#define SIZE_EIGHT_BYTES 3 -#define SIZE_SIXTEEN_BYTES 4 -#define SIZE_IN_NEXT_BYTE 5 -#define SIZE_IN_NEXT_WORD 6 -#define SIZE_IN_NEXT_LONG 7 - -/* Language Encoding Constants */ -#define LANG_ID_CODE_ENGLISH ((UINT16) 0x656e) /* "en" */ -#define LANG_ID_CHAR_ENCODE_UTF8 ((UINT16) 0x006a) /* UTF-8 */ - -/* Constants used for display purposes only. These define ovelapping attribute values */ -#define ATTR_ID_VERS_OR_GRP_OR_DRELNUM_OR_IPSUB_OR_SPECID 0x0200 -#define ATTR_ID_VEND_ID_OR_SERVICE_DB_STATE_OR_PARSE_VER 0x0201 -#define ATTR_ID_PROD_ID_OR_HID_DEV_SUBCLASS 0x0202 -#define ATTR_ID_PROD_VER_OR_HID_COUNTRY_CODE 0x0203 -#define ATTR_ID_PRIMARY_REC_OR_HID_VIRTUAL_CABLE 0x0204 -#define ATTR_ID_DI_VENDOR_ID_SOURCE_OR_HID_INIT_RECONNECT 0x0205 -#define ATTR_ID_SERV_VERS_OR_1284ID 0x0300 -#define ATTR_ID_DATA_STORES_OR_NETWORK 0x0301 -#define ATTR_ID_FAX_1_OR_AUD_VOL_OR_DEV_NAME 0x0302 -#define ATTR_ID_FORMATS_OR_FAX_2_0 0x0303 -#define ATTR_ID_FAX_CLASS_2_OR_FRIENDLY_NAME 0x0304 -#define ATTR_ID_NETADDRESS_OR_DEVLOCATION 0x0306 - -#endif - - diff --git a/tools/sdk/include/bluedroid/stack/smp_api.h b/tools/sdk/include/bluedroid/stack/smp_api.h deleted file mode 100644 index 6a3ca5af..00000000 --- a/tools/sdk/include/bluedroid/stack/smp_api.h +++ /dev/null @@ -1,511 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This file contains the SMP API function external definitions. - * - ******************************************************************************/ -#ifndef SMP_API_H -#define SMP_API_H - -#include "common/bt_target.h" - -#define SMP_PIN_CODE_LEN_MAX PIN_CODE_LEN -#define SMP_PIN_CODE_LEN_MIN 6 - -#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE -/* SMP command code */ -#define SMP_OPCODE_PAIRING_REQ 0x01 -#define SMP_OPCODE_PAIRING_RSP 0x02 -#define SMP_OPCODE_CONFIRM 0x03 -#define SMP_OPCODE_RAND 0x04 -#define SMP_OPCODE_PAIRING_FAILED 0x05 -#define SMP_OPCODE_ENCRYPT_INFO 0x06 -#define SMP_OPCODE_MASTER_ID 0x07 -#define SMP_OPCODE_IDENTITY_INFO 0x08 -#define SMP_OPCODE_ID_ADDR 0x09 -#define SMP_OPCODE_SIGN_INFO 0x0A -#define SMP_OPCODE_SEC_REQ 0x0B -#define SMP_OPCODE_PAIR_PUBLIC_KEY 0x0C -#define SMP_OPCODE_PAIR_DHKEY_CHECK 0x0D -#define SMP_OPCODE_PAIR_KEYPR_NOTIF 0x0E -#define SMP_OPCODE_MAX SMP_OPCODE_PAIR_KEYPR_NOTIF -#define SMP_OPCODE_MIN SMP_OPCODE_PAIRING_REQ -#define SMP_OPCODE_PAIR_COMMITM 0x0F -#endif - -/* SMP event type */ -#define SMP_IO_CAP_REQ_EVT 1 /* IO capability request event */ -#define SMP_SEC_REQUEST_EVT 2 /* SMP pairing request */ -#define SMP_PASSKEY_NOTIF_EVT 3 /* passkey notification event */ -#define SMP_PASSKEY_REQ_EVT 4 /* passkey request event */ -#define SMP_OOB_REQ_EVT 5 /* OOB request event */ -#define SMP_NC_REQ_EVT 6 /* Numeric Comparison request event */ -#define SMP_COMPLT_EVT 7 /* SMP complete event */ -#define SMP_PEER_KEYPR_NOT_EVT 8 /* Peer keypress notification received event */ -#define SMP_SC_OOB_REQ_EVT 9 /* SC OOB request event (both local and peer OOB data */ -/* can be expected in response) */ -#define SMP_SC_LOC_OOB_DATA_UP_EVT 10 /* SC OOB local data set is created */ -/* (as result of SMP_CrLocScOobData(...)) */ -#define SMP_BR_KEYS_REQ_EVT 12 /* SMP over BR keys request event */ -typedef UINT8 tSMP_EVT; - - -/* pairing failure reason code */ -#define SMP_PASSKEY_ENTRY_FAIL 0x01 -#define SMP_OOB_FAIL 0x02 -#define SMP_PAIR_AUTH_FAIL 0x03 -#define SMP_CONFIRM_VALUE_ERR 0x04 -#define SMP_PAIR_NOT_SUPPORT 0x05 -#define SMP_ENC_KEY_SIZE 0x06 -#define SMP_INVALID_CMD 0x07 -#define SMP_PAIR_FAIL_UNKNOWN 0x08 -#define SMP_REPEATED_ATTEMPTS 0x09 -#define SMP_INVALID_PARAMETERS 0x0A -#define SMP_DHKEY_CHK_FAIL 0x0B -#define SMP_NUMERIC_COMPAR_FAIL 0x0C -#define SMP_BR_PARING_IN_PROGR 0x0D -#define SMP_XTRANS_DERIVE_NOT_ALLOW 0x0E -#define SMP_MAX_FAIL_RSN_PER_SPEC SMP_XTRANS_DERIVE_NOT_ALLOW - -/* self defined error code */ -#define SMP_PAIR_INTERNAL_ERR (SMP_MAX_FAIL_RSN_PER_SPEC + 0x01) /* 0x0F */ - -/* 0x0F unknown IO capability, unable to decide association model */ -#define SMP_UNKNOWN_IO_CAP (SMP_MAX_FAIL_RSN_PER_SPEC + 0x02) /* 0x10 */ - -#define SMP_INIT_FAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x03) /* 0x11 */ -#define SMP_CONFIRM_FAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x04) /* 0x12 */ -#define SMP_BUSY (SMP_MAX_FAIL_RSN_PER_SPEC + 0x05) /* 0x13 */ -#define SMP_ENC_FAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x06) /* 0x14 */ -#define SMP_STARTED (SMP_MAX_FAIL_RSN_PER_SPEC + 0x07) /* 0x15 */ -#define SMP_RSP_TIMEOUT (SMP_MAX_FAIL_RSN_PER_SPEC + 0x08) /* 0x16 */ -#define SMP_DIV_NOT_AVAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x09) /* 0x17 */ - -/* 0x17 unspecified failed reason */ -#define SMP_FAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0A) /* 0x18 */ - -#define SMP_CONN_TOUT (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0B) /* 0x19 */ -#define SMP_SUCCESS 0 - -typedef UINT8 tSMP_STATUS; - - -/* Device IO capability */ -#define SMP_IO_CAP_OUT BTM_IO_CAP_OUT /* DisplayOnly */ -#define SMP_IO_CAP_IO BTM_IO_CAP_IO /* DisplayYesNo */ -#define SMP_IO_CAP_IN BTM_IO_CAP_IN /* KeyboardOnly */ -#define SMP_IO_CAP_NONE BTM_IO_CAP_NONE /* NoInputNoOutput */ -#define SMP_IO_CAP_KBDISP BTM_IO_CAP_KBDISP /* Keyboard Display */ -#define SMP_IO_CAP_MAX BTM_IO_CAP_MAX -typedef UINT8 tSMP_IO_CAP; - -#ifndef SMP_DEFAULT_IO_CAPS -#define SMP_DEFAULT_IO_CAPS SMP_IO_CAP_KBDISP -#endif - -/* OOB data present or not */ -enum { - SMP_OOB_NONE, - SMP_OOB_PRESENT, - SMP_OOB_UNKNOWN -}; -typedef UINT8 tSMP_OOB_FLAG; - -/* type of OOB data required from application */ -enum { - SMP_OOB_INVALID_TYPE, - SMP_OOB_PEER, - SMP_OOB_LOCAL, - SMP_OOB_BOTH -}; -typedef UINT8 tSMP_OOB_DATA_TYPE; - -#define SMP_AUTH_NO_BOND 0x00 -#define SMP_AUTH_GEN_BOND 0x01 //todo sdh change GEN_BOND to BOND - -/* SMP Authentication requirement */ -#define SMP_AUTH_YN_BIT (1 << 2) -#define SMP_SC_SUPPORT_BIT (1 << 3) -#define SMP_KP_SUPPORT_BIT (1 << 4) - -#define SMP_AUTH_MASK (SMP_AUTH_GEN_BOND|SMP_AUTH_YN_BIT|SMP_SC_SUPPORT_BIT|SMP_KP_SUPPORT_BIT) - -#define SMP_AUTH_BOND SMP_AUTH_GEN_BOND - -/* no MITM, No Bonding, encryption only */ -#define SMP_AUTH_NB_ENC_ONLY 0x00 //(SMP_AUTH_MASK | BTM_AUTH_SP_NO) - -/* MITM, No Bonding, Use IO Capability to determine authentication procedure */ -#define SMP_AUTH_NB_IOCAP (SMP_AUTH_NO_BOND | SMP_AUTH_YN_BIT) - -/* No MITM, General Bonding, Encryption only */ -#define SMP_AUTH_GB_ENC_ONLY (SMP_AUTH_GEN_BOND ) - -/* MITM, General Bonding, Use IO Capability to determine authentication procedure */ -#define SMP_AUTH_GB_IOCAP (SMP_AUTH_GEN_BOND | SMP_AUTH_YN_BIT) - -/* Secure Connections, no MITM, no Bonding */ -#define SMP_AUTH_SC_ENC_ONLY (SMP_SC_SUPPORT_BIT) - -/* Secure Connections, no MITM, Bonding */ -#define SMP_AUTH_SC_GB (SMP_SC_SUPPORT_BIT | SMP_AUTH_GEN_BOND) - -/* Secure Connections, MITM, no Bonding */ -#define SMP_AUTH_SC_MITM_NB (SMP_SC_SUPPORT_BIT | SMP_AUTH_YN_BIT | SMP_AUTH_NO_BOND) - -/* Secure Connections, MITM, Bonding */ -#define SMP_AUTH_SC_MITM_GB (SMP_SC_SUPPORT_BIT | SMP_AUTH_YN_BIT | SMP_AUTH_GEN_BOND) - -/* All AuthReq RFU bits are set to 1 - NOTE: reserved bit in Bonding_Flags is not set */ -#define SMP_AUTH_ALL_RFU_SET 0xF8 - -typedef UINT8 tSMP_AUTH_REQ; - -#define SMP_SEC_NONE 0 -#define SMP_SEC_UNAUTHENTICATE (1 << 0) -#define SMP_SEC_AUTHENTICATED (1 << 2) -typedef UINT8 tSMP_SEC_LEVEL; - -/* Maximum Encryption Key Size range */ -#define SMP_ENCR_KEY_SIZE_MIN 7 -#define SMP_ENCR_KEY_SIZE_MAX 16 - -/* SMP key types */ -#define SMP_SEC_KEY_TYPE_ENC (1 << 0) /* encryption key */ -#define SMP_SEC_KEY_TYPE_ID (1 << 1) /* identity key */ -#define SMP_SEC_KEY_TYPE_CSRK (1 << 2) /* slave CSRK */ -#define SMP_SEC_KEY_TYPE_LK (1 << 3) /* BR/EDR link key */ -typedef UINT8 tSMP_KEYS; - -#define SMP_BR_SEC_DEFAULT_KEY (SMP_SEC_KEY_TYPE_ENC | SMP_SEC_KEY_TYPE_ID | \ - SMP_SEC_KEY_TYPE_CSRK) - -/* default security key distribution value */ -#define SMP_SEC_DEFAULT_KEY (SMP_SEC_KEY_TYPE_ENC | SMP_SEC_KEY_TYPE_ID | \ - SMP_SEC_KEY_TYPE_CSRK | SMP_SEC_KEY_TYPE_LK) - -#define SMP_SC_KEY_STARTED 0 /* passkey entry started */ -#define SMP_SC_KEY_ENTERED 1 /* passkey digit entered */ -#define SMP_SC_KEY_ERASED 2 /* passkey digit erased */ -#define SMP_SC_KEY_CLEARED 3 /* passkey cleared */ -#define SMP_SC_KEY_COMPLT 4 /* passkey entry completed */ -#define SMP_SC_KEY_OUT_OF_RANGE 5 /* out of range */ -typedef UINT8 tSMP_SC_KEY_TYPE; - -/* data type for BTM_SP_IO_REQ_EVT */ -typedef struct { - tSMP_IO_CAP io_cap; /* local IO capabilities */ - tSMP_OOB_FLAG oob_data; /* OOB data present (locally) for the peer device */ - tSMP_AUTH_REQ auth_req; /* Authentication required (for local device) */ - UINT8 max_key_size; /* max encryption key size */ - tSMP_KEYS init_keys; /* initiator keys to be distributed */ - tSMP_KEYS resp_keys; /* responder keys */ -} tSMP_IO_REQ; - -typedef struct { - tSMP_STATUS reason; - tSMP_SEC_LEVEL sec_level; - BOOLEAN is_pair_cancel; - BOOLEAN smp_over_br; -} tSMP_CMPL; - -typedef struct { - BT_OCTET32 x; - BT_OCTET32 y; -} tSMP_PUBLIC_KEY; - -/* the data associated with the info sent to the peer via OOB interface */ -typedef struct { - BOOLEAN present; - BT_OCTET16 randomizer; - BT_OCTET16 commitment; - - tBLE_BD_ADDR addr_sent_to; - BT_OCTET32 private_key_used; /* is used to calculate: */ - /* publ_key_used = P-256(private_key_used, curve_p256.G) - send it to the */ - /* other side */ - /* dhkey = P-256(private_key_used, publ key rcvd from the other side) */ - tSMP_PUBLIC_KEY publ_key_used; /* P-256(private_key_used, curve_p256.G) */ -} tSMP_LOC_OOB_DATA; - -/* the data associated with the info received from the peer via OOB interface */ -typedef struct { - BOOLEAN present; - BT_OCTET16 randomizer; - BT_OCTET16 commitment; - tBLE_BD_ADDR addr_rcvd_from; -} tSMP_PEER_OOB_DATA; - -typedef struct { - tSMP_LOC_OOB_DATA loc_oob_data; - tSMP_PEER_OOB_DATA peer_oob_data; -} tSMP_SC_OOB_DATA; - - -typedef union { - UINT32 passkey; - tSMP_IO_REQ io_req; /* IO request */ - tSMP_CMPL cmplt; - tSMP_OOB_DATA_TYPE req_oob_type; - tSMP_LOC_OOB_DATA loc_oob_data; -} tSMP_EVT_DATA; - - -/* AES Encryption output */ -typedef struct { - UINT8 status; - UINT8 param_len; - UINT16 opcode; - UINT8 param_buf[BT_OCTET16_LEN]; -} tSMP_ENC; - -/* Security Manager events - Called by the stack when Security Manager related events occur.*/ -typedef UINT8 (tSMP_CALLBACK) (tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data); - -/* callback function for CMAC algorithm -*/ -typedef void (tCMAC_CMPL_CBACK)(UINT8 *p_mac, UINT16 tlen, UINT32 sign_counter); - -/***************************************************************************** -** External Function Declarations -*****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif -/* API of SMP */ - -/******************************************************************************* -** -** Function SMP_Init -** -** Description This function initializes the SMP unit. -** -** Returns void -** -*******************************************************************************/ -extern void SMP_Init(void); - -/******************************************************************************* -** -** Function SMP_Free -** -** Description This function de initializes the SMP unit. -** -** Returns void -** -*******************************************************************************/ -extern void SMP_Free(void); - - -/******************************************************************************* -** -** Function SMP_SetTraceLevel -** -** Description This function sets the trace level for SMP. If called with -** a value of 0xFF, it simply returns the current trace level. -** -** Returns The new or current trace level -** -*******************************************************************************/ -extern UINT8 SMP_SetTraceLevel (UINT8 new_level); - -/******************************************************************************* -** -** Function SMP_Register -** -** Description This function register for the SMP service callback. -** -** Returns void -** -*******************************************************************************/ -extern BOOLEAN SMP_Register (tSMP_CALLBACK *p_cback); - -/******************************************************************************* -** -** Function SMP_Pair -** -** Description This function is called to start a SMP pairing. -** -** Returns SMP_STARTED if bond started, else otherwise exception. -** -*******************************************************************************/ -extern tSMP_STATUS SMP_Pair (BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function SMP_BR_PairWith -** -** Description This function is called to start a SMP pairing over BR/EDR. -** -** Returns SMP_STARTED if pairing started, otherwise reason for failure. -** -*******************************************************************************/ -extern tSMP_STATUS SMP_BR_PairWith (BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function SMP_PairCancel -** -** Description This function is called to cancel a SMP pairing. -** -** Returns TRUE - pairing cancelled -** -*******************************************************************************/ -extern BOOLEAN SMP_PairCancel (BD_ADDR bd_addr); - -/******************************************************************************* -** -** Function SMP_SecurityGrant -** -** Description This function is called to grant security process. -** -** Parameters bd_addr - peer device bd address. -** res - result of the operation SMP_SUCCESS if success. -** Otherwise, SMP_REPEATED_ATTEMPTS is too many attempts. -** -** Returns None -** -*******************************************************************************/ -extern void SMP_SecurityGrant(BD_ADDR bd_addr, UINT8 res); - -/******************************************************************************* -** -** Function SMP_PasskeyReply -** -** Description This function is called after Security Manager submitted -** Passkey request to the application. -** -** Parameters: bd_addr - Address of the device for which PIN was requested -** res - result of the operation SMP_SUCCESS if success -** passkey - numeric value in the range of -** BTM_MIN_PASSKEY_VAL(0) - BTM_MAX_PASSKEY_VAL(999999(0xF423F)). -** -*******************************************************************************/ -extern void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey); - -/******************************************************************************* -** -** Function SMP_SetStaticPasskey -** -** Description This function is called to set static passkey -** -** -** Parameters: add - set static passkey when add is TRUE -** clear static passkey when add is FALSE -** passkey - static passkey -** -** -*******************************************************************************/ -extern void SMP_SetStaticPasskey (BOOLEAN add, UINT32 passkey); - -/******************************************************************************* -** -** Function SMP_ConfirmReply -** -** Description This function is called after Security Manager submitted -** numeric comparison request to the application. -** -** Parameters: bd_addr - Address of the device with which numeric -** comparison was requested -** res - comparison result SMP_SUCCESS if success -** -*******************************************************************************/ -extern void SMP_ConfirmReply (BD_ADDR bd_addr, UINT8 res); - -/******************************************************************************* -** -** Function SMP_OobDataReply -** -** Description This function is called to provide the OOB data for -** SMP in response to SMP_OOB_REQ_EVT -** -** Parameters: bd_addr - Address of the peer device -** res - result of the operation SMP_SUCCESS if success -** p_data - SM Randomizer C. -** -*******************************************************************************/ -extern void SMP_OobDataReply(BD_ADDR bd_addr, tSMP_STATUS res, UINT8 len, - UINT8 *p_data); - -/******************************************************************************* -** -** Function SMP_SecureConnectionOobDataReply -** -** Description This function is called to provide the SC OOB data for -** SMP in response to SMP_SC_OOB_REQ_EVT -** -** Parameters: p_data - pointer to the data -** -*******************************************************************************/ -extern void SMP_SecureConnectionOobDataReply(UINT8 *p_data); - -/******************************************************************************* -** -** Function SMP_Encrypt -** -** Description This function is called to encrypt the data with the specified -** key -** -** Parameters: key - Pointer to key key[0] conatins the MSB -** key_len - key length -** plain_text - Pointer to data to be encrypted -** plain_text[0] conatins the MSB -** pt_len - plain text length -** p_out - pointer to the encrypted outputs -** -** Returns Boolean - TRUE: encryption is successful -*******************************************************************************/ -extern BOOLEAN SMP_Encrypt (UINT8 *key, UINT8 key_len, - UINT8 *plain_text, UINT8 pt_len, - tSMP_ENC *p_out); - -/******************************************************************************* -** -** Function SMP_KeypressNotification -** -** Description This function is called to notify SM about Keypress Notification. -** -** Parameters: bd_addr - Address of the device to send keypress -** notification to -** value - keypress notification parameter value -** -*******************************************************************************/ -extern void SMP_KeypressNotification (BD_ADDR bd_addr, UINT8 value); - -/******************************************************************************* -** -** Function SMP_CreateLocalSecureConnectionsOobData -** -** Description This function is called to start creation of local SC OOB -** data set (tSMP_LOC_OOB_DATA). -** -** Parameters: bd_addr - Address of the device to send OOB data block -** to. -** -** Returns Boolean - TRUE: creation of local SC OOB data set started. -*******************************************************************************/ -extern BOOLEAN SMP_CreateLocalSecureConnectionsOobData ( - tBLE_BD_ADDR *addr_to_send_to); - -#ifdef __cplusplus -} -#endif -#endif /* SMP_API_H */ diff --git a/tools/sdk/include/bluedroid/wx_airsync_prf.h b/tools/sdk/include/bluedroid/wx_airsync_prf.h deleted file mode 100644 index 42b9036f..00000000 --- a/tools/sdk/include/bluedroid/wx_airsync_prf.h +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "prf_defs.h" - -#if (WX_AIRSYNC_CFG) - -#include "common/bt_target.h" -#include "stack/gatt_api.h" -#include "stack/gattdefs.h" -#include "bt_app_api.h" - - -/// Maximum Transmission Unit -#define ATT_DEFAULT_MTU (23) - -#define BLE_WECHAT_MAX_DATA_LEN (ATT_DEFAULT_MTU - 3) - - -//define the key serivce uuid -#define ATT_SVC_AIRSYNC 0xFEE7 -//define the airsync Char uuid -#define ATT_CHAR_AIRSYNC_WIT 0xFEC7 -#define ATT_CHAR_AIRSYBC_NTF 0xFEC8 -#define ATT_CHAR_AIRSYNC_READ 0xFEC9 - - -typedef void (tAIRSYNC_CBACK)(UINT8 app_id, UINT8 event, UINT8 len, UINT8 *data); - - -/// WX AirSync Service Attributes Indexes -enum { - WX_IDX_SVC, - WX_IDX_AIRSYNC_WIT_CHAR, - WX_IDX_AIRSYNC_WIT_VAL, - WX_IDX_AIRSYNC_NTF_CHAR, - WX_IDX_AIRSYNC_NTF_VAL, - WX_IDX_AIRSYNC_READ_CHAR, - WX_IDX_AIRSYNC_READ_VAL, - WX_IDX_AIRSYNC_NTF_CFG, - - WX_IDX_NB, -}; - -typedef struct { - BD_ADDR remote_bda; - BOOLEAN need_rsp; - UINT16 clt_cfg; -} tAirSync_WRITE_DATA; - -typedef struct { - BOOLEAN in_use; - BOOLEAN congest; - UINT16 conn_id; - BOOLEAN connected; - BD_ADDR remote_bda; - UINT32 trans_id; - UINT8 cur_srvc_id; - -} tAirSync_CLCB; - - -typedef struct { - UINT8 app_id; - UINT16 airsync_wirt_hdl; - UINT16 airsync_ntf_hdl; - UINT16 airsync_read_hdl; - UINT16 airsync_cfg_hdl; - - tAIRSYNC_CBACK *p_cback; - -} tAirSync_INST; - - -/* service engine control block */ -typedef struct { - tAirSync_CLCB clcb; /* connection link*/ - tGATT_IF gatt_if; - BOOLEAN enabled; - BOOLEAN is_primery; - tAirSync_INST airsync_inst; - UINT8 inst_id; -} tAIRSYNC_CB_ENV; - -void AirSync_CreateService(void); - -tAirSync_CLCB *airsync_env_clcb_alloc (UINT16 conn_id, BD_ADDR remote_bda); - -UINT16 AirSync_env_find_conn_id_by_bd_adddr(BD_ADDR bda); - -BOOLEAN AirSync_env_clcb_dealloc(UINT16 conn_id); - -tGATT_STATUS AirSync_Init(tAIRSYNC_CBACK *call_back); - -void AirSync_msg_notify(UINT8 len, UINT8 *button_msg); - -extern tAIRSYNC_CB_ENV airsync_cb_env; - -#endif ///WX_AIRSYNC_CFG diff --git a/tools/sdk/include/bootloader_support/bootloader_util.h b/tools/sdk/include/bootloader_support/bootloader_util.h new file mode 100644 index 00000000..30f8bd8d --- /dev/null +++ b/tools/sdk/include/bootloader_support/bootloader_util.h @@ -0,0 +1,34 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include + +/** + * @brief Check if half-open intervals overlap + * + * @param start1 interval 1 start + * @param end1 interval 1 end + * @param start2 interval 2 start + * @param end2 interval 2 end + * @return true iff [start1; end1) overlaps [start2; end2) + */ +static inline bool bootloader_util_regions_overlap( + const intptr_t start1, const intptr_t end1, + const intptr_t start2, const intptr_t end2) +{ + return (end1 > start2 && end2 > start1) || + !(end1 <= start2 || end2 <= start1); +} diff --git a/tools/sdk/include/bootloader_support/esp_efuse.h b/tools/sdk/include/bootloader_support/esp_efuse.h index 2f33b05a..c094a6ab 100644 --- a/tools/sdk/include/bootloader_support/esp_efuse.h +++ b/tools/sdk/include/bootloader_support/esp_efuse.h @@ -15,6 +15,7 @@ #define _ESP_EFUSE_H #include "soc/efuse_reg.h" +#include "esp_err.h" #ifdef __cplusplus extern "C" { @@ -58,6 +59,38 @@ void esp_efuse_reset(void); */ void esp_efuse_disable_basic_rom_console(void); +/* @brief Encode one or more sets of 6 byte sequences into + * 8 bytes suitable for 3/4 Coding Scheme. + * + * This function is only useful if the CODING_SCHEME efuse + * is set to value 1 for 3/4 Coding Scheme. + * + * @param[in] in_bytes Pointer to a sequence of bytes to encode for 3/4 Coding Scheme. Must have length in_bytes_len. After being written to hardware, these bytes will read back as little-endian words. + * @param[out] out_words Pointer to array of words suitable for writing to efuse write registers. Array must contain 2 words (8 bytes) for every 6 bytes in in_bytes_len. Can be a pointer to efuse write registers. + * @param in_bytes_len. Length of array pointed to by in_bytes, in bytes. Must be a multiple of 6. + * + * @return ESP_ERR_INVALID_ARG if either pointer is null or in_bytes_len is not a multiple of 6. ESP_OK otherwise. + */ +esp_err_t esp_efuse_apply_34_encoding(const uint8_t *in_bytes, uint32_t *out_words, size_t in_bytes_len); + +/* @brief Write random data to efuse key block write registers + * + * @note Caller is responsible for ensuring efuse + * block is empty and not write protected, before calling. + * + * @note Behaviour depends on coding scheme: a 256-bit key is + * generated and written for Coding Scheme "None", a 192-bit key + * is generated, extended to 256-bits by the Coding Scheme, + * and then writtten for 3/4 Coding Scheme. + * + * @note This function does not burn the new values, caller should + * call esp_efuse_burn_new_values() when ready to do this. + * + * @param blk_wdata0_reg Address of the first data write register + * in the block + */ +void esp_efuse_write_random_key(uint32_t blk_wdata0_reg); + #ifdef __cplusplus } #endif diff --git a/tools/sdk/include/bootloader_support/esp_image_format.h b/tools/sdk/include/bootloader_support/esp_image_format.h index 6d92a35b..bce3b1d7 100644 --- a/tools/sdk/include/bootloader_support/esp_image_format.h +++ b/tools/sdk/include/bootloader_support/esp_image_format.h @@ -81,6 +81,8 @@ typedef struct { _Static_assert(sizeof(esp_image_header_t) == 24, "binary image header should be 24 bytes"); +#define ESP_IMAGE_HASH_LEN 32 /* Length of the appended SHA-256 digest */ + /* Header of binary image segment */ typedef struct { uint32_t load_addr; @@ -201,6 +203,16 @@ esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metad */ esp_err_t esp_image_verify_bootloader(uint32_t *length); +/** + * @brief Verify the bootloader image. + * + * @param[out] Metadata for the image. Only valid if result is ESP_OK. + * + * @return As per esp_image_load_metadata(). + */ +esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data); + + typedef struct { uint32_t drom_addr; uint32_t drom_load_addr; diff --git a/tools/sdk/include/bluedroid/api/esp_a2dp_api.h b/tools/sdk/include/bt/esp_a2dp_api.h similarity index 100% rename from tools/sdk/include/bluedroid/api/esp_a2dp_api.h rename to tools/sdk/include/bt/esp_a2dp_api.h diff --git a/tools/sdk/include/bluedroid/api/esp_avrc_api.h b/tools/sdk/include/bt/esp_avrc_api.h similarity index 100% rename from tools/sdk/include/bluedroid/api/esp_avrc_api.h rename to tools/sdk/include/bt/esp_avrc_api.h diff --git a/tools/sdk/include/bluedroid/api/esp_blufi_api.h b/tools/sdk/include/bt/esp_blufi_api.h similarity index 100% rename from tools/sdk/include/bluedroid/api/esp_blufi_api.h rename to tools/sdk/include/bt/esp_blufi_api.h diff --git a/tools/sdk/include/bluedroid/api/esp_bt_defs.h b/tools/sdk/include/bt/esp_bt_defs.h similarity index 100% rename from tools/sdk/include/bluedroid/api/esp_bt_defs.h rename to tools/sdk/include/bt/esp_bt_defs.h diff --git a/tools/sdk/include/bluedroid/api/esp_bt_device.h b/tools/sdk/include/bt/esp_bt_device.h similarity index 100% rename from tools/sdk/include/bluedroid/api/esp_bt_device.h rename to tools/sdk/include/bt/esp_bt_device.h diff --git a/tools/sdk/include/bluedroid/api/esp_bt_main.h b/tools/sdk/include/bt/esp_bt_main.h similarity index 100% rename from tools/sdk/include/bluedroid/api/esp_bt_main.h rename to tools/sdk/include/bt/esp_bt_main.h diff --git a/tools/sdk/include/bluedroid/api/esp_gap_ble_api.h b/tools/sdk/include/bt/esp_gap_ble_api.h similarity index 90% rename from tools/sdk/include/bluedroid/api/esp_gap_ble_api.h rename to tools/sdk/include/bt/esp_gap_ble_api.h index d4bb6907..5a65decf 100644 --- a/tools/sdk/include/bluedroid/api/esp_gap_ble_api.h +++ b/tools/sdk/include/bt/esp_gap_ble_api.h @@ -54,12 +54,19 @@ typedef uint8_t esp_ble_key_type_t; #define ESP_LE_AUTH_NO_BOND 0x00 /*!< 0*/ /* relate to BTM_LE_AUTH_NO_BOND in stack/btm_api.h */ #define ESP_LE_AUTH_BOND 0x01 /*!< 1 << 0 */ /* relate to BTM_LE_AUTH_BOND in stack/btm_api.h */ #define ESP_LE_AUTH_REQ_MITM (1 << 2) /*!< 1 << 2 */ /* relate to BTM_LE_AUTH_REQ_MITM in stack/btm_api.h */ +#define ESP_LE_AUTH_REQ_BOND_MITM (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_MITM)/*!< 0101*/ #define ESP_LE_AUTH_REQ_SC_ONLY (1 << 3) /*!< 1 << 3 */ /* relate to BTM_LE_AUTH_REQ_SC_ONLY in stack/btm_api.h */ #define ESP_LE_AUTH_REQ_SC_BOND (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_SC_ONLY) /*!< 1001 */ /* relate to BTM_LE_AUTH_REQ_SC_BOND in stack/btm_api.h */ #define ESP_LE_AUTH_REQ_SC_MITM (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY) /*!< 1100 */ /* relate to BTM_LE_AUTH_REQ_SC_MITM in stack/btm_api.h */ #define ESP_LE_AUTH_REQ_SC_MITM_BOND (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY | ESP_LE_AUTH_BOND) /*!< 1101 */ /* relate to BTM_LE_AUTH_REQ_SC_MITM_BOND in stack/btm_api.h */ typedef uint8_t esp_ble_auth_req_t; /*!< combination of the above bit pattern */ +#define ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_DISABLE 0 +#define ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_ENABLE 1 + +#define ESP_BLE_OOB_DISABLE 0 +#define ESP_BLE_OOB_ENABLE 1 + /* relate to BTM_IO_CAP_xxx in stack/btm_api.h */ #define ESP_IO_CAP_OUT 0 /*!< DisplayOnly */ /* relate to BTM_IO_CAP_OUT in stack/btm_api.h */ #define ESP_IO_CAP_IO 1 /*!< DisplayYesNo */ /* relate to BTM_IO_CAP_IO in stack/btm_api.h */ @@ -158,6 +165,7 @@ typedef enum { ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT, /*!< When get the bond device list complete, the event comes */ ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT, /*!< When read the rssi complete, the event comes */ ESP_GAP_BLE_UPDATE_WHITELIST_COMPLETE_EVT, /*!< When add or remove whitelist complete, the event comes */ + ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT, /*!< When update duplicate exceptional list complete, the event comes */ ESP_GAP_BLE_EVT_MAX, } esp_gap_ble_cb_event_t; /// This is the old name, just for backwards compatibility @@ -266,6 +274,8 @@ typedef enum { ESP_BLE_SM_MAX_KEY_SIZE, ESP_BLE_SM_SET_STATIC_PASSKEY, ESP_BLE_SM_CLEAR_STATIC_PASSKEY, + ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH, + ESP_BLE_SM_OOB_SUPPORT, ESP_BLE_SM_MAX_PARAM, } esp_ble_sm_param_t; @@ -282,7 +292,7 @@ typedef struct { esp_ble_adv_type_t adv_type; /*!< Advertising type */ esp_ble_addr_type_t own_addr_type; /*!< Owner bluetooth device address type */ esp_bd_addr_t peer_addr; /*!< Peer device bluetooth device address */ - esp_ble_addr_type_t peer_addr_type; /*!< Peer device bluetooth device address type */ + esp_ble_addr_type_t peer_addr_type; /*!< Peer device bluetooth device address type, only support public address type and random address type */ esp_ble_adv_channel_t channel_map; /*!< Advertising channel map */ esp_ble_adv_filter_t adv_filter_policy; /*!< Advertising filter policy */ } esp_ble_adv_params_t; @@ -292,8 +302,21 @@ typedef struct { bool set_scan_rsp; /*!< Set this advertising data as scan response or not*/ bool include_name; /*!< Advertising data include device name or not */ bool include_txpower; /*!< Advertising data include TX power */ - int min_interval; /*!< Advertising data show advertising min interval */ - int max_interval; /*!< Advertising data show advertising max interval */ + int min_interval; /*!< Advertising data show slave preferred connection min interval. + The connection interval in the following manner: + connIntervalmin = Conn_Interval_Min * 1.25 ms + Conn_Interval_Min range: 0x0006 to 0x0C80 + Value of 0xFFFF indicates no specific minimum. + Values not defined above are reserved for future use.*/ + + int max_interval; /*!< Advertising data show slave preferred connection max interval. + The connection interval in the following manner: + connIntervalmax = Conn_Interval_Max * 1.25 ms + Conn_Interval_Max range: 0x0006 to 0x0C80 + Conn_Interval_Max shall be equal to or greater than the Conn_Interval_Min. + Value of 0xFFFF indicates no specific maximum. + Values not defined above are reserved for future use.*/ + int appearance; /*!< External appearance of device */ uint16_t manufacturer_len; /*!< Manufacturer data length */ uint8_t *p_manufacturer_data; /*!< Manufacturer data point */ @@ -349,8 +372,8 @@ typedef struct { Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms) Time = N * 0.625 msec Time Range: 2.5 msec to 10240 msec */ - esp_ble_scan_duplicate_t scan_duplicate; /*!< The Scan_Duplicates parameter controls whether the Link Layer should filter out - duplicate advertising reports (BLE_SCAN_DUPLICATE_ENABLE) to the Host, or if the Link Layer should generate + esp_ble_scan_duplicate_t scan_duplicate; /*!< The Scan_Duplicates parameter controls whether the Link Layer should filter out + duplicate advertising reports (BLE_SCAN_DUPLICATE_ENABLE) to the Host, or if the Link Layer should generate advertising reports for each packet received */ } esp_ble_scan_params_t; @@ -511,6 +534,7 @@ typedef struct uint8_t fail_reason; /*!< The HCI reason/error code for when success=FALSE */ esp_ble_addr_type_t addr_type; /*!< Peer device address type */ esp_bt_dev_type_t dev_type; /*!< Device type */ + esp_ble_auth_req_t auth_mode; /*!< authentication mode */ } esp_ble_auth_cmpl_t; /*!< The ble authentication complete cb type */ /** @@ -552,6 +576,28 @@ typedef enum{ ESP_BLE_WHITELIST_REMOVE = 0X00, /*!< remove mac from whitelist */ ESP_BLE_WHITELIST_ADD = 0X01, /*!< add address to whitelist */ }esp_ble_wl_opration_t; + +typedef enum { + ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_ADD = 0, /*!< Add device info into duplicate scan exceptional list */ + ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_REMOVE, /*!< Remove device info from duplicate scan exceptional list */ + ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_CLEAN, /*!< Clean duplicate scan exceptional list */ +} esp_bt_duplicate_exceptional_subcode_type_t; + +#define BLE_BIT(n) (1UL<<(n)) + +typedef enum { + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_ADV_ADDR = 0, /*!< BLE advertising address , device info will be added into ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ADDR_LIST */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_LINK_ID, /*!< BLE mesh link ID, it is for BLE mesh, device info will be added into ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_LINK_ID_LIST */ +} esp_ble_duplicate_exceptional_info_type_t; + +typedef enum { + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ADDR_LIST = BLE_BIT(0), /*!< duplicate scan exceptional addr list */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_LINK_ID_LIST = BLE_BIT(1), /*!< duplicate scan exceptional mesh link ID list */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ALL_LIST = (BLE_BIT(0) | BLE_BIT(1)), /*!< duplicate scan exceptional all list */ +} esp_duplicate_scan_exceptional_list_type_t; + +typedef uint8_t esp_duplicate_info_t[ESP_BD_ADDR_LEN]; + /** * @brief Gap callback parameters union */ @@ -697,6 +743,15 @@ typedef union { esp_bt_status_t status; /*!< Indicate the add or remove whitelist operation success status */ esp_ble_wl_opration_t wl_opration; /*!< The value is ESP_BLE_WHITELIST_ADD if add address to whitelist operation success, ESP_BLE_WHITELIST_REMOVE if remove address from the whitelist operation success */ } update_whitelist_cmpl; /*!< Event parameter of ESP_GAP_BLE_UPDATE_WHITELIST_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT + */ + struct ble_update_duplicate_exceptional_list_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate update duplicate scan exceptional list operation success status */ + uint8_t subcode; /*!< Define in esp_bt_duplicate_exceptional_subcode_type_t */ + uint16_t length; /*!< The length of device_info */ + esp_duplicate_info_t device_info; /*!< device information, when subcode is ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_CLEAN, the value is invalid */ + } update_duplicate_exceptional_list_cmpl; /*!< Event parameter of ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT */ } esp_ble_gap_cb_param_t; /** @@ -820,10 +875,8 @@ esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params); */ esp_err_t esp_ble_gap_set_pkt_data_len(esp_bd_addr_t remote_device, uint16_t tx_data_length); - - /** - * @brief This function set the random address for the application + * @brief This function sets the random address for the application * * @param[in] rand_addr: the random address which should be setting * @@ -834,6 +887,16 @@ esp_err_t esp_ble_gap_set_pkt_data_len(esp_bd_addr_t remote_device, uint16_t tx_ */ esp_err_t esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr); +/** + * @brief This function clears the random address for the application + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_clear_rand_addr(void); + /** @@ -936,8 +999,7 @@ esp_err_t esp_ble_gap_get_local_used_addr(esp_bd_addr_t local_used_addr, uint8_t * @param[in] type - finding ADV data type * @param[out] length - return the length of ADV data not including type * - * @return - ESP_OK : success - * - other : failed + * @return pointer of ADV data * */ uint8_t *esp_ble_resolve_adv_data(uint8_t *adv_data, uint8_t type, uint8_t *length); @@ -982,6 +1044,43 @@ esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_d */ esp_err_t esp_ble_gap_read_rssi(esp_bd_addr_t remote_addr); +/** + * @brief This function is called to add a device info into the duplicate scan exceptional list. + * + * + * @param[in] type: device info type, it is defined in esp_ble_duplicate_exceptional_info_type_t + * @param[in] device_info: the device information. + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_gap_add_duplicate_scan_exceptional_device(esp_ble_duplicate_exceptional_info_type_t type, esp_duplicate_info_t device_info); + +/** + * @brief This function is called to remove a device info from the duplicate scan exceptional list. + * + * + * @param[in] type: device info type, it is defined in esp_ble_duplicate_exceptional_info_type_t + * @param[in] device_info: the device information. + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_gap_remove_duplicate_scan_exceptional_device(esp_ble_duplicate_exceptional_info_type_t type, esp_duplicate_info_t device_info); + +/** + * @brief This function is called to clean the duplicate scan exceptional list. + * This API will delete all device information in the duplicate scan exceptional list. + * + * + * @param[in] list_type: duplicate scan exceptional list type, the value can be one or more of esp_duplicate_scan_exceptional_list_type_t. + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_gap_clean_duplicate_scan_exceptional_list(esp_duplicate_scan_exceptional_list_type_t list_type); + #if (SMP_INCLUDED == TRUE) /** * @brief Set a GAP security parameter value. Overrides the default value. @@ -1090,6 +1189,20 @@ int esp_ble_get_bond_device_num(void); */ esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_list); +/** +* @brief This function is called to provide the OOB data for +* SMP in response to ESP_GAP_BLE_OOB_REQ_EVT +* +* @param[in] bd_addr: BD address of the peer device. +* @param[in] TK: TK value, the TK value shall be a 128-bit random number +* @param[in] len: length of tk, should always be 128-bit +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t *TK, uint8_t len); + #endif /* #if (SMP_INCLUDED == TRUE) */ /** diff --git a/tools/sdk/include/bluedroid/api/esp_gap_bt_api.h b/tools/sdk/include/bt/esp_gap_bt_api.h similarity index 100% rename from tools/sdk/include/bluedroid/api/esp_gap_bt_api.h rename to tools/sdk/include/bt/esp_gap_bt_api.h diff --git a/tools/sdk/include/bluedroid/api/esp_gatt_common_api.h b/tools/sdk/include/bt/esp_gatt_common_api.h similarity index 100% rename from tools/sdk/include/bluedroid/api/esp_gatt_common_api.h rename to tools/sdk/include/bt/esp_gatt_common_api.h diff --git a/tools/sdk/include/bluedroid/api/esp_gatt_defs.h b/tools/sdk/include/bt/esp_gatt_defs.h similarity index 98% rename from tools/sdk/include/bluedroid/api/esp_gatt_defs.h rename to tools/sdk/include/bt/esp_gatt_defs.h index de4bc897..d6c140a1 100644 --- a/tools/sdk/include/bluedroid/api/esp_gatt_defs.h +++ b/tools/sdk/include/bt/esp_gatt_defs.h @@ -289,6 +289,11 @@ typedef uint8_t esp_gatt_char_prop_t; /// GATT maximum attribute length #define ESP_GATT_MAX_ATTR_LEN 600 //as same as GATT_MAX_ATTR_LEN +typedef enum { + ESP_GATT_SERVICE_FROM_REMOTE_DEVICE = 0, /* relate to BTA_GATTC_SERVICE_INFO_FROM_REMOTE_DEVICE in bta_gattc_int.h */ + ESP_GATT_SERVICE_FROM_NVS_FLASH = 1, /* relate to BTA_GATTC_SERVICE_INFO_FROM_NVS_FLASH in bta_gattc_int.h */ + ESP_GATT_SERVICE_FROM_UNKNOWN = 2, /* relate to BTA_GATTC_SERVICE_INFO_FROM_UNKNOWN in bta_gattc_int.h */ +} esp_service_source_t; /** * @brief Attribute description (used to create database) diff --git a/tools/sdk/include/bluedroid/api/esp_gattc_api.h b/tools/sdk/include/bt/esp_gattc_api.h similarity index 98% rename from tools/sdk/include/bluedroid/api/esp_gattc_api.h rename to tools/sdk/include/bt/esp_gattc_api.h index b0fabb7a..b494bcfd 100644 --- a/tools/sdk/include/bluedroid/api/esp_gattc_api.h +++ b/tools/sdk/include/bt/esp_gattc_api.h @@ -115,9 +115,10 @@ typedef union { * @brief ESP_GATTC_SEARCH_CMPL_EVT */ struct gattc_search_cmpl_evt_param { - esp_gatt_status_t status; /*!< Operation status */ - uint16_t conn_id; /*!< Connection id */ - } search_cmpl; /*!< Gatt client callback param of ESP_GATTC_SEARCH_CMPL_EVT */ + esp_gatt_status_t status; /*!< Operation status */ + uint16_t conn_id; /*!< Connection id */ + esp_service_source_t searched_service_source; /*!< The source of the service information */ + } search_cmpl; /*!< Gatt client callback param of ESP_GATTC_SEARCH_CMPL_EVT */ /** * @brief ESP_GATTC_SEARCH_RES_EVT @@ -346,7 +347,8 @@ esp_err_t esp_ble_gattc_send_mtu_req (esp_gatt_if_t gattc_if, uint16_t conn_id); /** - * @brief This function is called to request a GATT service discovery + * @brief This function is called to get service from local cache. + * If it does not exist, request a GATT service discovery * on a GATT server. This function report service search result * by a callback event, and followed by a service search complete * event. diff --git a/tools/sdk/include/bluedroid/api/esp_gatts_api.h b/tools/sdk/include/bt/esp_gatts_api.h similarity index 85% rename from tools/sdk/include/bluedroid/api/esp_gatts_api.h rename to tools/sdk/include/bt/esp_gatts_api.h index d25d2978..97296b1c 100644 --- a/tools/sdk/include/bluedroid/api/esp_gatts_api.h +++ b/tools/sdk/include/bt/esp_gatts_api.h @@ -25,31 +25,32 @@ extern "C" { /// GATT Server callback function events typedef enum { - ESP_GATTS_REG_EVT = 0, /*!< When register application id, the event comes */ - ESP_GATTS_READ_EVT = 1, /*!< When gatt client request read operation, the event comes */ - ESP_GATTS_WRITE_EVT = 2, /*!< When gatt client request write operation, the event comes */ - ESP_GATTS_EXEC_WRITE_EVT = 3, /*!< When gatt client request execute write, the event comes */ - ESP_GATTS_MTU_EVT = 4, /*!< When set mtu complete, the event comes */ - ESP_GATTS_CONF_EVT = 5, /*!< When receive confirm, the event comes */ - ESP_GATTS_UNREG_EVT = 6, /*!< When unregister application id, the event comes */ - ESP_GATTS_CREATE_EVT = 7, /*!< When create service complete, the event comes */ - ESP_GATTS_ADD_INCL_SRVC_EVT = 8, /*!< When add included service complete, the event comes */ - ESP_GATTS_ADD_CHAR_EVT = 9, /*!< When add characteristic complete, the event comes */ - ESP_GATTS_ADD_CHAR_DESCR_EVT = 10, /*!< When add descriptor complete, the event comes */ - ESP_GATTS_DELETE_EVT = 11, /*!< When delete service complete, the event comes */ - ESP_GATTS_START_EVT = 12, /*!< When start service complete, the event comes */ - ESP_GATTS_STOP_EVT = 13, /*!< When stop service complete, the event comes */ - ESP_GATTS_CONNECT_EVT = 14, /*!< When gatt client connect, the event comes */ - ESP_GATTS_DISCONNECT_EVT = 15, /*!< When gatt client disconnect, the event comes */ - ESP_GATTS_OPEN_EVT = 16, /*!< When connect to peer, the event comes */ - ESP_GATTS_CANCEL_OPEN_EVT = 17, /*!< When disconnect from peer, the event comes */ - ESP_GATTS_CLOSE_EVT = 18, /*!< When gatt server close, the event comes */ - ESP_GATTS_LISTEN_EVT = 19, /*!< When gatt listen to be connected the event comes */ - ESP_GATTS_CONGEST_EVT = 20, /*!< When congest happen, the event comes */ + ESP_GATTS_REG_EVT = 0, /*!< When register application id, the event comes */ + ESP_GATTS_READ_EVT = 1, /*!< When gatt client request read operation, the event comes */ + ESP_GATTS_WRITE_EVT = 2, /*!< When gatt client request write operation, the event comes */ + ESP_GATTS_EXEC_WRITE_EVT = 3, /*!< When gatt client request execute write, the event comes */ + ESP_GATTS_MTU_EVT = 4, /*!< When set mtu complete, the event comes */ + ESP_GATTS_CONF_EVT = 5, /*!< When receive confirm, the event comes */ + ESP_GATTS_UNREG_EVT = 6, /*!< When unregister application id, the event comes */ + ESP_GATTS_CREATE_EVT = 7, /*!< When create service complete, the event comes */ + ESP_GATTS_ADD_INCL_SRVC_EVT = 8, /*!< When add included service complete, the event comes */ + ESP_GATTS_ADD_CHAR_EVT = 9, /*!< When add characteristic complete, the event comes */ + ESP_GATTS_ADD_CHAR_DESCR_EVT = 10, /*!< When add descriptor complete, the event comes */ + ESP_GATTS_DELETE_EVT = 11, /*!< When delete service complete, the event comes */ + ESP_GATTS_START_EVT = 12, /*!< When start service complete, the event comes */ + ESP_GATTS_STOP_EVT = 13, /*!< When stop service complete, the event comes */ + ESP_GATTS_CONNECT_EVT = 14, /*!< When gatt client connect, the event comes */ + ESP_GATTS_DISCONNECT_EVT = 15, /*!< When gatt client disconnect, the event comes */ + ESP_GATTS_OPEN_EVT = 16, /*!< When connect to peer, the event comes */ + ESP_GATTS_CANCEL_OPEN_EVT = 17, /*!< When disconnect from peer, the event comes */ + ESP_GATTS_CLOSE_EVT = 18, /*!< When gatt server close, the event comes */ + ESP_GATTS_LISTEN_EVT = 19, /*!< When gatt listen to be connected the event comes */ + ESP_GATTS_CONGEST_EVT = 20, /*!< When congest happen, the event comes */ /* following is extra event */ - ESP_GATTS_RESPONSE_EVT = 21, /*!< When gatt send response complete, the event comes */ - ESP_GATTS_CREAT_ATTR_TAB_EVT = 22, - ESP_GATTS_SET_ATTR_VAL_EVT = 23, + ESP_GATTS_RESPONSE_EVT = 21, /*!< When gatt send response complete, the event comes */ + ESP_GATTS_CREAT_ATTR_TAB_EVT = 22, /*!< When gatt create table complete, the event comes */ + ESP_GATTS_SET_ATTR_VAL_EVT = 23, /*!< When gatt set attr value complete, the event comes */ + ESP_GATTS_SEND_SERVICE_CHANGE_EVT = 24, /*!< When gatt send service change indication complete, the event comes */ } esp_gatts_cb_event_t; /** @@ -119,6 +120,7 @@ typedef union { struct gatts_conf_evt_param { esp_gatt_status_t status; /*!< Operation status */ uint16_t conn_id; /*!< Connection id */ + uint16_t handle; /*!< attribute handle */ uint16_t len; /*!< The indication or notification value length, len is valid when send notification or indication failed */ uint8_t *value; /*!< The indication or notification value , value is valid when send notification or indication failed */ } conf; /*!< Gatt server callback param of ESP_GATTS_CONF_EVT (confirm) */ @@ -267,6 +269,13 @@ typedef union { esp_gatt_status_t status; /*!< Operation status*/ } set_attr_val; /*!< Gatt server callback param of ESP_GATTS_SET_ATTR_VAL_EVT */ + /** + * @brief ESP_GATTS_SEND_SERVICE_CHANGE_EVT + */ + struct gatts_send_service_change_evt_param{ + esp_gatt_status_t status; /*!< Operation status*/ + } service_change; /*!< Gatt server callback param of ESP_GATTS_SEND_SERVICE_CHANGE_EVT */ + } esp_ble_gatts_cb_param_t; /** @@ -550,6 +559,22 @@ esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, b */ esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id); +/** + * @brief Send service change indication + * + * @param[in] gatts_if: GATT server access interface + * @param[in] remote_bda: remote device bluetooth device address. + * If remote_bda is NULL then it will send service change + * indication to all the connected devices and if not then + * to a specific device + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_send_service_change_indication(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda); + #ifdef __cplusplus } #endif diff --git a/tools/sdk/include/bluedroid/api/esp_hf_client_api.h b/tools/sdk/include/bt/esp_hf_client_api.h similarity index 98% rename from tools/sdk/include/bluedroid/api/esp_hf_client_api.h rename to tools/sdk/include/bt/esp_hf_client_api.h index 67ec894e..dfc06ed5 100644 --- a/tools/sdk/include/bluedroid/api/esp_hf_client_api.h +++ b/tools/sdk/include/bt/esp_hf_client_api.h @@ -251,9 +251,9 @@ typedef union { } esp_hf_client_cb_param_t; /** - * @brief HFP client incoming data callback function, the callback is useful in case of + * @brief HFP client incoming data callback function, the callback is useful in case of * Voice Over HCI. - * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the + * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the * buffer is allocated inside bluetooth protocol stack and will be released after * invoke of the callback is finished. * @param[in] len : size(in bytes) in buf @@ -261,13 +261,13 @@ typedef union { typedef void (* esp_hf_client_incoming_data_cb_t)(const uint8_t *buf, uint32_t len); /** - * @brief HFP client outgoing data callback function, the callback is useful in case of - * Voice Over HCI. Once audio connection is set up and the application layer has - * prepared data to send, the lower layer will call this function to read data + * @brief HFP client outgoing data callback function, the callback is useful in case of + * Voice Over HCI. Once audio connection is set up and the application layer has + * prepared data to send, the lower layer will call this function to read data * and then send. This callback is supposed to be implemented as non-blocking, * and if data is not enough, return value 0 is supposed. - * - * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the + * + * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the * buffer is allocated inside bluetooth protocol stack and will be released after * invoke of the callback is finished. * @param[in] len : size(in bytes) in buf @@ -326,7 +326,7 @@ esp_err_t esp_hf_client_deinit(void); /** * - * @brief Connect to remote bluetooth HFP audio gateway(AG) device, must after esp_a2d_hf_client_init() + * @brief Connect to remote bluetooth HFP audio gateway(AG) device, must after esp_hf_client_init() * * @param[in] remote_bda: remote bluetooth device address * @@ -606,7 +606,7 @@ void esp_hf_client_outgoing_data_ready(void); /** * @brief Initialize the down sampling converter. This is a utility function that can - * only be used in the case that Voice Over HCI is enabled. + * only be used in the case that Voice Over HCI is enabled. * * @param[in] src_sps: original samples per second(source audio data, i.e. 48000, 32000, * 16000, 44100, 22050, 11025) diff --git a/tools/sdk/include/bluedroid/api/esp_hf_defs.h b/tools/sdk/include/bt/esp_hf_defs.h similarity index 100% rename from tools/sdk/include/bluedroid/api/esp_hf_defs.h rename to tools/sdk/include/bt/esp_hf_defs.h diff --git a/tools/sdk/include/bluedroid/api/esp_spp_api.h b/tools/sdk/include/bt/esp_spp_api.h similarity index 99% rename from tools/sdk/include/bluedroid/api/esp_spp_api.h rename to tools/sdk/include/bt/esp_spp_api.h index d7f35774..31bcf1c6 100644 --- a/tools/sdk/include/bluedroid/api/esp_spp_api.h +++ b/tools/sdk/include/bt/esp_spp_api.h @@ -190,8 +190,7 @@ esp_err_t esp_spp_register_callback(esp_spp_cb_t callback); /** * @brief This function is called to init SPP. * - * @param[in] mode: Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_CB. - * Now only supports ESP_SPP_MODE_CB mode, we will continue to update. + * @param[in] mode: Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_VFS. * * @return * - ESP_OK: success diff --git a/tools/sdk/include/coap/address.h b/tools/sdk/include/coap/address.h new file mode 100644 index 00000000..85db2046 --- /dev/null +++ b/tools/sdk/include/coap/address.h @@ -0,0 +1,152 @@ +/* + * address.h -- representation of network addresses + * + * Copyright (C) 2010-2011,2015-2016 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file address.h + * @brief Representation of network addresses + */ + +#ifndef _COAP_ADDRESS_H_ +#define _COAP_ADDRESS_H_ + +#include +#include +#include +#include +#include "libcoap.h" + +#ifdef WITH_LWIP +#include + +typedef struct coap_address_t { + uint16_t port; + ip_addr_t addr; +} coap_address_t; + +#define _coap_address_equals_impl(A, B) (!!ip_addr_cmp(&(A)->addr,&(B)->addr)) + +#define _coap_address_isany_impl(A) ip_addr_isany(&(A)->addr) + +#define _coap_is_mcast_impl(Address) ip_addr_ismulticast(&(Address)->addr) +#endif /* WITH_LWIP */ + +#ifdef WITH_CONTIKI +#include "uip.h" + +typedef struct coap_address_t { + uip_ipaddr_t addr; + unsigned short port; +} coap_address_t; + +#define _coap_address_equals_impl(A,B) \ + ((A)->port == (B)->port \ + && uip_ipaddr_cmp(&((A)->addr),&((B)->addr))) + +/** @todo implementation of _coap_address_isany_impl() for Contiki */ +#define _coap_address_isany_impl(A) 0 + +#define _coap_is_mcast_impl(Address) uip_is_addr_mcast(&((Address)->addr)) +#endif /* WITH_CONTIKI */ + +#ifdef WITH_POSIX +/** multi-purpose address abstraction */ +typedef struct coap_address_t { + socklen_t size; /**< size of addr */ + union { + struct sockaddr sa; + struct sockaddr_storage st; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + } addr; +} coap_address_t; + +/** + * Compares given address objects @p a and @p b. This function returns @c 1 if + * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be + * @c NULL; + */ +int coap_address_equals(const coap_address_t *a, const coap_address_t *b); + +static inline int +_coap_address_isany_impl(const coap_address_t *a) { + /* need to compare only relevant parts of sockaddr_in6 */ + switch (a->addr.sa.sa_family) { + case AF_INET: + return a->addr.sin.sin_addr.s_addr == INADDR_ANY; + case AF_INET6: + return memcmp(&in6addr_any, + &a->addr.sin6.sin6_addr, + sizeof(in6addr_any)) == 0; + default: + ; + } + + return 0; +} +#endif /* WITH_POSIX */ + +/** + * Resets the given coap_address_t object @p addr to its default values. In + * particular, the member size must be initialized to the available size for + * storing addresses. + * + * @param addr The coap_address_t object to initialize. + */ +static inline void +coap_address_init(coap_address_t *addr) { + assert(addr); + memset(addr, 0, sizeof(coap_address_t)); +#ifdef WITH_POSIX + /* lwip and Contiki have constant address sizes and doesn't need the .size part */ + addr->size = sizeof(addr->addr); +#endif +} + +#ifndef WITH_POSIX +/** + * Compares given address objects @p a and @p b. This function returns @c 1 if + * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be + * @c NULL; + */ +static inline int +coap_address_equals(const coap_address_t *a, const coap_address_t *b) { + assert(a); assert(b); + return _coap_address_equals_impl(a, b); +} +#endif + +/** + * Checks if given address object @p a denotes the wildcard address. This + * function returns @c 1 if this is the case, @c 0 otherwise. The parameters @p + * a must not be @c NULL; + */ +static inline int +coap_address_isany(const coap_address_t *a) { + assert(a); + return _coap_address_isany_impl(a); +} + +#ifdef WITH_POSIX +/** + * Checks if given address @p a denotes a multicast address. This function + * returns @c 1 if @p a is multicast, @c 0 otherwise. + */ +int coap_is_mcast(const coap_address_t *a); +#else /* WITH_POSIX */ +/** + * Checks if given address @p a denotes a multicast address. This function + * returns @c 1 if @p a is multicast, @c 0 otherwise. + */ +static inline int +coap_is_mcast(const coap_address_t *a) { + return a && _coap_is_mcast_impl(a); +} +#endif /* WITH_POSIX */ + +#endif /* _COAP_ADDRESS_H_ */ diff --git a/tools/sdk/include/coap/async.h b/tools/sdk/include/coap/async.h new file mode 100644 index 00000000..0c36defa --- /dev/null +++ b/tools/sdk/include/coap/async.h @@ -0,0 +1,146 @@ +/* + * async.h -- state management for asynchronous messages + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file async.h + * @brief State management for asynchronous messages + */ + +#ifndef _COAP_ASYNC_H_ +#define _COAP_ASYNC_H_ + +#include "net.h" + +#ifndef WITHOUT_ASYNC + +/** + * @defgroup coap_async Asynchronous Messaging + * @{ + * Structure for managing asynchronous state of CoAP resources. A + * coap_resource_t object holds a list of coap_async_state_t objects that can be + * used to generate a separate response in case a result of an operation cannot + * be delivered in time, or the resource has been explicitly subscribed to with + * the option @c observe. + */ +typedef struct coap_async_state_t { + unsigned char flags; /**< holds the flags to control behaviour */ + + /** + * Holds the internal time when the object was registered with a + * resource. This field will be updated whenever + * coap_register_async() is called for a specific resource. + */ + coap_tick_t created; + + /** + * This field can be used to register opaque application data with the + * asynchronous state object. + */ + void *appdata; + unsigned short message_id; /**< id of last message seen */ + coap_tid_t id; /**< transaction id */ + struct coap_async_state_t *next; /**< internally used for linking */ + coap_address_t peer; /**< the peer to notify */ + size_t tokenlen; /**< length of the token */ + unsigned char token[]; /**< the token to use in a response */ +} coap_async_state_t; + +/* Definitions for Async Status Flags These flags can be used to control the + * behaviour of asynchronous response generation. + */ +#define COAP_ASYNC_CONFIRM 0x01 /**< send confirmable response */ +#define COAP_ASYNC_SEPARATE 0x02 /**< send separate response */ +#define COAP_ASYNC_OBSERVED 0x04 /**< the resource is being observed */ + +/** release application data on destruction */ +#define COAP_ASYNC_RELEASE_DATA 0x08 + +/** + * Allocates a new coap_async_state_t object and fills its fields according to + * the given @p request. The @p flags are used to control generation of empty + * ACK responses to stop retransmissions and to release registered @p data when + * the resource is deleted by coap_free_async(). This function returns a pointer + * to the registered coap_async_t object or @c NULL on error. Note that this + * function will return @c NULL in case that an object with the same identifier + * is already registered. + * + * @param context The context to use. + * @param peer The remote peer that is to be asynchronously notified. + * @param request The request that is handled asynchronously. + * @param flags Flags to control state management. + * @param data Opaque application data to register. Note that the + * storage occupied by @p data is released on destruction + * only if flag COAP_ASYNC_RELEASE_DATA is set. + * + * @return A pointer to the registered coap_async_state_t object or @c + * NULL in case of an error. + */ +coap_async_state_t * +coap_register_async(coap_context_t *context, + coap_address_t *peer, + coap_pdu_t *request, + unsigned char flags, + void *data); + +/** + * Removes the state object identified by @p id from @p context. The removed + * object is returned in @p s, if found. Otherwise, @p s is undefined. This + * function returns @c 1 if the object was removed, @c 0 otherwise. Note that + * the storage allocated for the stored object is not released by this + * functions. You will have to call coap_free_async() to do so. + * + * @param context The context where the async object is registered. + * @param id The identifier of the asynchronous transaction. + * @param s Will be set to the object identified by @p id after removal. + * + * @return @c 1 if object was removed and @p s updated, or @c 0 if no + * object was found with the given id. @p s is valid only if the + * return value is @c 1. + */ +int coap_remove_async(coap_context_t *context, + coap_tid_t id, + coap_async_state_t **s); + +/** + * Releases the memory that was allocated by coap_async_state_init() for the + * object @p s. The registered application data will be released automatically + * if COAP_ASYNC_RELEASE_DATA is set. + * + * @param state The object to delete. + */ +void +coap_free_async(coap_async_state_t *state); + +/** + * Retrieves the object identified by @p id from the list of asynchronous + * transactions that are registered with @p context. This function returns a + * pointer to that object or @c NULL if not found. + * + * @param context The context where the asynchronous objects are registered + * with. + * @param id The id of the object to retrieve. + * + * @return A pointer to the object identified by @p id or @c NULL if + * not found. + */ +coap_async_state_t *coap_find_async(coap_context_t *context, coap_tid_t id); + +/** + * Updates the time stamp of @p s. + * + * @param s The state object to update. + */ +static inline void +coap_touch_async(coap_async_state_t *s) { coap_ticks(&s->created); } + +/** @} */ + +#endif /* WITHOUT_ASYNC */ + +#endif /* _COAP_ASYNC_H_ */ diff --git a/tools/sdk/include/coap/bits.h b/tools/sdk/include/coap/bits.h new file mode 100644 index 00000000..0b269166 --- /dev/null +++ b/tools/sdk/include/coap/bits.h @@ -0,0 +1,78 @@ +/* + * bits.h -- bit vector manipulation + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file bits.h + * @brief Bit vector manipulation + */ + +#ifndef _COAP_BITS_H_ +#define _COAP_BITS_H_ + +#include + +/** + * Sets the bit @p bit in bit-vector @p vec. This function returns @c 1 if bit + * was set or @c -1 on error (i.e. when the given bit does not fit in the + * vector). + * + * @param vec The bit-vector to change. + * @param size The size of @p vec in bytes. + * @param bit The bit to set in @p vec. + * + * @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise. + */ +inline static int +bits_setb(uint8_t *vec, size_t size, uint8_t bit) { + if (size <= (bit >> 3)) + return -1; + + *(vec + (bit >> 3)) |= (uint8_t)(1 << (bit & 0x07)); + return 1; +} + +/** + * Clears the bit @p bit from bit-vector @p vec. This function returns @c 1 if + * bit was cleared or @c -1 on error (i.e. when the given bit does not fit in + * the vector). + * + * @param vec The bit-vector to change. + * @param size The size of @p vec in bytes. + * @param bit The bit to clear from @p vec. + * + * @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise. + */ +inline static int +bits_clrb(uint8_t *vec, size_t size, uint8_t bit) { + if (size <= (bit >> 3)) + return -1; + + *(vec + (bit >> 3)) &= (uint8_t)(~(1 << (bit & 0x07))); + return 1; +} + +/** + * Gets the status of bit @p bit from bit-vector @p vec. This function returns + * @c 1 if the bit is set, @c 0 otherwise (even in case of an error). + * + * @param vec The bit-vector to read from. + * @param size The size of @p vec in bytes. + * @param bit The bit to get from @p vec. + * + * @return @c 1 if the bit is set, @c 0 otherwise. + */ +inline static int +bits_getb(const uint8_t *vec, size_t size, uint8_t bit) { + if (size <= (bit >> 3)) + return -1; + + return (*(vec + (bit >> 3)) & (1 << (bit & 0x07))) != 0; +} + +#endif /* _COAP_BITS_H_ */ diff --git a/tools/sdk/include/coap/block.h b/tools/sdk/include/coap/block.h new file mode 100644 index 00000000..9ce00311 --- /dev/null +++ b/tools/sdk/include/coap/block.h @@ -0,0 +1,137 @@ +/* + * block.h -- block transfer + * + * Copyright (C) 2010-2012,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_BLOCK_H_ +#define _COAP_BLOCK_H_ + +#include "encode.h" +#include "option.h" +#include "pdu.h" + +/** + * @defgroup block Block Transfer + * @{ + */ + +#ifndef COAP_MAX_BLOCK_SZX +/** + * The largest value for the SZX component in a Block option. Note that + * 1 << (COAP_MAX_BLOCK_SZX + 4) should not exceed COAP_MAX_PDU_SIZE. + */ +#define COAP_MAX_BLOCK_SZX 4 +#endif /* COAP_MAX_BLOCK_SZX */ + +/** + * Structure of Block options. + */ +typedef struct { + unsigned int num; /**< block number */ + unsigned int m:1; /**< 1 if more blocks follow, 0 otherwise */ + unsigned int szx:3; /**< block size */ +} coap_block_t; + +/** + * Returns the value of the least significant byte of a Block option @p opt. + * For zero-length options (i.e. num == m == szx == 0), COAP_OPT_BLOCK_LAST + * returns @c NULL. + */ +#define COAP_OPT_BLOCK_LAST(opt) \ + (COAP_OPT_LENGTH(opt) ? (COAP_OPT_VALUE(opt) + (COAP_OPT_LENGTH(opt)-1)) : 0) + +/** Returns the value of the More-bit of a Block option @p opt. */ +#define COAP_OPT_BLOCK_MORE(opt) \ + (COAP_OPT_LENGTH(opt) ? (*COAP_OPT_BLOCK_LAST(opt) & 0x08) : 0) + +/** Returns the value of the SZX-field of a Block option @p opt. */ +#define COAP_OPT_BLOCK_SZX(opt) \ + (COAP_OPT_LENGTH(opt) ? (*COAP_OPT_BLOCK_LAST(opt) & 0x07) : 0) + +/** + * Returns the value of field @c num in the given block option @p block_opt. + */ +unsigned int coap_opt_block_num(const coap_opt_t *block_opt); + +/** + * Checks if more than @p num blocks are required to deliver @p data_len + * bytes of data for a block size of 1 << (@p szx + 4). + */ +static inline int +coap_more_blocks(size_t data_len, unsigned int num, unsigned short szx) { + return ((num+1) << (szx + 4)) < data_len; +} + +/** Sets the More-bit in @p block_opt */ +static inline void +coap_opt_block_set_m(coap_opt_t *block_opt, int m) { + if (m) + *(COAP_OPT_VALUE(block_opt) + (COAP_OPT_LENGTH(block_opt) - 1)) |= 0x08; + else + *(COAP_OPT_VALUE(block_opt) + (COAP_OPT_LENGTH(block_opt) - 1)) &= ~0x08; +} + +/** + * Initializes @p block from @p pdu. @p type must be either COAP_OPTION_BLOCK1 + * or COAP_OPTION_BLOCK2. When option @p type was found in @p pdu, @p block is + * initialized with values from this option and the function returns the value + * @c 1. Otherwise, @c 0 is returned. + * + * @param pdu The pdu to search for option @p type. + * @param type The option to search for (must be COAP_OPTION_BLOCK1 or + * COAP_OPTION_BLOCK2). + * @param block The block structure to initilize. + * + * @return @c 1 on success, @c 0 otherwise. + */ +int coap_get_block(coap_pdu_t *pdu, unsigned short type, coap_block_t *block); + +/** + * Writes a block option of type @p type to message @p pdu. If the requested + * block size is too large to fit in @p pdu, it is reduced accordingly. An + * exception is made for the final block when less space is required. The actual + * length of the resource is specified in @p data_length. + * + * This function may change *block to reflect the values written to @p pdu. As + * the function takes into consideration the remaining space @p pdu, no more + * options should be added after coap_write_block_opt() has returned. + * + * @param block The block structure to use. On return, this object is + * updated according to the values that have been written to + * @p pdu. + * @param type COAP_OPTION_BLOCK1 or COAP_OPTION_BLOCK2. + * @param pdu The message where the block option should be written. + * @param data_length The length of the actual data that will be added the @p + * pdu by calling coap_add_block(). + * + * @return @c 1 on success, or a negative value on error. + */ +int coap_write_block_opt(coap_block_t *block, + unsigned short type, + coap_pdu_t *pdu, + size_t data_length); + +/** + * Adds the @p block_num block of size 1 << (@p block_szx + 4) from source @p + * data to @p pdu. + * + * @param pdu The message to add the block. + * @param len The length of @p data. + * @param data The source data to fill the block with. + * @param block_num The actual block number. + * @param block_szx Encoded size of block @p block_number. + * + * @return @c 1 on success, @c 0 otherwise. + */ +int coap_add_block(coap_pdu_t *pdu, + unsigned int len, + const unsigned char *data, + unsigned int block_num, + unsigned char block_szx); +/**@}*/ + +#endif /* _COAP_BLOCK_H_ */ diff --git a/tools/sdk/include/coap/coap/coap.h.in b/tools/sdk/include/coap/coap.h similarity index 61% rename from tools/sdk/include/coap/coap/coap.h.in rename to tools/sdk/include/coap/coap.h index 76ebc5eb..cbdc9dfc 100644 --- a/tools/sdk/include/coap/coap/coap.h.in +++ b/tools/sdk/include/coap/coap.h @@ -1,9 +1,15 @@ -/* +/* Modify head file implementation for ESP32 platform. + * + * Uses libcoap software implementation for failover when concurrent + * define operations are in use. + * * coap.h -- main header file for CoAP stack of libcoap * * Copyright (C) 2010-2012,2015-2016 Olaf Bergmann * 2015 Carsten Schoenert * + * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD + * * This file is part of the CoAP library libcoap. Please see README for terms * of use. */ @@ -13,21 +19,6 @@ #include "libcoap.h" -/* Define the address where bug reports for libcoap should be sent. */ -#define LIBCOAP_PACKAGE_BUGREPORT @PACKAGE_BUGREPORT@ - -/* Define the full name of libcoap. */ -#define LIBCOAP_PACKAGE_NAME @PACKAGE_NAME@ - -/* Define the full name and version of libcoap. */ -#define LIBCOAP_PACKAGE_STRING @PACKAGE_STRING@ - -/* Define the home page for libcoap. */ -#define LIBCOAP_PACKAGE_URL @PACKAGE_URL@ - -/* Define the version of libcoap this file belongs to. */ -#define LIBCOAP_PACKAGE_VERSION @PACKAGE_VERSION@ - #ifdef __cplusplus extern "C" { #endif diff --git a/tools/sdk/include/coap/coap_io.h b/tools/sdk/include/coap/coap_io.h new file mode 100644 index 00000000..7a48b319 --- /dev/null +++ b/tools/sdk/include/coap/coap_io.h @@ -0,0 +1,167 @@ +/* + * coap_io.h -- Default network I/O functions for libcoap + * + * Copyright (C) 2012-2013 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_IO_H_ +#define _COAP_IO_H_ + +#include +#include + +#include "address.h" + +/** + * Abstract handle that is used to identify a local network interface. + */ +typedef int coap_if_handle_t; + +/** Invalid interface handle */ +#define COAP_IF_INVALID -1 + +struct coap_packet_t; +typedef struct coap_packet_t coap_packet_t; + +struct coap_context_t; + +/** + * Abstraction of virtual endpoint that can be attached to coap_context_t. The + * tuple (handle, addr) must uniquely identify this endpoint. + */ +typedef struct coap_endpoint_t { +#if defined(WITH_POSIX) || defined(WITH_CONTIKI) + union { + int fd; /**< on POSIX systems */ + void *conn; /**< opaque connection (e.g. uip_conn in Contiki) */ + } handle; /**< opaque handle to identify this endpoint */ +#endif /* WITH_POSIX or WITH_CONTIKI */ + +#ifdef WITH_LWIP + struct udp_pcb *pcb; + /**< @FIXME --chrysn + * this was added in a hurry, not sure it confirms to the overall model */ + struct coap_context_t *context; +#endif /* WITH_LWIP */ + + coap_address_t addr; /**< local interface address */ + int ifindex; + int flags; +} coap_endpoint_t; + +#define COAP_ENDPOINT_NOSEC 0x00 +#define COAP_ENDPOINT_DTLS 0x01 + +coap_endpoint_t *coap_new_endpoint(const coap_address_t *addr, int flags); + +void coap_free_endpoint(coap_endpoint_t *ep); + +/** + * Function interface for data transmission. This function returns the number of + * bytes that have been transmitted, or a value less than zero on error. + * + * @param context The calling CoAP context. + * @param local_interface The local interface to send the data. + * @param dst The address of the receiver. + * @param data The data to send. + * @param datalen The actual length of @p data. + * + * @return The number of bytes written on success, or a value + * less than zero on error. + */ +ssize_t coap_network_send(struct coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + unsigned char *data, size_t datalen); + +/** + * Function interface for reading data. This function returns the number of + * bytes that have been read, or a value less than zero on error. In case of an + * error, @p *packet is set to NULL. + * + * @param ep The endpoint that is used for reading data from the network. + * @param packet A result parameter where a pointer to the received packet + * structure is stored. The caller must call coap_free_packet to + * release the storage used by this packet. + * + * @return The number of bytes received on success, or a value less than + * zero on error. + */ +ssize_t coap_network_read(coap_endpoint_t *ep, coap_packet_t **packet); + +#ifndef coap_mcast_interface +# define coap_mcast_interface(Local) 0 +#endif + +/** + * Releases the storage allocated for @p packet. + */ +void coap_free_packet(coap_packet_t *packet); + +/** + * Populate the coap_endpoint_t *target from the incoming packet's destination + * data. + * + * This is usually used to copy a packet's data into a node's local_if member. + */ +void coap_packet_populate_endpoint(coap_packet_t *packet, + coap_endpoint_t *target); + +/** + * Given an incoming packet, copy its source address into an address struct. + */ +void coap_packet_copy_source(coap_packet_t *packet, coap_address_t *target); + +/** + * Given a packet, set msg and msg_len to an address and length of the packet's + * data in memory. + * */ +void coap_packet_get_memmapped(coap_packet_t *packet, + unsigned char **address, + size_t *length); + +#ifdef WITH_LWIP +/** + * Get the pbuf of a packet. The caller takes over responsibility for freeing + * the pbuf. + */ +struct pbuf *coap_packet_extract_pbuf(coap_packet_t *packet); +#endif + +#ifdef WITH_CONTIKI +/* + * This is only included in coap_io.h instead of .c in order to be available for + * sizeof in mem.c. + */ +struct coap_packet_t { + coap_if_handle_t hnd; /**< the interface handle */ + coap_address_t src; /**< the packet's source address */ + coap_address_t dst; /**< the packet's destination address */ + const coap_endpoint_t *interface; + int ifindex; + void *session; /**< opaque session data */ + size_t length; /**< length of payload */ + unsigned char payload[]; /**< payload */ +}; +#endif + +#ifdef WITH_LWIP +/* + * This is only included in coap_io.h instead of .c in order to be available for + * sizeof in lwippools.h. + * Simple carry-over of the incoming pbuf that is later turned into a node. + * + * Source address data is currently side-banded via ip_current_dest_addr & co + * as the packets have limited lifetime anyway. + */ +struct coap_packet_t { + struct pbuf *pbuf; + const coap_endpoint_t *local_interface; + uint16_t srcport; +}; +#endif + +#endif /* _COAP_IO_H_ */ diff --git a/tools/sdk/include/coap/coap_time.h b/tools/sdk/include/coap/coap_time.h new file mode 100644 index 00000000..9357e5ff --- /dev/null +++ b/tools/sdk/include/coap/coap_time.h @@ -0,0 +1,142 @@ +/* + * coap_time.h -- Clock Handling + * + * Copyright (C) 2010-2013 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file coap_time.h + * @brief Clock Handling + */ + +#ifndef _COAP_TIME_H_ +#define _COAP_TIME_H_ + +/** + * @defgroup clock Clock Handling + * Default implementation of internal clock. + * @{ + */ + +#ifdef WITH_LWIP + +#include +#include + +/* lwIP provides ms in sys_now */ +#define COAP_TICKS_PER_SECOND 1000 + +typedef uint32_t coap_tick_t; +typedef uint32_t coap_time_t; +typedef int32_t coap_tick_diff_t; + +static inline void coap_ticks_impl(coap_tick_t *t) { + *t = sys_now(); +} + +static inline void coap_clock_init_impl(void) { +} + +#define coap_clock_init coap_clock_init_impl +#define coap_ticks coap_ticks_impl + +static inline coap_time_t coap_ticks_to_rt(coap_tick_t t) { + return t / COAP_TICKS_PER_SECOND; +} +#endif + +#ifdef WITH_CONTIKI +#include "clock.h" + +typedef clock_time_t coap_tick_t; +typedef clock_time_t coap_time_t; + +/** + * This data type is used to represent the difference between two clock_tick_t + * values. This data type must have the same size in memory as coap_tick_t to + * allow wrapping. + */ +typedef int coap_tick_diff_t; + +#define COAP_TICKS_PER_SECOND CLOCK_SECOND + +static inline void coap_clock_init(void) { + clock_init(); +} + +static inline void coap_ticks(coap_tick_t *t) { + *t = clock_time(); +} + +static inline coap_time_t coap_ticks_to_rt(coap_tick_t t) { + return t / COAP_TICKS_PER_SECOND; +} +#endif /* WITH_CONTIKI */ + +#ifdef WITH_POSIX +/** + * This data type represents internal timer ticks with COAP_TICKS_PER_SECOND + * resolution. + */ +typedef unsigned long coap_tick_t; + +/** + * CoAP time in seconds since epoch. + */ +typedef time_t coap_time_t; + +/** + * This data type is used to represent the difference between two clock_tick_t + * values. This data type must have the same size in memory as coap_tick_t to + * allow wrapping. + */ +typedef long coap_tick_diff_t; + +/** Use ms resolution on POSIX systems */ +#define COAP_TICKS_PER_SECOND 1000 + +/** + * Initializes the internal clock. + */ +void coap_clock_init(void); + +/** + * Sets @p t to the internal time with COAP_TICKS_PER_SECOND resolution. + */ +void coap_ticks(coap_tick_t *t); + +/** + * Helper function that converts coap ticks to wallclock time. On POSIX, this + * function returns the number of seconds since the epoch. On other systems, it + * may be the calculated number of seconds since last reboot or so. + * + * @param t Internal system ticks. + * + * @return The number of seconds that has passed since a specific reference + * point (seconds since epoch on POSIX). + */ +coap_time_t coap_ticks_to_rt(coap_tick_t t); +#endif /* WITH_POSIX */ + +/** + * Returns @c 1 if and only if @p a is less than @p b where less is defined on a + * signed data type. + */ +static inline int coap_time_lt(coap_tick_t a, coap_tick_t b) { + return ((coap_tick_diff_t)(a - b)) < 0; +} + +/** + * Returns @c 1 if and only if @p a is less than or equal @p b where less is + * defined on a signed data type. + */ +static inline int coap_time_le(coap_tick_t a, coap_tick_t b) { + return a == b || coap_time_lt(a,b); +} + +/** @} */ + +#endif /* _COAP_TIME_H_ */ diff --git a/tools/sdk/include/coap/debug.h b/tools/sdk/include/coap/debug.h new file mode 100644 index 00000000..e7c86aff --- /dev/null +++ b/tools/sdk/include/coap/debug.h @@ -0,0 +1,85 @@ +/* + * debug.h -- debug utilities + * + * Copyright (C) 2010-2011,2014 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_DEBUG_H_ +#define _COAP_DEBUG_H_ + +#ifndef COAP_DEBUG_FD +#define COAP_DEBUG_FD stdout +#endif + +#ifndef COAP_ERR_FD +#define COAP_ERR_FD stderr +#endif + +#ifdef HAVE_SYSLOG_H +#include +typedef short coap_log_t; +#else +/** Pre-defined log levels akin to what is used in \b syslog. */ +typedef enum { + LOG_EMERG=0, + LOG_ALERT, + LOG_CRIT, + LOG_ERR, + LOG_WARNING, + LOG_NOTICE, + LOG_INFO, + LOG_DEBUG +} coap_log_t; +#endif + +/** Returns the current log level. */ +coap_log_t coap_get_log_level(void); + +/** Sets the log level to the specified value. */ +void coap_set_log_level(coap_log_t level); + +/** Returns a zero-terminated string with the name of this library. */ +const char *coap_package_name(void); + +/** Returns a zero-terminated string with the library version. */ +const char *coap_package_version(void); + +/** + * Writes the given text to @c COAP_ERR_FD (for @p level <= @c LOG_CRIT) or @c + * COAP_DEBUG_FD (for @p level >= @c LOG_WARNING). The text is output only when + * @p level is below or equal to the log level that set by coap_set_log_level(). + */ +void coap_log_impl(coap_log_t level, const char *format, ...); + +#ifndef coap_log +#define coap_log(...) coap_log_impl(__VA_ARGS__) +#endif + +#ifndef NDEBUG + +/* A set of convenience macros for common log levels. */ +#define info(...) coap_log(LOG_INFO, __VA_ARGS__) +#define warn(...) coap_log(LOG_WARNING, __VA_ARGS__) +#define debug(...) coap_log(LOG_DEBUG, __VA_ARGS__) + +#include "pdu.h" +void coap_show_pdu(const coap_pdu_t *); + +struct coap_address_t; +size_t coap_print_addr(const struct coap_address_t *, unsigned char *, size_t); + +#else + +#define debug(...) +#define info(...) +#define warn(...) + +#define coap_show_pdu(x) +#define coap_print_addr(...) + +#endif /* NDEBUG */ + +#endif /* _COAP_DEBUG_H_ */ diff --git a/tools/sdk/include/coap/encode.h b/tools/sdk/include/coap/encode.h new file mode 100644 index 00000000..a5d290c4 --- /dev/null +++ b/tools/sdk/include/coap/encode.h @@ -0,0 +1,52 @@ +/* + * encode.h -- encoding and decoding of CoAP data types + * + * Copyright (C) 2010-2012 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_ENCODE_H_ +#define _COAP_ENCODE_H_ + +#if (BSD >= 199103) || defined(WITH_CONTIKI) +# include +#else +# include +#endif + +#define Nn 8 /* duplicate definition of N if built on sky motes */ +#define ENCODE_HEADER_SIZE 4 +#define HIBIT (1 << (Nn - 1)) +#define EMASK ((1 << ENCODE_HEADER_SIZE) - 1) +#define MMASK ((1 << Nn) - 1 - EMASK) +#define MAX_VALUE ( (1 << Nn) - (1 << ENCODE_HEADER_SIZE) ) * (1 << ((1 << ENCODE_HEADER_SIZE) - 1)) + +#define COAP_PSEUDOFP_DECODE_8_4(r) (r < HIBIT ? r : (r & MMASK) << (r & EMASK)) + +#ifndef HAVE_FLS +/* include this only if fls() is not available */ +extern int coap_fls(unsigned int i); +#else +#define coap_fls(i) fls(i) +#endif + +/* ls and s must be integer variables */ +#define COAP_PSEUDOFP_ENCODE_8_4_DOWN(v,ls) (v < HIBIT ? v : (ls = coap_fls(v) - Nn, (v >> ls) & MMASK) + ls) +#define COAP_PSEUDOFP_ENCODE_8_4_UP(v,ls,s) (v < HIBIT ? v : (ls = coap_fls(v) - Nn, (s = (((v + ((1<> ls) & MMASK)), s == 0 ? HIBIT + ls + 1 : s + ls)) + +/** + * Decodes multiple-length byte sequences. buf points to an input byte sequence + * of length len. Returns the decoded value. + */ +unsigned int coap_decode_var_bytes(unsigned char *buf,unsigned int len); + +/** + * Encodes multiple-length byte sequences. buf points to an output buffer of + * sufficient length to store the encoded bytes. val is the value to encode. + * Returns the number of bytes used to encode val or 0 on error. + */ +unsigned int coap_encode_var_bytes(unsigned char *buf, unsigned int val); + +#endif /* _COAP_ENCODE_H_ */ diff --git a/tools/sdk/include/coap/hashkey.h b/tools/sdk/include/coap/hashkey.h new file mode 100644 index 00000000..5cff67d2 --- /dev/null +++ b/tools/sdk/include/coap/hashkey.h @@ -0,0 +1,57 @@ +/* + * hashkey.h -- definition of hash key type and helper functions + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file hashkey.h + * @brief definition of hash key type and helper functions + */ + +#ifndef _COAP_HASHKEY_H_ +#define _COAP_HASHKEY_H_ + +#include "str.h" + +typedef unsigned char coap_key_t[4]; + +#ifndef coap_hash +/** + * Calculates a fast hash over the given string @p s of length @p len and stores + * the result into @p h. Depending on the exact implementation, this function + * cannot be used as one-way function to check message integrity or simlar. + * + * @param s The string used for hash calculation. + * @param len The length of @p s. + * @param h The result buffer to store the calculated hash key. + */ +void coap_hash_impl(const unsigned char *s, unsigned int len, coap_key_t h); + +#define coap_hash(String,Length,Result) \ + coap_hash_impl((String),(Length),(Result)) + +/* This is used to control the pre-set hash-keys for resources. */ +#define __COAP_DEFAULT_HASH +#else +#undef __COAP_DEFAULT_HASH +#endif /* coap_hash */ + +/** + * Calls coap_hash() with given @c str object as parameter. + * + * @param Str Must contain a pointer to a coap string object. + * @param H A coap_key_t object to store the result. + * + * @hideinitializer + */ +#define coap_str_hash(Str,H) { \ + assert(Str); \ + memset((H), 0, sizeof(coap_key_t)); \ + coap_hash((Str)->s, (Str)->length, (H)); \ + } + +#endif /* _COAP_HASHKEY_H_ */ diff --git a/tools/sdk/include/coap/libcoap.h b/tools/sdk/include/coap/libcoap.h new file mode 100644 index 00000000..214b9e23 --- /dev/null +++ b/tools/sdk/include/coap/libcoap.h @@ -0,0 +1,26 @@ +/* + * libcoap.h -- platform specific header file for CoAP stack + * + * Copyright (C) 2015 Carsten Schoenert + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _LIBCOAP_H_ +#define _LIBCOAP_H_ + +/* The non posix embedded platforms like Contiki, TinyOS, RIOT, ... doesn't have + * a POSIX compatible header structure so we have to slightly do some platform + * related things. Currently there is only Contiki available so we check for a + * CONTIKI environment and do *not* include the POSIX related network stuff. If + * there are other platforms in future there need to be analogous environments. + * + * The CONTIKI variable is within the Contiki build environment! */ + +#if !defined (CONTIKI) +#include +#include +#endif /* CONTIKI */ + +#endif /* _LIBCOAP_H_ */ diff --git a/tools/sdk/include/coap/lwippools.h b/tools/sdk/include/coap/lwippools.h new file mode 100644 index 00000000..0bfb3f52 --- /dev/null +++ b/tools/sdk/include/coap/lwippools.h @@ -0,0 +1,57 @@ +/* + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** Memory pool definitions for the libcoap when used with lwIP (which has its + * own mechanism for quickly allocating chunks of data with known sizes). Has + * to be findable by lwIP (ie. an #include must either directly + * include this or include something more generic which includes this), and + * MEMP_USE_CUSTOM_POOLS has to be set in lwipopts.h. */ + +#include "coap_config.h" +#include +#include +#include + +#ifndef MEMP_NUM_COAPCONTEXT +#define MEMP_NUM_COAPCONTEXT 1 +#endif + +#ifndef MEMP_NUM_COAPENDPOINT +#define MEMP_NUM_COAPENDPOINT 1 +#endif + +/* 1 is sufficient as this is very short-lived */ +#ifndef MEMP_NUM_COAPPACKET +#define MEMP_NUM_COAPPACKET 1 +#endif + +#ifndef MEMP_NUM_COAPNODE +#define MEMP_NUM_COAPNODE 4 +#endif + +#ifndef MEMP_NUM_COAPPDU +#define MEMP_NUM_COAPPDU MEMP_NUM_COAPNODE +#endif + +#ifndef MEMP_NUM_COAP_SUBSCRIPTION +#define MEMP_NUM_COAP_SUBSCRIPTION 4 +#endif + +#ifndef MEMP_NUM_COAPRESOURCE +#define MEMP_NUM_COAPRESOURCE 10 +#endif + +#ifndef MEMP_NUM_COAPRESOURCEATTR +#define MEMP_NUM_COAPRESOURCEATTR 20 +#endif + +LWIP_MEMPOOL(COAP_CONTEXT, MEMP_NUM_COAPCONTEXT, sizeof(coap_context_t), "COAP_CONTEXT") +LWIP_MEMPOOL(COAP_ENDPOINT, MEMP_NUM_COAPENDPOINT, sizeof(coap_endpoint_t), "COAP_ENDPOINT") +LWIP_MEMPOOL(COAP_PACKET, MEMP_NUM_COAPPACKET, sizeof(coap_packet_t), "COAP_PACKET") +LWIP_MEMPOOL(COAP_NODE, MEMP_NUM_COAPNODE, sizeof(coap_queue_t), "COAP_NODE") +LWIP_MEMPOOL(COAP_PDU, MEMP_NUM_COAPPDU, sizeof(coap_pdu_t), "COAP_PDU") +LWIP_MEMPOOL(COAP_subscription, MEMP_NUM_COAP_SUBSCRIPTION, sizeof(coap_subscription_t), "COAP_subscription") +LWIP_MEMPOOL(COAP_RESOURCE, MEMP_NUM_COAPRESOURCE, sizeof(coap_resource_t), "COAP_RESOURCE") +LWIP_MEMPOOL(COAP_RESOURCEATTR, MEMP_NUM_COAPRESOURCEATTR, sizeof(coap_attr_t), "COAP_RESOURCEATTR") diff --git a/tools/sdk/include/coap/mem.h b/tools/sdk/include/coap/mem.h new file mode 100644 index 00000000..fd3c69aa --- /dev/null +++ b/tools/sdk/include/coap/mem.h @@ -0,0 +1,111 @@ +/* + * mem.h -- CoAP memory handling + * + * Copyright (C) 2010-2011,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_MEM_H_ +#define _COAP_MEM_H_ + +#include + +#ifndef WITH_LWIP +/** + * Initializes libcoap's memory management. + * This function must be called once before coap_malloc() can be used on + * constrained devices. + */ +void coap_memory_init(void); +#endif /* WITH_LWIP */ + +/** + * Type specifiers for coap_malloc_type(). Memory objects can be typed to + * facilitate arrays of type objects to be used instead of dynamic memory + * management on constrained devices. + */ +typedef enum { + COAP_STRING, + COAP_ATTRIBUTE_NAME, + COAP_ATTRIBUTE_VALUE, + COAP_PACKET, + COAP_NODE, + COAP_CONTEXT, + COAP_ENDPOINT, + COAP_PDU, + COAP_PDU_BUF, + COAP_RESOURCE, + COAP_RESOURCEATTR +} coap_memory_tag_t; + +#ifndef WITH_LWIP + +/** + * Allocates a chunk of @p size bytes and returns a pointer to the newly + * allocated memory. The @p type is used to select the appropriate storage + * container on constrained devices. The storage allocated by coap_malloc_type() + * must be released with coap_free_type(). + * + * @param type The type of object to be stored. + * @param size The number of bytes requested. + * @return A pointer to the allocated storage or @c NULL on error. + */ +void *coap_malloc_type(coap_memory_tag_t type, size_t size); + +/** + * Releases the memory that was allocated by coap_malloc_type(). The type tag @p + * type must be the same that was used for allocating the object pointed to by + * @p . + * + * @param type The type of the object to release. + * @param p A pointer to memory that was allocated by coap_malloc_type(). + */ +void coap_free_type(coap_memory_tag_t type, void *p); + +/** + * Wrapper function to coap_malloc_type() for backwards compatibility. + */ +static inline void *coap_malloc(size_t size) { + return coap_malloc_type(COAP_STRING, size); +} + +/** + * Wrapper function to coap_free_type() for backwards compatibility. + */ +static inline void coap_free(void *object) { + coap_free_type(COAP_STRING, object); +} + +#endif /* not WITH_LWIP */ + +#ifdef WITH_LWIP + +#include + +/* no initialization needed with lwip (or, more precisely: lwip must be + * completely initialized anyway by the time coap gets active) */ +static inline void coap_memory_init(void) {} + +/* It would be nice to check that size equals the size given at the memp + * declaration, but i currently don't see a standard way to check that without + * sourcing the custom memp pools and becoming dependent of its syntax + */ +#define coap_malloc_type(type, size) memp_malloc(MEMP_ ## type) +#define coap_free_type(type, p) memp_free(MEMP_ ## type, p) + +/* Those are just here to make uri.c happy where string allocation has not been + * made conditional. + */ +static inline void *coap_malloc(size_t size) { + LWIP_ASSERT("coap_malloc must not be used in lwIP", 0); +} + +static inline void coap_free(void *pointer) { + LWIP_ASSERT("coap_free must not be used in lwIP", 0); +} + +#endif /* WITH_LWIP */ + +#endif /* _COAP_MEM_H_ */ diff --git a/tools/sdk/include/coap/net.h b/tools/sdk/include/coap/net.h new file mode 100644 index 00000000..014b4903 --- /dev/null +++ b/tools/sdk/include/coap/net.h @@ -0,0 +1,521 @@ +/* + * net.h -- CoAP network interface + * + * Copyright (C) 2010-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_NET_H_ +#define _COAP_NET_H_ + +#include +#include +#include +#include +#include + +#ifdef WITH_LWIP +#include +#endif + +#include "coap_io.h" +#include "coap_time.h" +#include "option.h" +#include "pdu.h" +#include "prng.h" + +struct coap_queue_t; + +typedef struct coap_queue_t { + struct coap_queue_t *next; + coap_tick_t t; /**< when to send PDU for the next time */ + unsigned char retransmit_cnt; /**< retransmission counter, will be removed + * when zero */ + unsigned int timeout; /**< the randomized timeout value */ + coap_endpoint_t local_if; /**< the local address interface */ + coap_address_t remote; /**< remote address */ + coap_tid_t id; /**< unique transaction id */ + coap_pdu_t *pdu; /**< the CoAP PDU to send */ +} coap_queue_t; + +/** Adds node to given queue, ordered by node->t. */ +int coap_insert_node(coap_queue_t **queue, coap_queue_t *node); + +/** Destroys specified node. */ +int coap_delete_node(coap_queue_t *node); + +/** Removes all items from given queue and frees the allocated storage. */ +void coap_delete_all(coap_queue_t *queue); + +/** Creates a new node suitable for adding to the CoAP sendqueue. */ +coap_queue_t *coap_new_node(void); + +struct coap_resource_t; +struct coap_context_t; +#ifndef WITHOUT_ASYNC +struct coap_async_state_t; +#endif + +/** Message handler that is used as call-back in coap_context_t */ +typedef void (*coap_response_handler_t)(struct coap_context_t *, + const coap_endpoint_t *local_interface, + const coap_address_t *remote, + coap_pdu_t *sent, + coap_pdu_t *received, + const coap_tid_t id); + +#define COAP_MID_CACHE_SIZE 3 +typedef struct { + unsigned char flags[COAP_MID_CACHE_SIZE]; + coap_key_t item[COAP_MID_CACHE_SIZE]; +} coap_mid_cache_t; + +/** The CoAP stack's global state is stored in a coap_context_t object */ +typedef struct coap_context_t { + coap_opt_filter_t known_options; + struct coap_resource_t *resources; /**< hash table or list of known resources */ + +#ifndef WITHOUT_ASYNC + /** + * list of asynchronous transactions */ + struct coap_async_state_t *async_state; +#endif /* WITHOUT_ASYNC */ + + /** + * The time stamp in the first element of the sendqeue is relative + * to sendqueue_basetime. */ + coap_tick_t sendqueue_basetime; + coap_queue_t *sendqueue; + coap_endpoint_t *endpoint; /**< the endpoint used for listening */ + +#ifdef WITH_POSIX + int sockfd; /**< send/receive socket */ +#endif /* WITH_POSIX */ + +#ifdef WITH_CONTIKI + struct uip_udp_conn *conn; /**< uIP connection object */ + struct etimer retransmit_timer; /**< fires when the next packet must be sent */ + struct etimer notify_timer; /**< used to check resources periodically */ +#endif /* WITH_CONTIKI */ + +#ifdef WITH_LWIP + uint8_t timer_configured; /**< Set to 1 when a retransmission is + * scheduled using lwIP timers for this + * context, otherwise 0. */ +#endif /* WITH_LWIP */ + + /** + * The last message id that was used is stored in this field. The initial + * value is set by coap_new_context() and is usually a random value. A new + * message id can be created with coap_new_message_id(). + */ + unsigned short message_id; + + /** + * The next value to be used for Observe. This field is global for all + * resources and will be updated when notifications are created. + */ + unsigned int observe; + + coap_response_handler_t response_handler; + + ssize_t (*network_send)(struct coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + unsigned char *data, size_t datalen); + + ssize_t (*network_read)(coap_endpoint_t *ep, coap_packet_t **packet); + +} coap_context_t; + +/** + * Registers a new message handler that is called whenever a response was + * received that matches an ongoing transaction. + * + * @param context The context to register the handler for. + * @param handler The response handler to register. + */ +static inline void +coap_register_response_handler(coap_context_t *context, + coap_response_handler_t handler) { + context->response_handler = handler; +} + +/** + * Registers the option type @p type with the given context object @p ctx. + * + * @param ctx The context to use. + * @param type The option type to register. + */ +inline static void +coap_register_option(coap_context_t *ctx, unsigned char type) { + coap_option_setb(ctx->known_options, type); +} + +/** + * Set sendqueue_basetime in the given context object @p ctx to @p now. This + * function returns the number of elements in the queue head that have timed + * out. + */ +unsigned int coap_adjust_basetime(coap_context_t *ctx, coap_tick_t now); + +/** + * Returns the next pdu to send without removing from sendqeue. + */ +coap_queue_t *coap_peek_next( coap_context_t *context ); + +/** + * Returns the next pdu to send and removes it from the sendqeue. + */ +coap_queue_t *coap_pop_next( coap_context_t *context ); + +/** + * Creates a new coap_context_t object that will hold the CoAP stack status. + */ +coap_context_t *coap_new_context(const coap_address_t *listen_addr); + +/** + * Returns a new message id and updates @p context->message_id accordingly. The + * message id is returned in network byte order to make it easier to read in + * tracing tools. + * + * @param context The current coap_context_t object. + * + * @return Incremented message id in network byte order. + */ +static inline unsigned short +coap_new_message_id(coap_context_t *context) { + context->message_id++; +#ifndef WITH_CONTIKI + return htons(context->message_id); +#else /* WITH_CONTIKI */ + return uip_htons(context->message_id); +#endif +} + +/** + * CoAP stack context must be released with coap_free_context(). This function + * clears all entries from the receive queue and send queue and deletes the + * resources that have been registered with @p context, and frees the attached + * endpoints. + */ +void coap_free_context(coap_context_t *context); + + +/** + * Sends a confirmed CoAP message to given destination. The memory that is + * allocated by pdu will not be released by coap_send_confirmed(). The caller + * must release the memory. + * + * @param context The CoAP context to use. + * @param local_interface The local network interface where the outbound + * packet is sent. + * @param dst The address to send to. + * @param pdu The CoAP PDU to send. + * + * @return The message id of the sent message or @c + * COAP_INVALID_TID on error. + */ +coap_tid_t coap_send_confirmed(coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + coap_pdu_t *pdu); + +/** + * Creates a new ACK PDU with specified error @p code. The options specified by + * the filter expression @p opts will be copied from the original request + * contained in @p request. Unless @c SHORT_ERROR_RESPONSE was defined at build + * time, the textual reason phrase for @p code will be added as payload, with + * Content-Type @c 0. + * This function returns a pointer to the new response message, or @c NULL on + * error. The storage allocated for the new message must be relased with + * coap_free(). + * + * @param request Specification of the received (confirmable) request. + * @param code The error code to set. + * @param opts An option filter that specifies which options to copy from + * the original request in @p node. + * + * @return A pointer to the new message or @c NULL on error. + */ +coap_pdu_t *coap_new_error_response(coap_pdu_t *request, + unsigned char code, + coap_opt_filter_t opts); + +/** + * Sends a non-confirmed CoAP message to given destination. The memory that is + * allocated by pdu will not be released by coap_send(). + * The caller must release the memory. + * + * @param context The CoAP context to use. + * @param local_interface The local network interface where the outbound packet + * is sent. + * @param dst The address to send to. + * @param pdu The CoAP PDU to send. + * + * @return The message id of the sent message or @c + * COAP_INVALID_TID on error. + */ +coap_tid_t coap_send(coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + coap_pdu_t *pdu); + +/** + * Sends an error response with code @p code for request @p request to @p dst. + * @p opts will be passed to coap_new_error_response() to copy marked options + * from the request. This function returns the transaction id if the message was + * sent, or @c COAP_INVALID_TID otherwise. + * + * @param context The context to use. + * @param request The original request to respond to. + * @param local_interface The local network interface where the outbound packet + * is sent. + * @param dst The remote peer that sent the request. + * @param code The response code. + * @param opts A filter that specifies the options to copy from the + * @p request. + * + * @return The transaction id if the message was sent, or @c + * COAP_INVALID_TID otherwise. + */ +coap_tid_t coap_send_error(coap_context_t *context, + coap_pdu_t *request, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + unsigned char code, + coap_opt_filter_t opts); + +/** + * Helper funktion to create and send a message with @p type (usually ACK or + * RST). This function returns @c COAP_INVALID_TID when the message was not + * sent, a valid transaction id otherwise. + * + * @param context The CoAP context. + * @param local_interface The local network interface where the outbound packet + * is sent. + * @param dst Where to send the context. + * @param request The request that should be responded to. + * @param type Which type to set. + * @return transaction id on success or @c COAP_INVALID_TID + * otherwise. + */ +coap_tid_t +coap_send_message_type(coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + coap_pdu_t *request, + unsigned char type); + +/** + * Sends an ACK message with code @c 0 for the specified @p request to @p dst. + * This function returns the corresponding transaction id if the message was + * sent or @c COAP_INVALID_TID on error. + * + * @param context The context to use. + * @param local_interface The local network interface where the outbound packet + * is sent. + * @param dst The destination address. + * @param request The request to be acknowledged. + * + * @return The transaction id if ACK was sent or @c + * COAP_INVALID_TID on error. + */ +coap_tid_t coap_send_ack(coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + coap_pdu_t *request); + +/** + * Sends an RST message with code @c 0 for the specified @p request to @p dst. + * This function returns the corresponding transaction id if the message was + * sent or @c COAP_INVALID_TID on error. + * + * @param context The context to use. + * @param local_interface The local network interface where the outbound packet + * is sent. + * @param dst The destination address. + * @param request The request to be reset. + * + * @return The transaction id if RST was sent or @c + * COAP_INVALID_TID on error. + */ +static inline coap_tid_t +coap_send_rst(coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + coap_pdu_t *request) { + return coap_send_message_type(context, + local_interface, + dst, request, + COAP_MESSAGE_RST); +} + +/** + * Handles retransmissions of confirmable messages + */ +coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node); + +/** + * Reads data from the network and tries to parse as CoAP PDU. On success, 0 is + * returned and a new node with the parsed PDU is added to the receive queue in + * the specified context object. + */ +int coap_read(coap_context_t *context); + +/** + * Parses and interprets a CoAP message with context @p ctx. This function + * returns @c 0 if the message was handled, or a value less than zero on + * error. + * + * @param ctx The current CoAP context. + * @param packet The received packet. + * + * @return @c 0 if message was handled successfully, or less than zero on + * error. + */ +int coap_handle_message(coap_context_t *ctx, + coap_packet_t *packet); + +/** + * Calculates a unique transaction id from given arguments @p peer and @p pdu. + * The id is returned in @p id. + * + * @param peer The remote party who sent @p pdu. + * @param pdu The message that initiated the transaction. + * @param id Set to the new id. + */ +void coap_transaction_id(const coap_address_t *peer, + const coap_pdu_t *pdu, + coap_tid_t *id); + +/** + * This function removes the element with given @p id from the list given list. + * If @p id was found, @p node is updated to point to the removed element. Note + * that the storage allocated by @p node is @b not released. The caller must do + * this manually using coap_delete_node(). This function returns @c 1 if the + * element with id @p id was found, @c 0 otherwise. For a return value of @c 0, + * the contents of @p node is undefined. + * + * @param queue The queue to search for @p id. + * @param id The node id to look for. + * @param node If found, @p node is updated to point to the removed node. You + * must release the storage pointed to by @p node manually. + * + * @return @c 1 if @p id was found, @c 0 otherwise. + */ +int coap_remove_from_queue(coap_queue_t **queue, + coap_tid_t id, + coap_queue_t **node); + +/** + * Removes the transaction identified by @p id from given @p queue. This is a + * convenience function for coap_remove_from_queue() with automatic deletion of + * the removed node. + * + * @param queue The queue to search for @p id. + * @param id The transaction id. + * + * @return @c 1 if node was found, removed and destroyed, @c 0 otherwise. + */ +inline static int +coap_remove_transaction(coap_queue_t **queue, coap_tid_t id) { + coap_queue_t *node; + if (!coap_remove_from_queue(queue, id, &node)) + return 0; + + coap_delete_node(node); + return 1; +} + +/** + * Retrieves transaction from the queue. + * + * @param queue The transaction queue to be searched. + * @param id Unique key of the transaction to find. + * + * @return A pointer to the transaction object or NULL if not found. + */ +coap_queue_t *coap_find_transaction(coap_queue_t *queue, coap_tid_t id); + +/** + * Cancels all outstanding messages for peer @p dst that have the specified + * token. + * + * @param context The context in use. + * @param dst Destination address of the messages to remove. + * @param token Message token. + * @param token_length Actual length of @p token. + */ +void coap_cancel_all_messages(coap_context_t *context, + const coap_address_t *dst, + const unsigned char *token, + size_t token_length); + +/** + * Dispatches the PDUs from the receive queue in given context. + */ +void coap_dispatch(coap_context_t *context, coap_queue_t *rcvd); + +/** + * Returns 1 if there are no messages to send or to dispatch in the context's + * queues. */ +int coap_can_exit(coap_context_t *context); + +/** + * Returns the current value of an internal tick counter. The counter counts \c + * COAP_TICKS_PER_SECOND ticks every second. + */ +void coap_ticks(coap_tick_t *); + +/** + * Verifies that @p pdu contains no unknown critical options. Options must be + * registered at @p ctx, using the function coap_register_option(). A basic set + * of options is registered automatically by coap_new_context(). This function + * returns @c 1 if @p pdu is ok, @c 0 otherwise. The given filter object @p + * unknown will be updated with the unknown options. As only @c COAP_MAX_OPT + * options can be signalled this way, remaining options must be examined + * manually. + * + * @code + coap_opt_filter_t f = COAP_OPT_NONE; + coap_opt_iterator_t opt_iter; + + if (coap_option_check_critical(ctx, pdu, f) == 0) { + coap_option_iterator_init(pdu, &opt_iter, f); + + while (coap_option_next(&opt_iter)) { + if (opt_iter.type & 0x01) { + ... handle unknown critical option in opt_iter ... + } + } + } + * @endcode + * + * @param ctx The context where all known options are registered. + * @param pdu The PDU to check. + * @param unknown The output filter that will be updated to indicate the + * unknown critical options found in @p pdu. + * + * @return @c 1 if everything was ok, @c 0 otherwise. + */ +int coap_option_check_critical(coap_context_t *ctx, + coap_pdu_t *pdu, + coap_opt_filter_t unknown); + +/** + * Creates a new response for given @p request with the contents of @c + * .well-known/core. The result is NULL on error or a newly allocated PDU that + * must be released by coap_delete_pdu(). + * + * @param context The current coap context to use. + * @param request The request for @c .well-known/core . + * + * @return A new 2.05 response for @c .well-known/core or NULL on error. + */ +coap_pdu_t *coap_wellknown_response(coap_context_t *context, + coap_pdu_t *request); + +#endif /* _COAP_NET_H_ */ diff --git a/tools/sdk/include/coap/option.h b/tools/sdk/include/coap/option.h new file mode 100644 index 00000000..ace2b81c --- /dev/null +++ b/tools/sdk/include/coap/option.h @@ -0,0 +1,410 @@ +/* + * option.h -- helpers for handling options in CoAP PDUs + * + * Copyright (C) 2010-2013 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file option.h + * @brief Helpers for handling options in CoAP PDUs + */ + +#ifndef _COAP_OPTION_H_ +#define _COAP_OPTION_H_ + +#include "bits.h" +#include "pdu.h" + +/** + * Use byte-oriented access methods here because sliding a complex struct + * coap_opt_t over the data buffer may cause bus error on certain platforms. + */ +typedef unsigned char coap_opt_t; +#define PCHAR(p) ((coap_opt_t *)(p)) + +/** Representation of CoAP options. */ +typedef struct { + unsigned short delta; + size_t length; + unsigned char *value; +} coap_option_t; + +/** + * Parses the option pointed to by @p opt into @p result. This function returns + * the number of bytes that have been parsed, or @c 0 on error. An error is + * signaled when illegal delta or length values are encountered or when option + * parsing would result in reading past the option (i.e. beyond opt + length). + * + * @param opt The beginning of the option to parse. + * @param length The maximum length of @p opt. + * @param result A pointer to the coap_option_t structure that is filled with + * actual values iff coap_opt_parse() > 0. + * @return The number of bytes parsed or @c 0 on error. + */ +size_t coap_opt_parse(const coap_opt_t *opt, + size_t length, + coap_option_t *result); + +/** + * Returns the size of the given option, taking into account a possible option + * jump. + * + * @param opt An option jump or the beginning of the option. + * @return The number of bytes between @p opt and the end of the option + * starting at @p opt. In case of an error, this function returns + * @c 0 as options need at least one byte storage space. + */ +size_t coap_opt_size(const coap_opt_t *opt); + +/** @deprecated { Use coap_opt_size() instead. } */ +#define COAP_OPT_SIZE(opt) coap_opt_size(opt) + +/** + * Calculates the beginning of the PDU's option section. + * + * @param pdu The PDU containing the options. + * @return A pointer to the first option if available, or @c NULL otherwise. + */ +coap_opt_t *options_start(coap_pdu_t *pdu); + +/** + * Interprets @p opt as pointer to a CoAP option and advances to + * the next byte past this option. + * @hideinitializer + */ +#define options_next(opt) \ + ((coap_opt_t *)((unsigned char *)(opt) + COAP_OPT_SIZE(opt))) + +/** + * @defgroup opt_filter Option Filters + * @{ + */ + +/** + * The number of option types below 256 that can be stored in an + * option filter. COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be + * at most 16. Each coap_option_filter_t object reserves + * ((COAP_OPT_FILTER_SHORT + 1) / 2) * 2 bytes for short options. + */ +#define COAP_OPT_FILTER_SHORT 6 + +/** + * The number of option types above 255 that can be stored in an + * option filter. COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be + * at most 16. Each coap_option_filter_t object reserves + * COAP_OPT_FILTER_LONG * 2 bytes for short options. + */ +#define COAP_OPT_FILTER_LONG 2 + +/* Ensure that COAP_OPT_FILTER_SHORT and COAP_OPT_FILTER_LONG are set + * correctly. */ +#if (COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG > 16) +#error COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be less or equal 16 +#endif /* (COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG > 16) */ + +/** The number of elements in coap_opt_filter_t. */ +#define COAP_OPT_FILTER_SIZE \ + (((COAP_OPT_FILTER_SHORT + 1) >> 1) + COAP_OPT_FILTER_LONG) +1 + +/** + * Fixed-size vector we use for option filtering. It is large enough + * to hold COAP_OPT_FILTER_SHORT entries with an option number between + * 0 and 255, and COAP_OPT_FILTER_LONG entries with an option number + * between 256 and 65535. Its internal structure is + * + * @code +struct { + uint16_t mask; + uint16_t long_opts[COAP_OPT_FILTER_LONG]; + uint8_t short_opts[COAP_OPT_FILTER_SHORT]; +} + * @endcode + * + * The first element contains a bit vector that indicates which fields + * in the remaining array are used. The first COAP_OPT_FILTER_LONG + * bits correspond to the long option types that are stored in the + * elements from index 1 to COAP_OPT_FILTER_LONG. The next + * COAP_OPT_FILTER_SHORT bits correspond to the short option types + * that are stored in the elements from index COAP_OPT_FILTER_LONG + 1 + * to COAP_OPT_FILTER_LONG + COAP_OPT_FILTER_SHORT. The latter + * elements are treated as bytes. + */ +typedef uint16_t coap_opt_filter_t[COAP_OPT_FILTER_SIZE]; + +/** Pre-defined filter that includes all options. */ +#define COAP_OPT_ALL NULL + +/** + * Clears filter @p f. + * + * @param f The filter to clear. + */ +static inline void +coap_option_filter_clear(coap_opt_filter_t f) { + memset(f, 0, sizeof(coap_opt_filter_t)); +} + +/** + * Sets the corresponding entry for @p type in @p filter. This + * function returns @c 1 if bit was set or @c 0 on error (i.e. when + * the given type does not fit in the filter). + * + * @param filter The filter object to change. + * @param type The type for which the bit should be set. + * + * @return @c 1 if bit was set, @c 0 otherwise. + */ +int coap_option_filter_set(coap_opt_filter_t filter, unsigned short type); + +/** + * Clears the corresponding entry for @p type in @p filter. This + * function returns @c 1 if bit was set or @c 0 on error (i.e. when + * the given type does not fit in the filter). + * + * @param filter The filter object to change. + * @param type The type that should be cleared from the filter. + * + * @return @c 1 if bit was set, @c 0 otherwise. + */ +int coap_option_filter_unset(coap_opt_filter_t filter, unsigned short type); + +/** + * Checks if @p type is contained in @p filter. This function returns + * @c 1 if found, @c 0 if not, or @c -1 on error (i.e. when the given + * type does not fit in the filter). + * + * @param filter The filter object to search. + * @param type The type to search for. + * + * @return @c 1 if @p type was found, @c 0 otherwise, or @c -1 on error. + */ +int coap_option_filter_get(const coap_opt_filter_t filter, unsigned short type); + +/** + * Sets the corresponding bit for @p type in @p filter. This function returns @c + * 1 if bit was set or @c -1 on error (i.e. when the given type does not fit in + * the filter). + * + * @deprecated Use coap_option_filter_set() instead. + * + * @param filter The filter object to change. + * @param type The type for which the bit should be set. + * + * @return @c 1 if bit was set, @c -1 otherwise. + */ +inline static int +coap_option_setb(coap_opt_filter_t filter, unsigned short type) { + return coap_option_filter_set(filter, type) ? 1 : -1; +} + +/** + * Clears the corresponding bit for @p type in @p filter. This function returns + * @c 1 if bit was cleared or @c -1 on error (i.e. when the given type does not + * fit in the filter). + * + * @deprecated Use coap_option_filter_unset() instead. + * + * @param filter The filter object to change. + * @param type The type for which the bit should be cleared. + * + * @return @c 1 if bit was set, @c -1 otherwise. + */ +inline static int +coap_option_clrb(coap_opt_filter_t filter, unsigned short type) { + return coap_option_filter_unset(filter, type) ? 1 : -1; +} + +/** + * Gets the corresponding bit for @p type in @p filter. This function returns @c + * 1 if the bit is set @c 0 if not, or @c -1 on error (i.e. when the given type + * does not fit in the filter). + * + * @deprecated Use coap_option_filter_get() instead. + * + * @param filter The filter object to read bit from. + * @param type The type for which the bit should be read. + * + * @return @c 1 if bit was set, @c 0 if not, @c -1 on error. + */ +inline static int +coap_option_getb(const coap_opt_filter_t filter, unsigned short type) { + return coap_option_filter_get(filter, type); +} + +/** + * Iterator to run through PDU options. This object must be + * initialized with coap_option_iterator_init(). Call + * coap_option_next() to walk through the list of options until + * coap_option_next() returns @c NULL. + * + * @code + * coap_opt_t *option; + * coap_opt_iterator_t opt_iter; + * coap_option_iterator_init(pdu, &opt_iter, COAP_OPT_ALL); + * + * while ((option = coap_option_next(&opt_iter))) { + * ... do something with option ... + * } + * @endcode + */ +typedef struct { + size_t length; /**< remaining length of PDU */ + unsigned short type; /**< decoded option type */ + unsigned int bad:1; /**< iterator object is ok if not set */ + unsigned int filtered:1; /**< denotes whether or not filter is used */ + coap_opt_t *next_option; /**< pointer to the unparsed next option */ + coap_opt_filter_t filter; /**< option filter */ +} coap_opt_iterator_t; + +/** + * Initializes the given option iterator @p oi to point to the beginning of the + * @p pdu's option list. This function returns @p oi on success, @c NULL + * otherwise (i.e. when no options exist). Note that a length check on the + * option list must be performed before coap_option_iterator_init() is called. + * + * @param pdu The PDU the options of which should be walked through. + * @param oi An iterator object that will be initilized. + * @param filter An optional option type filter. + * With @p type != @c COAP_OPT_ALL, coap_option_next() + * will return only options matching this bitmask. + * Fence-post options @c 14, @c 28, @c 42, ... are always + * skipped. + * + * @return The iterator object @p oi on success, @c NULL otherwise. + */ +coap_opt_iterator_t *coap_option_iterator_init(coap_pdu_t *pdu, + coap_opt_iterator_t *oi, + const coap_opt_filter_t filter); + +/** + * Updates the iterator @p oi to point to the next option. This function returns + * a pointer to that option or @c NULL if no more options exist. The contents of + * @p oi will be updated. In particular, @c oi->n specifies the current option's + * ordinal number (counted from @c 1), @c oi->type is the option's type code, + * and @c oi->option points to the beginning of the current option itself. When + * advanced past the last option, @c oi->option will be @c NULL. + * + * Note that options are skipped whose corresponding bits in the filter + * specified with coap_option_iterator_init() are @c 0. Options with type codes + * that do not fit in this filter hence will always be returned. + * + * @param oi The option iterator to update. + * + * @return The next option or @c NULL if no more options exist. + */ +coap_opt_t *coap_option_next(coap_opt_iterator_t *oi); + +/** + * Retrieves the first option of type @p type from @p pdu. @p oi must point to a + * coap_opt_iterator_t object that will be initialized by this function to + * filter only options with code @p type. This function returns the first option + * with this type, or @c NULL if not found. + * + * @param pdu The PDU to parse for options. + * @param type The option type code to search for. + * @param oi An iterator object to use. + * + * @return A pointer to the first option of type @p type, or @c NULL if + * not found. + */ +coap_opt_t *coap_check_option(coap_pdu_t *pdu, + unsigned short type, + coap_opt_iterator_t *oi); + +/** + * Encodes the given delta and length values into @p opt. This function returns + * the number of bytes that were required to encode @p delta and @p length or @c + * 0 on error. Note that the result indicates by how many bytes @p opt must be + * advanced to encode the option value. + * + * @param opt The option buffer space where @p delta and @p length are + * written. + * @param maxlen The maximum length of @p opt. + * @param delta The actual delta value to encode. + * @param length The actual length value to encode. + * + * @return The number of bytes used or @c 0 on error. + */ +size_t coap_opt_setheader(coap_opt_t *opt, + size_t maxlen, + unsigned short delta, + size_t length); + +/** + * Encodes option with given @p delta into @p opt. This function returns the + * number of bytes written to @p opt or @c 0 on error. This happens especially + * when @p opt does not provide sufficient space to store the option value, + * delta, and option jumps when required. + * + * @param opt The option buffer space where @p val is written. + * @param n Maximum length of @p opt. + * @param delta The option delta. + * @param val The option value to copy into @p opt. + * @param length The actual length of @p val. + * + * @return The number of bytes that have been written to @p opt or @c 0 on + * error. The return value will always be less than @p n. + */ +size_t coap_opt_encode(coap_opt_t *opt, + size_t n, + unsigned short delta, + const unsigned char *val, + size_t length); + +/** + * Decodes the delta value of the next option. This function returns the number + * of bytes read or @c 0 on error. The caller of this function must ensure that + * it does not read over the boundaries of @p opt (e.g. by calling + * coap_opt_check_delta(). + * + * @param opt The option to examine. + * + * @return The number of bytes read or @c 0 on error. + */ +unsigned short coap_opt_delta(const coap_opt_t *opt); + +/** @deprecated { Use coap_opt_delta() instead. } */ +#define COAP_OPT_DELTA(opt) coap_opt_delta(opt) + +/** @deprecated { Use coap_opt_encode() instead. } */ +#define COAP_OPT_SETDELTA(opt,val) \ + coap_opt_encode((opt), COAP_MAX_PDU_SIZE, (val), NULL, 0) + +/** + * Returns the length of the given option. @p opt must point to an option jump + * or the beginning of the option. This function returns @c 0 when @p opt is not + * an option or the actual length of @p opt (which can be @c 0 as well). + * + * @note {The rationale for using @c 0 in case of an error is that in most + * contexts, the result of this function is used to skip the next + * coap_opt_length() bytes.} + * + * @param opt The option whose length should be returned. + * + * @return The option's length or @c 0 when undefined. + */ +unsigned short coap_opt_length(const coap_opt_t *opt); + +/** @deprecated { Use coap_opt_length() instead. } */ +#define COAP_OPT_LENGTH(opt) coap_opt_length(opt) + +/** + * Returns a pointer to the value of the given option. @p opt must point to an + * option jump or the beginning of the option. This function returns @c NULL if + * @p opt is not a valid option. + * + * @param opt The option whose value should be returned. + * + * @return A pointer to the option value or @c NULL on error. + */ +unsigned char *coap_opt_value(coap_opt_t *opt); + +/** @deprecated { Use coap_opt_value() instead. } */ +#define COAP_OPT_VALUE(opt) coap_opt_value((coap_opt_t *)opt) + +/** @} */ + +#endif /* _OPTION_H_ */ diff --git a/tools/sdk/include/coap/pdu.h b/tools/sdk/include/coap/pdu.h new file mode 100644 index 00000000..7ed482de --- /dev/null +++ b/tools/sdk/include/coap/pdu.h @@ -0,0 +1,388 @@ +/* + * pdu.h -- CoAP message structure + * + * Copyright (C) 2010-2014 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file pdu.h + * @brief Pre-defined constants that reflect defaults for CoAP + */ + +#ifndef _COAP_PDU_H_ +#define _COAP_PDU_H_ + +#include "uri.h" + +#ifdef WITH_LWIP +#include +#endif + +#define COAP_DEFAULT_PORT 5683 /* CoAP default UDP port */ +#define COAP_DEFAULT_MAX_AGE 60 /* default maximum object lifetime in seconds */ +#ifndef COAP_MAX_PDU_SIZE +#define COAP_MAX_PDU_SIZE 1400 /* maximum size of a CoAP PDU */ +#endif /* COAP_MAX_PDU_SIZE */ + +#define COAP_DEFAULT_VERSION 1 /* version of CoAP supported */ +#define COAP_DEFAULT_SCHEME "coap" /* the default scheme for CoAP URIs */ + +/** well-known resources URI */ +#define COAP_DEFAULT_URI_WELLKNOWN ".well-known/core" + +#ifdef __COAP_DEFAULT_HASH +/* pre-calculated hash key for the default well-known URI */ +#define COAP_DEFAULT_WKC_HASHKEY "\345\130\144\245" +#endif + +/* CoAP message types */ + +#define COAP_MESSAGE_CON 0 /* confirmable message (requires ACK/RST) */ +#define COAP_MESSAGE_NON 1 /* non-confirmable message (one-shot message) */ +#define COAP_MESSAGE_ACK 2 /* used to acknowledge confirmable messages */ +#define COAP_MESSAGE_RST 3 /* indicates error in received messages */ + +/* CoAP request methods */ + +#define COAP_REQUEST_GET 1 +#define COAP_REQUEST_POST 2 +#define COAP_REQUEST_PUT 3 +#define COAP_REQUEST_DELETE 4 + +/* CoAP option types (be sure to update check_critical when adding options */ + +#define COAP_OPTION_IF_MATCH 1 /* C, opaque, 0-8 B, (none) */ +#define COAP_OPTION_URI_HOST 3 /* C, String, 1-255 B, destination address */ +#define COAP_OPTION_ETAG 4 /* E, opaque, 1-8 B, (none) */ +#define COAP_OPTION_IF_NONE_MATCH 5 /* empty, 0 B, (none) */ +#define COAP_OPTION_URI_PORT 7 /* C, uint, 0-2 B, destination port */ +#define COAP_OPTION_LOCATION_PATH 8 /* E, String, 0-255 B, - */ +#define COAP_OPTION_URI_PATH 11 /* C, String, 0-255 B, (none) */ +#define COAP_OPTION_CONTENT_FORMAT 12 /* E, uint, 0-2 B, (none) */ +#define COAP_OPTION_CONTENT_TYPE COAP_OPTION_CONTENT_FORMAT +#define COAP_OPTION_MAXAGE 14 /* E, uint, 0--4 B, 60 Seconds */ +#define COAP_OPTION_URI_QUERY 15 /* C, String, 1-255 B, (none) */ +#define COAP_OPTION_ACCEPT 17 /* C, uint, 0-2 B, (none) */ +#define COAP_OPTION_LOCATION_QUERY 20 /* E, String, 0-255 B, (none) */ +#define COAP_OPTION_PROXY_URI 35 /* C, String, 1-1034 B, (none) */ +#define COAP_OPTION_PROXY_SCHEME 39 /* C, String, 1-255 B, (none) */ +#define COAP_OPTION_SIZE1 60 /* E, uint, 0-4 B, (none) */ + +/* option types from RFC 7641 */ + +#define COAP_OPTION_OBSERVE 6 /* E, empty/uint, 0 B/0-3 B, (none) */ +#define COAP_OPTION_SUBSCRIPTION COAP_OPTION_OBSERVE + +/* selected option types from RFC 7959 */ + +#define COAP_OPTION_BLOCK2 23 /* C, uint, 0--3 B, (none) */ +#define COAP_OPTION_BLOCK1 27 /* C, uint, 0--3 B, (none) */ + +/* selected option types from RFC 7967 */ + +#define COAP_OPTION_NORESPONSE 258 /* N, uint, 0--1 B, 0 */ + +#define COAP_MAX_OPT 65535 /**< the highest option number we know */ + +/* CoAP result codes (HTTP-Code / 100 * 40 + HTTP-Code % 100) */ + +/* As of draft-ietf-core-coap-04, response codes are encoded to base + * 32, i.e. the three upper bits determine the response class while + * the remaining five fine-grained information specific to that class. + */ +#define COAP_RESPONSE_CODE(N) (((N)/100 << 5) | (N)%100) + +/* Determines the class of response code C */ +#define COAP_RESPONSE_CLASS(C) (((C) >> 5) & 0xFF) + +#ifndef SHORT_ERROR_RESPONSE +/** + * Returns a human-readable response phrase for the specified CoAP response @p + * code. This function returns @c NULL if not found. + * + * @param code The response code for which the literal phrase should be + * retrieved. + * + * @return A zero-terminated string describing the error, or @c NULL if not + * found. + */ +char *coap_response_phrase(unsigned char code); + +#define COAP_ERROR_PHRASE_LENGTH 32 /**< maximum length of error phrase */ + +#else +#define coap_response_phrase(x) ((char *)NULL) + +#define COAP_ERROR_PHRASE_LENGTH 0 /**< maximum length of error phrase */ +#endif /* SHORT_ERROR_RESPONSE */ + +/* The following definitions exist for backwards compatibility */ +#if 0 /* this does not exist any more */ +#define COAP_RESPONSE_100 40 /* 100 Continue */ +#endif +#define COAP_RESPONSE_200 COAP_RESPONSE_CODE(200) /* 2.00 OK */ +#define COAP_RESPONSE_201 COAP_RESPONSE_CODE(201) /* 2.01 Created */ +#define COAP_RESPONSE_304 COAP_RESPONSE_CODE(203) /* 2.03 Valid */ +#define COAP_RESPONSE_400 COAP_RESPONSE_CODE(400) /* 4.00 Bad Request */ +#define COAP_RESPONSE_404 COAP_RESPONSE_CODE(404) /* 4.04 Not Found */ +#define COAP_RESPONSE_405 COAP_RESPONSE_CODE(405) /* 4.05 Method Not Allowed */ +#define COAP_RESPONSE_415 COAP_RESPONSE_CODE(415) /* 4.15 Unsupported Media Type */ +#define COAP_RESPONSE_500 COAP_RESPONSE_CODE(500) /* 5.00 Internal Server Error */ +#define COAP_RESPONSE_501 COAP_RESPONSE_CODE(501) /* 5.01 Not Implemented */ +#define COAP_RESPONSE_503 COAP_RESPONSE_CODE(503) /* 5.03 Service Unavailable */ +#define COAP_RESPONSE_504 COAP_RESPONSE_CODE(504) /* 5.04 Gateway Timeout */ +#if 0 /* these response codes do not have a valid code any more */ +# define COAP_RESPONSE_X_240 240 /* Token Option required by server */ +# define COAP_RESPONSE_X_241 241 /* Uri-Authority Option required by server */ +#endif +#define COAP_RESPONSE_X_242 COAP_RESPONSE_CODE(402) /* Critical Option not supported */ + +/* CoAP media type encoding */ + +#define COAP_MEDIATYPE_TEXT_PLAIN 0 /* text/plain (UTF-8) */ +#define COAP_MEDIATYPE_APPLICATION_LINK_FORMAT 40 /* application/link-format */ +#define COAP_MEDIATYPE_APPLICATION_XML 41 /* application/xml */ +#define COAP_MEDIATYPE_APPLICATION_OCTET_STREAM 42 /* application/octet-stream */ +#define COAP_MEDIATYPE_APPLICATION_RDF_XML 43 /* application/rdf+xml */ +#define COAP_MEDIATYPE_APPLICATION_EXI 47 /* application/exi */ +#define COAP_MEDIATYPE_APPLICATION_JSON 50 /* application/json */ +#define COAP_MEDIATYPE_APPLICATION_CBOR 60 /* application/cbor */ + +/* Note that identifiers for registered media types are in the range 0-65535. We + * use an unallocated type here and hope for the best. */ +#define COAP_MEDIATYPE_ANY 0xff /* any media type */ + +/** + * coap_tid_t is used to store CoAP transaction id, i.e. a hash value + * built from the remote transport address and the message id of a + * CoAP PDU. Valid transaction ids are greater or equal zero. + */ +typedef int coap_tid_t; + +/** Indicates an invalid transaction id. */ +#define COAP_INVALID_TID -1 + +/** + * Indicates that a response is suppressed. This will occur for error + * responses if the request was received via IP multicast. + */ +#define COAP_DROPPED_RESPONSE -2 + +#ifdef WORDS_BIGENDIAN +typedef struct { + unsigned int version:2; /* protocol version */ + unsigned int type:2; /* type flag */ + unsigned int token_length:4; /* length of Token */ + unsigned int code:8; /* request method (value 1--10) or response + code (value 40-255) */ + unsigned short id; /* message id */ + unsigned char token[]; /* the actual token, if any */ +} coap_hdr_t; +#else +typedef struct { + unsigned int token_length:4; /* length of Token */ + unsigned int type:2; /* type flag */ + unsigned int version:2; /* protocol version */ + unsigned int code:8; /* request method (value 1--10) or response + code (value 40-255) */ + unsigned short id; /* transaction id (network byte order!) */ + unsigned char token[]; /* the actual token, if any */ +} coap_hdr_t; +#endif + +#define COAP_MESSAGE_IS_EMPTY(MSG) ((MSG)->code == 0) +#define COAP_MESSAGE_IS_REQUEST(MSG) (!COAP_MESSAGE_IS_EMPTY(MSG) \ + && ((MSG)->code < 32)) +#define COAP_MESSAGE_IS_RESPONSE(MSG) ((MSG)->code >= 64) + +#define COAP_OPT_LONG 0x0F /* OC == 0b1111 indicates that the option list + * in a CoAP message is limited by 0b11110000 + * marker */ + +#define COAP_OPT_END 0xF0 /* end marker */ + +#define COAP_PAYLOAD_START 0xFF /* payload marker */ + +/** + * Structures for more convenient handling of options. (To be used with ordered + * coap_list_t.) The option's data will be added to the end of the coap_option + * structure (see macro COAP_OPTION_DATA). + */ +typedef struct { + unsigned short key; /* the option key (no delta coding) */ + unsigned int length; +} coap_option; + +#define COAP_OPTION_KEY(option) (option).key +#define COAP_OPTION_LENGTH(option) (option).length +#define COAP_OPTION_DATA(option) ((unsigned char *)&(option) + sizeof(coap_option)) + +/** + * Header structure for CoAP PDUs + */ + +typedef struct { + size_t max_size; /**< allocated storage for options and data */ + coap_hdr_t *hdr; /**< Address of the first byte of the CoAP message. + * This may or may not equal (coap_hdr_t*)(pdu+1) + * depending on the memory management + * implementation. */ + unsigned short max_delta; /**< highest option number */ + unsigned short length; /**< PDU length (including header, options, data) */ + unsigned char *data; /**< payload */ + +#ifdef WITH_LWIP + struct pbuf *pbuf; /**< lwIP PBUF. The package data will always reside + * inside the pbuf's payload, but this pointer + * has to be kept because no exact offset can be + * given. This field must not be accessed from + * outside, because the pbuf's reference count + * is checked to be 1 when the pbuf is assigned + * to the pdu, and the pbuf stays exclusive to + * this pdu. */ +#endif +} coap_pdu_t; + +/** + * Options in coap_pdu_t are accessed with the macro COAP_OPTION. + */ +#define COAP_OPTION(node) ((coap_option *)(node)->options) + +#ifdef WITH_LWIP +/** + * Creates a CoAP PDU from an lwIP @p pbuf, whose reference is passed on to this + * function. + * + * The pbuf is checked for being contiguous, and for having only one reference. + * The reference is stored in the PDU and will be freed when the PDU is freed. + * + * (For now, these are fatal errors; in future, a new pbuf might be allocated, + * the data copied and the passed pbuf freed). + * + * This behaves like coap_pdu_init(0, 0, 0, pbuf->tot_len), and afterwards + * copying the contents of the pbuf to the pdu. + * + * @return A pointer to the new PDU object or @c NULL on error. + */ +coap_pdu_t * coap_pdu_from_pbuf(struct pbuf *pbuf); +#endif + +/** + * Creates a new CoAP PDU of given @p size (must be large enough to hold the + * basic CoAP message header (coap_hdr_t). The function returns a pointer to the + * node coap_pdu_t object on success, or @c NULL on error. The storage allocated + * for the result must be released with coap_delete_pdu(). + * + * @param type The type of the PDU (one of COAP_MESSAGE_CON, COAP_MESSAGE_NON, + * COAP_MESSAGE_ACK, COAP_MESSAGE_RST). + * @param code The message code. + * @param id The message id to set or COAP_INVALID_TID if unknown. + * @param size The number of bytes to allocate for the actual message. + * + * @return A pointer to the new PDU object or @c NULL on error. + */ +coap_pdu_t * +coap_pdu_init(unsigned char type, + unsigned char code, + unsigned short id, + size_t size); + +/** + * Clears any contents from @p pdu and resets @c version field, @c + * length and @c data pointers. @c max_size is set to @p size, any + * other field is set to @c 0. Note that @p pdu must be a valid + * pointer to a coap_pdu_t object created e.g. by coap_pdu_init(). + */ +void coap_pdu_clear(coap_pdu_t *pdu, size_t size); + +/** + * Creates a new CoAP PDU. + * The object is created on the heap and must be released using + * coap_delete_pdu(); + * + * @deprecated This function allocates the maximum storage for each + * PDU. Use coap_pdu_init() instead. + */ +coap_pdu_t *coap_new_pdu(void); + +void coap_delete_pdu(coap_pdu_t *); + +/** + * Parses @p data into the CoAP PDU structure given in @p result. + * This function returns @c 0 on error or a number greater than zero on success. + * + * @param data The raw data to parse as CoAP PDU. + * @param length The actual size of @p data. + * @param result The PDU structure to fill. Note that the structure must + * provide space for at least @p length bytes to hold the + * entire CoAP PDU. + * + * @return A value greater than zero on success or @c 0 on error. + */ +int coap_pdu_parse(unsigned char *data, + size_t length, + coap_pdu_t *result); + +/** + * Adds token of length @p len to @p pdu. + * Adding the token destroys any following contents of the pdu. Hence options + * and data must be added after coap_add_token() has been called. In @p pdu, + * length is set to @p len + @c 4, and max_delta is set to @c 0. This funtion + * returns @c 0 on error or a value greater than zero on success. + * + * @param pdu The PDU where the token is to be added. + * @param len The length of the new token. + * @param data The token to add. + * + * @return A value greater than zero on success, or @c 0 on error. + */ +int coap_add_token(coap_pdu_t *pdu, + size_t len, + const unsigned char *data); + +/** + * Adds option of given type to pdu that is passed as first + * parameter. + * coap_add_option() destroys the PDU's data, so coap_add_data() must be called + * after all options have been added. As coap_add_token() destroys the options + * following the token, the token must be added before coap_add_option() is + * called. This function returns the number of bytes written or @c 0 on error. + */ +size_t coap_add_option(coap_pdu_t *pdu, + unsigned short type, + unsigned int len, + const unsigned char *data); + +/** + * Adds option of given type to pdu that is passed as first parameter, but does + * not write a value. It works like coap_add_option with respect to calling + * sequence (i.e. after token and before data). This function returns a memory + * address to which the option data has to be written before the PDU can be + * sent, or @c NULL on error. + */ +unsigned char *coap_add_option_later(coap_pdu_t *pdu, + unsigned short type, + unsigned int len); + +/** + * Adds given data to the pdu that is passed as first parameter. Note that the + * PDU's data is destroyed by coap_add_option(). coap_add_data() must be called + * only once per PDU, otherwise the result is undefined. + */ +int coap_add_data(coap_pdu_t *pdu, + unsigned int len, + const unsigned char *data); + +/** + * Retrieves the length and data pointer of specified PDU. Returns 0 on error or + * 1 if *len and *data have correct values. Note that these values are destroyed + * with the pdu. + */ +int coap_get_data(coap_pdu_t *pdu, + size_t *len, + unsigned char **data); + +#endif /* _COAP_PDU_H_ */ diff --git a/tools/sdk/include/coap/prng.h b/tools/sdk/include/coap/prng.h new file mode 100644 index 00000000..da6d9534 --- /dev/null +++ b/tools/sdk/include/coap/prng.h @@ -0,0 +1,106 @@ +/* + * prng.h -- Pseudo Random Numbers + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file prng.h + * @brief Pseudo Random Numbers + */ + +#ifndef _COAP_PRNG_H_ +#define _COAP_PRNG_H_ + +/** + * @defgroup prng Pseudo Random Numbers + * @{ + */ + +#if defined(WITH_POSIX) || (defined(WITH_LWIP) && !defined(LWIP_RAND)) +#include + +/** + * Fills \p buf with \p len random bytes. This is the default implementation for + * prng(). You might want to change prng() to use a better PRNG on your specific + * platform. + */ +static inline int +coap_prng_impl(unsigned char *buf, size_t len) { + while (len--) + *buf++ = rand() & 0xFF; + return 1; +} +#endif /* WITH_POSIX */ + +#ifdef WITH_CONTIKI +#include + +/** + * Fills \p buf with \p len random bytes. This is the default implementation for + * prng(). You might want to change prng() to use a better PRNG on your specific + * platform. + */ +static inline int +contiki_prng_impl(unsigned char *buf, size_t len) { + unsigned short v = random_rand(); + while (len > sizeof(v)) { + memcpy(buf, &v, sizeof(v)); + len -= sizeof(v); + buf += sizeof(v); + v = random_rand(); + } + + memcpy(buf, &v, len); + return 1; +} + +#define prng(Buf,Length) contiki_prng_impl((Buf), (Length)) +#define prng_init(Value) random_init((unsigned short)(Value)) +#endif /* WITH_CONTIKI */ + +#if defined(WITH_LWIP) && defined(LWIP_RAND) +static inline int +lwip_prng_impl(unsigned char *buf, size_t len) { + u32_t v = LWIP_RAND(); + while (len > sizeof(v)) { + memcpy(buf, &v, sizeof(v)); + len -= sizeof(v); + buf += sizeof(v); + v = LWIP_RAND(); + } + + memcpy(buf, &v, len); + return 1; +} + +#define prng(Buf,Length) lwip_prng_impl((Buf), (Length)) +#define prng_init(Value) + +#endif /* WITH_LWIP */ + +#ifndef prng +/** + * Fills \p Buf with \p Length bytes of random data. + * + * @hideinitializer + */ +#define prng(Buf,Length) coap_prng_impl((Buf), (Length)) +#endif + +#ifndef prng_init +/** + * Called to set the PRNG seed. You may want to re-define this to allow for a + * better PRNG. + * + * @hideinitializer + */ +#define prng_init(Value) srand((unsigned long)(Value)) +#endif + +/** @} */ + +#endif /* _COAP_PRNG_H_ */ diff --git a/tools/sdk/include/coap/resource.h b/tools/sdk/include/coap/resource.h new file mode 100644 index 00000000..dbb19a8d --- /dev/null +++ b/tools/sdk/include/coap/resource.h @@ -0,0 +1,408 @@ +/* + * resource.h -- generic resource handling + * + * Copyright (C) 2010,2011,2014,2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file resource.h + * @brief Generic resource handling + */ + +#ifndef _COAP_RESOURCE_H_ +#define _COAP_RESOURCE_H_ + +# include + +#ifndef COAP_RESOURCE_CHECK_TIME +/** The interval in seconds to check if resources have changed. */ +#define COAP_RESOURCE_CHECK_TIME 2 +#endif /* COAP_RESOURCE_CHECK_TIME */ + +#ifdef COAP_RESOURCES_NOHASH +# include "utlist.h" +#else +# include "uthash.h" +#endif + +#include "hashkey.h" +#include "async.h" +#include "str.h" +#include "pdu.h" +#include "net.h" +#include "subscribe.h" + +/** + * Definition of message handler function (@sa coap_resource_t). + */ +typedef void (*coap_method_handler_t) + (coap_context_t *, + struct coap_resource_t *, + const coap_endpoint_t *, + coap_address_t *, + coap_pdu_t *, + str * /* token */, + coap_pdu_t * /* response */); + +#define COAP_ATTR_FLAGS_RELEASE_NAME 0x1 +#define COAP_ATTR_FLAGS_RELEASE_VALUE 0x2 + +typedef struct coap_attr_t { + struct coap_attr_t *next; + str name; + str value; + int flags; +} coap_attr_t; + +/** The URI passed to coap_resource_init() is free'd by coap_delete_resource(). */ +#define COAP_RESOURCE_FLAGS_RELEASE_URI 0x1 + +/** + * Notifications will be sent non-confirmable by default. RFC 7641 Section 4.5 + * https://tools.ietf.org/html/rfc7641#section-4.5 + */ +#define COAP_RESOURCE_FLAGS_NOTIFY_NON 0x0 + +/** + * Notifications will be sent confirmable by default. RFC 7641 Section 4.5 + * https://tools.ietf.org/html/rfc7641#section-4.5 + */ +#define COAP_RESOURCE_FLAGS_NOTIFY_CON 0x2 + +typedef struct coap_resource_t { + unsigned int dirty:1; /**< set to 1 if resource has changed */ + unsigned int partiallydirty:1; /**< set to 1 if some subscribers have not yet + * been notified of the last change */ + unsigned int observable:1; /**< can be observed */ + unsigned int cacheable:1; /**< can be cached */ + + /** + * Used to store handlers for the four coap methods @c GET, @c POST, @c PUT, + * and @c DELETE. coap_dispatch() will pass incoming requests to the handler + * that corresponds to its request method or generate a 4.05 response if no + * handler is available. + */ + coap_method_handler_t handler[4]; + + coap_key_t key; /**< the actual key bytes for this resource */ + +#ifdef COAP_RESOURCES_NOHASH + struct coap_resource_t *next; +#else + UT_hash_handle hh; +#endif + + coap_attr_t *link_attr; /**< attributes to be included with the link format */ + coap_subscription_t *subscribers; /**< list of observers for this resource */ + + /** + * Request URI for this resource. This field will point into the static + * memory. + */ + str uri; + int flags; + +} coap_resource_t; + +/** + * Creates a new resource object and initializes the link field to the string + * of length @p len. This function returns the new coap_resource_t object. + * + * @param uri The URI path of the new resource. + * @param len The length of @p uri. + * @param flags Flags for memory management (in particular release of memory). + * + * @return A pointer to the new object or @c NULL on error. + */ +coap_resource_t *coap_resource_init(const unsigned char *uri, + size_t len, int flags); + + +/** + * Sets the notification message type of resource @p r to given + * @p mode which must be one of @c COAP_RESOURCE_FLAGS_NOTIFY_NON + * or @c COAP_RESOURCE_FLAGS_NOTIFY_CON. + */ +static inline void +coap_resource_set_mode(coap_resource_t *r, int mode) { + r->flags = (r->flags & !COAP_RESOURCE_FLAGS_NOTIFY_CON) | mode; +} + +/** + * Registers the given @p resource for @p context. The resource must have been + * created by coap_resource_init(), the storage allocated for the resource will + * be released by coap_delete_resource(). + * + * @param context The context to use. + * @param resource The resource to store. + */ +void coap_add_resource(coap_context_t *context, coap_resource_t *resource); + +/** + * Deletes a resource identified by @p key. The storage allocated for that + * resource is freed. + * + * @param context The context where the resources are stored. + * @param key The unique key for the resource to delete. + * + * @return @c 1 if the resource was found (and destroyed), + * @c 0 otherwise. + */ +int coap_delete_resource(coap_context_t *context, coap_key_t key); + +/** + * Deletes all resources from given @p context and frees their storage. + * + * @param context The CoAP context with the resources to be deleted. + */ +void coap_delete_all_resources(coap_context_t *context); + +/** + * Registers a new attribute with the given @p resource. As the + * attributes str fields will point to @p name and @p val the + * caller must ensure that these pointers are valid during the + * attribute's lifetime. + * + * @param resource The resource to register the attribute with. + * @param name The attribute's name. + * @param nlen Length of @p name. + * @param val The attribute's value or @c NULL if none. + * @param vlen Length of @p val if specified. + * @param flags Flags for memory management (in particular release of + * memory). + * + * @return A pointer to the new attribute or @c NULL on error. + */ +coap_attr_t *coap_add_attr(coap_resource_t *resource, + const unsigned char *name, + size_t nlen, + const unsigned char *val, + size_t vlen, + int flags); + +/** + * Returns @p resource's coap_attr_t object with given @p name if found, @c NULL + * otherwise. + * + * @param resource The resource to search for attribute @p name. + * @param name Name of the requested attribute. + * @param nlen Actual length of @p name. + * @return The first attribute with specified @p name or @c NULL if none + * was found. + */ +coap_attr_t *coap_find_attr(coap_resource_t *resource, + const unsigned char *name, + size_t nlen); + +/** + * Deletes an attribute. + * + * @param attr Pointer to a previously created attribute. + * + */ +void coap_delete_attr(coap_attr_t *attr); + +/** + * Status word to encode the result of conditional print or copy operations such + * as coap_print_link(). The lower 28 bits of coap_print_status_t are used to + * encode the number of characters that has actually been printed, bits 28 to 31 + * encode the status. When COAP_PRINT_STATUS_ERROR is set, an error occurred + * during output. In this case, the other bits are undefined. + * COAP_PRINT_STATUS_TRUNC indicates that the output is truncated, i.e. the + * printing would have exceeded the current buffer. + */ +typedef unsigned int coap_print_status_t; + +#define COAP_PRINT_STATUS_MASK 0xF0000000u +#define COAP_PRINT_OUTPUT_LENGTH(v) ((v) & ~COAP_PRINT_STATUS_MASK) +#define COAP_PRINT_STATUS_ERROR 0x80000000u +#define COAP_PRINT_STATUS_TRUNC 0x40000000u + +/** + * Writes a description of this resource in link-format to given text buffer. @p + * len must be initialized to the maximum length of @p buf and will be set to + * the number of characters actually written if successful. This function + * returns @c 1 on success or @c 0 on error. + * + * @param resource The resource to describe. + * @param buf The output buffer to write the description to. + * @param len Must be initialized to the length of @p buf and + * will be set to the length of the printed link description. + * @param offset The offset within the resource description where to + * start writing into @p buf. This is useful for dealing + * with the Block2 option. @p offset is updated during + * output as it is consumed. + * + * @return If COAP_PRINT_STATUS_ERROR is set, an error occured. Otherwise, + * the lower 28 bits will indicate the number of characters that + * have actually been output into @p buffer. The flag + * COAP_PRINT_STATUS_TRUNC indicates that the output has been + * truncated. + */ +coap_print_status_t coap_print_link(const coap_resource_t *resource, + unsigned char *buf, + size_t *len, + size_t *offset); + +/** + * Registers the specified @p handler as message handler for the request type @p + * method + * + * @param resource The resource for which the handler shall be registered. + * @param method The CoAP request method to handle. + * @param handler The handler to register with @p resource. + */ +static inline void +coap_register_handler(coap_resource_t *resource, + unsigned char method, + coap_method_handler_t handler) { + assert(resource); + assert(method > 0 && (size_t)(method-1) < sizeof(resource->handler)/sizeof(coap_method_handler_t)); + resource->handler[method-1] = handler; +} + +/** + * Returns the resource identified by the unique string @p key. If no resource + * was found, this function returns @c NULL. + * + * @param context The context to look for this resource. + * @param key The unique key of the resource. + * + * @return A pointer to the resource or @c NULL if not found. + */ +coap_resource_t *coap_get_resource_from_key(coap_context_t *context, + coap_key_t key); + +/** + * Calculates the hash key for the resource requested by the Uri-Options of @p + * request. This function calls coap_hash() for every path segment. + * + * @param request The requesting pdu. + * @param key The resulting hash is stored in @p key. + */ +void coap_hash_request_uri(const coap_pdu_t *request, coap_key_t key); + +/** + * @addtogroup observe + */ + +/** + * Adds the specified peer as observer for @p resource. The subscription is + * identified by the given @p token. This function returns the registered + * subscription information if the @p observer has been added, or @c NULL on + * error. + * + * @param resource The observed resource. + * @param local_interface The local network interface where the observer is + * attached to. + * @param observer The remote peer that wants to received status updates. + * @param token The token that identifies this subscription. + * @return A pointer to the added/updated subscription + * information or @c NULL on error. + */ +coap_subscription_t *coap_add_observer(coap_resource_t *resource, + const coap_endpoint_t *local_interface, + const coap_address_t *observer, + const str *token); + +/** + * Returns a subscription object for given @p peer. + * + * @param resource The observed resource. + * @param peer The address to search for. + * @param token The token that identifies this subscription or @c NULL for + * any token. + * @return A valid subscription if exists or @c NULL otherwise. + */ +coap_subscription_t *coap_find_observer(coap_resource_t *resource, + const coap_address_t *peer, + const str *token); + +/** + * Marks an observer as alive. + * + * @param context The CoAP context to use. + * @param observer The transport address of the observer. + * @param token The corresponding token that has been used for the + * subscription. + */ +void coap_touch_observer(coap_context_t *context, + const coap_address_t *observer, + const str *token); + +/** + * Removes any subscription for @p observer from @p resource and releases the + * allocated storage. The result is @c 1 if an observation relationship with @p + * observer and @p token existed, @c 0 otherwise. + * + * @param resource The observed resource. + * @param observer The observer's address. + * @param token The token that identifies this subscription or @c NULL for + * any token. + * @return @c 1 if the observer has been deleted, @c 0 otherwise. + */ +int coap_delete_observer(coap_resource_t *resource, + const coap_address_t *observer, + const str *token); + +/** + * Checks for all known resources, if they are dirty and notifies subscribed + * observers. + */ +void coap_check_notify(coap_context_t *context); + +#ifdef COAP_RESOURCES_NOHASH + +#define RESOURCES_ADD(r, obj) \ + LL_PREPEND((r), (obj)) + +#define RESOURCES_DELETE(r, obj) \ + LL_DELETE((r), (obj)) + +#define RESOURCES_ITER(r,tmp) \ + coap_resource_t *tmp; \ + LL_FOREACH((r), tmp) + +#define RESOURCES_FIND(r, k, res) { \ + coap_resource_t *tmp; \ + (res) = tmp = NULL; \ + LL_FOREACH((r), tmp) { \ + if (memcmp((k), tmp->key, sizeof(coap_key_t)) == 0) { \ + (res) = tmp; \ + break; \ + } \ + } \ + } +#else /* COAP_RESOURCES_NOHASH */ + +#define RESOURCES_ADD(r, obj) \ + HASH_ADD(hh, (r), key, sizeof(coap_key_t), (obj)) + +#define RESOURCES_DELETE(r, obj) \ + HASH_DELETE(hh, (r), (obj)) + +#define RESOURCES_ITER(r,tmp) \ + coap_resource_t *tmp, *rtmp; \ + HASH_ITER(hh, (r), tmp, rtmp) + +#define RESOURCES_FIND(r, k, res) { \ + HASH_FIND(hh, (r), (k), sizeof(coap_key_t), (res)); \ + } + +#endif /* COAP_RESOURCES_NOHASH */ + +/** @} */ + +coap_print_status_t coap_print_wellknown(coap_context_t *, + unsigned char *, + size_t *, size_t, + coap_opt_t *); + +void coap_handle_failed_notify(coap_context_t *, + const coap_address_t *, + const str *); + +#endif /* _COAP_RESOURCE_H_ */ diff --git a/tools/sdk/include/coap/str.h b/tools/sdk/include/coap/str.h new file mode 100644 index 00000000..3dfa6731 --- /dev/null +++ b/tools/sdk/include/coap/str.h @@ -0,0 +1,33 @@ +/* + * str.h -- strings to be used in the CoAP library + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_STR_H_ +#define _COAP_STR_H_ + +#include + +typedef struct { + size_t length; /* length of string */ + unsigned char *s; /* string data */ +} str; + +#define COAP_SET_STR(st,l,v) { (st)->length = (l), (st)->s = (v); } + +/** + * Returns a new string object with at least size bytes storage allocated. The + * string must be released using coap_delete_string(); + */ +str *coap_new_string(size_t size); + +/** + * Deletes the given string and releases any memory allocated. + */ +void coap_delete_string(str *); + +#endif /* _COAP_STR_H_ */ diff --git a/tools/sdk/include/coap/subscribe.h b/tools/sdk/include/coap/subscribe.h new file mode 100644 index 00000000..52068642 --- /dev/null +++ b/tools/sdk/include/coap/subscribe.h @@ -0,0 +1,72 @@ +/* + * subscribe.h -- subscription handling for CoAP + * see draft-ietf-core-observe-16 + * + * Copyright (C) 2010-2012,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + + +#ifndef _COAP_SUBSCRIBE_H_ +#define _COAP_SUBSCRIBE_H_ + +#include "address.h" +#include "coap_io.h" + +/** + * @defgroup observe Resource observation + * @{ + */ + +/** + * The value COAP_OBSERVE_ESTABLISH in a GET request indicates a new observe + * relationship for (sender address, token) is requested. + */ +#define COAP_OBSERVE_ESTABLISH 0 + +/** + * The value COAP_OBSERVE_CANCEL in a GET request indicates that the observe + * relationship for (sender address, token) must be cancelled. + */ +#define COAP_OBSERVE_CANCEL 1 + +#ifndef COAP_OBS_MAX_NON +/** + * Number of notifications that may be sent non-confirmable before a confirmable + * message is sent to detect if observers are alive. The maximum allowed value + * here is @c 15. + */ +#define COAP_OBS_MAX_NON 5 +#endif /* COAP_OBS_MAX_NON */ + +#ifndef COAP_OBS_MAX_FAIL +/** + * Number of confirmable notifications that may fail (i.e. time out without + * being ACKed) before an observer is removed. The maximum value for + * COAP_OBS_MAX_FAIL is @c 3. + */ +#define COAP_OBS_MAX_FAIL 3 +#endif /* COAP_OBS_MAX_FAIL */ + +/** Subscriber information */ +typedef struct coap_subscription_t { + struct coap_subscription_t *next; /**< next element in linked list */ + coap_endpoint_t local_if; /**< local communication interface */ + coap_address_t subscriber; /**< address and port of subscriber */ + + unsigned int non_cnt:4; /**< up to 15 non-confirmable notifies allowed */ + unsigned int fail_cnt:2; /**< up to 3 confirmable notifies can fail */ + unsigned int dirty:1; /**< set if the notification temporarily could not be + * sent (in that case, the resource's partially + * dirty flag is set too) */ + size_t token_length; /**< actual length of token */ + unsigned char token[8]; /**< token used for subscription */ +} coap_subscription_t; + +void coap_subscription_init(coap_subscription_t *); + +/** @} */ + +#endif /* _COAP_SUBSCRIBE_H_ */ diff --git a/tools/sdk/include/coap/uri.h b/tools/sdk/include/coap/uri.h new file mode 100644 index 00000000..2340a7a6 --- /dev/null +++ b/tools/sdk/include/coap/uri.h @@ -0,0 +1,121 @@ +/* + * uri.h -- helper functions for URI treatment + * + * Copyright (C) 2010-2011,2016 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_URI_H_ +#define _COAP_URI_H_ + +#include "hashkey.h" +#include "str.h" + +/** + * Representation of parsed URI. Components may be filled from a string with + * coap_split_uri() and can be used as input for option-creation functions. + */ +typedef struct { + str host; /**< host part of the URI */ + unsigned short port; /**< The port in host byte order */ + str path; /**< Beginning of the first path segment. + Use coap_split_path() to create Uri-Path options */ + str query; /**< The query part if present */ +} coap_uri_t; + +/** + * Creates a new coap_uri_t object from the specified URI. Returns the new + * object or NULL on error. The memory allocated by the new coap_uri_t + * must be released using coap_free(). + * + * @param uri The URI path to copy. + * @param length The length of uri. + * + * @return New URI object or NULL on error. + */ +coap_uri_t *coap_new_uri(const unsigned char *uri, unsigned int length); + +/** + * Clones the specified coap_uri_t object. Thie function allocates sufficient + * memory to hold the coap_uri_t structure and its contents. The object must + * be released with coap_free(). */ +coap_uri_t *coap_clone_uri(const coap_uri_t *uri); + +/** + * Calculates a hash over the given path and stores the result in + * @p key. This function returns @c 0 on error or @c 1 on success. + * + * @param path The URI path to generate hash for. + * @param len The length of @p path. + * @param key The output buffer. + * + * @return @c 1 if @p key was set, @c 0 otherwise. + */ +int coap_hash_path(const unsigned char *path, size_t len, coap_key_t key); + +/** + * @defgroup uri_parse URI Parsing Functions + * + * CoAP PDUs contain normalized URIs with their path and query split into + * multiple segments. The functions in this module help splitting strings. + * @{ + */ + +/** + * Parses a given string into URI components. The identified syntactic + * components are stored in the result parameter @p uri. Optional URI + * components that are not specified will be set to { 0, 0 }, except for the + * port which is set to @c COAP_DEFAULT_PORT. This function returns @p 0 if + * parsing succeeded, a value less than zero otherwise. + * + * @param str_var The string to split up. + * @param len The actual length of @p str_var + * @param uri The coap_uri_t object to store the result. + * @return @c 0 on success, or < 0 on error. + * + */ +int coap_split_uri(const unsigned char *str_var, size_t len, coap_uri_t *uri); + +/** + * Splits the given URI path into segments. Each segment is preceded + * by an option pseudo-header with delta-value 0 and the actual length + * of the respective segment after percent-decoding. + * + * @param s The path string to split. + * @param length The actual length of @p s. + * @param buf Result buffer for parsed segments. + * @param buflen Maximum length of @p buf. Will be set to the actual number + * of bytes written into buf on success. + * + * @return The number of segments created or @c -1 on error. + */ +int coap_split_path(const unsigned char *s, + size_t length, + unsigned char *buf, + size_t *buflen); + +/** + * Splits the given URI query into segments. Each segment is preceded + * by an option pseudo-header with delta-value 0 and the actual length + * of the respective query term. + * + * @param s The query string to split. + * @param length The actual length of @p s. + * @param buf Result buffer for parsed segments. + * @param buflen Maximum length of @p buf. Will be set to the actual number + * of bytes written into buf on success. + * + * @return The number of segments created or @c -1 on error. + * + * @bug This function does not reserve additional space for delta > 12. + */ +int coap_split_query(const unsigned char *s, + size_t length, + unsigned char *buf, + size_t *buflen); + +/** @} */ + +#endif /* _COAP_URI_H_ */ diff --git a/tools/sdk/include/coap/uthash.h b/tools/sdk/include/coap/uthash.h new file mode 100644 index 00000000..32b7a81c --- /dev/null +++ b/tools/sdk/include/coap/uthash.h @@ -0,0 +1,963 @@ +/* +Copyright (c) 2003-2014, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTHASH_H +#define UTHASH_H + +#include /* memcmp,strlen */ +#include /* ptrdiff_t */ +#include /* exit() */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#define DECLTYPE(x) +#endif +#elif defined(__BORLANDC__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#define DECLTYPE(x) +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while(0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while(0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */ +#if defined (_WIN32) +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#include +#elif defined(__WATCOMC__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif +#else +#include +#endif + +#define UTHASH_VERSION 1.9.9 + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ +#endif +#ifndef uthash_malloc +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ +#endif + +#ifndef uthash_noexpand_fyi +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#endif +#ifndef uthash_expand_fyi +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhe */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + out=NULL; \ + if (head) { \ + unsigned _hf_bkt,_hf_hashv; \ + HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ + keyptr,keylen,out); \ + } \ + } \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0) +#define HASH_BLOOM_MAKE(tbl) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ + memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ +} while (0) + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0) + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + +#else +#define HASH_BLOOM_MAKE(tbl) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#define HASH_BLOOM_BYTELEN 0 +#endif + +#define HASH_MAKE_TABLE(hh,head) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ + sizeof(UT_hash_table)); \ + if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl->buckets, 0, \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ +} while(0) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add) + +#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ +do { \ + replaced=NULL; \ + HASH_FIND(hh,head,&((add)->fieldname),keylen_in,replaced); \ + if (replaced!=NULL) { \ + HASH_DELETE(hh,head,replaced); \ + }; \ + HASH_ADD(hh,head,fieldname,keylen_in,add); \ +} while(0) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.next = NULL; \ + (add)->hh.key = (char*)(keyptr); \ + (add)->hh.keylen = (unsigned)(keylen_in); \ + if (!(head)) { \ + head = (add); \ + (head)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh,head); \ + } else { \ + (head)->hh.tbl->tail->next = (add); \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail = &((add)->hh); \ + } \ + (head)->hh.tbl->num_items++; \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ + (add)->hh.hashv, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \ + HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ + HASH_FSCK(hh,head); \ +} while(0) + +#define HASH_TO_BKT( hashv, num_bkts, bkt ) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1)); \ +} while(0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ +do { \ + struct UT_hash_handle *_hd_hh_del; \ + if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + head = NULL; \ + } else { \ + unsigned _hd_bkt; \ + _hd_hh_del = &((delptr)->hh); \ + if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ + (head)->hh.tbl->tail = \ + (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho); \ + } \ + if ((delptr)->hh.prev) { \ + ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ + } else { \ + DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ + } \ + if (_hd_hh_del->next) { \ + ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \ + (head)->hh.tbl->hho))->prev = \ + _hd_hh_del->prev; \ + } \ + HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh,head); \ +} while (0) + + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ + HASH_FIND(hh,head,findstr,(unsigned)strlen(findstr),out) +#define HASH_ADD_STR(head,strfield,add) \ + HASH_ADD(hh,head,strfield[0],strlen(add->strfield),add) +#define HASH_REPLACE_STR(head,strfield,add,replaced) \ + HASH_REPLACE(hh,head,strfield[0],(unsigned)strlen(add->strfield),add,replaced) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_REPLACE_INT(head,intfield,add,replaced) \ + HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ + HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head) \ +do { \ + struct UT_hash_handle *_thh; \ + if (head) { \ + unsigned _bkt_i; \ + unsigned _count; \ + char *_prev; \ + _count = 0; \ + for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ + unsigned _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("invalid hh_prev %p, actual %p\n", \ + _thh->hh_prev, _prev ); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("invalid bucket count %u, actual %u\n", \ + (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid hh item count %u, actual %u\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + /* traverse hh in app order; check next/prev integrity, count */ \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev !=(char*)(_thh->prev)) { \ + HASH_OOPS("invalid prev %p, actual %p\n", \ + _thh->prev, _prev ); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ + (head)->hh.tbl->hho) : NULL ); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid app item count %u, actual %u\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ +#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _hb_keylen=keylen; \ + char *_hb_key=(char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen--) { (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; } \ + bkt = (hashv) & (num_bkts-1); \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _sx_i; \ + char *_hs_key=(char*)(key); \ + hashv = 0; \ + for(_sx_i=0; _sx_i < keylen; _sx_i++) \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + bkt = hashv & (num_bkts-1); \ +} while (0) +/* FNV-1a variation */ +#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _fn_i; \ + char *_hf_key=(char*)(key); \ + hashv = 2166136261UL; \ + for(_fn_i=0; _fn_i < keylen; _fn_i++) { \ + hashv = hashv ^ _hf_key[_fn_i]; \ + hashv = hashv * 16777619; \ + } \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _ho_i; \ + char *_ho_key=(char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + unsigned char *_hj_key=(unsigned char*)(key); \ + hashv = 0xfeedbeef; \ + _hj_i = _hj_j = 0x9e3779b9; \ + _hj_k = (unsigned)(keylen); \ + while (_hj_k >= 12) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12; \ + } \ + hashv += keylen; \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ + case 5: _hj_j += _hj_key[4]; \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ + case 1: _hj_i += _hj_key[0]; \ + /* case 0: nothing left to add */ \ + default: /* make gcc -Wswitch-default happy */ \ + ; \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned char *_sfh_key=(unsigned char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = keylen; \ + \ + int _sfh_rem = _sfh_len & 3; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabe; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = (uint32_t)(get16bits (_sfh_key+2)) << 11 ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)] << 18); \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#ifdef HASH_USING_NO_STRICT_ALIASING +/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. + * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. + * MurmurHash uses the faster approach only on CPU's where we know it's safe. + * + * Note the preprocessor built-in defines can be emitted using: + * + * gcc -m64 -dM -E - < /dev/null (on gcc) + * cc -## a.c (where a.c is a simple test file) (Sun Studio) + */ +#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) +#define MUR_GETBLOCK(p,i) p[i] +#else /* non intel */ +#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0) +#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1) +#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2) +#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3) +#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) +#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) +#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) +#else /* assume little endian non-intel */ +#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) +#endif +#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ + (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ + (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ + MUR_ONE_THREE(p)))) +#endif +#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +#define MUR_FMIX(_h) \ +do { \ + _h ^= _h >> 16; \ + _h *= 0x85ebca6b; \ + _h ^= _h >> 13; \ + _h *= 0xc2b2ae35l; \ + _h ^= _h >> 16; \ +} while(0) + +#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \ +do { \ + const uint8_t *_mur_data = (const uint8_t*)(key); \ + const int _mur_nblocks = (keylen) / 4; \ + uint32_t _mur_h1 = 0xf88D5353; \ + uint32_t _mur_c1 = 0xcc9e2d51; \ + uint32_t _mur_c2 = 0x1b873593; \ + uint32_t _mur_k1 = 0; \ + const uint8_t *_mur_tail; \ + const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \ + int _mur_i; \ + for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \ + _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + \ + _mur_h1 ^= _mur_k1; \ + _mur_h1 = MUR_ROTL32(_mur_h1,13); \ + _mur_h1 = _mur_h1*5+0xe6546b64; \ + } \ + _mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \ + _mur_k1=0; \ + switch((keylen) & 3) { \ + case 3: _mur_k1 ^= _mur_tail[2] << 16; \ + case 2: _mur_k1 ^= _mur_tail[1] << 8; \ + case 1: _mur_k1 ^= _mur_tail[0]; \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + _mur_h1 ^= _mur_k1; \ + } \ + _mur_h1 ^= (keylen); \ + MUR_FMIX(_mur_h1); \ + hashv = _mur_h1; \ + bkt = hashv & (num_bkts-1); \ +} while(0) +#endif /* HASH_USING_NO_STRICT_ALIASING */ + +/* key comparison function; return 0 if keys equal */ +#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ +do { \ + if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \ + else out=NULL; \ + while (out) { \ + if ((out)->hh.keylen == keylen_in) { \ + if ((HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) break; \ + } \ + if ((out)->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,(out)->hh.hh_next)); \ + else out = NULL; \ + } \ +} while(0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,addhh) \ +do { \ + head.count++; \ + (addhh)->hh_next = head.hh_head; \ + (addhh)->hh_prev = NULL; \ + if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ + (head).hh_head=addhh; \ + if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ + && (addhh)->tbl->noexpand != 1) { \ + HASH_EXPAND_BUCKETS((addhh)->tbl); \ + } \ +} while(0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(hh,head,hh_del) \ + (head).count--; \ + if ((head).hh_head == hh_del) { \ + (head).hh_head = hh_del->hh_next; \ + } \ + if (hh_del->hh_prev) { \ + hh_del->hh_prev->hh_next = hh_del->hh_next; \ + } \ + if (hh_del->hh_next) { \ + hh_del->hh_next->hh_prev = hh_del->hh_prev; \ + } + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(tbl) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ + memset(_he_new_buckets, 0, \ + 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + tbl->ideal_chain_maxlen = \ + (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ + ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ + tbl->nonideal_items = 0; \ + for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ + { \ + _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ + if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ + tbl->nonideal_items++; \ + _he_newbkt->expand_mult = _he_newbkt->count / \ + tbl->ideal_chain_maxlen; \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ + _he_thh; \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + tbl->num_buckets *= 2; \ + tbl->log2_num_buckets++; \ + tbl->buckets = _he_new_buckets; \ + tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ + (tbl->ineff_expands+1) : 0; \ + if (tbl->ineff_expands > 1) { \ + tbl->noexpand=1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ +} while(0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ + _hs_psize++; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + if (! (_hs_q) ) break; \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \ + if (_hs_psize == 0) { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \ + _hs_e = _hs_p; \ + if (_hs_p){ \ + _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + } \ + _hs_psize--; \ + } else if (( \ + cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ + ) <= 0) { \ + _hs_e = _hs_p; \ + if (_hs_p){ \ + _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + } \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail ) { \ + _hs_tail->next = ((_hs_e) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + if (_hs_e) { \ + _hs_e->prev = ((_hs_tail) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ + } \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + if (_hs_tail){ \ + _hs_tail->next = NULL; \ + } \ + if ( _hs_nmerges <= 1 ) { \ + _hs_looping=0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2; \ + } \ + HASH_FSCK(hh,head); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt=NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if (src) { \ + for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh) { _last_elt_hh->next = _elt; } \ + if (!dst) { \ + DECLTYPE_ASSIGN(dst,_elt); \ + HASH_MAKE_TABLE(hh_dst,dst); \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ + (dst)->hh_dst.tbl->num_items++; \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst,dst); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if (head) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)=NULL; \ + } \ +} while(0) + +#define HASH_OVERHEAD(hh,head) \ + ((head) ? ( \ + (size_t)((((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ + ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ + (sizeof(UT_hash_table)) + \ + (HASH_BLOOM_BYTELEN)))) : 0) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \ + el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \ + el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL)) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1 +#define HASH_BLOOM_SIGNATURE 0xb12220f2 + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + char bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ diff --git a/tools/sdk/include/coap/utlist.h b/tools/sdk/include/coap/utlist.h new file mode 100644 index 00000000..b5f3f04c --- /dev/null +++ b/tools/sdk/include/coap/utlist.h @@ -0,0 +1,757 @@ +/* +Copyright (c) 2007-2014, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTLIST_H +#define UTLIST_H + +#define UTLIST_VERSION 1.9.9 + +#include + +/* + * This file contains macros to manipulate singly and doubly-linked lists. + * + * 1. LL_ macros: singly-linked lists. + * 2. DL_ macros: doubly-linked lists. + * 3. CDL_ macros: circular doubly-linked lists. + * + * To use singly-linked lists, your structure must have a "next" pointer. + * To use doubly-linked lists, your structure must "prev" and "next" pointers. + * Either way, the pointer to the head of the list must be initialized to NULL. + * + * ----------------.EXAMPLE ------------------------- + * struct item { + * int id; + * struct item *prev, *next; + * } + * + * struct item *list = NULL: + * + * int main() { + * struct item *item; + * ... allocate and populate item ... + * DL_APPEND(list, item); + * } + * -------------------------------------------------- + * + * For doubly-linked lists, the append and delete macros are O(1) + * For singly-linked lists, append and delete are O(n) but prepend is O(1) + * The sort macro is O(n log(n)) for all types of single/double/circular lists. + */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ code), this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#ifdef _MSC_VER /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define LDECLTYPE(x) decltype(x) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#define LDECLTYPE(x) char* +#endif +#elif defined(__ICCARM__) +#define NO_DECLTYPE +#define LDECLTYPE(x) char* +#else /* GNU, Sun and other compilers */ +#define LDECLTYPE(x) __typeof(x) +#endif + +/* for VS2008 we use some workarounds to get around the lack of decltype, + * namely, we always reassign our tmp variable to the list head if we need + * to dereference its prev/next pointers, and save/restore the real head.*/ +#ifdef NO_DECLTYPE +#define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } +#define _NEXT(elt,list,next) ((char*)((list)->next)) +#define _NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } +/* #define _PREV(elt,list,prev) ((char*)((list)->prev)) */ +#define _PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } +#define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } +#define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } +#else +#define _SV(elt,list) +#define _NEXT(elt,list,next) ((elt)->next) +#define _NEXTASGN(elt,list,to,next) ((elt)->next)=(to) +/* #define _PREV(elt,list,prev) ((elt)->prev) */ +#define _PREVASGN(elt,list,to,prev) ((elt)->prev)=(to) +#define _RS(list) +#define _CASTASGN(a,b) (a)=(b) +#endif + +/****************************************************************************** + * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort * + * Unwieldy variable names used here to avoid shadowing passed-in variables. * + *****************************************************************************/ +#define LL_SORT(list, cmp) \ + LL_SORT2(list, cmp, next) + +#define LL_SORT2(list, cmp, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ + } \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + + +#define DL_SORT(list, cmp) \ + DL_SORT2(list, cmp, prev, next) + +#define DL_SORT2(list, cmp, prev, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + _CASTASGN(list->prev, _ls_tail); \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + +#define CDL_SORT(list, cmp) \ + CDL_SORT2(list, cmp, prev, next) + +#define CDL_SORT2(list, cmp, prev, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + LDECLTYPE(list) _ls_oldhead; \ + LDECLTYPE(list) _tmp; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + _CASTASGN(_ls_oldhead,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); \ + if (_NEXT(_ls_q,list,next) == _ls_oldhead) { \ + _ls_q = NULL; \ + } else { \ + _ls_q = _NEXT(_ls_q,list,next); \ + } \ + _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + _CASTASGN(list->prev,_ls_tail); \ + _CASTASGN(_tmp,list); \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp,next); _RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + +/****************************************************************************** + * singly linked list macros (non-circular) * + *****************************************************************************/ +#define LL_PREPEND(head,add) \ + LL_PREPEND2(head,add,next) + +#define LL_PREPEND2(head,add,next) \ +do { \ + (add)->next = head; \ + head = add; \ +} while (0) + +#define LL_CONCAT(head1,head2) \ + LL_CONCAT2(head1,head2,next) + +#define LL_CONCAT2(head1,head2,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head1) { \ + _tmp = head1; \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(head2); \ + } else { \ + (head1)=(head2); \ + } \ +} while (0) + +#define LL_APPEND(head,add) \ + LL_APPEND2(head,add,next) + +#define LL_APPEND2(head,add,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + (add)->next=NULL; \ + if (head) { \ + _tmp = head; \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(add); \ + } else { \ + (head)=(add); \ + } \ +} while (0) + +#define LL_DELETE(head,del) \ + LL_DELETE2(head,del,next) + +#define LL_DELETE2(head,del,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (del))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = ((del)->next); \ + } \ + } \ +} while (0) + +/* Here are VS2008 replacements for LL_APPEND and LL_DELETE */ +#define LL_APPEND_VS2008(head,add) \ + LL_APPEND2_VS2008(head,add,next) + +#define LL_APPEND2_VS2008(head,add,next) \ +do { \ + if (head) { \ + (add)->next = head; /* use add->next as a temp variable */ \ + while ((add)->next->next) { (add)->next = (add)->next->next; } \ + (add)->next->next=(add); \ + } else { \ + (head)=(add); \ + } \ + (add)->next=NULL; \ +} while (0) + +#define LL_DELETE_VS2008(head,del) \ + LL_DELETE2_VS2008(head,del,next) + +#define LL_DELETE2_VS2008(head,del,next) \ +do { \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + char *_tmp = (char*)(head); \ + while ((head)->next && ((head)->next != (del))) { \ + head = (head)->next; \ + } \ + if ((head)->next) { \ + (head)->next = ((del)->next); \ + } \ + { \ + char **_head_alias = (char**)&(head); \ + *_head_alias = _tmp; \ + } \ + } \ +} while (0) +#ifdef NO_DECLTYPE +#undef LL_APPEND +#define LL_APPEND LL_APPEND_VS2008 +#undef LL_DELETE +#define LL_DELETE LL_DELETE_VS2008 +#undef LL_DELETE2 +#define LL_DELETE2 LL_DELETE2_VS2008 +#undef LL_APPEND2 +#define LL_APPEND2 LL_APPEND2_VS2008 +#undef LL_CONCAT /* no LL_CONCAT_VS2008 */ +#undef DL_CONCAT /* no DL_CONCAT_VS2008 */ +#endif +/* end VS2008 replacements */ + +#define LL_COUNT(head,el,counter) \ + LL_COUNT2(head,el,counter,next) \ + +#define LL_COUNT2(head,el,counter,next) \ +{ \ + counter = 0; \ + LL_FOREACH2(head,el,next){ ++counter; } \ +} + +#define LL_FOREACH(head,el) \ + LL_FOREACH2(head,el,next) + +#define LL_FOREACH2(head,el,next) \ + for(el=head;el;el=(el)->next) + +#define LL_FOREACH_SAFE(head,el,tmp) \ + LL_FOREACH_SAFE2(head,el,tmp,next) + +#define LL_FOREACH_SAFE2(head,el,tmp,next) \ + for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) + +#define LL_SEARCH_SCALAR(head,out,field,val) \ + LL_SEARCH_SCALAR2(head,out,field,val,next) + +#define LL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while(0) + +#define LL_SEARCH(head,out,elt,cmp) \ + LL_SEARCH2(head,out,elt,cmp,next) + +#define LL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while(0) + +#define LL_REPLACE_ELEM(head, el, add) \ +do { \ + LDECLTYPE(head) _tmp; \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el)->next; \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ +} while (0) + +#define LL_PREPEND_ELEM(head, el, add) \ +do { \ + LDECLTYPE(head) _tmp; \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ +} while (0) \ + + +/****************************************************************************** + * doubly linked list macros (non-circular) * + *****************************************************************************/ +#define DL_PREPEND(head,add) \ + DL_PREPEND2(head,add,prev,next) + +#define DL_PREPEND2(head,add,prev,next) \ +do { \ + (add)->next = head; \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev = (add); \ + } else { \ + (add)->prev = (add); \ + } \ + (head) = (add); \ +} while (0) + +#define DL_APPEND(head,add) \ + DL_APPEND2(head,add,prev,next) + +#define DL_APPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev->next = (add); \ + (head)->prev = (add); \ + (add)->next = NULL; \ + } else { \ + (head)=(add); \ + (head)->prev = (head); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define DL_CONCAT(head1,head2) \ + DL_CONCAT2(head1,head2,prev,next) + +#define DL_CONCAT2(head1,head2,prev,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head2) { \ + if (head1) { \ + _tmp = (head2)->prev; \ + (head2)->prev = (head1)->prev; \ + (head1)->prev->next = (head2); \ + (head1)->prev = _tmp; \ + } else { \ + (head1)=(head2); \ + } \ + } \ +} while (0) + +#define DL_DELETE(head,del) \ + DL_DELETE2(head,del,prev,next) + +#define DL_DELETE2(head,del,prev,next) \ +do { \ + assert((del)->prev != NULL); \ + if ((del)->prev == (del)) { \ + (head)=NULL; \ + } else if ((del)==(head)) { \ + (del)->next->prev = (del)->prev; \ + (head) = (del)->next; \ + } else { \ + (del)->prev->next = (del)->next; \ + if ((del)->next) { \ + (del)->next->prev = (del)->prev; \ + } else { \ + (head)->prev = (del)->prev; \ + } \ + } \ +} while (0) + +#define DL_COUNT(head,el,counter) \ + DL_COUNT2(head,el,counter,next) \ + +#define DL_COUNT2(head,el,counter,next) \ +{ \ + counter = 0; \ + DL_FOREACH2(head,el,next){ ++counter; } \ +} + +#define DL_FOREACH(head,el) \ + DL_FOREACH2(head,el,next) + +#define DL_FOREACH2(head,el,next) \ + for(el=head;el;el=(el)->next) + +/* this version is safe for deleting the elements during iteration */ +#define DL_FOREACH_SAFE(head,el,tmp) \ + DL_FOREACH_SAFE2(head,el,tmp,next) + +#define DL_FOREACH_SAFE2(head,el,tmp,next) \ + for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) + +/* these are identical to their singly-linked list counterparts */ +#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR +#define DL_SEARCH LL_SEARCH +#define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2 +#define DL_SEARCH2 LL_SEARCH2 + +#define DL_REPLACE_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + (add)->next = (el)->next; \ + if ((el)->next == NULL) { \ + (add)->prev = (add); \ + } else { \ + (add)->prev = (el)->prev; \ + (add)->next->prev = (add); \ + } \ + } else { \ + (add)->next = (el)->next; \ + (add)->prev = (el)->prev; \ + (add)->prev->next = (add); \ + if ((el)->next == NULL) { \ + (head)->prev = (add); \ + } else { \ + (add)->next->prev = (add); \ + } \ + } \ +} while (0) + +#define DL_PREPEND_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->prev->next = (add); \ + } \ +} while (0) \ + + +/****************************************************************************** + * circular doubly linked list macros * + *****************************************************************************/ +#define CDL_PREPEND(head,add) \ + CDL_PREPEND2(head,add,prev,next) + +#define CDL_PREPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (add)->prev->next = (add); \ + } else { \ + (add)->prev = (add); \ + (add)->next = (add); \ + } \ +(head)=(add); \ +} while (0) + +#define CDL_DELETE(head,del) \ + CDL_DELETE2(head,del,prev,next) + +#define CDL_DELETE2(head,del,prev,next) \ +do { \ + if ( ((head)==(del)) && ((head)->next == (head))) { \ + (head) = 0L; \ + } else { \ + (del)->next->prev = (del)->prev; \ + (del)->prev->next = (del)->next; \ + if ((del) == (head)) (head)=(del)->next; \ + } \ +} while (0) + +#define CDL_COUNT(head,el,counter) \ + CDL_COUNT2(head,el,counter,next) \ + +#define CDL_COUNT2(head, el, counter,next) \ +{ \ + counter = 0; \ + CDL_FOREACH2(head,el,next){ ++counter; } \ +} + +#define CDL_FOREACH(head,el) \ + CDL_FOREACH2(head,el,next) + +#define CDL_FOREACH2(head,el,next) \ + for(el=head;el;el=((el)->next==head ? 0L : (el)->next)) + +#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ + CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) + +#define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) \ + for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \ + (el) && ((tmp2)=(el)->next, 1); \ + ((el) = (((el)==(tmp1)) ? 0L : (tmp2)))) + +#define CDL_SEARCH_SCALAR(head,out,field,val) \ + CDL_SEARCH_SCALAR2(head,out,field,val,next) + +#define CDL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + CDL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while(0) + +#define CDL_SEARCH(head,out,elt,cmp) \ + CDL_SEARCH2(head,out,elt,cmp,next) + +#define CDL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + CDL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while(0) + +#define CDL_REPLACE_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + if ((el)->next == (el)) { \ + (add)->next = (add); \ + (add)->prev = (add); \ + (head) = (add); \ + } else { \ + (add)->next = (el)->next; \ + (add)->prev = (el)->prev; \ + (add)->next->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ + } \ +} while (0) + +#define CDL_PREPEND_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ +} while (0) \ + +#endif /* UTLIST_H */ + diff --git a/tools/sdk/include/config/sdkconfig.h b/tools/sdk/include/config/sdkconfig.h index 95967a29..4c9f3200 100644 --- a/tools/sdk/include/config/sdkconfig.h +++ b/tools/sdk/include/config/sdkconfig.h @@ -10,7 +10,9 @@ #define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 16 #define CONFIG_MQTT_TRANSPORT_SSL 1 #define CONFIG_BLE_SMP_ENABLE 1 +#define CONFIG_SPIRAM_TYPE_AUTO 1 #define CONFIG_STACK_CHECK 1 +#define CONFIG_MB_SERIAL_TASK_PRIO 10 #define CONFIG_MQTT_PROTOCOL_311 1 #define CONFIG_TCP_RECVMBOX_SIZE 6 #define CONFIG_LWIP_ETHARP_TRUST_IP_MAC 1 @@ -32,6 +34,7 @@ #define CONFIG_MBEDTLS_AES_C 1 #define CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED 1 #define CONFIG_A2DP_SINK_TASK_STACK_SIZE 2048 +#define CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN 752 #define CONFIG_MBEDTLS_GCM_C 1 #define CONFIG_ESPTOOLPY_FLASHSIZE "4MB" #define CONFIG_SPIFFS_CACHE_WR 1 @@ -65,21 +68,24 @@ #define CONFIG_IP_LOST_TIMER_INTERVAL 120 #define CONFIG_SPIFFS_META_LENGTH 4 #define CONFIG_ESP32_PANIC_PRINT_REBOOT 1 +#define CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE 20 #define CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED 1 #define CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED 1 +#define CONFIG_MB_SERIAL_BUF_SIZE 256 #define CONFIG_CONSOLE_UART_BAUDRATE 115200 #define CONFIG_SPIRAM_SUPPORT 1 #define CONFIG_LWIP_MAX_SOCKETS 10 #define CONFIG_LWIP_NETIF_LOOPBACK 1 -#define CONFIG_SPIRAM_TYPE_ESPPSRAM32 1 #define CONFIG_EMAC_TASK_PRIORITY 20 #define CONFIG_TIMER_TASK_STACK_DEPTH 2048 #define CONFIG_TCP_MSS 1436 #define CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED 1 #define CONFIG_BTDM_CONTROLLER_MODE_BTDM 1 #define CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF 3 +#define CONFIG_TCPIP_TASK_AFFINITY_CPU0 1 #define CONFIG_FATFS_CODEPAGE 850 #define CONFIG_ULP_COPROC_RESERVE_MEM 512 +#define CONFIG_MB_UART_RXD 34 #define CONFIG_LWIP_MAX_UDP_PCBS 16 #define CONFIG_ESPTOOLPY_BAUD 921600 #define CONFIG_INT_WDT_CHECK_CPU1 1 @@ -95,6 +101,7 @@ #define CONFIG_FATFS_LFN_STACK 1 #define CONFIG_CONSOLE_UART_NUM 0 #define CONFIG_ESP32_APPTRACE_LOCK_ENABLE 1 +#define CONFIG_PTHREAD_STACK_MIN 768 #define CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC 1 #define CONFIG_TCP_OVERSIZE_MSS 1 #define CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS 1 @@ -108,8 +115,12 @@ #define CONFIG_LOG_DEFAULT_LEVEL_ERROR 1 #define CONFIG_TIMER_TASK_STACK_SIZE 4096 #define CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE 1 +#define CONFIG_SPIRAM_BANKSWITCH_ENABLE 1 #define CONFIG_MBEDTLS_X509_CRL_PARSE_C 1 #define CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR 1 +#define CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER 1 +#define CONFIG_MB_SERIAL_TASK_STACK_SIZE 2048 +#define CONFIG_GATTS_SEND_SERVICE_CHANGE_AUTO 1 #define CONFIG_LWIP_DHCPS_LEASE_UNIT 60 #define CONFIG_SPIFFS_USE_MAGIC 1 #define CONFIG_TCPIP_TASK_STACK_SIZE 2560 @@ -133,6 +144,7 @@ #define CONFIG_LOG_DEFAULT_LEVEL 1 #define CONFIG_TIMER_QUEUE_LENGTH 10 #define CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT 1 +#define CONFIG_GATTS_SEND_SERVICE_CHANGE_MODE 0 #define CONFIG_MAKE_WARN_UNDEFINED_VARIABLES 1 #define CONFIG_FATFS_TIMEOUT_MS 10000 #define CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM 10 @@ -147,28 +159,35 @@ #define CONFIG_MDNS_MAX_SERVICES 10 #define CONFIG_ULP_COPROC_ENABLED 1 #define CONFIG_HFP_AUDIO_DATA_PATH_PCM 1 +#define CONFIG_IDF_TARGET_ESP32 1 #define CONFIG_EMAC_CHECK_LINK_PERIOD_MS 2000 #define CONFIG_BTDM_LPCLK_SEL_MAIN_XTAL 1 #define CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED 1 #define CONFIG_LIBSODIUM_USE_MBEDTLS_SHA 1 +#define CONFIG_SW_COEXIST_PREFERENCE_WIFI 1 #define CONFIG_DMA_RX_BUF_NUM 10 #define CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED 1 #define CONFIG_TCP_SYNMAXRTX 6 +#define CONFIG_MB_UART_RTS 32 #define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA 1 #define CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF 0 #define CONFIG_HEAP_POISONING_LIGHT 1 #define CONFIG_PYTHON "python" +#define CONFIG_SPIRAM_BANKSWITCH_RESERVE 8 #define CONFIG_MBEDTLS_ECP_NIST_OPTIM 1 #define CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 1 #define CONFIG_ESPTOOLPY_COMPRESSED 1 #define CONFIG_PARTITION_TABLE_FILENAME "partitions_singleapp.csv" +#define CONFIG_MB_CONTROLLER_STACK_SIZE 4096 #define CONFIG_TCP_SND_BUF_DEFAULT 5744 #define CONFIG_GARP_TMR_INTERVAL 60 #define CONFIG_LWIP_DHCP_MAX_NTP_SERVERS 1 #define CONFIG_TCP_MSL 60000 #define CONFIG_MBEDTLS_SSL_PROTO_TLS1_1 1 #define CONFIG_LWIP_SO_REUSE_RXTOALL 1 +#define CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT 20 #define CONFIG_PARTITION_TABLE_SINGLE_APP 1 +#define CONFIG_UNITY_ENABLE_FLOAT 1 #define CONFIG_ESP32_WIFI_RX_BA_WIN 6 #define CONFIG_MBEDTLS_X509_CSR_PARSE_C 1 #define CONFIG_SPIFFS_USE_MTIME 1 @@ -176,7 +195,8 @@ #define CONFIG_LWIP_DHCP_RESTORE_LAST_IP 1 #define CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN 2 #define CONFIG_EMAC_TASK_STACK_SIZE 3072 -#define CONFIG_SW_COEXIST_PREFERENCE_VALUE 2 +#define CONFIG_MB_QUEUE_LENGTH 20 +#define CONFIG_SW_COEXIST_PREFERENCE_VALUE 0 #define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA 1 #define CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER 1 #define CONFIG_PPP_SUPPORT 1 @@ -188,6 +208,7 @@ #define CONFIG_MBEDTLS_PEM_PARSE_C 1 #define CONFIG_SPIFFS_GC_MAX_RUNS 10 #define CONFIG_ESP32_APPTRACE_DEST_NONE 1 +#define CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC 1 #define CONFIG_MBEDTLS_SSL_PROTO_TLS1_2 1 #define CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA 1 #define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM 32 @@ -208,13 +229,14 @@ #define CONFIG_MBEDTLS_TLS_ENABLED 1 #define CONFIG_LWIP_MAX_RAW_PCBS 16 #define CONFIG_SMP_ENABLE 1 -#define CONFIG_SPIRAM_SIZE 4194304 +#define CONFIG_SPIRAM_SIZE -1 #define CONFIG_MBEDTLS_SSL_SESSION_TICKETS 1 #define CONFIG_SPIFFS_MAX_PARTITIONS 3 #define CONFIG_ESP_ERR_TO_NAME_LOOKUP 1 #define CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_0 1 #define CONFIG_MBEDTLS_SSL_RENEGOTIATION 1 #define CONFIG_ESPTOOLPY_BEFORE_RESET 1 +#define CONFIG_MB_EVENT_QUEUE_TIMEOUT 20 #define CONFIG_ESPTOOLPY_BAUD_OTHER_VAL 115200 #define CONFIG_PPP_MPPE_SUPPORT 1 #define CONFIG_ENABLE_ARDUINO_DEPENDS 1 @@ -230,19 +252,20 @@ #define CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST 1 #define CONFIG_TCP_MAXRTX 12 #define CONFIG_ESPTOOLPY_AFTER "hard_reset" +#define CONFIG_TCPIP_TASK_AFFINITY 0x0 #define CONFIG_LWIP_SO_REUSE 1 #define CONFIG_DMA_TX_BUF_NUM 10 #define CONFIG_LWIP_MAX_LISTENING_TCP 16 #define CONFIG_FREERTOS_INTERRUPT_BACKTRACE 1 #define CONFIG_WL_SECTOR_SIZE 4096 #define CONFIG_ESP32_DEBUG_OCDAWARE 1 +#define CONFIG_MB_UART_TXD 33 #define CONFIG_MQTT_TRANSPORT_WEBSOCKET 1 #define CONFIG_TIMER_TASK_PRIORITY 1 #define CONFIG_PPP_PAP_SUPPORT 1 #define CONFIG_MBEDTLS_TLS_CLIENT 1 #define CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI 1 #define CONFIG_BT_ENABLED 1 -#define CONFIG_SW_COEXIST_PREFERENCE_BALANCE 1 #define CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED 1 #define CONFIG_MONITOR_BAUD 115200 #define CONFIG_ESP32_DEBUG_STUBS_ENABLE 1 @@ -265,9 +288,12 @@ #define CONFIG_CLASSIC_BT_ENABLED 1 #define CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK 1 #define CONFIG_OPENSSL_ASSERT_DO_NOTHING 1 +#define CONFIG_IDF_TARGET "esp32" #define CONFIG_WL_SECTOR_SIZE_4096 1 #define CONFIG_OPTIMIZATION_LEVEL_DEBUG 1 +#define CONFIG_FREERTOS_NO_AFFINITY 0x7FFFFFFF #define CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED 1 +#define CONFIG_MB_TIMER_INDEX 0 #define CONFIG_SCAN_DUPLICATE_TYPE 0 #define CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED 1 #define CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED 1 @@ -283,6 +309,7 @@ #define CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED 1 #define CONFIG_LWIP_LOOPBACK_MAX_PBUFS 8 #define CONFIG_A2DP_ENABLE 1 +#define CONFIG_MB_TIMER_GROUP 0 #define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1 #define CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE 1 #define CONFIG_SPIFFS_PAGE_SIZE 256 @@ -291,11 +318,13 @@ #define CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0 1 #define CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT 2048 #define CONFIG_LWIP_SO_RCVBUF 1 +#define CONFIG_MB_TIMER_PORT_ENABLED 1 #define CONFIG_DUPLICATE_SCAN_CACHE_SIZE 20 #define CONFIG_MONITOR_BAUD_OTHER_VAL 115200 #define CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF 1 #define CONFIG_ESPTOOLPY_PORT "/dev/cu.usbserial-DO00EAB0" #define CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS 1 +#define CONFIG_UNITY_ENABLE_DOUBLE 1 #define CONFIG_BLUEDROID_PINNED_TO_CORE 0 #define CONFIG_BTDM_MODEM_SLEEP_MODE_ORIG 1 #define CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR 1 diff --git a/tools/sdk/include/driver/driver/i2c.h b/tools/sdk/include/driver/driver/i2c.h index 8f8cb9a1..feb1d78b 100644 --- a/tools/sdk/include/driver/driver/i2c.h +++ b/tools/sdk/include/driver/driver/i2c.h @@ -420,6 +420,35 @@ esp_err_t i2c_set_period(i2c_port_t i2c_num, int high_period, int low_period); */ esp_err_t i2c_get_period(i2c_port_t i2c_num, int* high_period, int* low_period); +/** + * @brief enable hardware filter on I2C bus + * Sometimes the I2C bus is disturbed by high frequency noise(about 20ns), or the rising edge of + * the SCL clock is very slow, these may cause the master state machine broken. enable hardware + * filter can filter out high frequency interference and make the master more stable. + * @note + * Enable filter will slow the SCL clock. + * + * @param i2c_num I2C port number + * @param cyc_num the APB cycles need to be filtered(0<= cyc_num <=7). + * When the period of a pulse is less than cyc_num * APB_cycle, the I2C controller will ignore this pulse. + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t i2c_filter_enable(i2c_port_t i2c_num, uint8_t cyc_num); + +/** + * @brief disable filter on I2C bus + * + * @param i2c_num I2C port number + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t i2c_filter_disable(i2c_port_t i2c_num); + /** * @brief set I2C master start signal timing * diff --git a/tools/sdk/include/driver/driver/mcpwm.h b/tools/sdk/include/driver/driver/mcpwm.h index d1c10e86..301ca419 100644 --- a/tools/sdk/include/driver/driver/mcpwm.h +++ b/tools/sdk/include/driver/driver/mcpwm.h @@ -27,11 +27,12 @@ extern "C" { #endif /** - * @brief IO signals for MCPWM - * 6 MCPWM output pins that generate PWM signals - * 3 MCPWM fault input pins to detect faults like overcurrent, overvoltage, etc - * 3 MCPWM sync input pins to synchronize MCPWM outputs signals - * 3 MCPWM capture input pin to capture hall sell signal to measure time + * @brief IO signals for the MCPWM + * + * - 6 MCPWM output pins that generate PWM signals + * - 3 MCPWM fault input pins to detect faults like overcurrent, overvoltage, etc. + * - 3 MCPWM sync input pins to synchronize MCPWM outputs signals + * - 3 MCPWM capture input pins to gather feedback from controlled motors, using e.g. hall sensors */ typedef enum { MCPWM0A = 0, /*!0 if read operation was successful, the return value is the number -* of bytes actually read from the TLS/SSL connection. -* - 0 if read operation was not successful. The underlying -* connection was closed. -* - <0 if read operation was not successful, because either an -* error occured or an action must be taken by the calling process. -*/ + * - >0 if read operation was successful, the return value is the number + * of bytes actually read from the TLS/SSL connection. + * - 0 if read operation was not successful. The underlying + * connection was closed. + * - <0 if read operation was not successful, because either an + * error occured or an action must be taken by the calling process. + */ static inline ssize_t esp_tls_conn_read(esp_tls_t *tls, void *data, size_t datalen) { return tls->read(tls, (char *)data, datalen); @@ -181,6 +259,46 @@ void esp_tls_conn_delete(esp_tls_t *tls); */ size_t esp_tls_get_bytes_avail(esp_tls_t *tls); +/** + * @brief Create a global CA store with the buffer provided in cfg. + * + * This function should be called if the application wants to use the same CA store for + * multiple connections. The application must call this function before calling esp_tls_conn_new(). + * + * @param[in] cacert_pem_buf Buffer which has certificates in pem format. This buffer + * is used for creating a global CA store, which can be used + * by other tls connections. + * @param[in] cacert_pem_bytes Length of the buffer. + * + * @return + * - ESP_OK if creating global CA store was successful. + * - Other if an error occured or an action must be taken by the calling process. + */ +esp_err_t esp_tls_set_global_ca_store(const unsigned char *cacert_pem_buf, const unsigned int cacert_pem_bytes); + +/** + * @brief Get the pointer to the global CA store currently being used. + * + * The application must first call esp_tls_set_global_ca_store(). Then the same + * CA store could be used by the application for APIs other than esp_tls. + * + * @note Modifying the pointer might cause a failure in verifying the certificates. + * + * @return + * - Pointer to the global CA store currently being used if successful. + * - NULL if there is no global CA store set. + */ +mbedtls_x509_crt *esp_tls_get_global_ca_store(); + +/** + * @brief Free the global CA store currently being used. + * + * The memory being used by the global CA store to store all the parsed certificates is + * freed up. The application can call this API if it no longer needs the global CA store. + */ +void esp_tls_free_global_ca_store(); + + #ifdef __cplusplus } #endif diff --git a/tools/sdk/include/esp32/esp_attr.h b/tools/sdk/include/esp32/esp_attr.h index 5bf9a229..6d2d5ea8 100644 --- a/tools/sdk/include/esp32/esp_attr.h +++ b/tools/sdk/include/esp32/esp_attr.h @@ -39,14 +39,27 @@ // Forces code into RTC fast memory. See "docs/deep-sleep-stub.rst" #define RTC_IRAM_ATTR __attribute__((section(".rtc.text"))) +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY +// Forces bss variable into external memory. " +#define EXT_RAM_ATTR __attribute__((section(".ext_ram.bss"))) +#else +#define EXT_RAM_ATTR +#endif + // Forces data into RTC slow memory. See "docs/deep-sleep-stub.rst" // Any variable marked with this attribute will keep its value // during a deep sleep / wake cycle. #define RTC_DATA_ATTR __attribute__((section(".rtc.data"))) -// Forces read-only data into RTC slow memory. See "docs/deep-sleep-stub.rst" +// Forces read-only data into RTC memory. See "docs/deep-sleep-stub.rst" #define RTC_RODATA_ATTR __attribute__((section(".rtc.rodata"))) +// Allows to place data into RTC_SLOW memory. +#define RTC_SLOW_ATTR __attribute__((section(".rtc.force_slow"))) + +// Allows to place data into RTC_FAST memory. +#define RTC_FAST_ATTR __attribute__((section(".rtc.force_fast"))) + // Forces data into noinit section to avoid initialization after restart. #define __NOINIT_ATTR __attribute__((section(".noinit"))) @@ -55,4 +68,7 @@ // after restart or during a deep sleep / wake cycle. #define RTC_NOINIT_ATTR __attribute__((section(".rtc_noinit"))) +// Forces to not inline function +#define NOINLINE_ATTR __attribute__((noinline)) + #endif /* __ESP_ATTR_H__ */ diff --git a/tools/sdk/include/esp32/esp_clk.h b/tools/sdk/include/esp32/esp_clk.h index 1a91d26f..99e4f307 100644 --- a/tools/sdk/include/esp32/esp_clk.h +++ b/tools/sdk/include/esp32/esp_clk.h @@ -13,6 +13,7 @@ // limitations under the License. #pragma once +#include /** * @file esp_clk.h diff --git a/tools/sdk/include/esp32/esp_core_dump.h b/tools/sdk/include/esp32/esp_core_dump.h index c6634364..4c798f59 100644 --- a/tools/sdk/include/esp32/esp_core_dump.h +++ b/tools/sdk/include/esp32/esp_core_dump.h @@ -14,6 +14,11 @@ #ifndef ESP_CORE_DUMP_H_ #define ESP_CORE_DUMP_H_ + +/**************************************************************************************/ +/******************************** EXCEPTION MODE API **********************************/ +/**************************************************************************************/ + /** * @brief Initializes core dump module internal data. * @@ -25,29 +30,29 @@ void esp_core_dump_init(); * @brief Saves core dump to flash. * * The structure of data stored in flash is as follows: - * | MAGIC1 | + * * | TOTAL_LEN | TASKS_NUM | TCB_SIZE | * | TCB_ADDR_1 | STACK_TOP_1 | STACK_END_1 | TCB_1 | STACK_1 | * . . . . * . . . . * | TCB_ADDR_N | STACK_TOP_N | STACK_END_N | TCB_N | STACK_N | - * | MAGIC2 | + * | CRC32 | + * * Core dump in flash consists of header and data for every task in the system at the moment of crash. - * For flash data integrity control two magic numbers are used at the beginning and the end of core dump. + * For flash data integrity control CRC is used at the end of core the dump data. * The structure of core dump data is described below in details. - * 1) MAGIC1 and MAGIC2 are special numbers stored at the beginning and the end of core dump. - * They are used to control core dump data integrity. Size of every number is 4 bytes. - * 2) Core dump starts with header: - * 2.1) TOTAL_LEN is total length of core dump data in flash including magic numbers. Size is 4 bytes. - * 2.2) TASKS_NUM is the number of tasks for which data are stored. Size is 4 bytes. - * 2.3) TCB_SIZE is the size of task's TCB structure. Size is 4 bytes. - * 3) Core dump header is followed by the data for every task in the system. + * 1) Core dump starts with header: + * 1.1) TOTAL_LEN is total length of core dump data in flash including CRC. Size is 4 bytes. + * 1.2) TASKS_NUM is the number of tasks for which data are stored. Size is 4 bytes. + * 1.3) TCB_SIZE is the size of task's TCB structure. Size is 4 bytes. + * 2) Core dump header is followed by the data for every task in the system. * Task data are started with task header: - * 3.1) TCB_ADDR is the address of TCB in memory. Size is 4 bytes. - * 3.2) STACK_TOP is the top of task's stack (address of the topmost stack item). Size is 4 bytes. - * 3.2) STACK_END is the end of task's stack (address from which task's stack starts). Size is 4 bytes. - * 4) Task header is followed by TCB data. Size is TCB_SIZE bytes. - * 5) Task's stack is placed after TCB data. Size is (STACK_END - STACK_TOP) bytes. + * 2.1) TCB_ADDR is the address of TCB in memory. Size is 4 bytes. + * 2.2) STACK_TOP is the top of task's stack (address of the topmost stack item). Size is 4 bytes. + * 2.2) STACK_END is the end of task's stack (address from which task's stack starts). Size is 4 bytes. + * 3) Task header is followed by TCB data. Size is TCB_SIZE bytes. + * 4) Task's stack is placed after TCB data. Size is (STACK_END - STACK_TOP) bytes. + * 5) CRC is placed at the end of the data. */ void esp_core_dump_to_flash(); @@ -55,10 +60,26 @@ void esp_core_dump_to_flash(); * @brief Print base64-encoded core dump to UART. * * The structure of core dump data is the same as for data stored in flash (@see esp_core_dump_to_flash) with some notes: - * 1) Magic numbers are not present in core dump printed to UART. - * 2) Since magic numbers are omitted TOTAL_LEN does not include their size. + * 1) CRC is not present in core dump printed to UART. + * 2) Since CRC is omitted TOTAL_LEN does not include its size. * 3) Printed base64 data are surrounded with special messages to help user recognize the start and end of actual data. */ void esp_core_dump_to_uart(); + +/**************************************************************************************/ +/*********************************** USER MODE API ************************************/ +/**************************************************************************************/ + +/** + * @brief Retrieves address and size of coredump data in flash. + * This function is always available, even when core dump is disabled in menuconfig. + * + * @param out_addr pointer to store image address in flash. + * @param out_size pointer to store image size in flash (including CRC). In bytes. + * + * @return ESP_OK on success, otherwise \see esp_err_t + */ +esp_err_t esp_core_dump_image_get(size_t* out_addr, size_t *out_size); + #endif diff --git a/tools/sdk/include/esp32/esp_err.h b/tools/sdk/include/esp32/esp_err.h index 9dcb25af..6672f233 100644 --- a/tools/sdk/include/esp32/esp_err.h +++ b/tools/sdk/include/esp32/esp_err.h @@ -78,6 +78,9 @@ const char *esp_err_to_name_r(esp_err_t code, char *buf, size_t buflen); /** @cond */ void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) __attribute__((noreturn)); +/** @cond */ +void _esp_error_check_failed_without_abort(esp_err_t rc, const char *file, int line, const char *function, const char *expression); + #ifndef __ASSERT_FUNC /* This won't happen on IDF, which defines __ASSERT_FUNC in assert.h, but it does happen when building on the host which uses /usr/include/assert.h or equivalent. @@ -102,6 +105,13 @@ void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const cha esp_err_t __err_rc = (x); \ (void) sizeof(__err_rc); \ } while(0); +#elif defined(CONFIG_OPTIMIZATION_ASSERTIONS_SILENT) +#define ESP_ERROR_CHECK(x) do { \ + esp_err_t __err_rc = (x); \ + if (__err_rc != ESP_OK) { \ + abort(); \ + } \ + } while(0); #else #define ESP_ERROR_CHECK(x) do { \ esp_err_t __err_rc = (x); \ @@ -112,6 +122,27 @@ void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const cha } while(0); #endif +/** + * Macro which can be used to check the error code. Prints the error code, error location, and the failed statement to + * serial output. + * In comparison with ESP_ERROR_CHECK(), this prints the same error message but isn't terminating the program. + */ +#ifdef NDEBUG +#define ESP_ERROR_CHECK_WITHOUT_ABORT(x) ({ \ + esp_err_t __err_rc = (x); \ + __err_rc; \ + }) +#else +#define ESP_ERROR_CHECK_WITHOUT_ABORT(x) ({ \ + esp_err_t __err_rc = (x); \ + if (__err_rc != ESP_OK) { \ + _esp_error_check_failed_without_abort(__err_rc, __FILE__, __LINE__, \ + __ASSERT_FUNC, #x); \ + } \ + __err_rc; \ + }) +#endif //NDEBUG + #ifdef __cplusplus } #endif diff --git a/tools/sdk/include/esp32/esp_event.h b/tools/sdk/include/esp32/esp_event_legacy.h similarity index 100% rename from tools/sdk/include/esp32/esp_event.h rename to tools/sdk/include/esp32/esp_event_legacy.h diff --git a/tools/sdk/include/esp32/esp_flash_data_types.h b/tools/sdk/include/esp32/esp_flash_data_types.h index bb5aa299..9a26281b 100644 --- a/tools/sdk/include/esp32/esp_flash_data_types.h +++ b/tools/sdk/include/esp32/esp_flash_data_types.h @@ -60,6 +60,7 @@ typedef struct { #define PART_SUBTYPE_DATA_OTA 0x00 #define PART_SUBTYPE_DATA_RF 0x01 #define PART_SUBTYPE_DATA_WIFI 0x02 +#define PART_SUBTYPE_DATA_NVS_KEYS 0x04 #define PART_TYPE_END 0xff #define PART_SUBTYPE_END 0xff diff --git a/tools/sdk/include/esp32/esp_himem.h b/tools/sdk/include/esp32/esp_himem.h new file mode 100644 index 00000000..099d9260 --- /dev/null +++ b/tools/sdk/include/esp32/esp_himem.h @@ -0,0 +1,152 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//Opaque pointers as handles for ram/range data +typedef struct esp_himem_ramdata_t *esp_himem_handle_t; +typedef struct esp_himem_rangedata_t *esp_himem_rangehandle_t; + +//ESP32 MMU block size +#define ESP_HIMEM_BLKSZ (0x8000) + +#define ESP_HIMEM_MAPFLAG_RO 1 /*!< Indicates that a mapping will only be read from. Note that this is unused for now. */ + +/** + * @brief Allocate a block in high memory + * + * @param size Size of the to-be-allocated block, in bytes. Note that this needs to be + * a multiple of the external RAM mmu block size (32K). + * @param[out] handle_out Handle to be returned + * @returns - ESP_OK if succesful + * - ESP_ERR_NO_MEM if out of memory + * - ESP_ERR_INVALID_SIZE if size is not a multiple of 32K + */ +esp_err_t esp_himem_alloc(size_t size, esp_himem_handle_t *handle_out); + + +/** + * @brief Allocate a memory region to map blocks into + * + * This allocates a contiguous CPU memory region that can be used to map blocks + * of physical memory into. + * + * @param size Size of the range to be allocated. Note this needs to be a multiple of + * the external RAM mmu block size (32K). + * @param[out] handle_out Handle to be returned + * @returns - ESP_OK if succesful + * - ESP_ERR_NO_MEM if out of memory or address space + * - ESP_ERR_INVALID_SIZE if size is not a multiple of 32K + */ +esp_err_t esp_himem_alloc_map_range(size_t size, esp_himem_rangehandle_t *handle_out); + +/** + * @brief Map a block of high memory into the CPUs address space + * + * This effectively makes the block available for read/write operations. + * + * @note The region to be mapped needs to have offsets and sizes that are aligned to the + * SPI RAM MMU block size (32K) + * + * @param handle Handle to the block of memory, as given by esp_himem_alloc + * @param range Range handle to map the memory in + * @param ram_offset Offset into the block of physical memory of the block to map + * @param range_offset Offset into the address range where the block will be mapped + * @param len Length of region to map + * @param flags One of ESP_HIMEM_MAPFLAG_* + * @param[out] out_ptr Pointer to variable to store resulting memory pointer in + * @returns - ESP_OK if the memory could be mapped + * - ESP_ERR_INVALID_ARG if offset, range or len aren't MMU-block-aligned (32K) + * - ESP_ERR_INVALID_SIZE if the offsets/lengths don't fit in the allocated memory or range + * - ESP_ERR_INVALID_STATE if a block in the selected ram offset/length is already mapped, or + * if a block in the selected range offset/length already has a mapping. + */ +esp_err_t esp_himem_map(esp_himem_handle_t handle, esp_himem_rangehandle_t range, size_t ram_offset, size_t range_offset, size_t len, int flags, void **out_ptr); + + +/** + * @brief Free a block of physical memory + * + * This clears out the associated handle making the memory available for re-allocation again. + * This will only succeed if none of the memory blocks currently have a mapping. + * + * @param handle Handle to the block of memory, as given by esp_himem_alloc + * @returns - ESP_OK if the memory is succesfully freed + * - ESP_ERR_INVALID_ARG if the handle still is (partially) mapped + */ +esp_err_t esp_himem_free(esp_himem_handle_t handle); + + + +/** + * @brief Free a mapping range + * + * This clears out the associated handle making the range available for re-allocation again. + * This will only succeed if none of the range blocks currently are used for a mapping. + * + * @param handle Handle to the range block, as given by esp_himem_alloc_map_range + * @returns - ESP_OK if the memory is succesfully freed + * - ESP_ERR_INVALID_ARG if the handle still is (partially) mapped to + */ +esp_err_t esp_himem_free_map_range(esp_himem_rangehandle_t handle); + + +/** + * @brief Unmap a region + * + * @param range Range handle + * @param ptr Pointer returned by esp_himem_map + * @param len Length of the block to be unmapped. Must be aligned to the SPI RAM MMU blocksize (32K) + * @returns - ESP_OK if the memory is succesfully unmapped, + * - ESP_ERR_INVALID_ARG if ptr or len are invalid. + */ +esp_err_t esp_himem_unmap(esp_himem_rangehandle_t range, void *ptr, size_t len); + + +/** + * @brief Get total amount of memory under control of himem API + * + * @returns Amount of memory, in bytes + */ +size_t esp_himem_get_phys_size(); + +/** + * @brief Get free amount of memory under control of himem API + * + * @returns Amount of free memory, in bytes + */ +size_t esp_himem_get_free_size(); + + +/** + * @brief Get amount of SPI memory address space needed for bankswitching + * + * @note This is also weakly defined in esp32/spiram.c and returns 0 there, so + * if no other function in this file is used, no memory is reserved. + * + * @returns Amount of reserved area, in bytes + */ +size_t esp_himem_reserved_area_size(); + + +#ifdef __cplusplus +} +#endif + diff --git a/tools/sdk/include/esp32/esp_intr_alloc.h b/tools/sdk/include/esp32/esp_intr_alloc.h index b5420f79..edc4b9f2 100644 --- a/tools/sdk/include/esp32/esp_intr_alloc.h +++ b/tools/sdk/include/esp32/esp_intr_alloc.h @@ -194,18 +194,19 @@ esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusre /** * @brief Disable and free an interrupt. * - * Use an interrupt handle to disable the interrupt and release the resources - * associated with it. + * Use an interrupt handle to disable the interrupt and release the resources associated with it. + * If the current core is not the core that registered this interrupt, this routine will be assigned to + * the core that allocated this interrupt, blocking and waiting until the resource is successfully released. * * @note * When the handler shares its source with other handlers, the interrupt status * bits it's responsible for should be managed properly before freeing it. see - * ``esp_intr_disable`` for more details. + * ``esp_intr_disable`` for more details. Please do not call this function in ``esp_ipc_call_blocking``. * * @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus * - * @return ESP_ERR_INVALID_ARG if handle is invalid, or esp_intr_free runs on another core than - * where the interrupt is allocated on. + * @return ESP_ERR_INVALID_ARG the handle is NULL + * ESP_FAIL failed to release this handle * ESP_OK otherwise */ esp_err_t esp_intr_free(intr_handle_t handle); diff --git a/tools/sdk/include/esp32/esp_ipc.h b/tools/sdk/include/esp32/esp_ipc.h index b229cb33..477b3d0a 100644 --- a/tools/sdk/include/esp32/esp_ipc.h +++ b/tools/sdk/include/esp32/esp_ipc.h @@ -33,21 +33,6 @@ typedef void (*esp_ipc_func_t)(void* arg); * These APIs can only be used when FreeRTOS scheduler is running. */ - -/* - * Initialize inter-processor call module. This function is called automatically - * on CPU start and should not be called from the application. - * - * This function start two tasks, one on each CPU. These tasks are started - * with high priority. These tasks are normally inactive, waiting until one of - * the esp_ipc_call_* functions to be used. One of these tasks will be - * woken up to execute the callback provided to esp_ipc_call_nonblocking or - * esp_ipc_call_blocking. - */ -/** @cond */ -void esp_ipc_init(); -/** @endcond */ - /** * @brief Execute a function on the given CPU * diff --git a/tools/sdk/include/esp32/esp_mesh.h b/tools/sdk/include/esp32/esp_mesh.h index 6322dc60..8256e8cb 100644 --- a/tools/sdk/include/esp32/esp_mesh.h +++ b/tools/sdk/include/esp32/esp_mesh.h @@ -185,6 +185,8 @@ typedef enum { Fixed Root Setting of each device is variable as that setting changes of the root. */ MESH_EVENT_SCAN_DONE, /**< if self-organized networking is disabled, user can call esp_wifi_scan_start() to trigger this event, and add the corresponding scan done handler in this event. */ + MESH_EVENT_NETWORK_STATE, /**< network state, such as whether current mesh network has a root. */ + MESH_EVENT_STOP_RECONNECTION, /**< the root stops reconnecting to the router and non-root devices stop reconnecting to their parents. */ MESH_EVENT_MAX, } mesh_event_id_t; @@ -229,13 +231,18 @@ typedef enum { * @brief Mesh disconnect reason code */ typedef enum { - MESH_REASON_CYCLIC = 100, /**< cyclic is detected */ - MESH_REASON_PARENT_IDLE, /**< parent is idle */ - MESH_REASON_LEAF, /**< the connected device is changed to a leaf */ - MESH_REASON_DIFF_ID, /**< in different mesh ID */ - MESH_REASON_ROOTS, /**< root conflict is detected */ - MESH_REASON_PARENT_STOPPED, /**< parent has stopped the mesh */ - MESH_REASON_SCAN_FAIL, /**< scan fail */ + MESH_REASON_CYCLIC = 100, /**< cyclic is detected */ + MESH_REASON_PARENT_IDLE, /**< parent is idle */ + MESH_REASON_LEAF, /**< the connected device is changed to a leaf */ + MESH_REASON_DIFF_ID, /**< in different mesh ID */ + MESH_REASON_ROOTS, /**< root conflict is detected */ + MESH_REASON_PARENT_STOPPED, /**< parent has stopped the mesh */ + MESH_REASON_SCAN_FAIL, /**< scan fail */ + MESH_REASON_IE_UNKNOWN, /**< unknown IE */ + MESH_REASON_WAIVE_ROOT, /**< waive root */ + MESH_REASON_PARENT_WORSE, /**< parent with very poor RSSI */ + MESH_REASON_EMPTY_PASSWORD, /**< use an empty password to connect to an encrypted parent */ + MESH_REASON_PARENT_UNENCRYPTED, /**< connect to an unencrypted parent/router */ } mesh_disconnect_reason_t; /******************************************************* @@ -367,6 +374,13 @@ typedef struct { uint8_t number; /**< the number of APs scanned */ } mesh_event_scan_done_t; +/** + * @brief Network state information + */ +typedef struct { + bool is_rootless; /**< whether current mesh network has a root */ +} mesh_event_network_state_t; + /** * @brief Mesh event information */ @@ -390,6 +404,7 @@ typedef union { mesh_event_root_conflict_t root_conflict; /**< other powerful root */ mesh_event_root_fixed_t root_fixed; /**< fixed root */ mesh_event_scan_done_t scan_done; /**< scan done */ + mesh_event_network_state_t network_state; /**< network state, such as whether current mesh network has a root. */ } mesh_event_info_t; /** @@ -541,7 +556,7 @@ esp_err_t esp_mesh_deinit(void); * - Create TX and RX queues according to the configuration. * - Register mesh packets receive callback. * - * @attention This API shall be called after esp_mesh_init() and esp_mesh_set_config(). + * @attention  This API shall be called after mesh initialization and configuration. * * @return * - ESP_OK @@ -711,10 +726,10 @@ esp_err_t esp_mesh_recv_toDS(mesh_addr_t *from, mesh_addr_t *to, * Root conflict function could eliminate redundant roots connected with the same BSSID, but couldn't handle roots * connected with different BSSID. Because users might have such requirements of setting up routers with same SSID * for the future replacement. But in that case, if the above situations happen, please make sure applications - * implement forward functions on the root to guarantee devices in different mesh network can communicate with each other. + * implement forward functions on the root to guarantee devices in different mesh networks can communicate with each other. * max_connection of mesh softAP is limited by the max number of Wi-Fi softAP supported (max:10). * - * @attention This API shall be called between esp_mesh_init() and esp_mesh_start(). + * @attention This API shall be called before mesh is started after mesh is initialized. * * @param[in] config pointer to mesh stack configuration * @@ -739,7 +754,7 @@ esp_err_t esp_mesh_get_config(mesh_cfg_t *config); /** * @brief Get router configuration * - * @attention This API shall be called between esp_mesh_init() and esp_mesh_start(). + * @attention This API is used to dynamically modify the router configuration after mesh is configured. * * @param[in] router pointer to router configuration * @@ -763,7 +778,7 @@ esp_err_t esp_mesh_get_router(mesh_router_t *router); /** * @brief Set mesh network ID * - * @attention This API could be called either before esp_mesh_start() or after esp_mesh_start(). + * @attention This API is used to dynamically modify the mesh network ID. * * @param[in] id pointer to mesh network ID * @@ -786,6 +801,8 @@ esp_err_t esp_mesh_get_id(mesh_addr_t *id); /** * @brief Designate device type over the mesh network + * - MESH_ROOT: designates the root node for a mesh network + * - MESH_LEAF: designates a device as a standalone Wi-Fi station * * @param[in] type device type * @@ -806,10 +823,10 @@ esp_err_t esp_mesh_set_type(mesh_type_t type); mesh_type_t esp_mesh_get_type(void); /** - * @brief Set network max layer value (max:25, default:15) + * @brief Set network max layer value (max:25, default:25) * - Network max layer limits the max hop count. * - * @attention This API shall be called before esp_mesh_start(). + * @attention This API shall be called before mesh is started. * * @param[in] max_layer max layer value * @@ -830,7 +847,7 @@ int esp_mesh_get_max_layer(void); /** * @brief Set mesh softAP password * - * @attention This API shall be called before esp_mesh_start(). + * @attention This API shall be called before mesh is started. * * @param[in] pwd pointer to the password * @param[in] len password length @@ -845,7 +862,7 @@ esp_err_t esp_mesh_set_ap_password(const uint8_t *pwd, int len); /** * @brief Set mesh softAP authentication mode * - * @attention This API shall be called before esp_mesh_start(). + * @attention This API shall be called before mesh is started. * * @param[in] authmode authentication mode * @@ -866,7 +883,7 @@ wifi_auth_mode_t esp_mesh_get_ap_authmode(void); /** * @brief Set mesh softAP max connection value * - * @attention This API shall be called before esp_mesh_start(). + * @attention This API shall be called before mesh is started. * * @param[in] connections the number of max connections * @@ -914,16 +931,20 @@ esp_err_t esp_mesh_get_parent_bssid(mesh_addr_t *bssid); bool esp_mesh_is_root(void); /** - * @brief Enable/disable mesh networking self-organized, self-organized by default - * - If self-organized is disabled, users shall set a parent for the device via - * esp_mesh_set_parent(); + * @brief Enable/disable self-organized networking + * - Self-organized networking has three main functions: + * select the root node; + * find a preferred parent; + * initiate reconnection if a disconnection is detected. + * - Self-organized networking is enabled by default. + * - If self-organized is disabled, users should set a parent for the device via esp_mesh_set_parent(). * - * @attention This API could be called either before esp_mesh_start() or after esp_mesh_start(). + * @attention This API is used to dynamically modify whether to enable the self organizing. * * @param[in] enable enable or disable self-organized networking - * @param[in] select_parent - * - If self-organized networking is enabled, let the device search for a new parent or - * keep connecting to the previous parent. + * @param[in] select_parent Only valid when self-organized networking is enabled. + * - if select_parent is set to true, the root will give up its mesh root status and search for a new parent + * like other non-root devices. * * @return * - ESP_OK @@ -976,7 +997,7 @@ esp_err_t esp_mesh_waive_root(const mesh_vote_t *vote, int reason); * - During the networking, only obtaining vote percentage reaches this threshold, * the device could be a root. * - * @attention This API shall be called before esp_mesh_start(). + * @attention This API shall be called before mesh is started. * * @param[in] percentage vote percentage threshold * @@ -1090,7 +1111,7 @@ int esp_mesh_available_txupQ_num(const mesh_addr_t *addr, uint32_t *xseqno_in); /** * @brief Set the number of queue * - * @attention This API shall be called before esp_mesh_start(). + * @attention This API shall be called before mesh is started. * * @param[in] qsize default:32 (min:16) * @@ -1179,7 +1200,7 @@ bool esp_mesh_is_my_group(const mesh_addr_t *addr); /** * @brief Set mesh network capacity * - * @attention This API shall be called before esp_mesh_start(). + * @attention This API shall be called before mesh is started. * * @param[in] num mesh network capacity * @@ -1191,17 +1212,19 @@ bool esp_mesh_is_my_group(const mesh_addr_t *addr); esp_err_t esp_mesh_set_capacity_num(int num); /** - * @brief Get mesh network capacity + * @brief Get mesh network capacity * - * @return mesh network capacity + * @return mesh network capacity */ int esp_mesh_get_capacity_num(void); /** - * @brief Set mesh IE crypto functions + * @brief Set mesh IE crypto functions * - * @param[in] crypto_funcs crypto functions for mesh IE + * @attention This API can be called at any time after mesh is initialized. * + * @param[in] crypto_funcs crypto functions for mesh IE + * - If crypto_funcs is set to NULL, mesh IE is no longer encrypted. * @return * - ESP_OK */ @@ -1210,15 +1233,13 @@ esp_err_t esp_mesh_set_ie_crypto_funcs(const mesh_crypto_funcs_t *crypto_funcs); /** * @brief Set mesh IE crypto key * - * @attention This API shall be called after esp_mesh_set_config() and before esp_mesh_start(). + * @attention This API can be called at any time after mesh is initialized. * * @param[in] key ASCII crypto key * @param[in] len length in bytes, range:8~64 * * @return * - ESP_OK - * - ESP_ERR_MESH_NOT_ALLOWED - * - ESP_ERR_MESH_NOT_CONFIG * - ESP_MESH_ERR_ARGUMENT */ esp_err_t esp_mesh_set_ie_crypto_key(const char *key, int len); @@ -1236,9 +1257,9 @@ esp_err_t esp_mesh_set_ie_crypto_key(const char *key, int len); esp_err_t esp_mesh_get_ie_crypto_key(char *key, int len); /** - * @brief Set delay time before network starts root healing + * @brief Set delay time before starting root healing * - * @param[in] delay_ms delay time in milliseconds + * @param[in] delay_ms delay time in milliseconds * * @return * - ESP_OK @@ -1253,9 +1274,9 @@ esp_err_t esp_mesh_set_root_healing_delay(int delay_ms); int esp_mesh_get_root_healing_delay(void); /** - * @brief Set mesh event callback + * @brief Set mesh event callback * - * @param[in] event_cb mesh event call back + * @param[in] event_cb mesh event call back * * @return * - ESP_OK @@ -1285,12 +1306,23 @@ esp_err_t esp_mesh_fix_root(bool enable); bool esp_mesh_is_root_fixed(void); /** - * @brief Specify a parent for the device + * @brief Set a specified parent for the device + * + * @attention This API can be called at any time after mesh is configured. * * @param[in] parent parent configuration, the SSID and the channel of the parent are mandatory. - * @param[in] parent_mesh_id parent mesh ID, if not set, use the device default one. - * @param[in] my_type my mesh type - * @param[in] my_layer my mesh layer + * - If the BSSID is set, make sure that the SSID and BSSID represent the same parent, + * otherwise the device will never find this specified parent. + * @param[in] parent_mesh_id parent mesh ID, + * - If this value is not set, the original mesh ID is used. + * @param[in] my_type mesh type + * - If the parent set for the device is the same as the router in the network configuration, + * then my_type shall set MESH_ROOT and my_layer shall set MESH_ROOT_LAYER. + * @param[in] my_layer mesh layer + * - my_layer of the device may change after joining the network. + * - If my_type is set MESH_NODE, my_layer shall be greater than MESH_ROOT_LAYER. + * - If my_type is set MESH_LEAF, the device becomes a standalone Wi-Fi station and no longer + * has the ability to extend the network. * * @return * - ESP_OK @@ -1330,7 +1362,7 @@ esp_err_t esp_mesh_scan_get_ap_ie_len(int *len); esp_err_t esp_mesh_scan_get_ap_record(wifi_ap_record_t *ap_record, void *buffer); /** - * @brief flush upstream packets pending in to_parent queue and to_parent_p2p queue + * @brief Flush upstream packets pending in to_parent queue and to_parent_p2p queue * * @return * - ESP_OK @@ -1338,10 +1370,10 @@ esp_err_t esp_mesh_scan_get_ap_record(wifi_ap_record_t *ap_record, void *buffer) esp_err_t esp_mesh_flush_upstream_packets(void); /** - * @brief get the number of nodes in the subnet of a specific child + * @brief Get the number of nodes in the subnet of a specific child * - * @param child_mac an associated child address of this device - * @param nodes_num pointer to the number of nodes in the subnet of a specific child + * @param[in] child_mac an associated child address of this device + * @param[out] nodes_num pointer to the number of nodes in the subnet of a specific child * * @return * - ESP_OK @@ -1351,11 +1383,11 @@ esp_err_t esp_mesh_flush_upstream_packets(void); esp_err_t esp_mesh_get_subnet_nodes_num(const mesh_addr_t *child_mac, int *nodes_num); /** - * @brief get nodes in the subnet of a specific child + * @brief Get nodes in the subnet of a specific child * - * @param child_mac an associated child address of this device - * @param nodes pointer to nodes in the subnet of a specific child - * @param nodes_num the number of nodes in the subnet of a specific child + * @param[in] child_mac an associated child address of this device + * @param[out] nodes pointer to nodes in the subnet of a specific child + * @param[in] nodes_num the number of nodes in the subnet of a specific child * * @return * - ESP_OK @@ -1364,6 +1396,22 @@ esp_err_t esp_mesh_get_subnet_nodes_num(const mesh_addr_t *child_mac, int *nodes */ esp_err_t esp_mesh_get_subnet_nodes_list(const mesh_addr_t *child_mac, mesh_addr_t *nodes, int nodes_num); +/** + * @brief Disconnect from current parent + * + * @return + * - ESP_OK + */ +esp_err_t esp_mesh_disconnect(void); + +/** + * @brief Connect to current parent + * + * @return + * - ESP_OK + */ +esp_err_t esp_mesh_connect(void); + #ifdef __cplusplus } #endif diff --git a/tools/sdk/include/esp32/esp_mesh_internal.h b/tools/sdk/include/esp32/esp_mesh_internal.h index e1dbf7f7..e061c457 100644 --- a/tools/sdk/include/esp32/esp_mesh_internal.h +++ b/tools/sdk/include/esp32/esp_mesh_internal.h @@ -66,7 +66,7 @@ typedef struct { uint8_t oui[3]; /**< organization identifier */ /**< mesh networking IE content */ uint8_t type; /** ESP defined IE type */ - uint8_t encryped : 1; /**< whether mesh networking IE is encrypted */ + uint8_t encrypted : 1; /**< whether mesh networking IE is encrypted */ uint8_t version : 7; /**< mesh networking IE version */ /**< content */ uint8_t mesh_type; /**< mesh device type */ diff --git a/tools/sdk/include/esp32/esp_spiram.h b/tools/sdk/include/esp32/esp_spiram.h index aafd85ce..ab76f3b5 100644 --- a/tools/sdk/include/esp32/esp_spiram.h +++ b/tools/sdk/include/esp32/esp_spiram.h @@ -21,26 +21,12 @@ #include #include "esp_err.h" -typedef enum { - ESP_SPIRAM_VOLT_3V3 = 0, /*!< SPI RAM voltage is 3.3v */ - ESP_SPIRAM_VOLT_1V8 = 1, /*!< SPI RAM voltage is 1.8v */ - ESP_SPIRAM_VOLT_INVALID, /*!< SPI RAM voltage is invalid*/ -} esp_spiram_volt_t; - typedef enum { ESP_SPIRAM_SIZE_32MBITS = 0, /*!< SPI RAM size is 32 MBits */ ESP_SPIRAM_SIZE_64MBITS = 1, /*!< SPI RAM size is 64 MBits */ ESP_SPIRAM_SIZE_INVALID, /*!< SPI RAM size is invalid */ } esp_spiram_size_t; -/** - * @brief get SPI RAM voltage - * @return - * - ESP_SPIRAM_VOLT_INVALID if SPI RAM not enabled or not valid. - * - SPI RAM voltage - */ -esp_spiram_volt_t esp_spiram_get_chip_volt(); - /** * @brief get SPI RAM size * @return @@ -70,7 +56,7 @@ void esp_spiram_init_cache(); /** * @brief Memory test for SPI RAM. Should be called after SPI RAM is initialized and - * (in case of a dual-core system) the app CPU is online. This test overwrites the + * (in case of a dual-core system) the app CPU is online. This test overwrites the * memory with crap, so do not call after e.g. the heap allocator has stored important * stuff in SPI RAM. * @@ -116,4 +102,14 @@ void esp_spiram_writeback_cache(); esp_err_t esp_spiram_reserve_dma_pool(size_t size); +/** + * @brief If SPI RAM(PSRAM) has been initialized + * + * @return + * - true SPI RAM has been initialized successfully + * - false SPI RAM hasn't been initialized or initialized failed + */ +bool esp_spiram_is_initialized(void); + + #endif diff --git a/tools/sdk/include/esp32/esp_task.h b/tools/sdk/include/esp32/esp_task.h index 2f01e610..754014b5 100644 --- a/tools/sdk/include/esp32/esp_task.h +++ b/tools/sdk/include/esp32/esp_task.h @@ -27,6 +27,7 @@ #define _ESP_TASK_H_ #include "sdkconfig.h" +#include "freertos/FreeRTOSConfig.h" #define ESP_TASK_PRIO_MAX (configMAX_PRIORITIES) #define ESP_TASK_PRIO_MIN (0) diff --git a/tools/sdk/include/esp32/esp_wifi.h b/tools/sdk/include/esp32/esp_wifi.h index 66ccdcdd..c9899fa7 100644 --- a/tools/sdk/include/esp32/esp_wifi.h +++ b/tools/sdk/include/esp32/esp_wifi.h @@ -109,6 +109,7 @@ typedef struct { int tx_ba_win; /**< WiFi Block Ack TX window size */ int rx_ba_win; /**< WiFi Block Ack RX window size */ int wifi_task_core_id; /**< WiFi Task Core ID */ + int beacon_max_len; /**< WiFi softAP maximum length of the beacon */ int magic; /**< WiFi init magic number, it should be the last field */ } wifi_init_config_t; @@ -176,6 +177,12 @@ extern const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs; #define WIFI_TASK_CORE_ID 0 #endif +#ifdef CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN +#define WIFI_SOFTAP_BEACON_MAX_LEN CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN +#else +#define WIFI_SOFTAP_BEACON_MAX_LEN 752 +#endif + #define WIFI_INIT_CONFIG_DEFAULT() { \ .event_handler = &esp_event_send, \ .osi_funcs = &g_wifi_osi_funcs, \ @@ -193,6 +200,7 @@ extern const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs; .tx_ba_win = WIFI_DEFAULT_TX_BA_WIN,\ .rx_ba_win = WIFI_DEFAULT_RX_BA_WIN,\ .wifi_task_core_id = WIFI_TASK_CORE_ID,\ + .beacon_max_len = WIFI_SOFTAP_BEACON_MAX_LEN, \ .magic = WIFI_INIT_CONFIG_MAGIC\ }; diff --git a/tools/sdk/include/esp32/esp_wifi_internal.h b/tools/sdk/include/esp32/esp_wifi_internal.h index f486b7aa..acb78eaa 100644 --- a/tools/sdk/include/esp32/esp_wifi_internal.h +++ b/tools/sdk/include/esp32/esp_wifi_internal.h @@ -215,6 +215,15 @@ void *wifi_realloc( void *ptr, size_t size ); */ void *wifi_calloc( size_t n, size_t size ); +/** + * @brief Update WiFi MAC time + * + * @param uint32_t time_delta : time duration since the WiFi/BT common clock is disabled + * + * @return Always returns ESP_OK + */ +esp_err_t esp_wifi_internal_update_mac_time( uint32_t time_delta ); + #ifdef __cplusplus } #endif diff --git a/tools/sdk/include/esp32/hwcrypto/aes.h b/tools/sdk/include/esp32/hwcrypto/aes.h index cc0f5608..1dd5291f 100644 --- a/tools/sdk/include/esp32/hwcrypto/aes.h +++ b/tools/sdk/include/esp32/hwcrypto/aes.h @@ -51,6 +51,19 @@ typedef struct { uint8_t key[32]; } esp_aes_context; + +/** + * \brief The AES XTS context-type definition. + */ +typedef struct +{ + esp_aes_context crypt; /*!< The AES context to use for AES block + encryption or decryption. */ + esp_aes_context tweak; /*!< The AES context used for tweak + computation. */ +} esp_aes_xts_context; + + /** * \brief Lock access to AES hardware unit * @@ -86,6 +99,23 @@ void esp_aes_init( esp_aes_context *ctx ); */ void esp_aes_free( esp_aes_context *ctx ); +/** + * \brief This function initializes the specified AES XTS context. + * + * It must be the first API called before using + * the context. + * + * \param ctx The AES XTS context to initialize. + */ +void esp_aes_xts_init( esp_aes_xts_context *ctx ); + +/** + * \brief This function releases and clears the specified AES XTS context. + * + * \param ctx The AES XTS context to clear. + */ +void esp_aes_xts_free( esp_aes_xts_context *ctx ); + /** * \brief AES set key schedule (encryption or decryption) * @@ -233,6 +263,42 @@ int esp_aes_crypt_ctr( esp_aes_context *ctx, const unsigned char *input, unsigned char *output ); +/** + * \brief This function prepares an XTS context for encryption and + * sets the encryption key. + * + * \param ctx The AES XTS context to which the key should be bound. + * \param key The encryption key. This is comprised of the XTS key1 + * concatenated with the XTS key2. + * \param keybits The size of \p key passed in bits. Valid options are: + *
  • 256 bits (each of key1 and key2 is a 128-bit key)
  • + *
  • 512 bits (each of key1 and key2 is a 256-bit key)
+ * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +int esp_aes_xts_setkey_enc( esp_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits ); + +/** + * \brief This function prepares an XTS context for decryption and + * sets the decryption key. + * + * \param ctx The AES XTS context to which the key should be bound. + * \param key The decryption key. This is comprised of the XTS key1 + * concatenated with the XTS key2. + * \param keybits The size of \p key passed in bits. Valid options are: + *
  • 256 bits (each of key1 and key2 is a 128-bit key)
  • + *
  • 512 bits (each of key1 and key2 is a 256-bit key)
+ * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +int esp_aes_xts_setkey_dec( esp_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits ); + /** * \brief Internal AES block encryption function diff --git a/tools/sdk/include/esp32/rom/cache.h b/tools/sdk/include/esp32/rom/cache.h index 72aa33aa..4b923e66 100644 --- a/tools/sdk/include/esp32/rom/cache.h +++ b/tools/sdk/include/esp32/rom/cache.h @@ -83,6 +83,9 @@ static inline unsigned int IRAM_ATTR cache_flash_mmu_set(int cpu_no, int pid, un * @brief Set Ext-SRAM-Cache mmu mapping. * Please do not call this function in your SDK application. * + * Note that this code lives in IRAM and has a bugfix in respect to the ROM version + * of this function (which erroneously refused a vaddr > 2MiB + * * @param int cpu_no : CPU number, 0 for PRO cpu, 1 for APP cpu. * * @param int pod : process identifier. Range 0~7. @@ -106,18 +109,7 @@ static inline unsigned int IRAM_ATTR cache_flash_mmu_set(int cpu_no, int pid, un * 4 : mmu table to be written is out of range * 5 : vaddr is out of range */ -static inline unsigned int IRAM_ATTR cache_sram_mmu_set(int cpu_no, int pid, unsigned int vaddr, unsigned int paddr, int psize, int num) -{ - extern unsigned int cache_sram_mmu_set_rom(int cpu_no, int pid, unsigned int vaddr, unsigned int paddr, int psize, int num); - - unsigned int ret; - - DPORT_STALL_OTHER_CPU_START(); - ret = cache_sram_mmu_set_rom(cpu_no, pid, vaddr, paddr, psize, num); - DPORT_STALL_OTHER_CPU_END(); - - return ret; -} +unsigned int IRAM_ATTR cache_sram_mmu_set(int cpu_no, int pid, unsigned int vaddr, unsigned int paddr, int psize, int num); /** * @brief Initialise cache access for the cpu. diff --git a/tools/sdk/include/esp32/rom/uart.h b/tools/sdk/include/esp32/rom/uart.h index 0a3e1aeb..a010bfbc 100644 --- a/tools/sdk/include/esp32/rom/uart.h +++ b/tools/sdk/include/esp32/rom/uart.h @@ -36,7 +36,7 @@ extern "C" { #define RX_BUFF_SIZE 0x100 #define TX_BUFF_SIZE 100 -//uart int enalbe register ctrl bits +//uart int enable register ctrl bits #define UART_RCV_INTEN BIT0 #define UART_TRX_INTEN BIT1 #define UART_LINE_STATUS_INTEN BIT2 @@ -267,9 +267,11 @@ void uart_tx_flush(uint8_t uart_no); * here for compatibility. */ static inline void IRAM_ATTR uart_tx_wait_idle(uint8_t uart_no) { - while(REG_GET_FIELD(UART_STATUS_REG(uart_no), UART_ST_UTX_OUT)) { - ; - } + uint32_t status; + do { + status = READ_PERI_REG(UART_STATUS_REG(uart_no)); + /* either tx count or state is non-zero */ + } while ((status & (UART_ST_UTX_OUT_M | UART_TXFIFO_CNT_M)) != 0); } /** @@ -299,14 +301,14 @@ char uart_rx_one_char_block(void); * * @param uint8_t *pString : the pointer to store the string. * - * @param uint8_t MaxStrlen : the max string length, incude '\0'. + * @param uint8_t MaxStrlen : the max string length, include '\0'. * * @return OK. */ STATUS UartRxString(uint8_t *pString, uint8_t MaxStrlen); /** - * @brief Process uart recevied information in the interrupt handler. + * @brief Process uart received information in the interrupt handler. * Please do not call this function in SDK. * * @param void *para : the message receive buffer. diff --git a/tools/sdk/include/esp32/xtensa/config/core.h b/tools/sdk/include/esp32/xtensa/config/core.h index 98f1b196..0204757b 100644 --- a/tools/sdk/include/esp32/xtensa/config/core.h +++ b/tools/sdk/include/esp32/xtensa/config/core.h @@ -1401,5 +1401,16 @@ extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP7_IDENT); #define XCHAL_ERRATUM_497 0 #endif +/* + * Erratum 572 (releases TBD, but present in ESP32) + * Disable zero-overhead loop buffer to prevent rare illegal instruction + * exceptions while executing zero-overhead loops. + */ +#if ( XCHAL_HAVE_LOOPS && XCHAL_LOOP_BUFFER_SIZE != 0 ) +#define XCHAL_ERRATUM_572 1 +#else +#define XCHAL_ERRATUM_572 0 +#endif + #endif /*XTENSA_CONFIG_CORE_H*/ diff --git a/tools/sdk/include/esp_event/esp_event.h b/tools/sdk/include/esp_event/esp_event.h new file mode 100644 index 00000000..f095844a --- /dev/null +++ b/tools/sdk/include/esp_event/esp_event.h @@ -0,0 +1,336 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ESP_EVENT_H_ +#define ESP_EVENT_H_ + +#include "esp_err.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" + +#include "esp_event_base.h" +#include "esp_event_legacy.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/// Configuration for creating event loops +typedef struct { + int32_t queue_size; /**< size of the event loop queue */ + const char* task_name; /**< name of the event loop task; if NULL, + a dedicated task is not created for event loop*/ + UBaseType_t task_priority; /**< priority of the event loop task, ignored if task name is NULL */ + uint32_t task_stack_size; /**< stack size of the event loop task, ignored if task name is NULL */ + BaseType_t task_core_id; /**< core to which the event loop task is pinned to, + ignored if task name is NULL */ +} esp_event_loop_args_t; + +/** + * @brief Create a new event loop. + * + * @param[in] event_loop_args configuration structure for the event loop to create + * @param[out] event_loop handle to the created event loop + * + * @return + * - ESP_OK: Success + * - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list + * - ESP_FAIL: Failed to create task loop + * - Others: Fail + */ +esp_err_t esp_event_loop_create(const esp_event_loop_args_t* event_loop_args, esp_event_loop_handle_t* event_loop); + +/** + * @brief Delete an existing event loop. + * + * @param[in] event_loop event loop to delete + * + * @return + * - ESP_OK: Success + * - Others: Fail + */ +esp_err_t esp_event_loop_delete(esp_event_loop_handle_t event_loop); + +/** + * @brief Create default event loop + * + * @return + * - ESP_OK: Success + * - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list + * - ESP_FAIL: Failed to create task loop + * - Others: Fail + */ +esp_err_t esp_event_loop_create_default(); + +/** + * @brief Delete the default event loop + * + * @return + * - ESP_OK: Success + * - Others: Fail + */ +esp_err_t esp_event_loop_delete_default(); + +/** + * @brief Dispatch events posted to an event loop. + * + * This function is used to dispatch events posted to a loop with no dedicated task, i.e task name was set to NULL + * in event_loop_args argument during loop creation. This function includes an argument to limit the amount of time + * it runs, returning control to the caller when that time expires (or some time afterwards). There is no guarantee + * that a call to this function will exit at exactly the time of expiry. There is also no guarantee that events have + * been dispatched during the call, as the function might have spent all of the alloted time waiting on the event queue. + * Once an event has been unqueued, however, it is guaranteed to be dispatched. This guarantee contributes to not being + * able to exit exactly at time of expiry as (1) blocking on internal mutexes is necessary for dispatching the unqueued + * event, and (2) during dispatch of the unqueued event there is no way to control the time occupied by handler code + * execution. The guaranteed time of exit is therefore the alloted time + amount of time required to dispatch + * the last unqueued event. + * + * In cases where waiting on the queue times out, ESP_OK is returned and not ESP_ERR_TIMEOUT, since it is + * normal behavior. + * + * @param[in] event_loop event loop to dispatch posted events from + * @param[in] ticks_to_run number of ticks to run the loop + * + * @note encountering an unknown event that has been posted to the loop will only generate a warning, not an error. + * + * @return + * - ESP_OK: Success + * - Others: Fail + */ +esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t ticks_to_run); + +/** + * @brief Register an event handler to the system event loop. + * + * This function can be used to register a handler for either: (1) specific events, + * (2) all events of a certain event base, or (3) all events known by the system event loop. + * + * - specific events: specify exact event_base and event_id + * - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id + * - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id + * + * Registering multiple handlers to events is possible. Registering a single handler to multiple events is + * also possible. However, registering the same handler to the same event multiple times would cause the + * previous registrations to be overwritten. + * + * @param[in] event_base the base id of the event to register the handler for + * @param[in] event_id the id of the event to register the handler for + * @param[in] event_handler the handler function which gets called when the event is dispatched + * @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called + * + * @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should + * ensure that event_handler_arg still points to a valid location by the time the handler gets called + * + * @return + * - ESP_OK: Success + * - ESP_ERR_NO_MEM: Cannot allocate memory for the handler + * - ESP_ERR_INVALIG_ARG: Invalid combination of event base and event id + * - Others: Fail + */ +esp_err_t esp_event_handler_register(esp_event_base_t event_base, + int32_t event_id, + esp_event_handler_t event_handler, + void* event_handler_arg); + +/** + * @brief Register an event handler to a specific loop. + * + * This function behaves in the same manner as esp_event_handler_register, except the additional + * specification of the event loop to register the handler to. + * + * @param[in] event_loop the event loop to register this handler function to + * @param[in] event_base the base id of the event to register the handler for + * @param[in] event_id the id of the event to register the handler for + * @param[in] event_handler the handler function which gets called when the event is dispatched + * @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called + * + * @return + * - ESP_OK: Success + * - ESP_ERR_NO_MEM: Cannot allocate memory for the handler + * - ESP_ERR_INVALIG_ARG: Invalid combination of event base and event id + * - Others: Fail + */ +esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop, + esp_event_base_t event_base, + int32_t event_id, + esp_event_handler_t event_handler, + void* event_handler_arg); + +/** + * @brief Unregister a handler with the system event loop. + * + * This function can be used to unregister a handler so that it no longer gets called during dispatch. + * Handlers can be unregistered for either: (1) specific events, (2) all events of a certain event base, + * or (3) all events known by the system event loop + * + * - specific events: specify exact event_base and event_id + * - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id + * - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id + * + * This function ignores unregistration of handlers that has not been previously registered. + * + * @param[in] event_base the base of the event with which to unregister the handler + * @param[in] event_id the id of the event with which to unregister the handler + * @param[in] event_handler the handler to unregister + * + * @return ESP_OK success + * @return ESP_ERR_INVALIG_ARG invalid combination of event base and event id + * @return others fail + */ +esp_err_t esp_event_handler_unregister(esp_event_base_t event_base, int32_t event_id, esp_event_handler_t event_handler); + +/** + * @brief Unregister a handler with the system event loop. + * + * This function behaves in the same manner as esp_event_handler_unregister, except the additional specification of + * the event loop to unregister the handler with. + * + * @param[in] event_loop the event loop with which to unregister this handler function + * @param[in] event_base the base of the event with which to unregister the handler + * @param[in] event_id the id of the event with which to unregister the handler + * @param[in] event_handler the handler to unregister + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALIG_ARG: Invalid combination of event base and event id + * - Others: Fail + */ +esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop, + esp_event_base_t event_base, + int32_t event_id, + esp_event_handler_t event_handler); + +/** + * @brief Posts an event to the system default event loop. The event loop library keeps a copy of event_data and manages + * the copy's lifetime automatically (allocation + deletion); this ensures that the data the + * handler recieves is always valid. + * + * @param[in] event_base the event base that identifies the event + * @param[in] event_id the the event id that identifies the event + * @param[in] event_data the data, specific to the event occurence, that gets passed to the handler + * @param[in] event_data_size the size of the event data + * @param[in] ticks_to_wait number of ticks to block on a full event queue + * + * @note posting events from an ISR is not supported + * + * @return + * - ESP_OK: Success + * - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired + * - ESP_ERR_INVALIG_ARG: Invalid combination of event base and event id + * - Others: Fail + */ +esp_err_t esp_event_post(esp_event_base_t event_base, + int32_t event_id, + void* event_data, + size_t event_data_size, + TickType_t ticks_to_wait); + +/** + * @brief Posts an event to the specified event loop. The event loop library keeps a copy of event_data and manages + * the copy's lifetime automatically (allocation + deletion); this ensures that the data the + * handler recieves is always valid. + * + * This function behaves in the same manner as esp_event_post_to, except the additional specification of the event loop + * to post the event to. + * + * @param[in] event_loop the event loop to post to + * @param[in] event_base the event base that identifies the event + * @param[in] event_id the the event id that identifies the event + * @param[in] event_data the data, specific to the event occurence, that gets passed to the handler + * @param[in] event_data_size the size of the event data + * @param[in] ticks_to_wait number of ticks to block on a full event queue + * + * @note posting events from an ISR is not supported + * + * @return + * - ESP_OK: Success + * - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired + * - ESP_ERR_INVALIG_ARG: Invalid combination of event base and event id + * - Others: Fail + */ +esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop, + esp_event_base_t event_base, + int32_t event_id, + void* event_data, + size_t event_data_size, + TickType_t ticks_to_wait); + +/** + * @brief Dumps statistics of all event loops. + * + * Dumps event loop info in the format: + * + @verbatim + event loop + event + handler + handler + event + handler + handler + event loop + event + handler + ... + ... + ... + + where: + + event loop + format: address,name rx:total_recieved dr:total_dropped inv:total_number_of_invocations run:total_runtime + where: + address - memory address of the event loop + name - name of the event loop + total_recieved - number of successfully posted events + total_number_of_invocations - total number of handler invocations performed so far + total_runtime - total runtime of all invocations so far + + event + format: base:id proc:total_processed run:total_runtime + where: + base - event base + id - event id + total_processed - number of instances of this event that has been processed + total_runtime - total amount of time in microseconds used for invoking handlers of this event + + handler + format: address inv:total_invoked run:total_runtime + where: + address - address of the handler function + total_invoked - number of times this handler has been invoked + total_runtime - total amount of time used for invoking this handler + + @endverbatim + * + * @param[in] file the file stream to output to + * + * @note this function is a noop when CONFIG_EVENT_LOOP_PROFILING is disabled + * + * @return + * - ESP_OK: Success + * - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list + * - Others: Fail + */ +esp_err_t esp_event_dump(FILE* file); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // #ifndef ESP_EVENT_H_ \ No newline at end of file diff --git a/tools/sdk/include/esp_event/esp_event_base.h b/tools/sdk/include/esp_event/esp_event_base.h new file mode 100644 index 00000000..d2fd3804 --- /dev/null +++ b/tools/sdk/include/esp_event/esp_event_base.h @@ -0,0 +1,43 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ESP_EVENT_BASE_H_ +#define ESP_EVENT_BASE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// Defines for declaring and defining event base +#define ESP_EVENT_DECLARE_BASE(id) extern esp_event_base_t id; +#define ESP_EVENT_DEFINE_BASE(id) esp_event_base_t id = #id; + +// Event loop library types +typedef const char* esp_event_base_t; /**< unique pointer to a subsystem that exposes events */ +typedef void* esp_event_loop_handle_t; /**< a number that identifies an event with respect to a base */ +typedef void (*esp_event_handler_t)(void* event_handler_arg, + esp_event_base_t event_base, + int32_t event_id, + void* event_data); /**< function called when an event is posted to the queue */ + + +// Defines for registering/unregistering event handlers +#define ESP_EVENT_ANY_BASE NULL /**< register handler for any event base */ +#define ESP_EVENT_ANY_ID -1 /**< register handler for any event id */ + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef ESP_EVENT_BASE_H_ diff --git a/tools/sdk/include/esp_http_client/esp_http_client.h b/tools/sdk/include/esp_http_client/esp_http_client.h index 9043a48f..4e940a6d 100644 --- a/tools/sdk/include/esp_http_client/esp_http_client.h +++ b/tools/sdk/include/esp_http_client/esp_http_client.h @@ -114,6 +114,7 @@ typedef struct { esp_http_client_transport_t transport_type; /*!< HTTP transport type, see `esp_http_client_transport_t` */ int buffer_size; /*!< HTTP buffer size (both send and receive) */ void *user_data; /*!< HTTP user_data context */ + bool is_async; /*!< Set asynchronous mode, only supported with HTTPS for now */ } esp_http_client_config_t; @@ -123,6 +124,8 @@ typedef struct { #define ESP_ERR_HTTP_WRITE_DATA (ESP_ERR_HTTP_BASE + 3) /*!< Error write HTTP data */ #define ESP_ERR_HTTP_FETCH_HEADER (ESP_ERR_HTTP_BASE + 4) /*!< Error read HTTP header from server */ #define ESP_ERR_HTTP_INVALID_TRANSPORT (ESP_ERR_HTTP_BASE + 5) /*!< There are no transport support for the input scheme */ +#define ESP_ERR_HTTP_CONNECTING (ESP_ERR_HTTP_BASE + 6) /*!< HTTP connection hasn't been established yet */ +#define ESP_ERR_HTTP_EAGAIN (ESP_ERR_HTTP_BASE + 7) /*!< Mapping of errno EAGAIN to esp_err_t */ /** * @brief Start a HTTP session @@ -141,7 +144,10 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co /** * @brief Invoke this function after `esp_http_client_init` and all the options calls are made, and will perform the * transfer as described in the options. It must be called with the same esp_http_client_handle_t as input as the esp_http_client_init call returned. - * esp_http_client_perform performs the entire request in a blocking manner and returns when done, or if it failed. + * esp_http_client_perform performs the entire request in either blocking or non-blocking manner. By default, the API performs request in a blocking manner and returns when done, + * or if it failed, and in non-blocking manner, it returns if EAGAIN/EWOULDBLOCK or EINPROGRESS is encountered, or if it failed. And in case of non-blocking request, + * the user may call this API multiple times unless request & response is complete or there is a failure. To enable non-blocking esp_http_client_perform(), `is_async` member of esp_http_client_config_t + * must be set while making a call to esp_http_client_init() API. * You can do any amount of calls to esp_http_client_perform while using the same esp_http_client_handle_t. The underlying connection may be kept open if the server allows it. * If you intend to transfer more than one file, you are even encouraged to do so. * esp_http_client will then attempt to re-use the same connection for the following transfers, thus making the operations faster, less CPU intense and using less network resources. diff --git a/tools/sdk/include/http_server/http_server.h b/tools/sdk/include/esp_http_server/esp_http_server.h similarity index 72% rename from tools/sdk/include/http_server/http_server.h rename to tools/sdk/include/esp_http_server/esp_http_server.h index cdbd039c..793f3dd8 100644 --- a/tools/sdk/include/http_server/http_server.h +++ b/tools/sdk/include/esp_http_server/esp_http_server.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef _HTTP_SERVER_H_ -#define _HTTP_SERVER_H_ +#ifndef _ESP_HTTP_SERVER_H_ +#define _ESP_HTTP_SERVER_H_ #include #include @@ -27,6 +27,10 @@ extern "C" { #endif +/* +note: esp_https_server.h includes a customized copy of this +initializer that should be kept in sync +*/ #define HTTPD_DEFAULT_CONFIG() { \ .task_priority = tskIDLE_PRIORITY+5, \ .stack_size = 4096, \ @@ -39,7 +43,13 @@ extern "C" { .lru_purge_enable = false, \ .recv_wait_timeout = 5, \ .send_wait_timeout = 5, \ -}; + .global_user_ctx = NULL, \ + .global_user_ctx_free_fn = NULL, \ + .global_transport_ctx = NULL, \ + .global_transport_ctx_free_fn = NULL, \ + .open_fn = NULL, \ + .close_fn = NULL, \ +} #define ESP_ERR_HTTPD_BASE (0x8000) /*!< Starting number of HTTPD error codes */ #define ESP_ERR_HTTPD_HANDLERS_FULL (ESP_ERR_HTTPD_BASE + 1) /*!< All slots for registering URI handlers have been consumed */ @@ -70,6 +80,35 @@ typedef void* httpd_handle_t; */ typedef enum http_method httpd_method_t; +/** + * @brief Prototype for freeing context data (if any) + * @param[in] ctx : object to free + */ +typedef void (*httpd_free_ctx_fn_t)(void *ctx); + +/** + * @brief Function prototype for opening a session. + * + * Called immediately after the socket was opened to set up the send/recv functions and + * other parameters of the socket. + * + * @param[in] hd : server instance + * @param[in] sockfd : session socket file descriptor + * @return status + */ +typedef esp_err_t (*httpd_open_func_t)(httpd_handle_t hd, int sockfd); + +/** + * @brief Function prototype for closing a session. + * + * @note It's possible that the socket descriptor is invalid at this point, the function + * is called for all terminated sessions. Ensure proper handling of return codes. + * + * @param[in] hd : server instance + * @param[in] sockfd : session socket file descriptor + */ +typedef void (*httpd_close_func_t)(httpd_handle_t hd, int sockfd); + /** * @brief HTTP Server Configuration Structure * @@ -99,6 +138,63 @@ typedef struct httpd_config { bool lru_purge_enable; /*!< Purge "Least Recently Used" connection */ uint16_t recv_wait_timeout; /*!< Timeout for recv function (in seconds)*/ uint16_t send_wait_timeout; /*!< Timeout for send function (in seconds)*/ + + /** + * Global user context. + * + * This field can be used to store arbitrary user data within the server context. + * The value can be retrieved using the server handle, available e.g. in the httpd_req_t struct. + * + * When shutting down, the server frees up the user context by + * calling free() on the global_user_ctx field. If you wish to use a custom + * function for freeing the global user context, please specify that here. + */ + void * global_user_ctx; + + /** + * Free function for global user context + */ + httpd_free_ctx_fn_t global_user_ctx_free_fn; + + /** + * Global transport context. + * + * Similar to global_user_ctx, but used for session encoding or encryption (e.g. to hold the SSL context). + * It will be freed using free(), unless global_transport_ctx_free_fn is specified. + */ + void * global_transport_ctx; + + /** + * Free function for global transport context + */ + httpd_free_ctx_fn_t global_transport_ctx_free_fn; + + /** + * Custom session opening callback. + * + * Called on a new session socket just after accept(), but before reading any data. + * + * This is an opportunity to set up e.g. SSL encryption using global_transport_ctx + * and the send/recv/pending session overrides. + * + * If a context needs to be maintained between these functions, store it in the session using + * httpd_sess_set_transport_ctx() and retrieve it later with httpd_sess_get_transport_ctx() + */ + httpd_open_func_t open_fn; + + /** + * Custom session closing callback. + * + * Called when a session is deleted, before freeing user and transport contexts and before + * closing the socket. This is a place for custom de-init code common to all sockets. + * + * Set the user or transport context to NULL if it was freed here, so the server does not + * try to free it again. + * + * This function is run for all terminated sessions, including sessions where the socket + * was closed by the network stack - that is, the file descriptor may not be valid anymore. + */ + httpd_close_func_t close_fn; } httpd_config_t; /** @@ -180,11 +276,6 @@ esp_err_t httpd_stop(httpd_handle_t handle); * @{ */ -/** - * @brief Function type for freeing context data (if any) - */ -typedef void (*httpd_free_sess_ctx_fn_t)(void *sess_ctx); - /* Max supported HTTP request header length */ #define HTTPD_MAX_REQ_HDR_LEN CONFIG_HTTPD_MAX_REQ_HDR_LEN @@ -232,7 +323,7 @@ typedef struct httpd_req { * calling free() on the sess_ctx member. If you wish to use a custom * function for freeing the session context, please specify that here. */ - httpd_free_sess_ctx_fn_t free_ctx; + httpd_free_ctx_fn_t free_ctx; } httpd_req_t; /** @@ -348,21 +439,70 @@ esp_err_t httpd_unregister_uri(httpd_handle_t handle, const char* uri); * @{ */ +#define HTTPD_SOCK_ERR_FAIL -1 +#define HTTPD_SOCK_ERR_INVALID -2 +#define HTTPD_SOCK_ERR_TIMEOUT -3 + /** * @brief Prototype for HTTPDs low-level send function + * + * @note User specified send function must handle errors internally, + * depending upon the set value of errno, and return specific + * HTTPD_SOCK_ERR_ codes, which will eventually be conveyed as + * return value of httpd_send() function + * + * @param[in] hd : server instance + * @param[in] sockfd : session socket file descriptor + * @param[in] buf : buffer with bytes to send + * @param[in] buf_len : data size + * @param[in] flags : flags for the send() function * @return * - Bytes : The number of bytes sent successfully - * - -VE : In case of error + * - HTTPD_SOCK_ERR_INVALID : Invalid arguments + * - HTTPD_SOCK_ERR_TIMEOUT : Timeout/interrupted while calling socket send() + * - HTTPD_SOCK_ERR_FAIL : Unrecoverable error while calling socket send() */ -typedef int (*httpd_send_func_t)(int sockfd, const char *buf, size_t buf_len, int flags); +typedef int (*httpd_send_func_t)(httpd_handle_t hd, int sockfd, const char *buf, size_t buf_len, int flags); /** * @brief Prototype for HTTPDs low-level recv function + * + * @note User specified recv function must handle errors internally, + * depending upon the set value of errno, and return specific + * HTTPD_SOCK_ERR_ codes, which will eventually be conveyed as + * return value of httpd_req_recv() function + * + * @param[in] hd : server instance + * @param[in] sockfd : session socket file descriptor + * @param[in] buf : buffer with bytes to send + * @param[in] buf_len : data size + * @param[in] flags : flags for the send() function * @return * - Bytes : The number of bytes received successfully - * - -VE : In case of error + * - 0 : Buffer length parameter is zero / connection closed by peer + * - HTTPD_SOCK_ERR_INVALID : Invalid arguments + * - HTTPD_SOCK_ERR_TIMEOUT : Timeout/interrupted while calling socket recv() + * - HTTPD_SOCK_ERR_FAIL : Unrecoverable error while calling socket recv() */ -typedef int (*httpd_recv_func_t)(int sockfd, char *buf, size_t buf_len, int flags); +typedef int (*httpd_recv_func_t)(httpd_handle_t hd, int sockfd, char *buf, size_t buf_len, int flags); + +/** + * @brief Prototype for HTTPDs low-level "get pending bytes" function + * + * @note User specified pending function must handle errors internally, + * depending upon the set value of errno, and return specific + * HTTPD_SOCK_ERR_ codes, which will be handled accordingly in + * the server task. + * + * @param[in] hd : server instance + * @param[in] sockfd : session socket file descriptor + * @return + * - Bytes : The number of bytes waiting to be received + * - HTTPD_SOCK_ERR_INVALID : Invalid arguments + * - HTTPD_SOCK_ERR_TIMEOUT : Timeout/interrupted while calling socket pending() + * - HTTPD_SOCK_ERR_FAIL : Unrecoverable error while calling socket pending() + */ +typedef int (*httpd_pending_func_t)(httpd_handle_t hd, int sockfd); /** End of TX / RX * @} @@ -377,42 +517,64 @@ typedef int (*httpd_recv_func_t)(int sockfd, char *buf, size_t buf_len, int flag */ /** - * @brief Override web server's receive function + * @brief Override web server's receive function (by session FD) * * This function overrides the web server's receive function. This same function is - * used to read and parse HTTP headers as well as body. + * used to read HTTP request packets. * - * @note This API is supposed to be called only from the context of - * a URI handler where httpd_req_t* request pointer is valid. + * @note This API is supposed to be called either from the context of + * - an http session APIs where sockfd is a valid parameter + * - a URI handler where sockfd is obtained using httpd_req_to_sockfd() * - * @param[in] r The request being responded to - * @param[in] recv_func The receive function to be set for this request + * @param[in] hd HTTPD instance handle + * @param[in] sockfd Session socket FD + * @param[in] recv_func The receive function to be set for this session * * @return * - ESP_OK : On successfully registering override * - ESP_ERR_INVALID_ARG : Null arguments - * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request pointer */ -esp_err_t httpd_set_recv_override(httpd_req_t *r, httpd_recv_func_t recv_func); +esp_err_t httpd_sess_set_recv_override(httpd_handle_t hd, int sockfd, httpd_recv_func_t recv_func); /** - * @brief Override web server's send function + * @brief Override web server's send function (by session FD) * * This function overrides the web server's send function. This same function is * used to send out any response to any HTTP request. * - * @note This API is supposed to be called only from the context of - * a URI handler where httpd_req_t* request pointer is valid. + * @note This API is supposed to be called either from the context of + * - an http session APIs where sockfd is a valid parameter + * - a URI handler where sockfd is obtained using httpd_req_to_sockfd() * - * @param[in] r The request being responded to - * @param[in] send_func The send function to be set for this request + * @param[in] hd HTTPD instance handle + * @param[in] sockfd Session socket FD + * @param[in] send_func The send function to be set for this session * * @return * - ESP_OK : On successfully registering override * - ESP_ERR_INVALID_ARG : Null arguments - * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request pointer */ -esp_err_t httpd_set_send_override(httpd_req_t *r, httpd_send_func_t send_func); +esp_err_t httpd_sess_set_send_override(httpd_handle_t hd, int sockfd, httpd_send_func_t send_func); + +/** + * @brief Override web server's pending function (by session FD) + * + * This function overrides the web server's pending function. This function is + * used to test for pending bytes in a socket. + * + * @note This API is supposed to be called either from the context of + * - an http session APIs where sockfd is a valid parameter + * - a URI handler where sockfd is obtained using httpd_req_to_sockfd() + * + * @param[in] hd HTTPD instance handle + * @param[in] sockfd Session socket FD + * @param[in] pending_func The receive function to be set for this session + * + * @return + * - ESP_OK : On successfully registering override + * - ESP_ERR_INVALID_ARG : Null arguments + */ +esp_err_t httpd_sess_set_pending_override(httpd_handle_t hd, int sockfd, httpd_pending_func_t pending_func); /** * @brief Get the Socket Descriptor from the HTTP request @@ -422,7 +584,7 @@ esp_err_t httpd_set_send_override(httpd_req_t *r, httpd_send_func_t send_func); * This is useful when user wants to call functions that require * session socket fd, from within a URI handler, ie. : * httpd_sess_get_ctx(), - * httpd_trigger_sess_close(), + * httpd_sess_trigger_close(), * httpd_sess_update_timestamp(). * * @note This API is supposed to be called only from the context of @@ -460,9 +622,11 @@ int httpd_req_to_sockfd(httpd_req_t *r); * @param[in] buf_len Length of the buffer * * @return - * - Bytes : Number of bytes read into the buffer successfully - * - Zero : When no more data is left for read - * - -1 : On raw recv error / Null arguments / Request pointer is invalid + * - Bytes : Number of bytes read into the buffer successfully + * - 0 : Buffer length parameter is zero / connection closed by peer + * - HTTPD_SOCK_ERR_INVALID : Invalid arguments + * - HTTPD_SOCK_ERR_TIMEOUT : Timeout/interrupted while calling socket recv() + * - HTTPD_SOCK_ERR_FAIL : Unrecoverable error while calling socket recv() */ int httpd_req_recv(httpd_req_t *r, char *buf, size_t buf_len); @@ -608,7 +772,7 @@ esp_err_t httpd_query_key_value(const char *qry, const char *key, char *val, siz * * @param[in] r The request being responded to * @param[in] buf Buffer from where the content is to be fetched - * @param[in] buf_len Length of the buffer + * @param[in] buf_len Length of the buffer, -1 to use strlen() * * @return * - ESP_OK : On successfully sending the response packet @@ -617,7 +781,7 @@ esp_err_t httpd_query_key_value(const char *qry, const char *key, char *val, siz * - ESP_ERR_HTTPD_RESP_SEND : Error in raw send * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request */ -esp_err_t httpd_resp_send(httpd_req_t *r, const char *buf, size_t buf_len); +esp_err_t httpd_resp_send(httpd_req_t *r, const char *buf, ssize_t buf_len); /** * @brief API to send one HTTP chunk @@ -647,7 +811,7 @@ esp_err_t httpd_resp_send(httpd_req_t *r, const char *buf, size_t buf_len); * * @param[in] r The request being responded to * @param[in] buf Pointer to a buffer that stores the data - * @param[in] buf_len Length of the data from the buffer that should be sent out + * @param[in] buf_len Length of the data from the buffer that should be sent out, -1 to use strlen() * * @return * - ESP_OK : On successfully sending the response packet chunk @@ -656,7 +820,7 @@ esp_err_t httpd_resp_send(httpd_req_t *r, const char *buf, size_t buf_len); * - ESP_ERR_HTTPD_RESP_SEND : Error in raw send * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request pointer */ -esp_err_t httpd_resp_send_chunk(httpd_req_t *r, const char *buf, size_t buf_len); +esp_err_t httpd_resp_send_chunk(httpd_req_t *r, const char *buf, ssize_t buf_len); /* Some commonly used status codes */ #define HTTPD_200 "200 OK" /*!< HTTP Response 200 */ @@ -664,6 +828,7 @@ esp_err_t httpd_resp_send_chunk(httpd_req_t *r, const char *buf, size_t buf_len) #define HTTPD_207 "207 Multi-Status" /*!< HTTP Response 207 */ #define HTTPD_400 "400 Bad Request" /*!< HTTP Response 400 */ #define HTTPD_404 "404 Not Found" /*!< HTTP Response 404 */ +#define HTTPD_408 "408 Request Timeout" /*!< HTTP Response 408 */ #define HTTPD_500 "500 Internal Server Error" /*!< HTTP Response 500 */ /** @@ -768,6 +933,52 @@ esp_err_t httpd_resp_set_hdr(httpd_req_t *r, const char *field, const char *valu */ esp_err_t httpd_resp_send_404(httpd_req_t *r); +/** + * @brief Helper function for HTTP 408 + * + * Send HTTP 408 message. If you wish to send additional data in the body of the + * response, please use the lower-level functions directly. + * + * @note + * - This API is supposed to be called only from the context of + * a URI handler where httpd_req_t* request pointer is valid. + * - Once this API is called, all request headers are purged, so + * request headers need be copied into separate buffers if + * they are required later. + * + * @param[in] r The request being responded to + * + * @return + * - ESP_OK : On successfully sending the response packet + * - ESP_ERR_INVALID_ARG : Null arguments + * - ESP_ERR_HTTPD_RESP_SEND : Error in raw send + * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request pointer + */ +esp_err_t httpd_resp_send_408(httpd_req_t *r); + +/** + * @brief Helper function for HTTP 500 + * + * Send HTTP 500 message. If you wish to send additional data in the body of the + * response, please use the lower-level functions directly. + * + * @note + * - This API is supposed to be called only from the context of + * a URI handler where httpd_req_t* request pointer is valid. + * - Once this API is called, all request headers are purged, so + * request headers need be copied into separate buffers if + * they are required later. + * + * @param[in] r The request being responded to + * + * @return + * - ESP_OK : On successfully sending the response packet + * - ESP_ERR_INVALID_ARG : Null arguments + * - ESP_ERR_HTTPD_RESP_SEND : Error in raw send + * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request pointer + */ +esp_err_t httpd_resp_send_500(httpd_req_t *r); + /** * @brief Raw HTTP send * @@ -796,7 +1007,9 @@ esp_err_t httpd_resp_send_404(httpd_req_t *r); * * @return * - Bytes : Number of bytes that were sent successfully - * - -1 : Error in raw send / Invalid request / Null arguments + * - HTTPD_SOCK_ERR_INVALID : Invalid arguments + * - HTTPD_SOCK_ERR_TIMEOUT : Timeout/interrupted while calling socket send() + * - HTTPD_SOCK_ERR_FAIL : Unrecoverable error while calling socket send() */ int httpd_send(httpd_req_t *r, const char *buf, size_t buf_len); @@ -829,6 +1042,57 @@ int httpd_send(httpd_req_t *r, const char *buf, size_t buf_len); */ void *httpd_sess_get_ctx(httpd_handle_t handle, int sockfd); +/** + * @brief Set session context by socket descriptor + * + * @param[in] handle Handle to server returned by httpd_start + * @param[in] sockfd The socket descriptor for which the context should be extracted. + * @param[in] ctx Context object to assign to the session + * @param[in] free_fn Function that should be called to free the context + */ +void httpd_sess_set_ctx(httpd_handle_t handle, int sockfd, void *ctx, httpd_free_ctx_fn_t free_fn); + +/** + * @brief Get session 'transport' context by socket descriptor + * @see httpd_sess_get_ctx() + * + * This context is used by the send/receive functions, for example to manage SSL context. + * + * @param[in] handle Handle to server returned by httpd_start + * @param[in] sockfd The socket descriptor for which the context should be extracted. + * @return + * - void* : Pointer to the transport context associated with this session + * - NULL : Empty context / Invalid handle / Invalid socket fd + */ +void *httpd_sess_get_transport_ctx(httpd_handle_t handle, int sockfd); + +/** + * @brief Set session 'transport' context by socket descriptor + * @see httpd_sess_set_ctx() + * + * @param[in] handle Handle to server returned by httpd_start + * @param[in] sockfd The socket descriptor for which the context should be extracted. + * @param[in] ctx Transport context object to assign to the session + * @param[in] free_fn Function that should be called to free the transport context + */ +void httpd_sess_set_transport_ctx(httpd_handle_t handle, int sockfd, void *ctx, httpd_free_ctx_fn_t free_fn); + +/** + * @brief Get HTTPD global user context (it was set in the server config struct) + * + * @param[in] handle Handle to server returned by httpd_start + * @return global user context + */ +void *httpd_get_global_user_ctx(httpd_handle_t handle); + +/** + * @brief Get HTTPD global transport context (it was set in the server config struct) + * + * @param[in] handle Handle to server returned by httpd_start + * @return global transport context + */ +void *httpd_get_global_transport_ctx(httpd_handle_t handle); + /** * @brief Trigger an httpd session close externally * @@ -844,7 +1108,7 @@ void *httpd_sess_get_ctx(httpd_handle_t handle, int sockfd); * - ESP_ERR_NOT_FOUND : Socket fd not found * - ESP_ERR_INVALID_ARG : Null arguments */ -esp_err_t httpd_trigger_sess_close(httpd_handle_t handle, int sockfd); +esp_err_t httpd_sess_trigger_close(httpd_handle_t handle, int sockfd); /** * @brief Update timestamp for a given socket @@ -921,4 +1185,4 @@ esp_err_t httpd_queue_work(httpd_handle_t handle, httpd_work_fn_t work, void *ar } #endif -#endif /* ! _HTTP_SERVER_H_ */ +#endif /* ! _ESP_HTTP_SERVER_H_ */ diff --git a/tools/sdk/include/esp_http_server/http_server.h b/tools/sdk/include/esp_http_server/http_server.h new file mode 100644 index 00000000..56f73c5b --- /dev/null +++ b/tools/sdk/include/esp_http_server/http_server.h @@ -0,0 +1,2 @@ +#warning http_server.h has been renamed to esp_http_server.h, please update include directives +#include "esp_http_server.h" diff --git a/tools/sdk/include/esp_https_server/esp_https_server.h b/tools/sdk/include/esp_https_server/esp_https_server.h new file mode 100644 index 00000000..2b7343e7 --- /dev/null +++ b/tools/sdk/include/esp_https_server/esp_https_server.h @@ -0,0 +1,117 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _ESP_HTTPS_SERVER_H_ +#define _ESP_HTTPS_SERVER_H_ + +#include +#include "esp_err.h" +#include "esp_http_server.h" + +typedef enum { + HTTPD_SSL_TRANSPORT_SECURE, // SSL Enabled + HTTPD_SSL_TRANSPORT_INSECURE // SSL disabled +} httpd_ssl_transport_mode_t; + +/** + * HTTPS server config struct + * + * Please use HTTPD_SSL_CONFIG_DEFAULT() to initialize it. + */ +struct httpd_ssl_config { + /** + * Underlying HTTPD server config + * + * Parameters like task stack size and priority can be adjusted here. + */ + httpd_config_t httpd; + + /** CA certificate */ + const uint8_t *cacert_pem; + + /** CA certificate byte length */ + size_t cacert_len; + + /** Private key */ + const uint8_t *prvtkey_pem; + + /** Private key byte length */ + size_t prvtkey_len; + + /** Transport Mode (default secure) */ + httpd_ssl_transport_mode_t transport_mode; + + /** Port used when transport mode is secure (default 443) */ + uint16_t port_secure; + + /** Port used when transport mode is insecure (default 80) */ + uint16_t port_insecure; +}; + +typedef struct httpd_ssl_config httpd_ssl_config_t; + +/** + * Default config struct init + * + * (http_server default config had to be copied for customization) + * + * Notes: + * - port is set when starting the server, according to 'transport_mode' + * - one socket uses ~ 40kB RAM with SSL, we reduce the default socket count to 4 + * - SSL sockets are usually long-lived, closing LRU prevents pool exhaustion DOS + * - Stack size may need adjustments depending on the user application + */ +#define HTTPD_SSL_CONFIG_DEFAULT() { \ + .httpd = { \ + .task_priority = tskIDLE_PRIORITY+5, \ + .stack_size = 10240, \ + .server_port = 0, \ + .ctrl_port = 32768, \ + .max_open_sockets = 4, \ + .max_uri_handlers = 8, \ + .max_resp_headers = 8, \ + .backlog_conn = 5, \ + .lru_purge_enable = true, \ + .recv_wait_timeout = 5, \ + .send_wait_timeout = 5, \ + .global_user_ctx = NULL, \ + .global_user_ctx_free_fn = NULL, \ + .global_transport_ctx = NULL, \ + .global_transport_ctx_free_fn = NULL, \ + .open_fn = NULL, \ + .close_fn = NULL, \ + }, \ + .transport_mode = HTTPD_SSL_TRANSPORT_SECURE, \ + .port_secure = 443, \ + .port_insecure = 80, \ +} + +/** + * Create a SSL capable HTTP server (secure mode may be disabled in config) + * + * @param[in,out] config - server config, must not be const. Does not have to stay valid after + * calling this function. + * @param[out] handle - storage for the server handle, must be a valid pointer + * @return success + */ +esp_err_t httpd_ssl_start(httpd_handle_t *handle, httpd_ssl_config_t *config); + +/** + * Stop the server. Blocks until the server is shut down. + * + * @param[in] handle + */ +void httpd_ssl_stop(httpd_handle_t handle); + +#endif // _ESP_HTTPS_SERVER_H_ diff --git a/tools/sdk/include/freertos/freertos/ringbuf.h b/tools/sdk/include/esp_ringbuf/freertos/ringbuf.h similarity index 100% rename from tools/sdk/include/freertos/freertos/ringbuf.h rename to tools/sdk/include/esp_ringbuf/freertos/ringbuf.h diff --git a/tools/sdk/include/ethernet/esp_eth.h b/tools/sdk/include/ethernet/esp_eth.h index 0d39b8ef..beb99049 100644 --- a/tools/sdk/include/ethernet/esp_eth.h +++ b/tools/sdk/include/ethernet/esp_eth.h @@ -28,10 +28,10 @@ typedef enum { ETH_MODE_MII, } eth_mode_t; -typedef enum { +typedef enum { ETH_CLOCK_GPIO0_IN = 0, ETH_CLOCK_GPIO16_OUT = 2, - ETH_CLOCK_GPIO17_OUT = 3, + ETH_CLOCK_GPIO17_OUT = 3 } eth_clock_mode_t; typedef enum { @@ -83,7 +83,7 @@ typedef bool (*eth_phy_check_link_func)(void); typedef void (*eth_phy_check_init_func)(void); typedef eth_speed_mode_t (*eth_phy_get_speed_mode_func)(void); typedef eth_duplex_mode_t (*eth_phy_get_duplex_mode_func)(void); -typedef void (*eth_phy_func)(void); +typedef esp_err_t (*eth_phy_func)(void); typedef esp_err_t (*eth_tcpip_input_func)(void *buffer, uint16_t len, void *eb); typedef void (*eth_gpio_config_func)(void); typedef bool (*eth_phy_get_partner_pause_enable_func)(void); @@ -94,27 +94,26 @@ typedef void (*eth_phy_power_enable_func)(bool enable); * */ typedef struct { - eth_phy_base_t phy_addr; /*!< phy base addr (0~31) */ - eth_mode_t mac_mode; /*!< mac mode only support RMII now */ - eth_clock_mode_t clock_mode; /*!< external/internal clock mode selecton */ - eth_tcpip_input_func tcpip_input; /*!< tcpip input func */ - eth_phy_func phy_init; /*!< phy init func */ - eth_phy_check_link_func phy_check_link; /*!< phy check link func */ - eth_phy_check_init_func phy_check_init; /*!< phy check init func */ - eth_phy_get_speed_mode_func phy_get_speed_mode; /*!< phy check init func */ - eth_phy_get_duplex_mode_func phy_get_duplex_mode; /*!< phy check init func */ - eth_gpio_config_func gpio_config; /*!< gpio config func */ - bool flow_ctrl_enable; /*!< flag of flow ctrl enable */ - eth_phy_get_partner_pause_enable_func phy_get_partner_pause_enable; /*!< get partner pause enable */ - eth_phy_power_enable_func phy_power_enable; /*!< enable or disable phy power */ - + eth_phy_base_t phy_addr; /*!< phy base addr (0~31) */ + eth_mode_t mac_mode; /*!< mac mode only support RMII now */ + eth_clock_mode_t clock_mode; /*!< external/internal clock mode selecton */ + eth_tcpip_input_func tcpip_input; /*!< tcpip input func */ + eth_phy_func phy_init; /*!< phy init func */ + eth_phy_check_link_func phy_check_link; /*!< phy check link func */ + eth_phy_check_init_func phy_check_init; /*!< phy check init func */ + eth_phy_get_speed_mode_func phy_get_speed_mode; /*!< phy check init func */ + eth_phy_get_duplex_mode_func phy_get_duplex_mode; /*!< phy check init func */ + eth_gpio_config_func gpio_config; /*!< gpio config func */ + bool flow_ctrl_enable; /*!< flag of flow ctrl enable */ + eth_phy_get_partner_pause_enable_func phy_get_partner_pause_enable; /*!< get partner pause enable */ + eth_phy_power_enable_func phy_power_enable; /*!< enable or disable phy power */ + uint32_t reset_timeout_ms; /*!< timeout value for reset emac */ } eth_config_t; - /** * @brief Init ethernet mac * - * @note config can not be NULL,and phy chip must be suitable to phy init func. + * @note config can not be NULL, and phy chip must be suitable to phy init func. * * @param[in] config mac init data. * @@ -143,7 +142,7 @@ esp_err_t esp_eth_deinit(void); * This function may be called, if you only need to initialize the Ethernet * driver without having to use the network stack on top. * - * @note config can not be NULL,and phy chip must be suitable to phy init func. + * @note config can not be NULL, and phy chip must be suitable to phy init func. * @param[in] config mac init data. * * @return @@ -155,7 +154,7 @@ esp_err_t esp_eth_init_internal(eth_config_t *config); /** * @brief Send packet from tcp/ip to mac * - * @note buf can not be NULL,size must be less than 1580 + * @note buf can not be NULL, size must be less than 1580 * * @param[in] buf: start address of packet data. * @@ -170,7 +169,7 @@ esp_err_t esp_eth_tx(uint8_t *buf, uint16_t size); /** * @brief Enable ethernet interface * - * @note Shout be called after esp_eth_init + * @note Should be called after esp_eth_init * * @return * - ESP_OK @@ -181,7 +180,7 @@ esp_err_t esp_eth_enable(void); /** * @brief Disable ethernet interface * - * @note Shout be called after esp_eth_init + * @note Should be called after esp_eth_init * * @return * - ESP_OK @@ -199,24 +198,24 @@ esp_err_t esp_eth_disable(void); void esp_eth_get_mac(uint8_t mac[6]); /** - * @brief Read phy reg with smi interface. + * @brief Write PHY reg with SMI interface. * - * @note phy base addr must be right. + * @note PHY base addr must be right. * - * @param[in] reg_num: phy reg num. + * @param[in] reg_num: PHY reg num. * - * @param[in] value: value which write to phy reg. + * @param[in] value: value which is written to PHY reg. */ void esp_eth_smi_write(uint32_t reg_num, uint16_t value); /** - * @brief Read phy reg with smi interface. + * @brief Read PHY reg with SMI interface. * - * @note phy base addr must be right. + * @note PHY base addr must be right. * - * @param[in] reg_num: phy reg num. + * @param[in] reg_num: PHY reg num. * - * @return value what read from phy reg + * @return value that is read from PHY reg */ uint16_t esp_eth_smi_read(uint32_t reg_num); @@ -253,9 +252,9 @@ static inline esp_err_t esp_eth_smi_wait_set(uint32_t reg_num, uint16_t value_ma /** * @brief Free emac rx buf. * - * @note buf can not be null,and it is tcpip input buf. + * @note buf can not be null, and it is tcpip input buf. * - * @param[in] buf: start address of recevie packet data. + * @param[in] buf: start address of received packet data. * */ void esp_eth_free_rx_buf(void *buf); @@ -263,7 +262,7 @@ void esp_eth_free_rx_buf(void *buf); /** * @brief Set mac of ethernet interface. * - * @note user can call this function after emac_init,and the new mac address will be enabled after emac_enable. + * @note user can call this function after emac_init, and the new mac address will be enabled after emac_enable. * * @param[in] mac: the Mac address. * @@ -273,6 +272,14 @@ void esp_eth_free_rx_buf(void *buf); */ esp_err_t esp_eth_set_mac(const uint8_t mac[6]); +/** + * @brief Get Ethernet link speed + * + * @return eth_speed_mode_t ETH_SPEED_MODE_10M when link speed is 10Mbps + * ETH_SPEED_MODE_100M when link speed is 100Mbps + */ +eth_speed_mode_t esp_eth_get_speed(void); + #ifdef __cplusplus } #endif diff --git a/tools/sdk/include/ethernet/eth_phy/phy_lan8720.h b/tools/sdk/include/ethernet/eth_phy/phy_lan8720.h index 8c579ef5..325820bd 100644 --- a/tools/sdk/include/ethernet/eth_phy/phy_lan8720.h +++ b/tools/sdk/include/ethernet/eth_phy/phy_lan8720.h @@ -51,7 +51,7 @@ void phy_lan8720_power_enable(bool); /** @brief Default LAN8720 phy_init function. */ -void phy_lan8720_init(void); +esp_err_t phy_lan8720_init(void); /** @brief Default LAN8720 PHY configuration * diff --git a/tools/sdk/include/ethernet/eth_phy/phy_reg.h b/tools/sdk/include/ethernet/eth_phy/phy_reg.h index 33c9a064..7dbf02b2 100644 --- a/tools/sdk/include/ethernet/eth_phy/phy_reg.h +++ b/tools/sdk/include/ethernet/eth_phy/phy_reg.h @@ -14,24 +14,40 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + /* This header contains register/bit masks for the standard PHY MII registers that should be supported by all PHY models. */ -#define MII_BASIC_MODE_CONTROL_REG (0x0) -#define MII_SOFTWARE_RESET BIT(15) +#define MII_BASIC_MODE_CONTROL_REG (0x0) +#define MII_SOFTWARE_RESET BIT(15) +#define MII_SPEED_SELECT BIT(13) +#define MII_AUTO_NEGOTIATION_ENABLE BIT(12) +#define MII_POWER_DOWN BIT(11) +#define MII_RESTART_AUTO_NEGOTIATION BIT(9) +#define MII_DUPLEX_MODE BIT(8) -#define MII_BASIC_MODE_STATUS_REG (0x1) -#define MII_AUTO_NEGOTIATION_COMPLETE BIT(5) -#define MII_LINK_STATUS BIT(2) +#define MII_BASIC_MODE_STATUS_REG (0x1) +#define MII_AUTO_NEGOTIATION_COMPLETE BIT(5) +#define MII_LINK_STATUS BIT(2) -#define MII_PHY_IDENTIFIER_1_REG (0x2) -#define MII_PHY_IDENTIFIER_2_REG (0x3) +#define MII_PHY_IDENTIFIER_1_REG (0x2) +#define MII_PHY_IDENTIFIER_2_REG (0x3) -#define MII_AUTO_NEG_ADVERTISEMENT_REG (0x4) -#define MII_ASM_DIR BIT(11) -#define MII_PAUSE BIT(10) +#define MII_AUTO_NEGOTIATION_ADVERTISEMENT_REG (0x4) +#define MII_ASM_DIR BIT(11) +#define MII_PAUSE BIT(10) -#define MII_PHY_LINK_PARTNER_ABILITY_REG (0x5) -#define MII_PARTNER_ASM_DIR BIT(11) -#define MII_PARTNER_PAUSE BIT(10) +#define MII_PHY_LINK_PARTNER_ABILITY_REG (0x5) +#define MII_PARTNER_ASM_DIR BIT(11) +#define MII_PARTNER_PAUSE BIT(10) + +/******************************legacy*******************************/ +#define MII_AUTO_NEG_ADVERTISEMENT_REG MII_AUTO_NEGOTIATION_ADVERTISEMENT_REG + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/include/ethernet/eth_phy/phy_tlk110.h b/tools/sdk/include/ethernet/eth_phy/phy_tlk110.h index ff61c322..e6b2d974 100644 --- a/tools/sdk/include/ethernet/eth_phy/phy_tlk110.h +++ b/tools/sdk/include/ethernet/eth_phy/phy_tlk110.h @@ -50,7 +50,7 @@ void phy_tlk110_power_enable(bool); /** @brief Default TLK110 phy_init function. */ -void phy_tlk110_init(void); +esp_err_t phy_tlk110_init(void); /** @brief Default TLK110 PHY configuration * diff --git a/tools/sdk/include/expat/.gitignore b/tools/sdk/include/expat/.gitignore deleted file mode 100644 index 9c9cf881..00000000 --- a/tools/sdk/include/expat/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -Makefile -.libs -*.lo -expat.h -Debug -Debug-w -Release -Release-w -expat.ncb -expat.opt -expat.plg -Debug_static -Debug-w_static -Release_static -Release-w_static -expat_static.plg -expatw.plg -expatw_static.plg diff --git a/tools/sdk/include/expat/Makefile.am b/tools/sdk/include/expat/Makefile.am deleted file mode 100644 index d655a29f..00000000 --- a/tools/sdk/include/expat/Makefile.am +++ /dev/null @@ -1,77 +0,0 @@ -# -# __ __ _ -# ___\ \/ /_ __ __ _| |_ -# / _ \\ /| '_ \ / _` | __| -# | __// \| |_) | (_| | |_ -# \___/_/\_\ .__/ \__,_|\__| -# |_| XML parser -# -# Copyright (c) 2017 Expat development team -# Licensed under the MIT license: -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to permit -# persons to whom the Software is furnished to do so, subject to the -# following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -# NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -# USE OR OTHER DEALINGS IN THE SOFTWARE. - -include_HEADERS = \ - ../expat_config.h \ - expat.h \ - expat_external.h - -lib_LTLIBRARIES = libexpat.la - -libexpat_la_LDFLAGS = \ - -no-undefined \ - -version-info @LIBCURRENT@:@LIBREVISION@:@LIBAGE@ \ - -rpath $(libdir) - -libexpat_la_SOURCES = \ - loadlibrary.c \ - xmlparse.c \ - xmltok.c \ - xmlrole.c - -doc_DATA = \ - ../AUTHORS \ - ../Changes - -install-data-hook: - cd "$(DESTDIR)$(docdir)" && $(am__mv) Changes changelog - -uninstall-local: - $(RM) "$(DESTDIR)$(docdir)/changelog" - -EXTRA_DIST = \ - ascii.h \ - asciitab.h \ - expat_external.h \ - expat.h \ - iasciitab.h \ - internal.h \ - latin1tab.h \ - libexpat.def \ - libexpatw.def \ - nametab.h \ - siphash.h \ - utf8tab.h \ - winconfig.h \ - xmlrole.h \ - xmltok.h \ - xmltok_impl.c \ - xmltok_impl.h \ - xmltok_ns.c diff --git a/tools/sdk/include/expat/expat.vcxproj b/tools/sdk/include/expat/expat.vcxproj deleted file mode 100644 index 66d646e7..00000000 --- a/tools/sdk/include/expat/expat.vcxproj +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Template - Win32 - - - - - - {45A5074D-66E8-44A4-A03F-018027B528D6} - 10.0.16299.0 - - - - Application - v141 - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - .\..\win32\bin\Debug\ - .\..\win32\tmp\Debug\ - true - - - .\..\win32\bin\Release\ - .\..\win32\tmp\Release\ - false - - - - MultiThreadedDebug - Default - true - Disabled - true - Level3 - EditAndContinue - _DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - .\..\win32\tmp\Debug\ - true - .\..\win32\tmp\Debug\expat.pch - .\..\win32\tmp\Debug\ - .\..\win32\tmp\Debug\ - EnableFastChecks - - - true - _DEBUG;%(PreprocessorDefinitions) - .\..\win32\bin\Debug\expat.tlb - true - Win32 - - - 0x0409 - _DEBUG;%(PreprocessorDefinitions) - - - true - .\..\win32\bin\Debug\expat.bsc - - - true - true - true - Console - ..\win32\bin\Debug\libexpat.dll - .\..\win32\bin\Debug\libexpat.lib - .\libexpat.def - - - - - MultiThreaded - Default - true - true - MaxSpeed - true - Level3 - NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - .\..\win32\tmp\Release\ - .\..\win32\tmp\Release\expat.pch - - .\..\win32\tmp\Release\ - .\..\win32\tmp\Release\ - - - true - NDEBUG;%(PreprocessorDefinitions) - .\..\win32\bin\Release\expat.tlb - true - Win32 - - - 0x0409 - NDEBUG;%(PreprocessorDefinitions) - - - true - .\..\win32\bin\Release\expat.bsc - - - true - true - Console - ..\win32\bin\Release\libexpat.dll - .\..\win32\bin\Release\libexpat.lib - .\libexpat.def - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tools/sdk/include/expat/expat.vcxproj.filters b/tools/sdk/include/expat/expat.vcxproj.filters deleted file mode 100644 index 61c52b58..00000000 --- a/tools/sdk/include/expat/expat.vcxproj.filters +++ /dev/null @@ -1,83 +0,0 @@ - - - - - {f01bb743-0ef8-4601-bc44-378fc0abe768} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {c22177dc-5748-4bb1-816e-df311093bf72} - h;hpp;hxx;hm;inl - - - {41146e15-3129-4e5e-bb0f-6b78bb4701b9} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - \ No newline at end of file diff --git a/tools/sdk/include/expat/expat_static.vcxproj b/tools/sdk/include/expat/expat_static.vcxproj deleted file mode 100644 index b4265e01..00000000 --- a/tools/sdk/include/expat/expat_static.vcxproj +++ /dev/null @@ -1,149 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Template - Win32 - - - - - - {58A821BC-E4AF-4DF4-9A54-2BAA22B92615} - 10.0.16299.0 - - - - Application - v141 - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - .\..\win32\bin\Release\ - .\..\win32\tmp\Release_static\ - false - - - .\..\win32\bin\Debug\ - .\..\win32\tmp\Debug_static\ - true - - - - MultiThreaded - Default - true - true - MaxSpeed - true - Level3 - _WINDOWS;NDEBUG;_LIB;%(PreprocessorDefinitions) - .\..\win32\tmp\Release_static\ - .\..\win32\tmp\Release_static\expat_static.pch - .\..\win32\tmp\Release_static\ - .\..\win32\tmp\Release_static\ - - - 0x0409 - NDEBUG;%(PreprocessorDefinitions) - - - true - .\..\win32\bin\Release\expat_static.bsc - - - true - ..\win32\bin\Release\libexpatMT.lib - - - - - MultiThreadedDebug - Default - true - Disabled - true - Level3 - EditAndContinue - _DEBUG;_WINDOWS;_LIB;%(PreprocessorDefinitions) - .\..\win32\tmp\Debug_static\ - true - .\..\win32\tmp\Debug_static\expat_static.pch - .\..\win32\tmp\Debug_static\ - .\..\win32\tmp\Debug_static\ - EnableFastChecks - - - 0x0409 - _DEBUG;%(PreprocessorDefinitions) - - - true - .\..\win32\bin\Debug\expat_static.bsc - - - true - ..\win32\bin\Debug\libexpatMT.lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tools/sdk/include/expat/expat_static.vcxproj.filters b/tools/sdk/include/expat/expat_static.vcxproj.filters deleted file mode 100644 index a2fe03e6..00000000 --- a/tools/sdk/include/expat/expat_static.vcxproj.filters +++ /dev/null @@ -1,74 +0,0 @@ - - - - - {ef375f25-3490-4376-8deb-a8a8bebc0194} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {f1cd6f85-7111-4c1b-abad-37c79851ca34} - h;hpp;hxx;hm;inl - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/tools/sdk/include/expat/expatw.vcxproj b/tools/sdk/include/expat/expatw.vcxproj deleted file mode 100644 index c7083092..00000000 --- a/tools/sdk/include/expat/expatw.vcxproj +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Template - Win32 - - - - - - {C04F1C11-7079-48AD-A90B-6F59B7A55BEF} - 10.0.16299.0 - - - - Application - v141 - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - .\..\win32\bin\Release\ - .\..\win32\tmp\Release-w\ - false - - - .\..\win32\bin\Debug\ - .\..\win32\tmp\Debug-w\ - true - - - - MultiThreaded - Default - true - true - MaxSpeed - true - Level3 - NDEBUG;_WINDOWS;_USRDLL;XML_UNICODE_WCHAR_T;%(PreprocessorDefinitions) - .\..\win32\tmp\Release-w\ - .\..\win32\tmp\Release-w\expatw.pch - - .\..\win32\tmp\Release-w\ - .\..\win32\tmp\Release-w\ - - - true - NDEBUG;%(PreprocessorDefinitions) - .\..\win32\bin\Release\expatw.tlb - true - Win32 - - - 0x0409 - NDEBUG;%(PreprocessorDefinitions) - - - true - .\..\win32\bin\Release\expatw.bsc - - - true - true - Console - ..\win32\bin\Release\libexpatw.dll - .\..\win32\bin\Release\libexpatw.lib - .\libexpatw.def - - - - - MultiThreadedDebug - Default - true - Disabled - true - Level3 - EditAndContinue - _DEBUG;_WINDOWS;_USRDLL;XML_UNICODE_WCHAR_T;%(PreprocessorDefinitions) - .\..\win32\tmp\Debug-w\ - true - .\..\win32\tmp\Debug-w\expatw.pch - .\..\win32\tmp\Debug-w\ - .\..\win32\tmp\Debug-w\ - EnableFastChecks - - - true - _DEBUG;%(PreprocessorDefinitions) - .\..\win32\bin\Debug\expatw.tlb - true - Win32 - - - 0x0409 - _DEBUG;%(PreprocessorDefinitions) - - - true - .\..\win32\bin\Debug\expatw.bsc - - - true - true - true - Console - ..\win32\bin\Debug\libexpatw.dll - .\..\win32\bin\Debug\libexpatw.lib - .\libexpatw.def - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tools/sdk/include/expat/expatw.vcxproj.filters b/tools/sdk/include/expat/expatw.vcxproj.filters deleted file mode 100644 index fb3909c9..00000000 --- a/tools/sdk/include/expat/expatw.vcxproj.filters +++ /dev/null @@ -1,83 +0,0 @@ - - - - - {fea8fd20-7d6d-4664-a821-1ab5a29dadbd} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {0ceb9aa0-672d-4a6b-bff9-345c51aab04c} - h;hpp;hxx;hm;inl - - - {d62ff6fc-7f74-443d-a048-31ef02a6f99f} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - \ No newline at end of file diff --git a/tools/sdk/include/expat/expatw_static.vcxproj b/tools/sdk/include/expat/expatw_static.vcxproj deleted file mode 100644 index a917b48e..00000000 --- a/tools/sdk/include/expat/expatw_static.vcxproj +++ /dev/null @@ -1,149 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Template - Win32 - - - - - - {9220B0F2-C895-4CB2-91D1-1C16C4ECB759} - 10.0.16299.0 - - - - Application - v141 - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - .\..\win32\bin\Debug\ - .\..\win32\tmp\Debug-w_static\ - true - - - .\..\win32\bin\Release\ - .\..\win32\tmp\Release-w_static\ - false - - - - MultiThreadedDebug - Default - true - Disabled - true - Level3 - EditAndContinue - _DEBUG;_WINDOWS;_LIB;XML_UNICODE_WCHAR_T;%(PreprocessorDefinitions) - .\..\win32\tmp\Debug-w_static\ - true - .\..\win32\tmp\Debug-w_static\expatw_static.pch - .\..\win32\tmp\Debug-w_static\ - .\..\win32\tmp\Debug-w_static\ - EnableFastChecks - - - 0x0409 - _DEBUG;%(PreprocessorDefinitions) - - - true - .\..\win32\bin\Debug\expatw_static.bsc - - - true - ..\win32\bin\Debug\libexpatwMT.lib - - - - - MultiThreaded - Default - true - true - MaxSpeed - true - Level3 - _WINDOWS;NDEBUG;_LIB;XML_UNICODE_WCHAR_T;%(PreprocessorDefinitions) - .\..\win32\tmp\Release-w_static\ - .\..\win32\tmp\Release-w_static\expatw_static.pch - .\..\win32\tmp\Release-w_static\ - .\..\win32\tmp\Release-w_static\ - - - 0x0409 - NDEBUG;%(PreprocessorDefinitions) - - - true - .\..\win32\bin\Release\expatw_static.bsc - - - true - ..\win32\bin\Release\libexpatwMT.lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tools/sdk/include/expat/expatw_static.vcxproj.filters b/tools/sdk/include/expat/expatw_static.vcxproj.filters deleted file mode 100644 index 724d9f8c..00000000 --- a/tools/sdk/include/expat/expatw_static.vcxproj.filters +++ /dev/null @@ -1,74 +0,0 @@ - - - - - {c0226397-04be-42b5-ba75-257ac91ef7fa} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {3d74dc56-3aec-4ee9-b700-7203f44e015d} - h;hpp;hxx;hm;inl - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/tools/sdk/include/expat/libexpat.def b/tools/sdk/include/expat/libexpat.def deleted file mode 100644 index d08f5b7c..00000000 --- a/tools/sdk/include/expat/libexpat.def +++ /dev/null @@ -1,78 +0,0 @@ -; DEF file for MS VC++ - -LIBRARY -EXPORTS - XML_DefaultCurrent @1 - XML_ErrorString @2 - XML_ExpatVersion @3 - XML_ExpatVersionInfo @4 - XML_ExternalEntityParserCreate @5 - XML_GetBase @6 - XML_GetBuffer @7 - XML_GetCurrentByteCount @8 - XML_GetCurrentByteIndex @9 - XML_GetCurrentColumnNumber @10 - XML_GetCurrentLineNumber @11 - XML_GetErrorCode @12 - XML_GetIdAttributeIndex @13 - XML_GetInputContext @14 - XML_GetSpecifiedAttributeCount @15 - XML_Parse @16 - XML_ParseBuffer @17 - XML_ParserCreate @18 - XML_ParserCreateNS @19 - XML_ParserCreate_MM @20 - XML_ParserFree @21 - XML_SetAttlistDeclHandler @22 - XML_SetBase @23 - XML_SetCdataSectionHandler @24 - XML_SetCharacterDataHandler @25 - XML_SetCommentHandler @26 - XML_SetDefaultHandler @27 - XML_SetDefaultHandlerExpand @28 - XML_SetDoctypeDeclHandler @29 - XML_SetElementDeclHandler @30 - XML_SetElementHandler @31 - XML_SetEncoding @32 - XML_SetEndCdataSectionHandler @33 - XML_SetEndDoctypeDeclHandler @34 - XML_SetEndElementHandler @35 - XML_SetEndNamespaceDeclHandler @36 - XML_SetEntityDeclHandler @37 - XML_SetExternalEntityRefHandler @38 - XML_SetExternalEntityRefHandlerArg @39 - XML_SetNamespaceDeclHandler @40 - XML_SetNotStandaloneHandler @41 - XML_SetNotationDeclHandler @42 - XML_SetParamEntityParsing @43 - XML_SetProcessingInstructionHandler @44 - XML_SetReturnNSTriplet @45 - XML_SetStartCdataSectionHandler @46 - XML_SetStartDoctypeDeclHandler @47 - XML_SetStartElementHandler @48 - XML_SetStartNamespaceDeclHandler @49 - XML_SetUnknownEncodingHandler @50 - XML_SetUnparsedEntityDeclHandler @51 - XML_SetUserData @52 - XML_SetXmlDeclHandler @53 - XML_UseParserAsHandlerArg @54 -; added with version 1.95.3 - XML_ParserReset @55 - XML_SetSkippedEntityHandler @56 -; added with version 1.95.5 - XML_GetFeatureList @57 - XML_UseForeignDTD @58 -; added with version 1.95.6 - XML_FreeContentModel @59 - XML_MemMalloc @60 - XML_MemRealloc @61 - XML_MemFree @62 -; added with version 1.95.8 - XML_StopParser @63 - XML_ResumeParser @64 - XML_GetParsingStatus @65 -; added with version 2.1.1 -; XML_GetAttributeInfo @66 - XML_SetHashSalt @67@ -; added with version 2.2.5 - _INTERNAL_trim_to_complete_utf8_characters @68@ \ No newline at end of file diff --git a/tools/sdk/include/expat/libexpatw.def b/tools/sdk/include/expat/libexpatw.def deleted file mode 100644 index 928e01b1..00000000 --- a/tools/sdk/include/expat/libexpatw.def +++ /dev/null @@ -1,78 +0,0 @@ -; DEF file for MS VC++ - -LIBRARY -EXPORTS - XML_DefaultCurrent @1 - XML_ErrorString @2 - XML_ExpatVersion @3 - XML_ExpatVersionInfo @4 - XML_ExternalEntityParserCreate @5 - XML_GetBase @6 - XML_GetBuffer @7 - XML_GetCurrentByteCount @8 - XML_GetCurrentByteIndex @9 - XML_GetCurrentColumnNumber @10 - XML_GetCurrentLineNumber @11 - XML_GetErrorCode @12 - XML_GetIdAttributeIndex @13 - XML_GetInputContext @14 - XML_GetSpecifiedAttributeCount @15 - XML_Parse @16 - XML_ParseBuffer @17 - XML_ParserCreate @18 - XML_ParserCreateNS @19 - XML_ParserCreate_MM @20 - XML_ParserFree @21 - XML_SetAttlistDeclHandler @22 - XML_SetBase @23 - XML_SetCdataSectionHandler @24 - XML_SetCharacterDataHandler @25 - XML_SetCommentHandler @26 - XML_SetDefaultHandler @27 - XML_SetDefaultHandlerExpand @28 - XML_SetDoctypeDeclHandler @29 - XML_SetElementDeclHandler @30 - XML_SetElementHandler @31 - XML_SetEncoding @32 - XML_SetEndCdataSectionHandler @33 - XML_SetEndDoctypeDeclHandler @34 - XML_SetEndElementHandler @35 - XML_SetEndNamespaceDeclHandler @36 - XML_SetEntityDeclHandler @37 - XML_SetExternalEntityRefHandler @38 - XML_SetExternalEntityRefHandlerArg @39 - XML_SetNamespaceDeclHandler @40 - XML_SetNotStandaloneHandler @41 - XML_SetNotationDeclHandler @42 - XML_SetParamEntityParsing @43 - XML_SetProcessingInstructionHandler @44 - XML_SetReturnNSTriplet @45 - XML_SetStartCdataSectionHandler @46 - XML_SetStartDoctypeDeclHandler @47 - XML_SetStartElementHandler @48 - XML_SetStartNamespaceDeclHandler @49 - XML_SetUnknownEncodingHandler @50 - XML_SetUnparsedEntityDeclHandler @51 - XML_SetUserData @52 - XML_SetXmlDeclHandler @53 - XML_UseParserAsHandlerArg @54 -; added with version 1.95.3 - XML_ParserReset @55 - XML_SetSkippedEntityHandler @56 -; added with version 1.95.5 - XML_GetFeatureList @57 - XML_UseForeignDTD @58 -; added with version 1.95.6 - XML_FreeContentModel @59 - XML_MemMalloc @60 - XML_MemRealloc @61 - XML_MemFree @62 -; added with version 1.95.8 - XML_StopParser @63 - XML_ResumeParser @64 - XML_GetParsingStatus @65 -; added with version 2.1.1 -; XML_GetAttributeInfo @66 - XML_SetHashSalt @67@ -; added with version 2.2.5 - _INTERNAL_trim_to_complete_utf8_characters @68@ diff --git a/tools/sdk/include/expat/loadlibrary.c b/tools/sdk/include/expat/loadlibrary.c deleted file mode 100644 index 35fdf98b..00000000 --- a/tools/sdk/include/expat/loadlibrary.c +++ /dev/null @@ -1,143 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2016 - 2017, Steve Holme, . - * Copyright (C) 2017, Expat development team - * - * All rights reserved. - * Licensed under the MIT license: - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH - * THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder shall - * not be used in advertising or otherwise to promote the sale, use or other - * dealings in this Software without prior written authorization of the - * copyright holder. - * - ***************************************************************************/ - -#if defined(_WIN32) - -#include -#include - - -HMODULE _Expat_LoadLibrary(LPCTSTR filename); - - -#if !defined(LOAD_WITH_ALTERED_SEARCH_PATH) -#define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 -#endif - -#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32) -#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 -#endif - -/* We use our own typedef here since some headers might lack these */ -typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD); - -/* See function definitions in winbase.h */ -#ifdef UNICODE -# ifdef _WIN32_WCE -# define LOADLIBARYEX L"LoadLibraryExW" -# else -# define LOADLIBARYEX "LoadLibraryExW" -# endif -#else -# define LOADLIBARYEX "LoadLibraryExA" -#endif - - -/* - * _Expat_LoadLibrary() - * - * This is used to dynamically load DLLs using the most secure method available - * for the version of Windows that we are running on. - * - * Parameters: - * - * filename [in] - The filename or full path of the DLL to load. If only the - * filename is passed then the DLL will be loaded from the - * Windows system directory. - * - * Returns the handle of the module on success; otherwise NULL. - */ -HMODULE _Expat_LoadLibrary(LPCTSTR filename) -{ - HMODULE hModule = NULL; - LOADLIBRARYEX_FN pLoadLibraryEx = NULL; - - /* Get a handle to kernel32 so we can access it's functions at runtime */ - HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32")); - if(!hKernel32) - return NULL; /* LCOV_EXCL_LINE */ - - /* Attempt to find LoadLibraryEx() which is only available on Windows 2000 - and above */ - pLoadLibraryEx = (LOADLIBRARYEX_FN) GetProcAddress(hKernel32, LOADLIBARYEX); - - /* Detect if there's already a path in the filename and load the library if - there is. Note: Both back slashes and forward slashes have been supported - since the earlier days of DOS at an API level although they are not - supported by command prompt */ - if(_tcspbrk(filename, TEXT("\\/"))) { - /** !checksrc! disable BANNEDFUNC 1 **/ - hModule = pLoadLibraryEx ? - pLoadLibraryEx(filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) : - LoadLibrary(filename); - } - /* Detect if KB2533623 is installed, as LOAD_LIBARY_SEARCH_SYSTEM32 is only - supported on Windows Vista, Windows Server 2008, Windows 7 and Windows - Server 2008 R2 with this patch or natively on Windows 8 and above */ - else if(pLoadLibraryEx && GetProcAddress(hKernel32, "AddDllDirectory")) { - /* Load the DLL from the Windows system directory */ - hModule = pLoadLibraryEx(filename, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); - } - else { - /* Attempt to get the Windows system path */ - UINT systemdirlen = GetSystemDirectory(NULL, 0); - if(systemdirlen) { - /* Allocate space for the full DLL path (Room for the null terminator - is included in systemdirlen) */ - size_t filenamelen = _tcslen(filename); - TCHAR *path = malloc(sizeof(TCHAR) * (systemdirlen + 1 + filenamelen)); - if(path && GetSystemDirectory(path, systemdirlen)) { - /* Calculate the full DLL path */ - _tcscpy(path + _tcslen(path), TEXT("\\")); - _tcscpy(path + _tcslen(path), filename); - - /* Load the DLL from the Windows system directory */ - /** !checksrc! disable BANNEDFUNC 1 **/ - hModule = pLoadLibraryEx ? - pLoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) : - LoadLibrary(path); - - } - free(path); - } - } - - return hModule; -} - -#else /* defined(_WIN32) */ - -/* ISO C requires a translation unit to contain at least one declaration - [-Wempty-translation-unit] */ -typedef int _TRANSLATION_UNIT_LOAD_LIBRARY_C_NOT_EMTPY; - -#endif /* defined(_WIN32) */ diff --git a/tools/sdk/include/expat/xmlparse.c b/tools/sdk/include/expat/xmlparse.c deleted file mode 100644 index 90a237f3..00000000 --- a/tools/sdk/include/expat/xmlparse.c +++ /dev/null @@ -1,7195 +0,0 @@ -/* 4b74aa710b4ed5ce464b0ce544852cb47bf905c85a49c7bae2749f5885cb966d (2.2.5+) - __ __ _ - ___\ \/ /_ __ __ _| |_ - / _ \\ /| '_ \ / _` | __| - | __// \| |_) | (_| | |_ - \___/_/\_\ .__/ \__,_|\__| - |_| XML parser - - Copyright (c) 1997-2000 Thai Open Source Software Center Ltd - Copyright (c) 2000-2017 Expat development team - Licensed under the MIT license: - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to permit - persons to whom the Software is furnished to do so, subject to the - following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN - NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#if !defined(_GNU_SOURCE) -# define _GNU_SOURCE 1 /* syscall prototype */ -#endif - -#include -#include /* memset(), memcpy() */ -#include -#include /* UINT_MAX */ -#include /* fprintf */ -#include /* getenv */ - -#ifdef _WIN32 -#define getpid GetCurrentProcessId -#else -#include /* gettimeofday() */ -#include /* getpid() */ -#include /* getpid() */ -#include /* O_RDONLY */ -#include -#endif - -#define XML_BUILDING_EXPAT 1 - -#ifdef _WIN32 -#include "winconfig.h" -#elif defined(HAVE_EXPAT_CONFIG_H) -#include -#endif /* ndef _WIN32 */ - -#include "ascii.h" -#include "expat.h" -#include "siphash.h" - -#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) -# if defined(HAVE_GETRANDOM) -# include /* getrandom */ -# else -# include /* syscall */ -# include /* SYS_getrandom */ -# endif -# if ! defined(GRND_NONBLOCK) -# define GRND_NONBLOCK 0x0001 -# endif /* defined(GRND_NONBLOCK) */ -#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ - -#if defined(HAVE_LIBBSD) \ - && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM)) -# include -#endif - -#if defined(_WIN32) && !defined(LOAD_LIBRARY_SEARCH_SYSTEM32) -# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 -#endif - -#if !defined(HAVE_GETRANDOM) && !defined(HAVE_SYSCALL_GETRANDOM) \ - && !defined(HAVE_ARC4RANDOM_BUF) && !defined(HAVE_ARC4RANDOM) \ - && !defined(XML_DEV_URANDOM) \ - && !defined(_WIN32) \ - && !defined(XML_POOR_ENTROPY) -# error \ - You do not have support for any sources of high quality entropy \ - enabled. For end user security, that is probably not what you want. \ - \ - Your options include: \ - * Linux + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \ - * Linux + glibc <2.25 (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \ - * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \ - * BSD / macOS <10.7 (arc4random): HAVE_ARC4RANDOM, \ - * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ - * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ - * Linux / BSD / macOS (/dev/urandom): XML_DEV_URANDOM \ - * Windows (RtlGenRandom): _WIN32. \ - \ - If insist on not using any of these, bypass this error by defining \ - XML_POOR_ENTROPY; you have been warned. \ - \ - If you have reasons to patch this detection code away or need changes \ - to the build system, please open a bug. Thank you! -#endif - - -#ifdef XML_UNICODE -#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX -#define XmlConvert XmlUtf16Convert -#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding -#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS -#define XmlEncode XmlUtf16Encode -/* Using pointer subtraction to convert to integer type. */ -#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1)) -typedef unsigned short ICHAR; -#else -#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX -#define XmlConvert XmlUtf8Convert -#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding -#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS -#define XmlEncode XmlUtf8Encode -#define MUST_CONVERT(enc, s) (!(enc)->isUtf8) -typedef char ICHAR; -#endif - - -#ifndef XML_NS - -#define XmlInitEncodingNS XmlInitEncoding -#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding -#undef XmlGetInternalEncodingNS -#define XmlGetInternalEncodingNS XmlGetInternalEncoding -#define XmlParseXmlDeclNS XmlParseXmlDecl - -#endif - -#ifdef XML_UNICODE - -#ifdef XML_UNICODE_WCHAR_T -#define XML_T(x) (const wchar_t)x -#define XML_L(x) L ## x -#else -#define XML_T(x) (const unsigned short)x -#define XML_L(x) x -#endif - -#else - -#define XML_T(x) x -#define XML_L(x) x - -#endif - -/* Round up n to be a multiple of sz, where sz is a power of 2. */ -#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) - -/* Handle the case where memmove() doesn't exist. */ -#ifndef HAVE_MEMMOVE -#ifdef HAVE_BCOPY -#define memmove(d,s,l) bcopy((s),(d),(l)) -#else -#error memmove does not exist on this platform, nor is a substitute available -#endif /* HAVE_BCOPY */ -#endif /* HAVE_MEMMOVE */ - -#include "internal.h" -#include "xmltok.h" -#include "xmlrole.h" - -typedef const XML_Char *KEY; - -typedef struct { - KEY name; -} NAMED; - -typedef struct { - NAMED **v; - unsigned char power; - size_t size; - size_t used; - const XML_Memory_Handling_Suite *mem; -} HASH_TABLE; - -static size_t -keylen(KEY s); - -static void -copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key); - -/* For probing (after a collision) we need a step size relative prime - to the hash table size, which is a power of 2. We use double-hashing, - since we can calculate a second hash value cheaply by taking those bits - of the first hash value that were discarded (masked out) when the table - index was calculated: index = hash & mask, where mask = table->size - 1. - We limit the maximum step size to table->size / 4 (mask >> 2) and make - it odd, since odd numbers are always relative prime to a power of 2. -*/ -#define SECOND_HASH(hash, mask, power) \ - ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2)) -#define PROBE_STEP(hash, mask, power) \ - ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) - -typedef struct { - NAMED **p; - NAMED **end; -} HASH_TABLE_ITER; - -#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ -#define INIT_DATA_BUF_SIZE 1024 -#define INIT_ATTS_SIZE 16 -#define INIT_ATTS_VERSION 0xFFFFFFFF -#define INIT_BLOCK_SIZE 1024 -#define INIT_BUFFER_SIZE 1024 - -#define EXPAND_SPARE 24 - -typedef struct binding { - struct prefix *prefix; - struct binding *nextTagBinding; - struct binding *prevPrefixBinding; - const struct attribute_id *attId; - XML_Char *uri; - int uriLen; - int uriAlloc; -} BINDING; - -typedef struct prefix { - const XML_Char *name; - BINDING *binding; -} PREFIX; - -typedef struct { - const XML_Char *str; - const XML_Char *localPart; - const XML_Char *prefix; - int strLen; - int uriLen; - int prefixLen; -} TAG_NAME; - -/* TAG represents an open element. - The name of the element is stored in both the document and API - encodings. The memory buffer 'buf' is a separately-allocated - memory area which stores the name. During the XML_Parse()/ - XMLParseBuffer() when the element is open, the memory for the 'raw' - version of the name (in the document encoding) is shared with the - document buffer. If the element is open across calls to - XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to - contain the 'raw' name as well. - - A parser re-uses these structures, maintaining a list of allocated - TAG objects in a free list. -*/ -typedef struct tag { - struct tag *parent; /* parent of this element */ - const char *rawName; /* tagName in the original encoding */ - int rawNameLength; - TAG_NAME name; /* tagName in the API encoding */ - char *buf; /* buffer for name components */ - char *bufEnd; /* end of the buffer */ - BINDING *bindings; -} TAG; - -typedef struct { - const XML_Char *name; - const XML_Char *textPtr; - int textLen; /* length in XML_Chars */ - int processed; /* # of processed bytes - when suspended */ - const XML_Char *systemId; - const XML_Char *base; - const XML_Char *publicId; - const XML_Char *notation; - XML_Bool open; - XML_Bool is_param; - XML_Bool is_internal; /* true if declared in internal subset outside PE */ -} ENTITY; - -typedef struct { - enum XML_Content_Type type; - enum XML_Content_Quant quant; - const XML_Char * name; - int firstchild; - int lastchild; - int childcnt; - int nextsib; -} CONTENT_SCAFFOLD; - -#define INIT_SCAFFOLD_ELEMENTS 32 - -typedef struct block { - struct block *next; - int size; - XML_Char s[1]; -} BLOCK; - -typedef struct { - BLOCK *blocks; - BLOCK *freeBlocks; - const XML_Char *end; - XML_Char *ptr; - XML_Char *start; - const XML_Memory_Handling_Suite *mem; -} STRING_POOL; - -/* The XML_Char before the name is used to determine whether - an attribute has been specified. */ -typedef struct attribute_id { - XML_Char *name; - PREFIX *prefix; - XML_Bool maybeTokenized; - XML_Bool xmlns; -} ATTRIBUTE_ID; - -typedef struct { - const ATTRIBUTE_ID *id; - XML_Bool isCdata; - const XML_Char *value; -} DEFAULT_ATTRIBUTE; - -typedef struct { - unsigned long version; - unsigned long hash; - const XML_Char *uriName; -} NS_ATT; - -typedef struct { - const XML_Char *name; - PREFIX *prefix; - const ATTRIBUTE_ID *idAtt; - int nDefaultAtts; - int allocDefaultAtts; - DEFAULT_ATTRIBUTE *defaultAtts; -} ELEMENT_TYPE; - -typedef struct { - HASH_TABLE generalEntities; - HASH_TABLE elementTypes; - HASH_TABLE attributeIds; - HASH_TABLE prefixes; - STRING_POOL pool; - STRING_POOL entityValuePool; - /* false once a parameter entity reference has been skipped */ - XML_Bool keepProcessing; - /* true once an internal or external PE reference has been encountered; - this includes the reference to an external subset */ - XML_Bool hasParamEntityRefs; - XML_Bool standalone; -#ifdef XML_DTD - /* indicates if external PE has been read */ - XML_Bool paramEntityRead; - HASH_TABLE paramEntities; -#endif /* XML_DTD */ - PREFIX defaultPrefix; - /* === scaffolding for building content model === */ - XML_Bool in_eldecl; - CONTENT_SCAFFOLD *scaffold; - unsigned contentStringLen; - unsigned scaffSize; - unsigned scaffCount; - int scaffLevel; - int *scaffIndex; -} DTD; - -typedef struct open_internal_entity { - const char *internalEventPtr; - const char *internalEventEndPtr; - struct open_internal_entity *next; - ENTITY *entity; - int startTagLevel; - XML_Bool betweenDecl; /* WFC: PE Between Declarations */ -} OPEN_INTERNAL_ENTITY; - -typedef enum XML_Error PTRCALL Processor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr); - -static Processor prologProcessor; -static Processor prologInitProcessor; -static Processor contentProcessor; -static Processor cdataSectionProcessor; -#ifdef XML_DTD -static Processor ignoreSectionProcessor; -static Processor externalParEntProcessor; -static Processor externalParEntInitProcessor; -static Processor entityValueProcessor; -static Processor entityValueInitProcessor; -#endif /* XML_DTD */ -static Processor epilogProcessor; -static Processor errorProcessor; -static Processor externalEntityInitProcessor; -static Processor externalEntityInitProcessor2; -static Processor externalEntityInitProcessor3; -static Processor externalEntityContentProcessor; -static Processor internalEntityProcessor; - -static enum XML_Error -handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName); -static enum XML_Error -processXmlDecl(XML_Parser parser, int isGeneralTextEntity, - const char *s, const char *next); -static enum XML_Error -initializeEncoding(XML_Parser parser); -static enum XML_Error -doProlog(XML_Parser parser, const ENCODING *enc, const char *s, - const char *end, int tok, const char *next, const char **nextPtr, - XML_Bool haveMore); -static enum XML_Error -processInternalEntity(XML_Parser parser, ENTITY *entity, - XML_Bool betweenDecl); -static enum XML_Error -doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, - const char *start, const char *end, const char **endPtr, - XML_Bool haveMore); -static enum XML_Error -doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, - const char *end, const char **nextPtr, XML_Bool haveMore); -#ifdef XML_DTD -static enum XML_Error -doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, - const char *end, const char **nextPtr, XML_Bool haveMore); -#endif /* XML_DTD */ - -static void -freeBindings(XML_Parser parser, BINDING *bindings); -static enum XML_Error -storeAtts(XML_Parser parser, const ENCODING *, const char *s, - TAG_NAME *tagNamePtr, BINDING **bindingsPtr); -static enum XML_Error -addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, - const XML_Char *uri, BINDING **bindingsPtr); -static int -defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, - XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser); -static enum XML_Error -storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, - const char *, const char *, STRING_POOL *); -static enum XML_Error -appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, - const char *, const char *, STRING_POOL *); -static ATTRIBUTE_ID * -getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, - const char *end); -static int -setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); -static enum XML_Error -storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, - const char *end); -static int -reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, - const char *start, const char *end); -static int -reportComment(XML_Parser parser, const ENCODING *enc, const char *start, - const char *end); -static void -reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, - const char *end); - -static const XML_Char * getContext(XML_Parser parser); -static XML_Bool -setContext(XML_Parser parser, const XML_Char *context); - -static void FASTCALL normalizePublicId(XML_Char *s); - -static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms); -/* do not call if m_parentParser != NULL */ -static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms); -static void -dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms); -static int -dtdCopy(XML_Parser oldParser, - DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms); -static int -copyEntityTable(XML_Parser oldParser, - HASH_TABLE *, STRING_POOL *, const HASH_TABLE *); -static NAMED * -lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize); -static void FASTCALL -hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms); -static void FASTCALL hashTableClear(HASH_TABLE *); -static void FASTCALL hashTableDestroy(HASH_TABLE *); -static void FASTCALL -hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *); -static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *); - -static void FASTCALL -poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms); -static void FASTCALL poolClear(STRING_POOL *); -static void FASTCALL poolDestroy(STRING_POOL *); -static XML_Char * -poolAppend(STRING_POOL *pool, const ENCODING *enc, - const char *ptr, const char *end); -static XML_Char * -poolStoreString(STRING_POOL *pool, const ENCODING *enc, - const char *ptr, const char *end); -static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); -static const XML_Char * FASTCALL -poolCopyString(STRING_POOL *pool, const XML_Char *s); -static const XML_Char * -poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n); -static const XML_Char * FASTCALL -poolAppendString(STRING_POOL *pool, const XML_Char *s); - -static int FASTCALL nextScaffoldPart(XML_Parser parser); -static XML_Content * build_model(XML_Parser parser); -static ELEMENT_TYPE * -getElementType(XML_Parser parser, const ENCODING *enc, - const char *ptr, const char *end); - -static XML_Char *copyString(const XML_Char *s, - const XML_Memory_Handling_Suite *memsuite); - -static unsigned long generate_hash_secret_salt(XML_Parser parser); -static XML_Bool startParsing(XML_Parser parser); - -static XML_Parser -parserCreate(const XML_Char *encodingName, - const XML_Memory_Handling_Suite *memsuite, - const XML_Char *nameSep, - DTD *dtd); - -static void -parserInit(XML_Parser parser, const XML_Char *encodingName); - -#define poolStart(pool) ((pool)->start) -#define poolEnd(pool) ((pool)->ptr) -#define poolLength(pool) ((pool)->ptr - (pool)->start) -#define poolChop(pool) ((void)--(pool->ptr)) -#define poolLastChar(pool) (((pool)->ptr)[-1]) -#define poolDiscard(pool) ((pool)->ptr = (pool)->start) -#define poolFinish(pool) ((pool)->start = (pool)->ptr) -#define poolAppendChar(pool, c) \ - (((pool)->ptr == (pool)->end && !poolGrow(pool)) \ - ? 0 \ - : ((*((pool)->ptr)++ = c), 1)) - -struct XML_ParserStruct { - /* The first member must be m_userData so that the XML_GetUserData - macro works. */ - void *m_userData; - void *m_handlerArg; - char *m_buffer; - const XML_Memory_Handling_Suite m_mem; - /* first character to be parsed */ - const char *m_bufferPtr; - /* past last character to be parsed */ - char *m_bufferEnd; - /* allocated end of m_buffer */ - const char *m_bufferLim; - XML_Index m_parseEndByteIndex; - const char *m_parseEndPtr; - XML_Char *m_dataBuf; - XML_Char *m_dataBufEnd; - XML_StartElementHandler m_startElementHandler; - XML_EndElementHandler m_endElementHandler; - XML_CharacterDataHandler m_characterDataHandler; - XML_ProcessingInstructionHandler m_processingInstructionHandler; - XML_CommentHandler m_commentHandler; - XML_StartCdataSectionHandler m_startCdataSectionHandler; - XML_EndCdataSectionHandler m_endCdataSectionHandler; - XML_DefaultHandler m_defaultHandler; - XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; - XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; - XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; - XML_NotationDeclHandler m_notationDeclHandler; - XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; - XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; - XML_NotStandaloneHandler m_notStandaloneHandler; - XML_ExternalEntityRefHandler m_externalEntityRefHandler; - XML_Parser m_externalEntityRefHandlerArg; - XML_SkippedEntityHandler m_skippedEntityHandler; - XML_UnknownEncodingHandler m_unknownEncodingHandler; - XML_ElementDeclHandler m_elementDeclHandler; - XML_AttlistDeclHandler m_attlistDeclHandler; - XML_EntityDeclHandler m_entityDeclHandler; - XML_XmlDeclHandler m_xmlDeclHandler; - const ENCODING *m_encoding; - INIT_ENCODING m_initEncoding; - const ENCODING *m_internalEncoding; - const XML_Char *m_protocolEncodingName; - XML_Bool m_ns; - XML_Bool m_ns_triplets; - void *m_unknownEncodingMem; - void *m_unknownEncodingData; - void *m_unknownEncodingHandlerData; - void (XMLCALL *m_unknownEncodingRelease)(void *); - PROLOG_STATE m_prologState; - Processor *m_processor; - enum XML_Error m_errorCode; - const char *m_eventPtr; - const char *m_eventEndPtr; - const char *m_positionPtr; - OPEN_INTERNAL_ENTITY *m_openInternalEntities; - OPEN_INTERNAL_ENTITY *m_freeInternalEntities; - XML_Bool m_defaultExpandInternalEntities; - int m_tagLevel; - ENTITY *m_declEntity; - const XML_Char *m_doctypeName; - const XML_Char *m_doctypeSysid; - const XML_Char *m_doctypePubid; - const XML_Char *m_declAttributeType; - const XML_Char *m_declNotationName; - const XML_Char *m_declNotationPublicId; - ELEMENT_TYPE *m_declElementType; - ATTRIBUTE_ID *m_declAttributeId; - XML_Bool m_declAttributeIsCdata; - XML_Bool m_declAttributeIsId; - DTD *m_dtd; - const XML_Char *m_curBase; - TAG *m_tagStack; - TAG *m_freeTagList; - BINDING *m_inheritedBindings; - BINDING *m_freeBindingList; - int m_attsSize; - int m_nSpecifiedAtts; - int m_idAttIndex; - ATTRIBUTE *m_atts; - NS_ATT *m_nsAtts; - unsigned long m_nsAttsVersion; - unsigned char m_nsAttsPower; -#ifdef XML_ATTR_INFO - XML_AttrInfo *m_attInfo; -#endif - POSITION m_position; - STRING_POOL m_tempPool; - STRING_POOL m_temp2Pool; - char *m_groupConnector; - unsigned int m_groupSize; - XML_Char m_namespaceSeparator; - XML_Parser m_parentParser; - XML_ParsingStatus m_parsingStatus; -#ifdef XML_DTD - XML_Bool m_isParamEntity; - XML_Bool m_useForeignDTD; - enum XML_ParamEntityParsing m_paramEntityParsing; -#endif - unsigned long m_hash_secret_salt; -}; - -#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s))) -#define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p),(s))) -#define FREE(parser, p) (parser->m_mem.free_fcn((p))) - - -XML_Parser XMLCALL -XML_ParserCreate(const XML_Char *encodingName) -{ - return XML_ParserCreate_MM(encodingName, NULL, NULL); -} - -XML_Parser XMLCALL -XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) -{ - XML_Char tmp[2]; - *tmp = nsSep; - return XML_ParserCreate_MM(encodingName, NULL, tmp); -} - -static const XML_Char implicitContext[] = { - ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p, - ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, - ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, - ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, - ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e, - ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0' -}; - - -/* To avoid warnings about unused functions: */ -#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) - -#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) - -/* Obtain entropy on Linux 3.17+ */ -static int -writeRandomBytes_getrandom_nonblock(void * target, size_t count) { - int success = 0; /* full count bytes written? */ - size_t bytesWrittenTotal = 0; - const unsigned int getrandomFlags = GRND_NONBLOCK; - - do { - void * const currentTarget = (void*)((char*)target + bytesWrittenTotal); - const size_t bytesToWrite = count - bytesWrittenTotal; - - const int bytesWrittenMore = -#if defined(HAVE_GETRANDOM) - getrandom(currentTarget, bytesToWrite, getrandomFlags); -#else - syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags); -#endif - - if (bytesWrittenMore > 0) { - bytesWrittenTotal += bytesWrittenMore; - if (bytesWrittenTotal >= count) - success = 1; - } - } while (! success && (errno == EINTR)); - - return success; -} - -#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ - - -#if ! defined(_WIN32) && defined(XML_DEV_URANDOM) - -/* Extract entropy from /dev/urandom */ -static int -writeRandomBytes_dev_urandom(void * target, size_t count) { - int success = 0; /* full count bytes written? */ - size_t bytesWrittenTotal = 0; - - const int fd = open("/dev/urandom", O_RDONLY); - if (fd < 0) { - return 0; - } - - do { - void * const currentTarget = (void*)((char*)target + bytesWrittenTotal); - const size_t bytesToWrite = count - bytesWrittenTotal; - - const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite); - - if (bytesWrittenMore > 0) { - bytesWrittenTotal += bytesWrittenMore; - if (bytesWrittenTotal >= count) - success = 1; - } - } while (! success && (errno == EINTR)); - - close(fd); - return success; -} - -#endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ - -#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ - - -#if defined(HAVE_ARC4RANDOM) - -static void -writeRandomBytes_arc4random(void * target, size_t count) { - size_t bytesWrittenTotal = 0; - - while (bytesWrittenTotal < count) { - const uint32_t random32 = arc4random(); - size_t i = 0; - - for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); - i++, bytesWrittenTotal++) { - const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); - ((uint8_t *)target)[bytesWrittenTotal] = random8; - } - } -} - -#endif /* defined(HAVE_ARC4RANDOM) */ - - -#ifdef _WIN32 - -typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG); -HMODULE _Expat_LoadLibrary(LPCTSTR filename); /* see loadlibrary.c */ - -/* Obtain entropy on Windows XP / Windows Server 2003 and later. - * Hint on RtlGenRandom and the following article from libsodium. - * - * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI - * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/ - */ -static int -writeRandomBytes_RtlGenRandom(void * target, size_t count) { - int success = 0; /* full count bytes written? */ - const HMODULE advapi32 = _Expat_LoadLibrary(TEXT("ADVAPI32.DLL")); - - if (advapi32) { - const RTLGENRANDOM_FUNC RtlGenRandom - = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036"); - if (RtlGenRandom) { - if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) { - success = 1; - } - } - FreeLibrary(advapi32); - } - - return success; -} - -#endif /* _WIN32 */ - - -#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) - -static unsigned long -gather_time_entropy(void) -{ -#ifdef _WIN32 - FILETIME ft; - GetSystemTimeAsFileTime(&ft); /* never fails */ - return ft.dwHighDateTime ^ ft.dwLowDateTime; -#else - struct timeval tv; - int gettimeofday_res; - - gettimeofday_res = gettimeofday(&tv, NULL); - -#if defined(NDEBUG) - (void)gettimeofday_res; -#else - assert (gettimeofday_res == 0); -#endif /* defined(NDEBUG) */ - - /* Microseconds time is <20 bits entropy */ - return tv.tv_usec; -#endif -} - -#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ - - -static unsigned long -ENTROPY_DEBUG(const char * label, unsigned long entropy) { - const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG"); - if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) { - fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", - label, - (int)sizeof(entropy) * 2, entropy, - (unsigned long)sizeof(entropy)); - } - return entropy; -} - -static unsigned long -generate_hash_secret_salt(XML_Parser parser) -{ - unsigned long entropy; - (void)parser; - - /* "Failproof" high quality providers: */ -#if defined(HAVE_ARC4RANDOM_BUF) - arc4random_buf(&entropy, sizeof(entropy)); - return ENTROPY_DEBUG("arc4random_buf", entropy); -#elif defined(HAVE_ARC4RANDOM) - writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy)); - return ENTROPY_DEBUG("arc4random", entropy); -#else - /* Try high quality providers first .. */ -#ifdef _WIN32 - if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) { - return ENTROPY_DEBUG("RtlGenRandom", entropy); - } -#elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) - if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) { - return ENTROPY_DEBUG("getrandom", entropy); - } -#endif -#if ! defined(_WIN32) && defined(XML_DEV_URANDOM) - if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) { - return ENTROPY_DEBUG("/dev/urandom", entropy); - } -#endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ - /* .. and self-made low quality for backup: */ - - /* Process ID is 0 bits entropy if attacker has local access */ - entropy = gather_time_entropy() ^ getpid(); - - /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */ - if (sizeof(unsigned long) == 4) { - return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647); - } else { - return ENTROPY_DEBUG("fallback(8)", - entropy * (unsigned long)2305843009213693951ULL); - } -#endif -} - -static unsigned long -get_hash_secret_salt(XML_Parser parser) { - if (parser->m_parentParser != NULL) - return get_hash_secret_salt(parser->m_parentParser); - return parser->m_hash_secret_salt; -} - -static XML_Bool /* only valid for root parser */ -startParsing(XML_Parser parser) -{ - /* hash functions must be initialized before setContext() is called */ - if (parser->m_hash_secret_salt == 0) - parser->m_hash_secret_salt = generate_hash_secret_salt(parser); - if (parser->m_ns) { - /* implicit context only set for root parser, since child - parsers (i.e. external entity parsers) will inherit it - */ - return setContext(parser, implicitContext); - } - return XML_TRUE; -} - -XML_Parser XMLCALL -XML_ParserCreate_MM(const XML_Char *encodingName, - const XML_Memory_Handling_Suite *memsuite, - const XML_Char *nameSep) -{ - return parserCreate(encodingName, memsuite, nameSep, NULL); -} - -static XML_Parser -parserCreate(const XML_Char *encodingName, - const XML_Memory_Handling_Suite *memsuite, - const XML_Char *nameSep, - DTD *dtd) -{ - XML_Parser parser; - - if (memsuite) { - XML_Memory_Handling_Suite *mtemp; - parser = (XML_Parser) - memsuite->malloc_fcn(sizeof(struct XML_ParserStruct)); - if (parser != NULL) { - mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); - mtemp->malloc_fcn = memsuite->malloc_fcn; - mtemp->realloc_fcn = memsuite->realloc_fcn; - mtemp->free_fcn = memsuite->free_fcn; - } - } - else { - XML_Memory_Handling_Suite *mtemp; - parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct)); - if (parser != NULL) { - mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); - mtemp->malloc_fcn = malloc; - mtemp->realloc_fcn = realloc; - mtemp->free_fcn = free; - } - } - - if (!parser) - return parser; - - parser->m_buffer = NULL; - parser->m_bufferLim = NULL; - - parser->m_attsSize = INIT_ATTS_SIZE; - parser->m_atts = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE)); - if (parser->m_atts == NULL) { - FREE(parser, parser); - return NULL; - } -#ifdef XML_ATTR_INFO - parser->m_attInfo = (XML_AttrInfo*)MALLOC(parser, parser->m_attsSize * sizeof(XML_AttrInfo)); - if (parser->m_attInfo == NULL) { - FREE(parser, parser->m_atts); - FREE(parser, parser); - return NULL; - } -#endif - parser->m_dataBuf = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char)); - if (parser->m_dataBuf == NULL) { - FREE(parser, parser->m_atts); -#ifdef XML_ATTR_INFO - FREE(parser, parser->m_attInfo); -#endif - FREE(parser, parser); - return NULL; - } - parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE; - - if (dtd) - parser->m_dtd = dtd; - else { - parser->m_dtd = dtdCreate(&parser->m_mem); - if (parser->m_dtd == NULL) { - FREE(parser, parser->m_dataBuf); - FREE(parser, parser->m_atts); -#ifdef XML_ATTR_INFO - FREE(parser, parser->m_attInfo); -#endif - FREE(parser, parser); - return NULL; - } - } - - parser->m_freeBindingList = NULL; - parser->m_freeTagList = NULL; - parser->m_freeInternalEntities = NULL; - - parser->m_groupSize = 0; - parser->m_groupConnector = NULL; - - parser->m_unknownEncodingHandler = NULL; - parser->m_unknownEncodingHandlerData = NULL; - - parser->m_namespaceSeparator = ASCII_EXCL; - parser->m_ns = XML_FALSE; - parser->m_ns_triplets = XML_FALSE; - - parser->m_nsAtts = NULL; - parser->m_nsAttsVersion = 0; - parser->m_nsAttsPower = 0; - - parser->m_protocolEncodingName = NULL; - - poolInit(&parser->m_tempPool, &(parser->m_mem)); - poolInit(&parser->m_temp2Pool, &(parser->m_mem)); - parserInit(parser, encodingName); - - if (encodingName && !parser->m_protocolEncodingName) { - XML_ParserFree(parser); - return NULL; - } - - if (nameSep) { - parser->m_ns = XML_TRUE; - parser->m_internalEncoding = XmlGetInternalEncodingNS(); - parser->m_namespaceSeparator = *nameSep; - } - else { - parser->m_internalEncoding = XmlGetInternalEncoding(); - } - - return parser; -} - -static void -parserInit(XML_Parser parser, const XML_Char *encodingName) -{ - parser->m_processor = prologInitProcessor; - XmlPrologStateInit(&parser->m_prologState); - if (encodingName != NULL) { - parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); - } - parser->m_curBase = NULL; - XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0); - parser->m_userData = NULL; - parser->m_handlerArg = NULL; - parser->m_startElementHandler = NULL; - parser->m_endElementHandler = NULL; - parser->m_characterDataHandler = NULL; - parser->m_processingInstructionHandler = NULL; - parser->m_commentHandler = NULL; - parser->m_startCdataSectionHandler = NULL; - parser->m_endCdataSectionHandler = NULL; - parser->m_defaultHandler = NULL; - parser->m_startDoctypeDeclHandler = NULL; - parser->m_endDoctypeDeclHandler = NULL; - parser->m_unparsedEntityDeclHandler = NULL; - parser->m_notationDeclHandler = NULL; - parser->m_startNamespaceDeclHandler = NULL; - parser->m_endNamespaceDeclHandler = NULL; - parser->m_notStandaloneHandler = NULL; - parser->m_externalEntityRefHandler = NULL; - parser->m_externalEntityRefHandlerArg = parser; - parser->m_skippedEntityHandler = NULL; - parser->m_elementDeclHandler = NULL; - parser->m_attlistDeclHandler = NULL; - parser->m_entityDeclHandler = NULL; - parser->m_xmlDeclHandler = NULL; - parser->m_bufferPtr = parser->m_buffer; - parser->m_bufferEnd = parser->m_buffer; - parser->m_parseEndByteIndex = 0; - parser->m_parseEndPtr = NULL; - parser->m_declElementType = NULL; - parser->m_declAttributeId = NULL; - parser->m_declEntity = NULL; - parser->m_doctypeName = NULL; - parser->m_doctypeSysid = NULL; - parser->m_doctypePubid = NULL; - parser->m_declAttributeType = NULL; - parser->m_declNotationName = NULL; - parser->m_declNotationPublicId = NULL; - parser->m_declAttributeIsCdata = XML_FALSE; - parser->m_declAttributeIsId = XML_FALSE; - memset(&parser->m_position, 0, sizeof(POSITION)); - parser->m_errorCode = XML_ERROR_NONE; - parser->m_eventPtr = NULL; - parser->m_eventEndPtr = NULL; - parser->m_positionPtr = NULL; - parser->m_openInternalEntities = NULL; - parser->m_defaultExpandInternalEntities = XML_TRUE; - parser->m_tagLevel = 0; - parser->m_tagStack = NULL; - parser->m_inheritedBindings = NULL; - parser->m_nSpecifiedAtts = 0; - parser->m_unknownEncodingMem = NULL; - parser->m_unknownEncodingRelease = NULL; - parser->m_unknownEncodingData = NULL; - parser->m_parentParser = NULL; - parser->m_parsingStatus.parsing = XML_INITIALIZED; -#ifdef XML_DTD - parser->m_isParamEntity = XML_FALSE; - parser->m_useForeignDTD = XML_FALSE; - parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; -#endif - parser->m_hash_secret_salt = 0; -} - -/* moves list of bindings to m_freeBindingList */ -static void FASTCALL -moveToFreeBindingList(XML_Parser parser, BINDING *bindings) -{ - while (bindings) { - BINDING *b = bindings; - bindings = bindings->nextTagBinding; - b->nextTagBinding = parser->m_freeBindingList; - parser->m_freeBindingList = b; - } -} - -XML_Bool XMLCALL -XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) -{ - TAG *tStk; - OPEN_INTERNAL_ENTITY *openEntityList; - - if (parser == NULL) - return XML_FALSE; - - if (parser->m_parentParser) - return XML_FALSE; - /* move m_tagStack to m_freeTagList */ - tStk = parser->m_tagStack; - while (tStk) { - TAG *tag = tStk; - tStk = tStk->parent; - tag->parent = parser->m_freeTagList; - moveToFreeBindingList(parser, tag->bindings); - tag->bindings = NULL; - parser->m_freeTagList = tag; - } - /* move m_openInternalEntities to m_freeInternalEntities */ - openEntityList = parser->m_openInternalEntities; - while (openEntityList) { - OPEN_INTERNAL_ENTITY *openEntity = openEntityList; - openEntityList = openEntity->next; - openEntity->next = parser->m_freeInternalEntities; - parser->m_freeInternalEntities = openEntity; - } - moveToFreeBindingList(parser, parser->m_inheritedBindings); - FREE(parser, parser->m_unknownEncodingMem); - if (parser->m_unknownEncodingRelease) - parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); - poolClear(&parser->m_tempPool); - poolClear(&parser->m_temp2Pool); - FREE(parser, (void *)parser->m_protocolEncodingName); - parser->m_protocolEncodingName = NULL; - parserInit(parser, encodingName); - dtdReset(parser->m_dtd, &parser->m_mem); - return XML_TRUE; -} - -enum XML_Status XMLCALL -XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) -{ - if (parser == NULL) - return XML_STATUS_ERROR; - /* Block after XML_Parse()/XML_ParseBuffer() has been called. - XXX There's no way for the caller to determine which of the - XXX possible error cases caused the XML_STATUS_ERROR return. - */ - if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) - return XML_STATUS_ERROR; - - /* Get rid of any previous encoding name */ - FREE(parser, (void *)parser->m_protocolEncodingName); - - if (encodingName == NULL) - /* No new encoding name */ - parser->m_protocolEncodingName = NULL; - else { - /* Copy the new encoding name into allocated memory */ - parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); - if (!parser->m_protocolEncodingName) - return XML_STATUS_ERROR; - } - return XML_STATUS_OK; -} - -XML_Parser XMLCALL -XML_ExternalEntityParserCreate(XML_Parser oldParser, - const XML_Char *context, - const XML_Char *encodingName) -{ - XML_Parser parser = oldParser; - DTD *newDtd = NULL; - DTD *oldDtd; - XML_StartElementHandler oldStartElementHandler; - XML_EndElementHandler oldEndElementHandler; - XML_CharacterDataHandler oldCharacterDataHandler; - XML_ProcessingInstructionHandler oldProcessingInstructionHandler; - XML_CommentHandler oldCommentHandler; - XML_StartCdataSectionHandler oldStartCdataSectionHandler; - XML_EndCdataSectionHandler oldEndCdataSectionHandler; - XML_DefaultHandler oldDefaultHandler; - XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler; - XML_NotationDeclHandler oldNotationDeclHandler; - XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler; - XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler; - XML_NotStandaloneHandler oldNotStandaloneHandler; - XML_ExternalEntityRefHandler oldExternalEntityRefHandler; - XML_SkippedEntityHandler oldSkippedEntityHandler; - XML_UnknownEncodingHandler oldUnknownEncodingHandler; - XML_ElementDeclHandler oldElementDeclHandler; - XML_AttlistDeclHandler oldAttlistDeclHandler; - XML_EntityDeclHandler oldEntityDeclHandler; - XML_XmlDeclHandler oldXmlDeclHandler; - ELEMENT_TYPE * oldDeclElementType; - - void *oldUserData; - void *oldHandlerArg; - XML_Bool oldDefaultExpandInternalEntities; - XML_Parser oldExternalEntityRefHandlerArg; -#ifdef XML_DTD - enum XML_ParamEntityParsing oldParamEntityParsing; - int oldInEntityValue; -#endif - XML_Bool oldns_triplets; - /* Note that the new parser shares the same hash secret as the old - parser, so that dtdCopy and copyEntityTable can lookup values - from hash tables associated with either parser without us having - to worry which hash secrets each table has. - */ - unsigned long oldhash_secret_salt; - - /* Validate the oldParser parameter before we pull everything out of it */ - if (oldParser == NULL) - return NULL; - - /* Stash the original parser contents on the stack */ - oldDtd = parser->m_dtd; - oldStartElementHandler = parser->m_startElementHandler; - oldEndElementHandler = parser->m_endElementHandler; - oldCharacterDataHandler = parser->m_characterDataHandler; - oldProcessingInstructionHandler = parser->m_processingInstructionHandler; - oldCommentHandler = parser->m_commentHandler; - oldStartCdataSectionHandler = parser->m_startCdataSectionHandler; - oldEndCdataSectionHandler = parser->m_endCdataSectionHandler; - oldDefaultHandler = parser->m_defaultHandler; - oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler; - oldNotationDeclHandler = parser->m_notationDeclHandler; - oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler; - oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler; - oldNotStandaloneHandler = parser->m_notStandaloneHandler; - oldExternalEntityRefHandler = parser->m_externalEntityRefHandler; - oldSkippedEntityHandler = parser->m_skippedEntityHandler; - oldUnknownEncodingHandler = parser->m_unknownEncodingHandler; - oldElementDeclHandler = parser->m_elementDeclHandler; - oldAttlistDeclHandler = parser->m_attlistDeclHandler; - oldEntityDeclHandler = parser->m_entityDeclHandler; - oldXmlDeclHandler = parser->m_xmlDeclHandler; - oldDeclElementType = parser->m_declElementType; - - oldUserData = parser->m_userData; - oldHandlerArg = parser->m_handlerArg; - oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities; - oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg; -#ifdef XML_DTD - oldParamEntityParsing = parser->m_paramEntityParsing; - oldInEntityValue = parser->m_prologState.inEntityValue; -#endif - oldns_triplets = parser->m_ns_triplets; - /* Note that the new parser shares the same hash secret as the old - parser, so that dtdCopy and copyEntityTable can lookup values - from hash tables associated with either parser without us having - to worry which hash secrets each table has. - */ - oldhash_secret_salt = parser->m_hash_secret_salt; - -#ifdef XML_DTD - if (!context) - newDtd = oldDtd; -#endif /* XML_DTD */ - - /* Note that the magical uses of the pre-processor to make field - access look more like C++ require that `parser' be overwritten - here. This makes this function more painful to follow than it - would be otherwise. - */ - if (parser->m_ns) { - XML_Char tmp[2]; - *tmp = parser->m_namespaceSeparator; - parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); - } - else { - parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd); - } - - if (!parser) - return NULL; - - parser->m_startElementHandler = oldStartElementHandler; - parser->m_endElementHandler = oldEndElementHandler; - parser->m_characterDataHandler = oldCharacterDataHandler; - parser->m_processingInstructionHandler = oldProcessingInstructionHandler; - parser->m_commentHandler = oldCommentHandler; - parser->m_startCdataSectionHandler = oldStartCdataSectionHandler; - parser->m_endCdataSectionHandler = oldEndCdataSectionHandler; - parser->m_defaultHandler = oldDefaultHandler; - parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; - parser->m_notationDeclHandler = oldNotationDeclHandler; - parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler; - parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler; - parser->m_notStandaloneHandler = oldNotStandaloneHandler; - parser->m_externalEntityRefHandler = oldExternalEntityRefHandler; - parser->m_skippedEntityHandler = oldSkippedEntityHandler; - parser->m_unknownEncodingHandler = oldUnknownEncodingHandler; - parser->m_elementDeclHandler = oldElementDeclHandler; - parser->m_attlistDeclHandler = oldAttlistDeclHandler; - parser->m_entityDeclHandler = oldEntityDeclHandler; - parser->m_xmlDeclHandler = oldXmlDeclHandler; - parser->m_declElementType = oldDeclElementType; - parser->m_userData = oldUserData; - if (oldUserData == oldHandlerArg) - parser->m_handlerArg = parser->m_userData; - else - parser->m_handlerArg = parser; - if (oldExternalEntityRefHandlerArg != oldParser) - parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; - parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities; - parser->m_ns_triplets = oldns_triplets; - parser->m_hash_secret_salt = oldhash_secret_salt; - parser->m_parentParser = oldParser; -#ifdef XML_DTD - parser->m_paramEntityParsing = oldParamEntityParsing; - parser->m_prologState.inEntityValue = oldInEntityValue; - if (context) { -#endif /* XML_DTD */ - if (!dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem) - || !setContext(parser, context)) { - XML_ParserFree(parser); - return NULL; - } - parser->m_processor = externalEntityInitProcessor; -#ifdef XML_DTD - } - else { - /* The DTD instance referenced by parser->m_dtd is shared between the document's - root parser and external PE parsers, therefore one does not need to - call setContext. In addition, one also *must* not call setContext, - because this would overwrite existing prefix->binding pointers in - parser->m_dtd with ones that get destroyed with the external PE parser. - This would leave those prefixes with dangling pointers. - */ - parser->m_isParamEntity = XML_TRUE; - XmlPrologStateInitExternalEntity(&parser->m_prologState); - parser->m_processor = externalParEntInitProcessor; - } -#endif /* XML_DTD */ - return parser; -} - -static void FASTCALL -destroyBindings(BINDING *bindings, XML_Parser parser) -{ - for (;;) { - BINDING *b = bindings; - if (!b) - break; - bindings = b->nextTagBinding; - FREE(parser, b->uri); - FREE(parser, b); - } -} - -void XMLCALL -XML_ParserFree(XML_Parser parser) -{ - TAG *tagList; - OPEN_INTERNAL_ENTITY *entityList; - if (parser == NULL) - return; - /* free m_tagStack and m_freeTagList */ - tagList = parser->m_tagStack; - for (;;) { - TAG *p; - if (tagList == NULL) { - if (parser->m_freeTagList == NULL) - break; - tagList = parser->m_freeTagList; - parser->m_freeTagList = NULL; - } - p = tagList; - tagList = tagList->parent; - FREE(parser, p->buf); - destroyBindings(p->bindings, parser); - FREE(parser, p); - } - /* free m_openInternalEntities and m_freeInternalEntities */ - entityList = parser->m_openInternalEntities; - for (;;) { - OPEN_INTERNAL_ENTITY *openEntity; - if (entityList == NULL) { - if (parser->m_freeInternalEntities == NULL) - break; - entityList = parser->m_freeInternalEntities; - parser->m_freeInternalEntities = NULL; - } - openEntity = entityList; - entityList = entityList->next; - FREE(parser, openEntity); - } - - destroyBindings(parser->m_freeBindingList, parser); - destroyBindings(parser->m_inheritedBindings, parser); - poolDestroy(&parser->m_tempPool); - poolDestroy(&parser->m_temp2Pool); - FREE(parser, (void *)parser->m_protocolEncodingName); -#ifdef XML_DTD - /* external parameter entity parsers share the DTD structure - parser->m_dtd with the root parser, so we must not destroy it - */ - if (!parser->m_isParamEntity && parser->m_dtd) -#else - if (parser->m_dtd) -#endif /* XML_DTD */ - dtdDestroy(parser->m_dtd, (XML_Bool)!parser->m_parentParser, &parser->m_mem); - FREE(parser, (void *)parser->m_atts); -#ifdef XML_ATTR_INFO - FREE(parser, (void *)parser->m_attInfo); -#endif - FREE(parser, parser->m_groupConnector); - FREE(parser, parser->m_buffer); - FREE(parser, parser->m_dataBuf); - FREE(parser, parser->m_nsAtts); - FREE(parser, parser->m_unknownEncodingMem); - if (parser->m_unknownEncodingRelease) - parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); - FREE(parser, parser); -} - -void XMLCALL -XML_UseParserAsHandlerArg(XML_Parser parser) -{ - if (parser != NULL) - parser->m_handlerArg = parser; -} - -enum XML_Error XMLCALL -XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) -{ - if (parser == NULL) - return XML_ERROR_INVALID_ARGUMENT; -#ifdef XML_DTD - /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) - return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; - parser->m_useForeignDTD = useDTD; - return XML_ERROR_NONE; -#else - return XML_ERROR_FEATURE_REQUIRES_XML_DTD; -#endif -} - -void XMLCALL -XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) -{ - if (parser == NULL) - return; - /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) - return; - parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE; -} - -void XMLCALL -XML_SetUserData(XML_Parser parser, void *p) -{ - if (parser == NULL) - return; - if (parser->m_handlerArg == parser->m_userData) - parser->m_handlerArg = parser->m_userData = p; - else - parser->m_userData = p; -} - -enum XML_Status XMLCALL -XML_SetBase(XML_Parser parser, const XML_Char *p) -{ - if (parser == NULL) - return XML_STATUS_ERROR; - if (p) { - p = poolCopyString(&parser->m_dtd->pool, p); - if (!p) - return XML_STATUS_ERROR; - parser->m_curBase = p; - } - else - parser->m_curBase = NULL; - return XML_STATUS_OK; -} - -const XML_Char * XMLCALL -XML_GetBase(XML_Parser parser) -{ - if (parser == NULL) - return NULL; - return parser->m_curBase; -} - -int XMLCALL -XML_GetSpecifiedAttributeCount(XML_Parser parser) -{ - if (parser == NULL) - return -1; - return parser->m_nSpecifiedAtts; -} - -int XMLCALL -XML_GetIdAttributeIndex(XML_Parser parser) -{ - if (parser == NULL) - return -1; - return parser->m_idAttIndex; -} - -#ifdef XML_ATTR_INFO -const XML_AttrInfo * XMLCALL -XML_GetAttributeInfo(XML_Parser parser) -{ - if (parser == NULL) - return NULL; - return parser->m_attInfo; -} -#endif - -void XMLCALL -XML_SetElementHandler(XML_Parser parser, - XML_StartElementHandler start, - XML_EndElementHandler end) -{ - if (parser == NULL) - return; - parser->m_startElementHandler = start; - parser->m_endElementHandler = end; -} - -void XMLCALL -XML_SetStartElementHandler(XML_Parser parser, - XML_StartElementHandler start) { - if (parser != NULL) - parser->m_startElementHandler = start; -} - -void XMLCALL -XML_SetEndElementHandler(XML_Parser parser, - XML_EndElementHandler end) { - if (parser != NULL) - parser->m_endElementHandler = end; -} - -void XMLCALL -XML_SetCharacterDataHandler(XML_Parser parser, - XML_CharacterDataHandler handler) -{ - if (parser != NULL) - parser->m_characterDataHandler = handler; -} - -void XMLCALL -XML_SetProcessingInstructionHandler(XML_Parser parser, - XML_ProcessingInstructionHandler handler) -{ - if (parser != NULL) - parser->m_processingInstructionHandler = handler; -} - -void XMLCALL -XML_SetCommentHandler(XML_Parser parser, - XML_CommentHandler handler) -{ - if (parser != NULL) - parser->m_commentHandler = handler; -} - -void XMLCALL -XML_SetCdataSectionHandler(XML_Parser parser, - XML_StartCdataSectionHandler start, - XML_EndCdataSectionHandler end) -{ - if (parser == NULL) - return; - parser->m_startCdataSectionHandler = start; - parser->m_endCdataSectionHandler = end; -} - -void XMLCALL -XML_SetStartCdataSectionHandler(XML_Parser parser, - XML_StartCdataSectionHandler start) { - if (parser != NULL) - parser->m_startCdataSectionHandler = start; -} - -void XMLCALL -XML_SetEndCdataSectionHandler(XML_Parser parser, - XML_EndCdataSectionHandler end) { - if (parser != NULL) - parser->m_endCdataSectionHandler = end; -} - -void XMLCALL -XML_SetDefaultHandler(XML_Parser parser, - XML_DefaultHandler handler) -{ - if (parser == NULL) - return; - parser->m_defaultHandler = handler; - parser->m_defaultExpandInternalEntities = XML_FALSE; -} - -void XMLCALL -XML_SetDefaultHandlerExpand(XML_Parser parser, - XML_DefaultHandler handler) -{ - if (parser == NULL) - return; - parser->m_defaultHandler = handler; - parser->m_defaultExpandInternalEntities = XML_TRUE; -} - -void XMLCALL -XML_SetDoctypeDeclHandler(XML_Parser parser, - XML_StartDoctypeDeclHandler start, - XML_EndDoctypeDeclHandler end) -{ - if (parser == NULL) - return; - parser->m_startDoctypeDeclHandler = start; - parser->m_endDoctypeDeclHandler = end; -} - -void XMLCALL -XML_SetStartDoctypeDeclHandler(XML_Parser parser, - XML_StartDoctypeDeclHandler start) { - if (parser != NULL) - parser->m_startDoctypeDeclHandler = start; -} - -void XMLCALL -XML_SetEndDoctypeDeclHandler(XML_Parser parser, - XML_EndDoctypeDeclHandler end) { - if (parser != NULL) - parser->m_endDoctypeDeclHandler = end; -} - -void XMLCALL -XML_SetUnparsedEntityDeclHandler(XML_Parser parser, - XML_UnparsedEntityDeclHandler handler) -{ - if (parser != NULL) - parser->m_unparsedEntityDeclHandler = handler; -} - -void XMLCALL -XML_SetNotationDeclHandler(XML_Parser parser, - XML_NotationDeclHandler handler) -{ - if (parser != NULL) - parser->m_notationDeclHandler = handler; -} - -void XMLCALL -XML_SetNamespaceDeclHandler(XML_Parser parser, - XML_StartNamespaceDeclHandler start, - XML_EndNamespaceDeclHandler end) -{ - if (parser == NULL) - return; - parser->m_startNamespaceDeclHandler = start; - parser->m_endNamespaceDeclHandler = end; -} - -void XMLCALL -XML_SetStartNamespaceDeclHandler(XML_Parser parser, - XML_StartNamespaceDeclHandler start) { - if (parser != NULL) - parser->m_startNamespaceDeclHandler = start; -} - -void XMLCALL -XML_SetEndNamespaceDeclHandler(XML_Parser parser, - XML_EndNamespaceDeclHandler end) { - if (parser != NULL) - parser->m_endNamespaceDeclHandler = end; -} - -void XMLCALL -XML_SetNotStandaloneHandler(XML_Parser parser, - XML_NotStandaloneHandler handler) -{ - if (parser != NULL) - parser->m_notStandaloneHandler = handler; -} - -void XMLCALL -XML_SetExternalEntityRefHandler(XML_Parser parser, - XML_ExternalEntityRefHandler handler) -{ - if (parser != NULL) - parser->m_externalEntityRefHandler = handler; -} - -void XMLCALL -XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) -{ - if (parser == NULL) - return; - if (arg) - parser->m_externalEntityRefHandlerArg = (XML_Parser)arg; - else - parser->m_externalEntityRefHandlerArg = parser; -} - -void XMLCALL -XML_SetSkippedEntityHandler(XML_Parser parser, - XML_SkippedEntityHandler handler) -{ - if (parser != NULL) - parser->m_skippedEntityHandler = handler; -} - -void XMLCALL -XML_SetUnknownEncodingHandler(XML_Parser parser, - XML_UnknownEncodingHandler handler, - void *data) -{ - if (parser == NULL) - return; - parser->m_unknownEncodingHandler = handler; - parser->m_unknownEncodingHandlerData = data; -} - -void XMLCALL -XML_SetElementDeclHandler(XML_Parser parser, - XML_ElementDeclHandler eldecl) -{ - if (parser != NULL) - parser->m_elementDeclHandler = eldecl; -} - -void XMLCALL -XML_SetAttlistDeclHandler(XML_Parser parser, - XML_AttlistDeclHandler attdecl) -{ - if (parser != NULL) - parser->m_attlistDeclHandler = attdecl; -} - -void XMLCALL -XML_SetEntityDeclHandler(XML_Parser parser, - XML_EntityDeclHandler handler) -{ - if (parser != NULL) - parser->m_entityDeclHandler = handler; -} - -void XMLCALL -XML_SetXmlDeclHandler(XML_Parser parser, - XML_XmlDeclHandler handler) { - if (parser != NULL) - parser->m_xmlDeclHandler = handler; -} - -int XMLCALL -XML_SetParamEntityParsing(XML_Parser parser, - enum XML_ParamEntityParsing peParsing) -{ - if (parser == NULL) - return 0; - /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) - return 0; -#ifdef XML_DTD - parser->m_paramEntityParsing = peParsing; - return 1; -#else - return peParsing == XML_PARAM_ENTITY_PARSING_NEVER; -#endif -} - -int XMLCALL -XML_SetHashSalt(XML_Parser parser, - unsigned long hash_salt) -{ - if (parser == NULL) - return 0; - if (parser->m_parentParser) - return XML_SetHashSalt(parser->m_parentParser, hash_salt); - /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) - return 0; - parser->m_hash_secret_salt = hash_salt; - return 1; -} - -enum XML_Status XMLCALL -XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) -{ - if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) { - if (parser != NULL) - parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT; - return XML_STATUS_ERROR; - } - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: - parser->m_errorCode = XML_ERROR_SUSPENDED; - return XML_STATUS_ERROR; - case XML_FINISHED: - parser->m_errorCode = XML_ERROR_FINISHED; - return XML_STATUS_ERROR; - case XML_INITIALIZED: - if (parser->m_parentParser == NULL && !startParsing(parser)) { - parser->m_errorCode = XML_ERROR_NO_MEMORY; - return XML_STATUS_ERROR; - } - default: - parser->m_parsingStatus.parsing = XML_PARSING; - } - - if (len == 0) { - parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; - if (!isFinal) - return XML_STATUS_OK; - parser->m_positionPtr = parser->m_bufferPtr; - parser->m_parseEndPtr = parser->m_bufferEnd; - - /* If data are left over from last buffer, and we now know that these - data are the final chunk of input, then we have to check them again - to detect errors based on that fact. - */ - parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); - - if (parser->m_errorCode == XML_ERROR_NONE) { - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: - /* It is hard to be certain, but it seems that this case - * cannot occur. This code is cleaning up a previous parse - * with no new data (since len == 0). Changing the parsing - * state requires getting to execute a handler function, and - * there doesn't seem to be an opportunity for that while in - * this circumstance. - * - * Given the uncertainty, we retain the code but exclude it - * from coverage tests. - * - * LCOV_EXCL_START - */ - XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position); - parser->m_positionPtr = parser->m_bufferPtr; - return XML_STATUS_SUSPENDED; - /* LCOV_EXCL_STOP */ - case XML_INITIALIZED: - case XML_PARSING: - parser->m_parsingStatus.parsing = XML_FINISHED; - /* fall through */ - default: - return XML_STATUS_OK; - } - } - parser->m_eventEndPtr = parser->m_eventPtr; - parser->m_processor = errorProcessor; - return XML_STATUS_ERROR; - } -#ifndef XML_CONTEXT_BYTES - else if (parser->m_bufferPtr == parser->m_bufferEnd) { - const char *end; - int nLeftOver; - enum XML_Status result; - /* Detect overflow (a+b > MAX <==> b > MAX-a) */ - if (len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) { - parser->m_errorCode = XML_ERROR_NO_MEMORY; - parser->m_eventPtr = parser->m_eventEndPtr = NULL; - parser->m_processor = errorProcessor; - return XML_STATUS_ERROR; - } - parser->m_parseEndByteIndex += len; - parser->m_positionPtr = s; - parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; - - parser->m_errorCode = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end); - - if (parser->m_errorCode != XML_ERROR_NONE) { - parser->m_eventEndPtr = parser->m_eventPtr; - parser->m_processor = errorProcessor; - return XML_STATUS_ERROR; - } - else { - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: - result = XML_STATUS_SUSPENDED; - break; - case XML_INITIALIZED: - case XML_PARSING: - if (isFinal) { - parser->m_parsingStatus.parsing = XML_FINISHED; - return XML_STATUS_OK; - } - /* fall through */ - default: - result = XML_STATUS_OK; - } - } - - XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, &parser->m_position); - nLeftOver = s + len - end; - if (nLeftOver) { - if (parser->m_buffer == NULL || nLeftOver > parser->m_bufferLim - parser->m_buffer) { - /* avoid _signed_ integer overflow */ - char *temp = NULL; - const int bytesToAllocate = (int)((unsigned)len * 2U); - if (bytesToAllocate > 0) { - temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate); - } - if (temp == NULL) { - parser->m_errorCode = XML_ERROR_NO_MEMORY; - parser->m_eventPtr = parser->m_eventEndPtr = NULL; - parser->m_processor = errorProcessor; - return XML_STATUS_ERROR; - } - parser->m_buffer = temp; - parser->m_bufferLim = parser->m_buffer + bytesToAllocate; - } - memcpy(parser->m_buffer, end, nLeftOver); - } - parser->m_bufferPtr = parser->m_buffer; - parser->m_bufferEnd = parser->m_buffer + nLeftOver; - parser->m_positionPtr = parser->m_bufferPtr; - parser->m_parseEndPtr = parser->m_bufferEnd; - parser->m_eventPtr = parser->m_bufferPtr; - parser->m_eventEndPtr = parser->m_bufferPtr; - return result; - } -#endif /* not defined XML_CONTEXT_BYTES */ - else { - void *buff = XML_GetBuffer(parser, len); - if (buff == NULL) - return XML_STATUS_ERROR; - else { - memcpy(buff, s, len); - return XML_ParseBuffer(parser, len, isFinal); - } - } -} - -enum XML_Status XMLCALL -XML_ParseBuffer(XML_Parser parser, int len, int isFinal) -{ - const char *start; - enum XML_Status result = XML_STATUS_OK; - - if (parser == NULL) - return XML_STATUS_ERROR; - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: - parser->m_errorCode = XML_ERROR_SUSPENDED; - return XML_STATUS_ERROR; - case XML_FINISHED: - parser->m_errorCode = XML_ERROR_FINISHED; - return XML_STATUS_ERROR; - case XML_INITIALIZED: - if (parser->m_parentParser == NULL && !startParsing(parser)) { - parser->m_errorCode = XML_ERROR_NO_MEMORY; - return XML_STATUS_ERROR; - } - default: - parser->m_parsingStatus.parsing = XML_PARSING; - } - - start = parser->m_bufferPtr; - parser->m_positionPtr = start; - parser->m_bufferEnd += len; - parser->m_parseEndPtr = parser->m_bufferEnd; - parser->m_parseEndByteIndex += len; - parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; - - parser->m_errorCode = parser->m_processor(parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr); - - if (parser->m_errorCode != XML_ERROR_NONE) { - parser->m_eventEndPtr = parser->m_eventPtr; - parser->m_processor = errorProcessor; - return XML_STATUS_ERROR; - } - else { - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: - result = XML_STATUS_SUSPENDED; - break; - case XML_INITIALIZED: - case XML_PARSING: - if (isFinal) { - parser->m_parsingStatus.parsing = XML_FINISHED; - return result; - } - default: ; /* should not happen */ - } - } - - XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position); - parser->m_positionPtr = parser->m_bufferPtr; - return result; -} - -void * XMLCALL -XML_GetBuffer(XML_Parser parser, int len) -{ - if (parser == NULL) - return NULL; - if (len < 0) { - parser->m_errorCode = XML_ERROR_NO_MEMORY; - return NULL; - } - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: - parser->m_errorCode = XML_ERROR_SUSPENDED; - return NULL; - case XML_FINISHED: - parser->m_errorCode = XML_ERROR_FINISHED; - return NULL; - default: ; - } - - if (len > parser->m_bufferLim - parser->m_bufferEnd) { -#ifdef XML_CONTEXT_BYTES - int keep; -#endif /* defined XML_CONTEXT_BYTES */ - /* Do not invoke signed arithmetic overflow: */ - int neededSize = (int) ((unsigned)len + (unsigned)(parser->m_bufferEnd - parser->m_bufferPtr)); - if (neededSize < 0) { - parser->m_errorCode = XML_ERROR_NO_MEMORY; - return NULL; - } -#ifdef XML_CONTEXT_BYTES - keep = (int)(parser->m_bufferPtr - parser->m_buffer); - if (keep > XML_CONTEXT_BYTES) - keep = XML_CONTEXT_BYTES; - neededSize += keep; -#endif /* defined XML_CONTEXT_BYTES */ - if (neededSize <= parser->m_bufferLim - parser->m_buffer) { -#ifdef XML_CONTEXT_BYTES - if (keep < parser->m_bufferPtr - parser->m_buffer) { - int offset = (int)(parser->m_bufferPtr - parser->m_buffer) - keep; - memmove(parser->m_buffer, &parser->m_buffer[offset], parser->m_bufferEnd - parser->m_bufferPtr + keep); - parser->m_bufferEnd -= offset; - parser->m_bufferPtr -= offset; - } -#else - memmove(parser->m_buffer, parser->m_bufferPtr, parser->m_bufferEnd - parser->m_bufferPtr); - parser->m_bufferEnd = parser->m_buffer + (parser->m_bufferEnd - parser->m_bufferPtr); - parser->m_bufferPtr = parser->m_buffer; -#endif /* not defined XML_CONTEXT_BYTES */ - } - else { - char *newBuf; - int bufferSize = (int)(parser->m_bufferLim - parser->m_bufferPtr); - if (bufferSize == 0) - bufferSize = INIT_BUFFER_SIZE; - do { - /* Do not invoke signed arithmetic overflow: */ - bufferSize = (int) (2U * (unsigned) bufferSize); - } while (bufferSize < neededSize && bufferSize > 0); - if (bufferSize <= 0) { - parser->m_errorCode = XML_ERROR_NO_MEMORY; - return NULL; - } - newBuf = (char *)MALLOC(parser, bufferSize); - if (newBuf == 0) { - parser->m_errorCode = XML_ERROR_NO_MEMORY; - return NULL; - } - parser->m_bufferLim = newBuf + bufferSize; -#ifdef XML_CONTEXT_BYTES - if (parser->m_bufferPtr) { - int keep = (int)(parser->m_bufferPtr - parser->m_buffer); - if (keep > XML_CONTEXT_BYTES) - keep = XML_CONTEXT_BYTES; - memcpy(newBuf, &parser->m_bufferPtr[-keep], parser->m_bufferEnd - parser->m_bufferPtr + keep); - FREE(parser, parser->m_buffer); - parser->m_buffer = newBuf; - parser->m_bufferEnd = parser->m_buffer + (parser->m_bufferEnd - parser->m_bufferPtr) + keep; - parser->m_bufferPtr = parser->m_buffer + keep; - } - else { - parser->m_bufferEnd = newBuf + (parser->m_bufferEnd - parser->m_bufferPtr); - parser->m_bufferPtr = parser->m_buffer = newBuf; - } -#else - if (parser->m_bufferPtr) { - memcpy(newBuf, parser->m_bufferPtr, parser->m_bufferEnd - parser->m_bufferPtr); - FREE(parser, parser->m_buffer); - } - parser->m_bufferEnd = newBuf + (parser->m_bufferEnd - parser->m_bufferPtr); - parser->m_bufferPtr = parser->m_buffer = newBuf; -#endif /* not defined XML_CONTEXT_BYTES */ - } - parser->m_eventPtr = parser->m_eventEndPtr = NULL; - parser->m_positionPtr = NULL; - } - return parser->m_bufferEnd; -} - -enum XML_Status XMLCALL -XML_StopParser(XML_Parser parser, XML_Bool resumable) -{ - if (parser == NULL) - return XML_STATUS_ERROR; - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: - if (resumable) { - parser->m_errorCode = XML_ERROR_SUSPENDED; - return XML_STATUS_ERROR; - } - parser->m_parsingStatus.parsing = XML_FINISHED; - break; - case XML_FINISHED: - parser->m_errorCode = XML_ERROR_FINISHED; - return XML_STATUS_ERROR; - default: - if (resumable) { -#ifdef XML_DTD - if (parser->m_isParamEntity) { - parser->m_errorCode = XML_ERROR_SUSPEND_PE; - return XML_STATUS_ERROR; - } -#endif - parser->m_parsingStatus.parsing = XML_SUSPENDED; - } - else - parser->m_parsingStatus.parsing = XML_FINISHED; - } - return XML_STATUS_OK; -} - -enum XML_Status XMLCALL -XML_ResumeParser(XML_Parser parser) -{ - enum XML_Status result = XML_STATUS_OK; - - if (parser == NULL) - return XML_STATUS_ERROR; - if (parser->m_parsingStatus.parsing != XML_SUSPENDED) { - parser->m_errorCode = XML_ERROR_NOT_SUSPENDED; - return XML_STATUS_ERROR; - } - parser->m_parsingStatus.parsing = XML_PARSING; - - parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); - - if (parser->m_errorCode != XML_ERROR_NONE) { - parser->m_eventEndPtr = parser->m_eventPtr; - parser->m_processor = errorProcessor; - return XML_STATUS_ERROR; - } - else { - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: - result = XML_STATUS_SUSPENDED; - break; - case XML_INITIALIZED: - case XML_PARSING: - if (parser->m_parsingStatus.finalBuffer) { - parser->m_parsingStatus.parsing = XML_FINISHED; - return result; - } - default: ; - } - } - - XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position); - parser->m_positionPtr = parser->m_bufferPtr; - return result; -} - -void XMLCALL -XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) -{ - if (parser == NULL) - return; - assert(status != NULL); - *status = parser->m_parsingStatus; -} - -enum XML_Error XMLCALL -XML_GetErrorCode(XML_Parser parser) -{ - if (parser == NULL) - return XML_ERROR_INVALID_ARGUMENT; - return parser->m_errorCode; -} - -XML_Index XMLCALL -XML_GetCurrentByteIndex(XML_Parser parser) -{ - if (parser == NULL) - return -1; - if (parser->m_eventPtr) - return (XML_Index)(parser->m_parseEndByteIndex - (parser->m_parseEndPtr - parser->m_eventPtr)); - return -1; -} - -int XMLCALL -XML_GetCurrentByteCount(XML_Parser parser) -{ - if (parser == NULL) - return 0; - if (parser->m_eventEndPtr && parser->m_eventPtr) - return (int)(parser->m_eventEndPtr - parser->m_eventPtr); - return 0; -} - -const char * XMLCALL -XML_GetInputContext(XML_Parser parser, int *offset, int *size) -{ -#ifdef XML_CONTEXT_BYTES - if (parser == NULL) - return NULL; - if (parser->m_eventPtr && parser->m_buffer) { - if (offset != NULL) - *offset = (int)(parser->m_eventPtr - parser->m_buffer); - if (size != NULL) - *size = (int)(parser->m_bufferEnd - parser->m_buffer); - return parser->m_buffer; - } -#else - (void)parser; - (void)offset; - (void)size; -#endif /* defined XML_CONTEXT_BYTES */ - return (char *) 0; -} - -XML_Size XMLCALL -XML_GetCurrentLineNumber(XML_Parser parser) -{ - if (parser == NULL) - return 0; - if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { - XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position); - parser->m_positionPtr = parser->m_eventPtr; - } - return parser->m_position.lineNumber + 1; -} - -XML_Size XMLCALL -XML_GetCurrentColumnNumber(XML_Parser parser) -{ - if (parser == NULL) - return 0; - if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { - XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position); - parser->m_positionPtr = parser->m_eventPtr; - } - return parser->m_position.columnNumber; -} - -void XMLCALL -XML_FreeContentModel(XML_Parser parser, XML_Content *model) -{ - if (parser != NULL) - FREE(parser, model); -} - -void * XMLCALL -XML_MemMalloc(XML_Parser parser, size_t size) -{ - if (parser == NULL) - return NULL; - return MALLOC(parser, size); -} - -void * XMLCALL -XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) -{ - if (parser == NULL) - return NULL; - return REALLOC(parser, ptr, size); -} - -void XMLCALL -XML_MemFree(XML_Parser parser, void *ptr) -{ - if (parser != NULL) - FREE(parser, ptr); -} - -void XMLCALL -XML_DefaultCurrent(XML_Parser parser) -{ - if (parser == NULL) - return; - if (parser->m_defaultHandler) { - if (parser->m_openInternalEntities) - reportDefault(parser, - parser->m_internalEncoding, - parser->m_openInternalEntities->internalEventPtr, - parser->m_openInternalEntities->internalEventEndPtr); - else - reportDefault(parser, parser->m_encoding, parser->m_eventPtr, parser->m_eventEndPtr); - } -} - -const XML_LChar * XMLCALL -XML_ErrorString(enum XML_Error code) -{ - switch (code) { - case XML_ERROR_NONE: - return NULL; - case XML_ERROR_NO_MEMORY: - return XML_L("out of memory"); - case XML_ERROR_SYNTAX: - return XML_L("syntax error"); - case XML_ERROR_NO_ELEMENTS: - return XML_L("no element found"); - case XML_ERROR_INVALID_TOKEN: - return XML_L("not well-formed (invalid token)"); - case XML_ERROR_UNCLOSED_TOKEN: - return XML_L("unclosed token"); - case XML_ERROR_PARTIAL_CHAR: - return XML_L("partial character"); - case XML_ERROR_TAG_MISMATCH: - return XML_L("mismatched tag"); - case XML_ERROR_DUPLICATE_ATTRIBUTE: - return XML_L("duplicate attribute"); - case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: - return XML_L("junk after document element"); - case XML_ERROR_PARAM_ENTITY_REF: - return XML_L("illegal parameter entity reference"); - case XML_ERROR_UNDEFINED_ENTITY: - return XML_L("undefined entity"); - case XML_ERROR_RECURSIVE_ENTITY_REF: - return XML_L("recursive entity reference"); - case XML_ERROR_ASYNC_ENTITY: - return XML_L("asynchronous entity"); - case XML_ERROR_BAD_CHAR_REF: - return XML_L("reference to invalid character number"); - case XML_ERROR_BINARY_ENTITY_REF: - return XML_L("reference to binary entity"); - case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: - return XML_L("reference to external entity in attribute"); - case XML_ERROR_MISPLACED_XML_PI: - return XML_L("XML or text declaration not at start of entity"); - case XML_ERROR_UNKNOWN_ENCODING: - return XML_L("unknown encoding"); - case XML_ERROR_INCORRECT_ENCODING: - return XML_L("encoding specified in XML declaration is incorrect"); - case XML_ERROR_UNCLOSED_CDATA_SECTION: - return XML_L("unclosed CDATA section"); - case XML_ERROR_EXTERNAL_ENTITY_HANDLING: - return XML_L("error in processing external entity reference"); - case XML_ERROR_NOT_STANDALONE: - return XML_L("document is not standalone"); - case XML_ERROR_UNEXPECTED_STATE: - return XML_L("unexpected parser state - please send a bug report"); - case XML_ERROR_ENTITY_DECLARED_IN_PE: - return XML_L("entity declared in parameter entity"); - case XML_ERROR_FEATURE_REQUIRES_XML_DTD: - return XML_L("requested feature requires XML_DTD support in Expat"); - case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: - return XML_L("cannot change setting once parsing has begun"); - /* Added in 1.95.7. */ - case XML_ERROR_UNBOUND_PREFIX: - return XML_L("unbound prefix"); - /* Added in 1.95.8. */ - case XML_ERROR_UNDECLARING_PREFIX: - return XML_L("must not undeclare prefix"); - case XML_ERROR_INCOMPLETE_PE: - return XML_L("incomplete markup in parameter entity"); - case XML_ERROR_XML_DECL: - return XML_L("XML declaration not well-formed"); - case XML_ERROR_TEXT_DECL: - return XML_L("text declaration not well-formed"); - case XML_ERROR_PUBLICID: - return XML_L("illegal character(s) in public id"); - case XML_ERROR_SUSPENDED: - return XML_L("parser suspended"); - case XML_ERROR_NOT_SUSPENDED: - return XML_L("parser not suspended"); - case XML_ERROR_ABORTED: - return XML_L("parsing aborted"); - case XML_ERROR_FINISHED: - return XML_L("parsing finished"); - case XML_ERROR_SUSPEND_PE: - return XML_L("cannot suspend in external parameter entity"); - /* Added in 2.0.0. */ - case XML_ERROR_RESERVED_PREFIX_XML: - return XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"); - case XML_ERROR_RESERVED_PREFIX_XMLNS: - return XML_L("reserved prefix (xmlns) must not be declared or undeclared"); - case XML_ERROR_RESERVED_NAMESPACE_URI: - return XML_L("prefix must not be bound to one of the reserved namespace names"); - /* Added in 2.2.5. */ - case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */ - return XML_L("invalid argument"); - } - return NULL; -} - -const XML_LChar * XMLCALL -XML_ExpatVersion(void) { - - /* V1 is used to string-ize the version number. However, it would - string-ize the actual version macro *names* unless we get them - substituted before being passed to V1. CPP is defined to expand - a macro, then rescan for more expansions. Thus, we use V2 to expand - the version macros, then CPP will expand the resulting V1() macro - with the correct numerals. */ - /* ### I'm assuming cpp is portable in this respect... */ - -#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c) -#define V2(a,b,c) XML_L("expat_")V1(a,b,c) - - return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); - -#undef V1 -#undef V2 -} - -XML_Expat_Version XMLCALL -XML_ExpatVersionInfo(void) -{ - XML_Expat_Version version; - - version.major = XML_MAJOR_VERSION; - version.minor = XML_MINOR_VERSION; - version.micro = XML_MICRO_VERSION; - - return version; -} - -const XML_Feature * XMLCALL -XML_GetFeatureList(void) -{ - static const XML_Feature features[] = { - {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), - sizeof(XML_Char)}, - {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), - sizeof(XML_LChar)}, -#ifdef XML_UNICODE - {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0}, -#endif -#ifdef XML_UNICODE_WCHAR_T - {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0}, -#endif -#ifdef XML_DTD - {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, -#endif -#ifdef XML_CONTEXT_BYTES - {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), - XML_CONTEXT_BYTES}, -#endif -#ifdef XML_MIN_SIZE - {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0}, -#endif -#ifdef XML_NS - {XML_FEATURE_NS, XML_L("XML_NS"), 0}, -#endif -#ifdef XML_LARGE_SIZE - {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0}, -#endif -#ifdef XML_ATTR_INFO - {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0}, -#endif - {XML_FEATURE_END, NULL, 0} - }; - - return features; -} - -/* Initially tag->rawName always points into the parse buffer; - for those TAG instances opened while the current parse buffer was - processed, and not yet closed, we need to store tag->rawName in a more - permanent location, since the parse buffer is about to be discarded. -*/ -static XML_Bool -storeRawNames(XML_Parser parser) -{ - TAG *tag = parser->m_tagStack; - while (tag) { - int bufSize; - int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); - char *rawNameBuf = tag->buf + nameLen; - /* Stop if already stored. Since m_tagStack is a stack, we can stop - at the first entry that has already been copied; everything - below it in the stack is already been accounted for in a - previous call to this function. - */ - if (tag->rawName == rawNameBuf) - break; - /* For re-use purposes we need to ensure that the - size of tag->buf is a multiple of sizeof(XML_Char). - */ - bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); - if (bufSize > tag->bufEnd - tag->buf) { - char *temp = (char *)REALLOC(parser, tag->buf, bufSize); - if (temp == NULL) - return XML_FALSE; - /* if tag->name.str points to tag->buf (only when namespace - processing is off) then we have to update it - */ - if (tag->name.str == (XML_Char *)tag->buf) - tag->name.str = (XML_Char *)temp; - /* if tag->name.localPart is set (when namespace processing is on) - then update it as well, since it will always point into tag->buf - */ - if (tag->name.localPart) - tag->name.localPart = (XML_Char *)temp + (tag->name.localPart - - (XML_Char *)tag->buf); - tag->buf = temp; - tag->bufEnd = temp + bufSize; - rawNameBuf = temp + nameLen; - } - memcpy(rawNameBuf, tag->rawName, tag->rawNameLength); - tag->rawName = rawNameBuf; - tag = tag->parent; - } - return XML_TRUE; -} - -static enum XML_Error PTRCALL -contentProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - enum XML_Error result = doContent(parser, 0, parser->m_encoding, start, end, - endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); - if (result == XML_ERROR_NONE) { - if (!storeRawNames(parser)) - return XML_ERROR_NO_MEMORY; - } - return result; -} - -static enum XML_Error PTRCALL -externalEntityInitProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - enum XML_Error result = initializeEncoding(parser); - if (result != XML_ERROR_NONE) - return result; - parser->m_processor = externalEntityInitProcessor2; - return externalEntityInitProcessor2(parser, start, end, endPtr); -} - -static enum XML_Error PTRCALL -externalEntityInitProcessor2(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - const char *next = start; /* XmlContentTok doesn't always set the last arg */ - int tok = XmlContentTok(parser->m_encoding, start, end, &next); - switch (tok) { - case XML_TOK_BOM: - /* If we are at the end of the buffer, this would cause the next stage, - i.e. externalEntityInitProcessor3, to pass control directly to - doContent (by detecting XML_TOK_NONE) without processing any xml text - declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. - */ - if (next == end && !parser->m_parsingStatus.finalBuffer) { - *endPtr = next; - return XML_ERROR_NONE; - } - start = next; - break; - case XML_TOK_PARTIAL: - if (!parser->m_parsingStatus.finalBuffer) { - *endPtr = start; - return XML_ERROR_NONE; - } - parser->m_eventPtr = start; - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - if (!parser->m_parsingStatus.finalBuffer) { - *endPtr = start; - return XML_ERROR_NONE; - } - parser->m_eventPtr = start; - return XML_ERROR_PARTIAL_CHAR; - } - parser->m_processor = externalEntityInitProcessor3; - return externalEntityInitProcessor3(parser, start, end, endPtr); -} - -static enum XML_Error PTRCALL -externalEntityInitProcessor3(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - int tok; - const char *next = start; /* XmlContentTok doesn't always set the last arg */ - parser->m_eventPtr = start; - tok = XmlContentTok(parser->m_encoding, start, end, &next); - parser->m_eventEndPtr = next; - - switch (tok) { - case XML_TOK_XML_DECL: - { - enum XML_Error result; - result = processXmlDecl(parser, 1, start, next); - if (result != XML_ERROR_NONE) - return result; - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: - *endPtr = next; - return XML_ERROR_NONE; - case XML_FINISHED: - return XML_ERROR_ABORTED; - default: - start = next; - } - } - break; - case XML_TOK_PARTIAL: - if (!parser->m_parsingStatus.finalBuffer) { - *endPtr = start; - return XML_ERROR_NONE; - } - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - if (!parser->m_parsingStatus.finalBuffer) { - *endPtr = start; - return XML_ERROR_NONE; - } - return XML_ERROR_PARTIAL_CHAR; - } - parser->m_processor = externalEntityContentProcessor; - parser->m_tagLevel = 1; - return externalEntityContentProcessor(parser, start, end, endPtr); -} - -static enum XML_Error PTRCALL -externalEntityContentProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - enum XML_Error result = doContent(parser, 1, parser->m_encoding, start, end, - endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); - if (result == XML_ERROR_NONE) { - if (!storeRawNames(parser)) - return XML_ERROR_NO_MEMORY; - } - return result; -} - -static enum XML_Error -doContent(XML_Parser parser, - int startTagLevel, - const ENCODING *enc, - const char *s, - const char *end, - const char **nextPtr, - XML_Bool haveMore) -{ - /* save one level of indirection */ - DTD * const dtd = parser->m_dtd; - - const char **eventPP; - const char **eventEndPP; - if (enc == parser->m_encoding) { - eventPP = &parser->m_eventPtr; - eventEndPP = &parser->m_eventEndPtr; - } - else { - eventPP = &(parser->m_openInternalEntities->internalEventPtr); - eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); - } - *eventPP = s; - - for (;;) { - const char *next = s; /* XmlContentTok doesn't always set the last arg */ - int tok = XmlContentTok(enc, s, end, &next); - *eventEndPP = next; - switch (tok) { - case XML_TOK_TRAILING_CR: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - *eventEndPP = end; - if (parser->m_characterDataHandler) { - XML_Char c = 0xA; - parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); - } - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, end); - /* We are at the end of the final buffer, should we check for - XML_SUSPENDED, XML_FINISHED? - */ - if (startTagLevel == 0) - return XML_ERROR_NO_ELEMENTS; - if (parser->m_tagLevel != startTagLevel) - return XML_ERROR_ASYNC_ENTITY; - *nextPtr = end; - return XML_ERROR_NONE; - case XML_TOK_NONE: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - if (startTagLevel > 0) { - if (parser->m_tagLevel != startTagLevel) - return XML_ERROR_ASYNC_ENTITY; - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_NO_ELEMENTS; - case XML_TOK_INVALID: - *eventPP = next; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_ENTITY_REF: - { - const XML_Char *name; - ENTITY *entity; - XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (ch) { - if (parser->m_characterDataHandler) - parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1); - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - break; - } - name = poolStoreString(&dtd->pool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) - return XML_ERROR_NO_MEMORY; - entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); - poolDiscard(&dtd->pool); - /* First, determine if a check for an existing declaration is needed; - if yes, check that the entity exists, and that it is internal, - otherwise call the skipped entity or default handler. - */ - if (!dtd->hasParamEntityRefs || dtd->standalone) { - if (!entity) - return XML_ERROR_UNDEFINED_ENTITY; - else if (!entity->is_internal) - return XML_ERROR_ENTITY_DECLARED_IN_PE; - } - else if (!entity) { - if (parser->m_skippedEntityHandler) - parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - break; - } - if (entity->open) - return XML_ERROR_RECURSIVE_ENTITY_REF; - if (entity->notation) - return XML_ERROR_BINARY_ENTITY_REF; - if (entity->textPtr) { - enum XML_Error result; - if (!parser->m_defaultExpandInternalEntities) { - if (parser->m_skippedEntityHandler) - parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name, 0); - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - break; - } - result = processInternalEntity(parser, entity, XML_FALSE); - if (result != XML_ERROR_NONE) - return result; - } - else if (parser->m_externalEntityRefHandler) { - const XML_Char *context; - entity->open = XML_TRUE; - context = getContext(parser); - entity->open = XML_FALSE; - if (!context) - return XML_ERROR_NO_MEMORY; - if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, - context, - entity->base, - entity->systemId, - entity->publicId)) - return XML_ERROR_EXTERNAL_ENTITY_HANDLING; - poolDiscard(&parser->m_tempPool); - } - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - break; - } - case XML_TOK_START_TAG_NO_ATTS: - /* fall through */ - case XML_TOK_START_TAG_WITH_ATTS: - { - TAG *tag; - enum XML_Error result; - XML_Char *toPtr; - if (parser->m_freeTagList) { - tag = parser->m_freeTagList; - parser->m_freeTagList = parser->m_freeTagList->parent; - } - else { - tag = (TAG *)MALLOC(parser, sizeof(TAG)); - if (!tag) - return XML_ERROR_NO_MEMORY; - tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE); - if (!tag->buf) { - FREE(parser, tag); - return XML_ERROR_NO_MEMORY; - } - tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; - } - tag->bindings = NULL; - tag->parent = parser->m_tagStack; - parser->m_tagStack = tag; - tag->name.localPart = NULL; - tag->name.prefix = NULL; - tag->rawName = s + enc->minBytesPerChar; - tag->rawNameLength = XmlNameLength(enc, tag->rawName); - ++parser->m_tagLevel; - { - const char *rawNameEnd = tag->rawName + tag->rawNameLength; - const char *fromPtr = tag->rawName; - toPtr = (XML_Char *)tag->buf; - for (;;) { - int bufSize; - int convLen; - const enum XML_Convert_Result convert_res = XmlConvert(enc, - &fromPtr, rawNameEnd, - (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); - convLen = (int)(toPtr - (XML_Char *)tag->buf); - if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { - tag->name.strLen = convLen; - break; - } - bufSize = (int)(tag->bufEnd - tag->buf) << 1; - { - char *temp = (char *)REALLOC(parser, tag->buf, bufSize); - if (temp == NULL) - return XML_ERROR_NO_MEMORY; - tag->buf = temp; - tag->bufEnd = temp + bufSize; - toPtr = (XML_Char *)temp + convLen; - } - } - } - tag->name.str = (XML_Char *)tag->buf; - *toPtr = XML_T('\0'); - result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); - if (result) - return result; - if (parser->m_startElementHandler) - parser->m_startElementHandler(parser->m_handlerArg, tag->name.str, - (const XML_Char **)parser->m_atts); - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - poolClear(&parser->m_tempPool); - break; - } - case XML_TOK_EMPTY_ELEMENT_NO_ATTS: - /* fall through */ - case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: - { - const char *rawName = s + enc->minBytesPerChar; - enum XML_Error result; - BINDING *bindings = NULL; - XML_Bool noElmHandlers = XML_TRUE; - TAG_NAME name; - name.str = poolStoreString(&parser->m_tempPool, enc, rawName, - rawName + XmlNameLength(enc, rawName)); - if (!name.str) - return XML_ERROR_NO_MEMORY; - poolFinish(&parser->m_tempPool); - result = storeAtts(parser, enc, s, &name, &bindings); - if (result != XML_ERROR_NONE) { - freeBindings(parser, bindings); - return result; - } - poolFinish(&parser->m_tempPool); - if (parser->m_startElementHandler) { - parser->m_startElementHandler(parser->m_handlerArg, name.str, (const XML_Char **)parser->m_atts); - noElmHandlers = XML_FALSE; - } - if (parser->m_endElementHandler) { - if (parser->m_startElementHandler) - *eventPP = *eventEndPP; - parser->m_endElementHandler(parser->m_handlerArg, name.str); - noElmHandlers = XML_FALSE; - } - if (noElmHandlers && parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - poolClear(&parser->m_tempPool); - freeBindings(parser, bindings); - } - if ((parser->m_tagLevel == 0) && - !((parser->m_parsingStatus.parsing == XML_FINISHED) || (parser->m_parsingStatus.parsing == XML_SUSPENDED))) { - return epilogProcessor(parser, next, end, nextPtr); - } - break; - case XML_TOK_END_TAG: - if (parser->m_tagLevel == startTagLevel) - return XML_ERROR_ASYNC_ENTITY; - else { - int len; - const char *rawName; - TAG *tag = parser->m_tagStack; - parser->m_tagStack = tag->parent; - tag->parent = parser->m_freeTagList; - parser->m_freeTagList = tag; - rawName = s + enc->minBytesPerChar*2; - len = XmlNameLength(enc, rawName); - if (len != tag->rawNameLength - || memcmp(tag->rawName, rawName, len) != 0) { - *eventPP = rawName; - return XML_ERROR_TAG_MISMATCH; - } - --parser->m_tagLevel; - if (parser->m_endElementHandler) { - const XML_Char *localPart; - const XML_Char *prefix; - XML_Char *uri; - localPart = tag->name.localPart; - if (parser->m_ns && localPart) { - /* localPart and prefix may have been overwritten in - tag->name.str, since this points to the binding->uri - buffer which gets re-used; so we have to add them again - */ - uri = (XML_Char *)tag->name.str + tag->name.uriLen; - /* don't need to check for space - already done in storeAtts() */ - while (*localPart) *uri++ = *localPart++; - prefix = (XML_Char *)tag->name.prefix; - if (parser->m_ns_triplets && prefix) { - *uri++ = parser->m_namespaceSeparator; - while (*prefix) *uri++ = *prefix++; - } - *uri = XML_T('\0'); - } - parser->m_endElementHandler(parser->m_handlerArg, tag->name.str); - } - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - while (tag->bindings) { - BINDING *b = tag->bindings; - if (parser->m_endNamespaceDeclHandler) - parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); - tag->bindings = tag->bindings->nextTagBinding; - b->nextTagBinding = parser->m_freeBindingList; - parser->m_freeBindingList = b; - b->prefix->binding = b->prevPrefixBinding; - } - if (parser->m_tagLevel == 0) - return epilogProcessor(parser, next, end, nextPtr); - } - break; - case XML_TOK_CHAR_REF: - { - int n = XmlCharRefNumber(enc, s); - if (n < 0) - return XML_ERROR_BAD_CHAR_REF; - if (parser->m_characterDataHandler) { - XML_Char buf[XML_ENCODE_MAX]; - parser->m_characterDataHandler(parser->m_handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); - } - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - } - break; - case XML_TOK_XML_DECL: - return XML_ERROR_MISPLACED_XML_PI; - case XML_TOK_DATA_NEWLINE: - if (parser->m_characterDataHandler) { - XML_Char c = 0xA; - parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); - } - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - break; - case XML_TOK_CDATA_SECT_OPEN: - { - enum XML_Error result; - if (parser->m_startCdataSectionHandler) - parser->m_startCdataSectionHandler(parser->m_handlerArg); -#if 0 - /* Suppose you doing a transformation on a document that involves - changing only the character data. You set up a defaultHandler - and a characterDataHandler. The defaultHandler simply copies - characters through. The characterDataHandler does the - transformation and writes the characters out escaping them as - necessary. This case will fail to work if we leave out the - following two lines (because & and < inside CDATA sections will - be incorrectly escaped). - - However, now we have a start/endCdataSectionHandler, so it seems - easier to let the user deal with this. - */ - else if (parser->m_characterDataHandler) - parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0); -#endif - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore); - if (result != XML_ERROR_NONE) - return result; - else if (!next) { - parser->m_processor = cdataSectionProcessor; - return result; - } - } - break; - case XML_TOK_TRAILING_RSQB: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - if (parser->m_characterDataHandler) { - if (MUST_CONVERT(enc, s)) { - ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; - XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); - parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, - (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); - } - else - parser->m_characterDataHandler(parser->m_handlerArg, - (XML_Char *)s, - (int)((XML_Char *)end - (XML_Char *)s)); - } - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, end); - /* We are at the end of the final buffer, should we check for - XML_SUSPENDED, XML_FINISHED? - */ - if (startTagLevel == 0) { - *eventPP = end; - return XML_ERROR_NO_ELEMENTS; - } - if (parser->m_tagLevel != startTagLevel) { - *eventPP = end; - return XML_ERROR_ASYNC_ENTITY; - } - *nextPtr = end; - return XML_ERROR_NONE; - case XML_TOK_DATA_CHARS: - { - XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; - if (charDataHandler) { - if (MUST_CONVERT(enc, s)) { - for (;;) { - ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; - const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); - *eventEndPP = s; - charDataHandler(parser->m_handlerArg, parser->m_dataBuf, - (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); - if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) - break; - *eventPP = s; - } - } - else - charDataHandler(parser->m_handlerArg, - (XML_Char *)s, - (int)((XML_Char *)next - (XML_Char *)s)); - } - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - } - break; - case XML_TOK_PI: - if (!reportProcessingInstruction(parser, enc, s, next)) - return XML_ERROR_NO_MEMORY; - break; - case XML_TOK_COMMENT: - if (!reportComment(parser, enc, s, next)) - return XML_ERROR_NO_MEMORY; - break; - default: - /* All of the tokens produced by XmlContentTok() have their own - * explicit cases, so this default is not strictly necessary. - * However it is a useful safety net, so we retain the code and - * simply exclude it from the coverage tests. - * - * LCOV_EXCL_START - */ - if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - break; - /* LCOV_EXCL_STOP */ - } - *eventPP = s = next; - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: - *nextPtr = next; - return XML_ERROR_NONE; - case XML_FINISHED: - return XML_ERROR_ABORTED; - default: ; - } - } - /* not reached */ -} - -/* This function does not call free() on the allocated memory, merely - * moving it to the parser's m_freeBindingList where it can be freed or - * reused as appropriate. - */ -static void -freeBindings(XML_Parser parser, BINDING *bindings) -{ - while (bindings) { - BINDING *b = bindings; - - /* m_startNamespaceDeclHandler will have been called for this - * binding in addBindings(), so call the end handler now. - */ - if (parser->m_endNamespaceDeclHandler) - parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); - - bindings = bindings->nextTagBinding; - b->nextTagBinding = parser->m_freeBindingList; - parser->m_freeBindingList = b; - b->prefix->binding = b->prevPrefixBinding; - } -} - -/* Precondition: all arguments must be non-NULL; - Purpose: - - normalize attributes - - check attributes for well-formedness - - generate namespace aware attribute names (URI, prefix) - - build list of attributes for startElementHandler - - default attributes - - process namespace declarations (check and report them) - - generate namespace aware element name (URI, prefix) -*/ -static enum XML_Error -storeAtts(XML_Parser parser, const ENCODING *enc, - const char *attStr, TAG_NAME *tagNamePtr, - BINDING **bindingsPtr) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ - ELEMENT_TYPE *elementType; - int nDefaultAtts; - const XML_Char **appAtts; /* the attribute list for the application */ - int attIndex = 0; - int prefixLen; - int i; - int n; - XML_Char *uri; - int nPrefixes = 0; - BINDING *binding; - const XML_Char *localPart; - - /* lookup the element type name */ - elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0); - if (!elementType) { - const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); - if (!name) - return XML_ERROR_NO_MEMORY; - elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, - sizeof(ELEMENT_TYPE)); - if (!elementType) - return XML_ERROR_NO_MEMORY; - if (parser->m_ns && !setElementTypePrefix(parser, elementType)) - return XML_ERROR_NO_MEMORY; - } - nDefaultAtts = elementType->nDefaultAtts; - - /* get the attributes from the tokenizer */ - n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts); - if (n + nDefaultAtts > parser->m_attsSize) { - int oldAttsSize = parser->m_attsSize; - ATTRIBUTE *temp; -#ifdef XML_ATTR_INFO - XML_AttrInfo *temp2; -#endif - parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; - temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, parser->m_attsSize * sizeof(ATTRIBUTE)); - if (temp == NULL) { - parser->m_attsSize = oldAttsSize; - return XML_ERROR_NO_MEMORY; - } - parser->m_atts = temp; -#ifdef XML_ATTR_INFO - temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo)); - if (temp2 == NULL) { - parser->m_attsSize = oldAttsSize; - return XML_ERROR_NO_MEMORY; - } - parser->m_attInfo = temp2; -#endif - if (n > oldAttsSize) - XmlGetAttributes(enc, attStr, n, parser->m_atts); - } - - appAtts = (const XML_Char **)parser->m_atts; - for (i = 0; i < n; i++) { - ATTRIBUTE *currAtt = &parser->m_atts[i]; -#ifdef XML_ATTR_INFO - XML_AttrInfo *currAttInfo = &parser->m_attInfo[i]; -#endif - /* add the name and value to the attribute list */ - ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name, - currAtt->name - + XmlNameLength(enc, currAtt->name)); - if (!attId) - return XML_ERROR_NO_MEMORY; -#ifdef XML_ATTR_INFO - currAttInfo->nameStart = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name); - currAttInfo->nameEnd = currAttInfo->nameStart + - XmlNameLength(enc, currAtt->name); - currAttInfo->valueStart = parser->m_parseEndByteIndex - - (parser->m_parseEndPtr - currAtt->valuePtr); - currAttInfo->valueEnd = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->valueEnd); -#endif - /* Detect duplicate attributes by their QNames. This does not work when - namespace processing is turned on and different prefixes for the same - namespace are used. For this case we have a check further down. - */ - if ((attId->name)[-1]) { - if (enc == parser->m_encoding) - parser->m_eventPtr = parser->m_atts[i].name; - return XML_ERROR_DUPLICATE_ATTRIBUTE; - } - (attId->name)[-1] = 1; - appAtts[attIndex++] = attId->name; - if (!parser->m_atts[i].normalized) { - enum XML_Error result; - XML_Bool isCdata = XML_TRUE; - - /* figure out whether declared as other than CDATA */ - if (attId->maybeTokenized) { - int j; - for (j = 0; j < nDefaultAtts; j++) { - if (attId == elementType->defaultAtts[j].id) { - isCdata = elementType->defaultAtts[j].isCdata; - break; - } - } - } - - /* normalize the attribute value */ - result = storeAttributeValue(parser, enc, isCdata, - parser->m_atts[i].valuePtr, parser->m_atts[i].valueEnd, - &parser->m_tempPool); - if (result) - return result; - appAtts[attIndex] = poolStart(&parser->m_tempPool); - poolFinish(&parser->m_tempPool); - } - else { - /* the value did not need normalizing */ - appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, parser->m_atts[i].valuePtr, - parser->m_atts[i].valueEnd); - if (appAtts[attIndex] == 0) - return XML_ERROR_NO_MEMORY; - poolFinish(&parser->m_tempPool); - } - /* handle prefixed attribute names */ - if (attId->prefix) { - if (attId->xmlns) { - /* deal with namespace declarations here */ - enum XML_Error result = addBinding(parser, attId->prefix, attId, - appAtts[attIndex], bindingsPtr); - if (result) - return result; - --attIndex; - } - else { - /* deal with other prefixed names later */ - attIndex++; - nPrefixes++; - (attId->name)[-1] = 2; - } - } - else - attIndex++; - } - - /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ - parser->m_nSpecifiedAtts = attIndex; - if (elementType->idAtt && (elementType->idAtt->name)[-1]) { - for (i = 0; i < attIndex; i += 2) - if (appAtts[i] == elementType->idAtt->name) { - parser->m_idAttIndex = i; - break; - } - } - else - parser->m_idAttIndex = -1; - - /* do attribute defaulting */ - for (i = 0; i < nDefaultAtts; i++) { - const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i; - if (!(da->id->name)[-1] && da->value) { - if (da->id->prefix) { - if (da->id->xmlns) { - enum XML_Error result = addBinding(parser, da->id->prefix, da->id, - da->value, bindingsPtr); - if (result) - return result; - } - else { - (da->id->name)[-1] = 2; - nPrefixes++; - appAtts[attIndex++] = da->id->name; - appAtts[attIndex++] = da->value; - } - } - else { - (da->id->name)[-1] = 1; - appAtts[attIndex++] = da->id->name; - appAtts[attIndex++] = da->value; - } - } - } - appAtts[attIndex] = 0; - - /* expand prefixed attribute names, check for duplicates, - and clear flags that say whether attributes were specified */ - i = 0; - if (nPrefixes) { - int j; /* hash table index */ - unsigned long version = parser->m_nsAttsVersion; - int nsAttsSize = (int)1 << parser->m_nsAttsPower; - unsigned char oldNsAttsPower = parser->m_nsAttsPower; - /* size of hash table must be at least 2 * (# of prefixed attributes) */ - if ((nPrefixes << 1) >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */ - NS_ATT *temp; - /* hash table size must also be a power of 2 and >= 8 */ - while (nPrefixes >> parser->m_nsAttsPower++); - if (parser->m_nsAttsPower < 3) - parser->m_nsAttsPower = 3; - nsAttsSize = (int)1 << parser->m_nsAttsPower; - temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT)); - if (!temp) { - /* Restore actual size of memory in m_nsAtts */ - parser->m_nsAttsPower = oldNsAttsPower; - return XML_ERROR_NO_MEMORY; - } - parser->m_nsAtts = temp; - version = 0; /* force re-initialization of m_nsAtts hash table */ - } - /* using a version flag saves us from initializing m_nsAtts every time */ - if (!version) { /* initialize version flags when version wraps around */ - version = INIT_ATTS_VERSION; - for (j = nsAttsSize; j != 0; ) - parser->m_nsAtts[--j].version = version; - } - parser->m_nsAttsVersion = --version; - - /* expand prefixed names and check for duplicates */ - for (; i < attIndex; i += 2) { - const XML_Char *s = appAtts[i]; - if (s[-1] == 2) { /* prefixed */ - ATTRIBUTE_ID *id; - const BINDING *b; - unsigned long uriHash; - struct siphash sip_state; - struct sipkey sip_key; - - copy_salt_to_sipkey(parser, &sip_key); - sip24_init(&sip_state, &sip_key); - - ((XML_Char *)s)[-1] = 0; /* clear flag */ - id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0); - if (!id || !id->prefix) { - /* This code is walking through the appAtts array, dealing - * with (in this case) a prefixed attribute name. To be in - * the array, the attribute must have already been bound, so - * has to have passed through the hash table lookup once - * already. That implies that an entry for it already - * exists, so the lookup above will return a pointer to - * already allocated memory. There is no opportunaity for - * the allocator to fail, so the condition above cannot be - * fulfilled. - * - * Since it is difficult to be certain that the above - * analysis is complete, we retain the test and merely - * remove the code from coverage tests. - */ - return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ - } - b = id->prefix->binding; - if (!b) - return XML_ERROR_UNBOUND_PREFIX; - - for (j = 0; j < b->uriLen; j++) { - const XML_Char c = b->uri[j]; - if (!poolAppendChar(&parser->m_tempPool, c)) - return XML_ERROR_NO_MEMORY; - } - - sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char)); - - while (*s++ != XML_T(ASCII_COLON)) - ; - - sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char)); - - do { /* copies null terminator */ - if (!poolAppendChar(&parser->m_tempPool, *s)) - return XML_ERROR_NO_MEMORY; - } while (*s++); - - uriHash = (unsigned long)sip24_final(&sip_state); - - { /* Check hash table for duplicate of expanded name (uriName). - Derived from code in lookup(parser, HASH_TABLE *table, ...). - */ - unsigned char step = 0; - unsigned long mask = nsAttsSize - 1; - j = uriHash & mask; /* index into hash table */ - while (parser->m_nsAtts[j].version == version) { - /* for speed we compare stored hash values first */ - if (uriHash == parser->m_nsAtts[j].hash) { - const XML_Char *s1 = poolStart(&parser->m_tempPool); - const XML_Char *s2 = parser->m_nsAtts[j].uriName; - /* s1 is null terminated, but not s2 */ - for (; *s1 == *s2 && *s1 != 0; s1++, s2++); - if (*s1 == 0) - return XML_ERROR_DUPLICATE_ATTRIBUTE; - } - if (!step) - step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower); - j < step ? (j += nsAttsSize - step) : (j -= step); - } - } - - if (parser->m_ns_triplets) { /* append namespace separator and prefix */ - parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator; - s = b->prefix->name; - do { - if (!poolAppendChar(&parser->m_tempPool, *s)) - return XML_ERROR_NO_MEMORY; - } while (*s++); - } - - /* store expanded name in attribute list */ - s = poolStart(&parser->m_tempPool); - poolFinish(&parser->m_tempPool); - appAtts[i] = s; - - /* fill empty slot with new version, uriName and hash value */ - parser->m_nsAtts[j].version = version; - parser->m_nsAtts[j].hash = uriHash; - parser->m_nsAtts[j].uriName = s; - - if (!--nPrefixes) { - i += 2; - break; - } - } - else /* not prefixed */ - ((XML_Char *)s)[-1] = 0; /* clear flag */ - } - } - /* clear flags for the remaining attributes */ - for (; i < attIndex; i += 2) - ((XML_Char *)(appAtts[i]))[-1] = 0; - for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) - binding->attId->name[-1] = 0; - - if (!parser->m_ns) - return XML_ERROR_NONE; - - /* expand the element type name */ - if (elementType->prefix) { - binding = elementType->prefix->binding; - if (!binding) - return XML_ERROR_UNBOUND_PREFIX; - localPart = tagNamePtr->str; - while (*localPart++ != XML_T(ASCII_COLON)) - ; - } - else if (dtd->defaultPrefix.binding) { - binding = dtd->defaultPrefix.binding; - localPart = tagNamePtr->str; - } - else - return XML_ERROR_NONE; - prefixLen = 0; - if (parser->m_ns_triplets && binding->prefix->name) { - for (; binding->prefix->name[prefixLen++];) - ; /* prefixLen includes null terminator */ - } - tagNamePtr->localPart = localPart; - tagNamePtr->uriLen = binding->uriLen; - tagNamePtr->prefix = binding->prefix->name; - tagNamePtr->prefixLen = prefixLen; - for (i = 0; localPart[i++];) - ; /* i includes null terminator */ - n = i + binding->uriLen + prefixLen; - if (n > binding->uriAlloc) { - TAG *p; - uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char)); - if (!uri) - return XML_ERROR_NO_MEMORY; - binding->uriAlloc = n + EXPAND_SPARE; - memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); - for (p = parser->m_tagStack; p; p = p->parent) - if (p->name.str == binding->uri) - p->name.str = uri; - FREE(parser, binding->uri); - binding->uri = uri; - } - /* if m_namespaceSeparator != '\0' then uri includes it already */ - uri = binding->uri + binding->uriLen; - memcpy(uri, localPart, i * sizeof(XML_Char)); - /* we always have a namespace separator between localPart and prefix */ - if (prefixLen) { - uri += i - 1; - *uri = parser->m_namespaceSeparator; /* replace null terminator */ - memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); - } - tagNamePtr->str = binding->uri; - return XML_ERROR_NONE; -} - -/* addBinding() overwrites the value of prefix->binding without checking. - Therefore one must keep track of the old value outside of addBinding(). -*/ -static enum XML_Error -addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, - const XML_Char *uri, BINDING **bindingsPtr) -{ - static const XML_Char xmlNamespace[] = { - ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, - ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, - ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, - ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH, - ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, - ASCII_e, '\0' - }; - static const int xmlLen = - (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1; - static const XML_Char xmlnsNamespace[] = { - ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, - ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, - ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0, - ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s, - ASCII_SLASH, '\0' - }; - static const int xmlnsLen = - (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1; - - XML_Bool mustBeXML = XML_FALSE; - XML_Bool isXML = XML_TRUE; - XML_Bool isXMLNS = XML_TRUE; - - BINDING *b; - int len; - - /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */ - if (*uri == XML_T('\0') && prefix->name) - return XML_ERROR_UNDECLARING_PREFIX; - - if (prefix->name - && prefix->name[0] == XML_T(ASCII_x) - && prefix->name[1] == XML_T(ASCII_m) - && prefix->name[2] == XML_T(ASCII_l)) { - - /* Not allowed to bind xmlns */ - if (prefix->name[3] == XML_T(ASCII_n) - && prefix->name[4] == XML_T(ASCII_s) - && prefix->name[5] == XML_T('\0')) - return XML_ERROR_RESERVED_PREFIX_XMLNS; - - if (prefix->name[3] == XML_T('\0')) - mustBeXML = XML_TRUE; - } - - for (len = 0; uri[len]; len++) { - if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len])) - isXML = XML_FALSE; - - if (!mustBeXML && isXMLNS - && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) - isXMLNS = XML_FALSE; - } - isXML = isXML && len == xmlLen; - isXMLNS = isXMLNS && len == xmlnsLen; - - if (mustBeXML != isXML) - return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML - : XML_ERROR_RESERVED_NAMESPACE_URI; - - if (isXMLNS) - return XML_ERROR_RESERVED_NAMESPACE_URI; - - if (parser->m_namespaceSeparator) - len++; - if (parser->m_freeBindingList) { - b = parser->m_freeBindingList; - if (len > b->uriAlloc) { - XML_Char *temp = (XML_Char *)REALLOC(parser, b->uri, - sizeof(XML_Char) * (len + EXPAND_SPARE)); - if (temp == NULL) - return XML_ERROR_NO_MEMORY; - b->uri = temp; - b->uriAlloc = len + EXPAND_SPARE; - } - parser->m_freeBindingList = b->nextTagBinding; - } - else { - b = (BINDING *)MALLOC(parser, sizeof(BINDING)); - if (!b) - return XML_ERROR_NO_MEMORY; - b->uri = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE)); - if (!b->uri) { - FREE(parser, b); - return XML_ERROR_NO_MEMORY; - } - b->uriAlloc = len + EXPAND_SPARE; - } - b->uriLen = len; - memcpy(b->uri, uri, len * sizeof(XML_Char)); - if (parser->m_namespaceSeparator) - b->uri[len - 1] = parser->m_namespaceSeparator; - b->prefix = prefix; - b->attId = attId; - b->prevPrefixBinding = prefix->binding; - /* NULL binding when default namespace undeclared */ - if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix) - prefix->binding = NULL; - else - prefix->binding = b; - b->nextTagBinding = *bindingsPtr; - *bindingsPtr = b; - /* if attId == NULL then we are not starting a namespace scope */ - if (attId && parser->m_startNamespaceDeclHandler) - parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name, - prefix->binding ? uri : 0); - return XML_ERROR_NONE; -} - -/* The idea here is to avoid using stack for each CDATA section when - the whole file is parsed with one call. -*/ -static enum XML_Error PTRCALL -cdataSectionProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - enum XML_Error result = doCdataSection(parser, parser->m_encoding, &start, end, - endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); - if (result != XML_ERROR_NONE) - return result; - if (start) { - if (parser->m_parentParser) { /* we are parsing an external entity */ - parser->m_processor = externalEntityContentProcessor; - return externalEntityContentProcessor(parser, start, end, endPtr); - } - else { - parser->m_processor = contentProcessor; - return contentProcessor(parser, start, end, endPtr); - } - } - return result; -} - -/* startPtr gets set to non-null if the section is closed, and to null if - the section is not yet closed. -*/ -static enum XML_Error -doCdataSection(XML_Parser parser, - const ENCODING *enc, - const char **startPtr, - const char *end, - const char **nextPtr, - XML_Bool haveMore) -{ - const char *s = *startPtr; - const char **eventPP; - const char **eventEndPP; - if (enc == parser->m_encoding) { - eventPP = &parser->m_eventPtr; - *eventPP = s; - eventEndPP = &parser->m_eventEndPtr; - } - else { - eventPP = &(parser->m_openInternalEntities->internalEventPtr); - eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); - } - *eventPP = s; - *startPtr = NULL; - - for (;;) { - const char *next; - int tok = XmlCdataSectionTok(enc, s, end, &next); - *eventEndPP = next; - switch (tok) { - case XML_TOK_CDATA_SECT_CLOSE: - if (parser->m_endCdataSectionHandler) - parser->m_endCdataSectionHandler(parser->m_handlerArg); -#if 0 - /* see comment under XML_TOK_CDATA_SECT_OPEN */ - else if (parser->m_characterDataHandler) - parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0); -#endif - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - *startPtr = next; - *nextPtr = next; - if (parser->m_parsingStatus.parsing == XML_FINISHED) - return XML_ERROR_ABORTED; - else - return XML_ERROR_NONE; - case XML_TOK_DATA_NEWLINE: - if (parser->m_characterDataHandler) { - XML_Char c = 0xA; - parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); - } - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - break; - case XML_TOK_DATA_CHARS: - { - XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; - if (charDataHandler) { - if (MUST_CONVERT(enc, s)) { - for (;;) { - ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; - const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); - *eventEndPP = next; - charDataHandler(parser->m_handlerArg, parser->m_dataBuf, - (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); - if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) - break; - *eventPP = s; - } - } - else - charDataHandler(parser->m_handlerArg, - (XML_Char *)s, - (int)((XML_Char *)next - (XML_Char *)s)); - } - else if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - } - break; - case XML_TOK_INVALID: - *eventPP = next; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL_CHAR: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_PARTIAL: - case XML_TOK_NONE: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_UNCLOSED_CDATA_SECTION; - default: - /* Every token returned by XmlCdataSectionTok() has its own - * explicit case, so this default case will never be executed. - * We retain it as a safety net and exclude it from the coverage - * statistics. - * - * LCOV_EXCL_START - */ - *eventPP = next; - return XML_ERROR_UNEXPECTED_STATE; - /* LCOV_EXCL_STOP */ - } - - *eventPP = s = next; - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: - *nextPtr = next; - return XML_ERROR_NONE; - case XML_FINISHED: - return XML_ERROR_ABORTED; - default: ; - } - } - /* not reached */ -} - -#ifdef XML_DTD - -/* The idea here is to avoid using stack for each IGNORE section when - the whole file is parsed with one call. -*/ -static enum XML_Error PTRCALL -ignoreSectionProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - enum XML_Error result = doIgnoreSection(parser, parser->m_encoding, &start, end, - endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); - if (result != XML_ERROR_NONE) - return result; - if (start) { - parser->m_processor = prologProcessor; - return prologProcessor(parser, start, end, endPtr); - } - return result; -} - -/* startPtr gets set to non-null is the section is closed, and to null - if the section is not yet closed. -*/ -static enum XML_Error -doIgnoreSection(XML_Parser parser, - const ENCODING *enc, - const char **startPtr, - const char *end, - const char **nextPtr, - XML_Bool haveMore) -{ - const char *next; - int tok; - const char *s = *startPtr; - const char **eventPP; - const char **eventEndPP; - if (enc == parser->m_encoding) { - eventPP = &parser->m_eventPtr; - *eventPP = s; - eventEndPP = &parser->m_eventEndPtr; - } - else { - /* It's not entirely clear, but it seems the following two lines - * of code cannot be executed. The only occasions on which 'enc' - * is not 'encoding' are when this function is called - * from the internal entity processing, and IGNORE sections are an - * error in internal entities. - * - * Since it really isn't clear that this is true, we keep the code - * and just remove it from our coverage tests. - * - * LCOV_EXCL_START - */ - eventPP = &(parser->m_openInternalEntities->internalEventPtr); - eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); - /* LCOV_EXCL_STOP */ - } - *eventPP = s; - *startPtr = NULL; - tok = XmlIgnoreSectionTok(enc, s, end, &next); - *eventEndPP = next; - switch (tok) { - case XML_TOK_IGNORE_SECT: - if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - *startPtr = next; - *nextPtr = next; - if (parser->m_parsingStatus.parsing == XML_FINISHED) - return XML_ERROR_ABORTED; - else - return XML_ERROR_NONE; - case XML_TOK_INVALID: - *eventPP = next; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL_CHAR: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_PARTIAL: - case XML_TOK_NONE: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ - default: - /* All of the tokens that XmlIgnoreSectionTok() returns have - * explicit cases to handle them, so this default case is never - * executed. We keep it as a safety net anyway, and remove it - * from our test coverage statistics. - * - * LCOV_EXCL_START - */ - *eventPP = next; - return XML_ERROR_UNEXPECTED_STATE; - /* LCOV_EXCL_STOP */ - } - /* not reached */ -} - -#endif /* XML_DTD */ - -static enum XML_Error -initializeEncoding(XML_Parser parser) -{ - const char *s; -#ifdef XML_UNICODE - char encodingBuf[128]; - /* See comments abount `protoclEncodingName` in parserInit() */ - if (!parser->m_protocolEncodingName) - s = NULL; - else { - int i; - for (i = 0; parser->m_protocolEncodingName[i]; i++) { - if (i == sizeof(encodingBuf) - 1 - || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) { - encodingBuf[0] = '\0'; - break; - } - encodingBuf[i] = (char)parser->m_protocolEncodingName[i]; - } - encodingBuf[i] = '\0'; - s = encodingBuf; - } -#else - s = parser->m_protocolEncodingName; -#endif - if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(&parser->m_initEncoding, &parser->m_encoding, s)) - return XML_ERROR_NONE; - return handleUnknownEncoding(parser, parser->m_protocolEncodingName); -} - -static enum XML_Error -processXmlDecl(XML_Parser parser, int isGeneralTextEntity, - const char *s, const char *next) -{ - const char *encodingName = NULL; - const XML_Char *storedEncName = NULL; - const ENCODING *newEncoding = NULL; - const char *version = NULL; - const char *versionend; - const XML_Char *storedversion = NULL; - int standalone = -1; - if (!(parser->m_ns - ? XmlParseXmlDeclNS - : XmlParseXmlDecl)(isGeneralTextEntity, - parser->m_encoding, - s, - next, - &parser->m_eventPtr, - &version, - &versionend, - &encodingName, - &newEncoding, - &standalone)) { - if (isGeneralTextEntity) - return XML_ERROR_TEXT_DECL; - else - return XML_ERROR_XML_DECL; - } - if (!isGeneralTextEntity && standalone == 1) { - parser->m_dtd->standalone = XML_TRUE; -#ifdef XML_DTD - if (parser->m_paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) - parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; -#endif /* XML_DTD */ - } - if (parser->m_xmlDeclHandler) { - if (encodingName != NULL) { - storedEncName = poolStoreString(&parser->m_temp2Pool, - parser->m_encoding, - encodingName, - encodingName - + XmlNameLength(parser->m_encoding, encodingName)); - if (!storedEncName) - return XML_ERROR_NO_MEMORY; - poolFinish(&parser->m_temp2Pool); - } - if (version) { - storedversion = poolStoreString(&parser->m_temp2Pool, - parser->m_encoding, - version, - versionend - parser->m_encoding->minBytesPerChar); - if (!storedversion) - return XML_ERROR_NO_MEMORY; - } - parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName, standalone); - } - else if (parser->m_defaultHandler) - reportDefault(parser, parser->m_encoding, s, next); - if (parser->m_protocolEncodingName == NULL) { - if (newEncoding) { - /* Check that the specified encoding does not conflict with what - * the parser has already deduced. Do we have the same number - * of bytes in the smallest representation of a character? If - * this is UTF-16, is it the same endianness? - */ - if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar - || (newEncoding->minBytesPerChar == 2 && - newEncoding != parser->m_encoding)) { - parser->m_eventPtr = encodingName; - return XML_ERROR_INCORRECT_ENCODING; - } - parser->m_encoding = newEncoding; - } - else if (encodingName) { - enum XML_Error result; - if (!storedEncName) { - storedEncName = poolStoreString( - &parser->m_temp2Pool, parser->m_encoding, encodingName, - encodingName + XmlNameLength(parser->m_encoding, encodingName)); - if (!storedEncName) - return XML_ERROR_NO_MEMORY; - } - result = handleUnknownEncoding(parser, storedEncName); - poolClear(&parser->m_temp2Pool); - if (result == XML_ERROR_UNKNOWN_ENCODING) - parser->m_eventPtr = encodingName; - return result; - } - } - - if (storedEncName || storedversion) - poolClear(&parser->m_temp2Pool); - - return XML_ERROR_NONE; -} - -static enum XML_Error -handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) -{ - if (parser->m_unknownEncodingHandler) { - XML_Encoding info; - int i; - for (i = 0; i < 256; i++) - info.map[i] = -1; - info.convert = NULL; - info.data = NULL; - info.release = NULL; - if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData, encodingName, - &info)) { - ENCODING *enc; - parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding()); - if (!parser->m_unknownEncodingMem) { - if (info.release) - info.release(info.data); - return XML_ERROR_NO_MEMORY; - } - enc = (parser->m_ns - ? XmlInitUnknownEncodingNS - : XmlInitUnknownEncoding)(parser->m_unknownEncodingMem, - info.map, - info.convert, - info.data); - if (enc) { - parser->m_unknownEncodingData = info.data; - parser->m_unknownEncodingRelease = info.release; - parser->m_encoding = enc; - return XML_ERROR_NONE; - } - } - if (info.release != NULL) - info.release(info.data); - } - return XML_ERROR_UNKNOWN_ENCODING; -} - -static enum XML_Error PTRCALL -prologInitProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - enum XML_Error result = initializeEncoding(parser); - if (result != XML_ERROR_NONE) - return result; - parser->m_processor = prologProcessor; - return prologProcessor(parser, s, end, nextPtr); -} - -#ifdef XML_DTD - -static enum XML_Error PTRCALL -externalParEntInitProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - enum XML_Error result = initializeEncoding(parser); - if (result != XML_ERROR_NONE) - return result; - - /* we know now that XML_Parse(Buffer) has been called, - so we consider the external parameter entity read */ - parser->m_dtd->paramEntityRead = XML_TRUE; - - if (parser->m_prologState.inEntityValue) { - parser->m_processor = entityValueInitProcessor; - return entityValueInitProcessor(parser, s, end, nextPtr); - } - else { - parser->m_processor = externalParEntProcessor; - return externalParEntProcessor(parser, s, end, nextPtr); - } -} - -static enum XML_Error PTRCALL -entityValueInitProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - int tok; - const char *start = s; - const char *next = start; - parser->m_eventPtr = start; - - for (;;) { - tok = XmlPrologTok(parser->m_encoding, start, end, &next); - parser->m_eventEndPtr = next; - if (tok <= 0) { - if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { - *nextPtr = s; - return XML_ERROR_NONE; - } - switch (tok) { - case XML_TOK_INVALID: - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_NONE: /* start == end */ - default: - break; - } - /* found end of entity value - can store it now */ - return storeEntityValue(parser, parser->m_encoding, s, end); - } - else if (tok == XML_TOK_XML_DECL) { - enum XML_Error result; - result = processXmlDecl(parser, 0, start, next); - if (result != XML_ERROR_NONE) - return result; - /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For that - * to happen, a parameter entity parsing handler must have - * attempted to suspend the parser, which fails and raises an - * error. The parser can be aborted, but can't be suspended. - */ - if (parser->m_parsingStatus.parsing == XML_FINISHED) - return XML_ERROR_ABORTED; - *nextPtr = next; - /* stop scanning for text declaration - we found one */ - parser->m_processor = entityValueProcessor; - return entityValueProcessor(parser, next, end, nextPtr); - } - /* If we are at the end of the buffer, this would cause XmlPrologTok to - return XML_TOK_NONE on the next call, which would then cause the - function to exit with *nextPtr set to s - that is what we want for other - tokens, but not for the BOM - we would rather like to skip it; - then, when this routine is entered the next time, XmlPrologTok will - return XML_TOK_INVALID, since the BOM is still in the buffer - */ - else if (tok == XML_TOK_BOM && next == end && !parser->m_parsingStatus.finalBuffer) { - *nextPtr = next; - return XML_ERROR_NONE; - } - /* If we get this token, we have the start of what might be a - normal tag, but not a declaration (i.e. it doesn't begin with - "m_eventPtr = start; - } -} - -static enum XML_Error PTRCALL -externalParEntProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - const char *next = s; - int tok; - - tok = XmlPrologTok(parser->m_encoding, s, end, &next); - if (tok <= 0) { - if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { - *nextPtr = s; - return XML_ERROR_NONE; - } - switch (tok) { - case XML_TOK_INVALID: - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_NONE: /* start == end */ - default: - break; - } - } - /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. - However, when parsing an external subset, doProlog will not accept a BOM - as valid, and report a syntax error, so we have to skip the BOM - */ - else if (tok == XML_TOK_BOM) { - s = next; - tok = XmlPrologTok(parser->m_encoding, s, end, &next); - } - - parser->m_processor = prologProcessor; - return doProlog(parser, parser->m_encoding, s, end, tok, next, - nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); -} - -static enum XML_Error PTRCALL -entityValueProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - const char *start = s; - const char *next = s; - const ENCODING *enc = parser->m_encoding; - int tok; - - for (;;) { - tok = XmlPrologTok(enc, start, end, &next); - if (tok <= 0) { - if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { - *nextPtr = s; - return XML_ERROR_NONE; - } - switch (tok) { - case XML_TOK_INVALID: - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_NONE: /* start == end */ - default: - break; - } - /* found end of entity value - can store it now */ - return storeEntityValue(parser, enc, s, end); - } - start = next; - } -} - -#endif /* XML_DTD */ - -static enum XML_Error PTRCALL -prologProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - const char *next = s; - int tok = XmlPrologTok(parser->m_encoding, s, end, &next); - return doProlog(parser, parser->m_encoding, s, end, tok, next, - nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); -} - -static enum XML_Error -doProlog(XML_Parser parser, - const ENCODING *enc, - const char *s, - const char *end, - int tok, - const char *next, - const char **nextPtr, - XML_Bool haveMore) -{ -#ifdef XML_DTD - static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' }; -#endif /* XML_DTD */ - static const XML_Char atypeCDATA[] = - { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; - static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' }; - static const XML_Char atypeIDREF[] = - { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' }; - static const XML_Char atypeIDREFS[] = - { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' }; - static const XML_Char atypeENTITY[] = - { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' }; - static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N, - ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' }; - static const XML_Char atypeNMTOKEN[] = { - ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' }; - static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T, - ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' }; - static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T, - ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' }; - static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' }; - static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' }; - - /* save one level of indirection */ - DTD * const dtd = parser->m_dtd; - - const char **eventPP; - const char **eventEndPP; - enum XML_Content_Quant quant; - - if (enc == parser->m_encoding) { - eventPP = &parser->m_eventPtr; - eventEndPP = &parser->m_eventEndPtr; - } - else { - eventPP = &(parser->m_openInternalEntities->internalEventPtr); - eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); - } - - for (;;) { - int role; - XML_Bool handleDefault = XML_TRUE; - *eventPP = s; - *eventEndPP = next; - if (tok <= 0) { - if (haveMore && tok != XML_TOK_INVALID) { - *nextPtr = s; - return XML_ERROR_NONE; - } - switch (tok) { - case XML_TOK_INVALID: - *eventPP = next; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - return XML_ERROR_PARTIAL_CHAR; - case -XML_TOK_PROLOG_S: - tok = -tok; - break; - case XML_TOK_NONE: -#ifdef XML_DTD - /* for internal PE NOT referenced between declarations */ - if (enc != parser->m_encoding && !parser->m_openInternalEntities->betweenDecl) { - *nextPtr = s; - return XML_ERROR_NONE; - } - /* WFC: PE Between Declarations - must check that PE contains - complete markup, not only for external PEs, but also for - internal PEs if the reference occurs between declarations. - */ - if (parser->m_isParamEntity || enc != parser->m_encoding) { - if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc) - == XML_ROLE_ERROR) - return XML_ERROR_INCOMPLETE_PE; - *nextPtr = s; - return XML_ERROR_NONE; - } -#endif /* XML_DTD */ - return XML_ERROR_NO_ELEMENTS; - default: - tok = -tok; - next = end; - break; - } - } - role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc); - switch (role) { - case XML_ROLE_XML_DECL: - { - enum XML_Error result = processXmlDecl(parser, 0, s, next); - if (result != XML_ERROR_NONE) - return result; - enc = parser->m_encoding; - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_DOCTYPE_NAME: - if (parser->m_startDoctypeDeclHandler) { - parser->m_doctypeName = poolStoreString(&parser->m_tempPool, enc, s, next); - if (!parser->m_doctypeName) - return XML_ERROR_NO_MEMORY; - poolFinish(&parser->m_tempPool); - parser->m_doctypePubid = NULL; - handleDefault = XML_FALSE; - } - parser->m_doctypeSysid = NULL; /* always initialize to NULL */ - break; - case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: - if (parser->m_startDoctypeDeclHandler) { - parser->m_startDoctypeDeclHandler(parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, - parser->m_doctypePubid, 1); - parser->m_doctypeName = NULL; - poolClear(&parser->m_tempPool); - handleDefault = XML_FALSE; - } - break; -#ifdef XML_DTD - case XML_ROLE_TEXT_DECL: - { - enum XML_Error result = processXmlDecl(parser, 1, s, next); - if (result != XML_ERROR_NONE) - return result; - enc = parser->m_encoding; - handleDefault = XML_FALSE; - } - break; -#endif /* XML_DTD */ - case XML_ROLE_DOCTYPE_PUBLIC_ID: -#ifdef XML_DTD - parser->m_useForeignDTD = XML_FALSE; - parser->m_declEntity = (ENTITY *)lookup(parser, - &dtd->paramEntities, - externalSubsetName, - sizeof(ENTITY)); - if (!parser->m_declEntity) - return XML_ERROR_NO_MEMORY; -#endif /* XML_DTD */ - dtd->hasParamEntityRefs = XML_TRUE; - if (parser->m_startDoctypeDeclHandler) { - XML_Char *pubId; - if (!XmlIsPublicId(enc, s, next, eventPP)) - return XML_ERROR_PUBLICID; - pubId = poolStoreString(&parser->m_tempPool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!pubId) - return XML_ERROR_NO_MEMORY; - normalizePublicId(pubId); - poolFinish(&parser->m_tempPool); - parser->m_doctypePubid = pubId; - handleDefault = XML_FALSE; - goto alreadyChecked; - } - /* fall through */ - case XML_ROLE_ENTITY_PUBLIC_ID: - if (!XmlIsPublicId(enc, s, next, eventPP)) - return XML_ERROR_PUBLICID; - alreadyChecked: - if (dtd->keepProcessing && parser->m_declEntity) { - XML_Char *tem = poolStoreString(&dtd->pool, - enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!tem) - return XML_ERROR_NO_MEMORY; - normalizePublicId(tem); - parser->m_declEntity->publicId = tem; - poolFinish(&dtd->pool); - /* Don't suppress the default handler if we fell through from - * the XML_ROLE_DOCTYPE_PUBLIC_ID case. - */ - if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID) - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_DOCTYPE_CLOSE: - if (parser->m_doctypeName) { - parser->m_startDoctypeDeclHandler(parser->m_handlerArg, parser->m_doctypeName, - parser->m_doctypeSysid, parser->m_doctypePubid, 0); - poolClear(&parser->m_tempPool); - handleDefault = XML_FALSE; - } - /* parser->m_doctypeSysid will be non-NULL in the case of a previous - XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler - was not set, indicating an external subset - */ -#ifdef XML_DTD - if (parser->m_doctypeSysid || parser->m_useForeignDTD) { - XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; - dtd->hasParamEntityRefs = XML_TRUE; - if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) { - ENTITY *entity = (ENTITY *)lookup(parser, - &dtd->paramEntities, - externalSubsetName, - sizeof(ENTITY)); - if (!entity) { - /* The external subset name "#" will have already been - * inserted into the hash table at the start of the - * external entity parsing, so no allocation will happen - * and lookup() cannot fail. - */ - return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ - } - if (parser->m_useForeignDTD) - entity->base = parser->m_curBase; - dtd->paramEntityRead = XML_FALSE; - if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, - 0, - entity->base, - entity->systemId, - entity->publicId)) - return XML_ERROR_EXTERNAL_ENTITY_HANDLING; - if (dtd->paramEntityRead) { - if (!dtd->standalone && - parser->m_notStandaloneHandler && - !parser->m_notStandaloneHandler(parser->m_handlerArg)) - return XML_ERROR_NOT_STANDALONE; - } - /* if we didn't read the foreign DTD then this means that there - is no external subset and we must reset dtd->hasParamEntityRefs - */ - else if (!parser->m_doctypeSysid) - dtd->hasParamEntityRefs = hadParamEntityRefs; - /* end of DTD - no need to update dtd->keepProcessing */ - } - parser->m_useForeignDTD = XML_FALSE; - } -#endif /* XML_DTD */ - if (parser->m_endDoctypeDeclHandler) { - parser->m_endDoctypeDeclHandler(parser->m_handlerArg); - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_INSTANCE_START: -#ifdef XML_DTD - /* if there is no DOCTYPE declaration then now is the - last chance to read the foreign DTD - */ - if (parser->m_useForeignDTD) { - XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; - dtd->hasParamEntityRefs = XML_TRUE; - if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) { - ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, - externalSubsetName, - sizeof(ENTITY)); - if (!entity) - return XML_ERROR_NO_MEMORY; - entity->base = parser->m_curBase; - dtd->paramEntityRead = XML_FALSE; - if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, - 0, - entity->base, - entity->systemId, - entity->publicId)) - return XML_ERROR_EXTERNAL_ENTITY_HANDLING; - if (dtd->paramEntityRead) { - if (!dtd->standalone && - parser->m_notStandaloneHandler && - !parser->m_notStandaloneHandler(parser->m_handlerArg)) - return XML_ERROR_NOT_STANDALONE; - } - /* if we didn't read the foreign DTD then this means that there - is no external subset and we must reset dtd->hasParamEntityRefs - */ - else - dtd->hasParamEntityRefs = hadParamEntityRefs; - /* end of DTD - no need to update dtd->keepProcessing */ - } - } -#endif /* XML_DTD */ - parser->m_processor = contentProcessor; - return contentProcessor(parser, s, end, nextPtr); - case XML_ROLE_ATTLIST_ELEMENT_NAME: - parser->m_declElementType = getElementType(parser, enc, s, next); - if (!parser->m_declElementType) - return XML_ERROR_NO_MEMORY; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_NAME: - parser->m_declAttributeId = getAttributeId(parser, enc, s, next); - if (!parser->m_declAttributeId) - return XML_ERROR_NO_MEMORY; - parser->m_declAttributeIsCdata = XML_FALSE; - parser->m_declAttributeType = NULL; - parser->m_declAttributeIsId = XML_FALSE; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_CDATA: - parser->m_declAttributeIsCdata = XML_TRUE; - parser->m_declAttributeType = atypeCDATA; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_ID: - parser->m_declAttributeIsId = XML_TRUE; - parser->m_declAttributeType = atypeID; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_IDREF: - parser->m_declAttributeType = atypeIDREF; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: - parser->m_declAttributeType = atypeIDREFS; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: - parser->m_declAttributeType = atypeENTITY; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: - parser->m_declAttributeType = atypeENTITIES; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: - parser->m_declAttributeType = atypeNMTOKEN; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: - parser->m_declAttributeType = atypeNMTOKENS; - checkAttListDeclHandler: - if (dtd->keepProcessing && parser->m_attlistDeclHandler) - handleDefault = XML_FALSE; - break; - case XML_ROLE_ATTRIBUTE_ENUM_VALUE: - case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: - if (dtd->keepProcessing && parser->m_attlistDeclHandler) { - const XML_Char *prefix; - if (parser->m_declAttributeType) { - prefix = enumValueSep; - } - else { - prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE - ? notationPrefix - : enumValueStart); - } - if (!poolAppendString(&parser->m_tempPool, prefix)) - return XML_ERROR_NO_MEMORY; - if (!poolAppend(&parser->m_tempPool, enc, s, next)) - return XML_ERROR_NO_MEMORY; - parser->m_declAttributeType = parser->m_tempPool.start; - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: - case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: - if (dtd->keepProcessing) { - if (!defineAttribute(parser->m_declElementType, parser->m_declAttributeId, - parser->m_declAttributeIsCdata, parser->m_declAttributeIsId, - 0, parser)) - return XML_ERROR_NO_MEMORY; - if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { - if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) - || (*parser->m_declAttributeType == XML_T(ASCII_N) - && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { - /* Enumerated or Notation type */ - if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) - || !poolAppendChar(&parser->m_tempPool, XML_T('\0'))) - return XML_ERROR_NO_MEMORY; - parser->m_declAttributeType = parser->m_tempPool.start; - poolFinish(&parser->m_tempPool); - } - *eventEndPP = s; - parser->m_attlistDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, - parser->m_declAttributeId->name, parser->m_declAttributeType, - 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); - poolClear(&parser->m_tempPool); - handleDefault = XML_FALSE; - } - } - break; - case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: - case XML_ROLE_FIXED_ATTRIBUTE_VALUE: - if (dtd->keepProcessing) { - const XML_Char *attVal; - enum XML_Error result = - storeAttributeValue(parser, enc, parser->m_declAttributeIsCdata, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar, - &dtd->pool); - if (result) - return result; - attVal = poolStart(&dtd->pool); - poolFinish(&dtd->pool); - /* ID attributes aren't allowed to have a default */ - if (!defineAttribute(parser->m_declElementType, parser->m_declAttributeId, - parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser)) - return XML_ERROR_NO_MEMORY; - if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { - if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) - || (*parser->m_declAttributeType == XML_T(ASCII_N) - && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { - /* Enumerated or Notation type */ - if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) - || !poolAppendChar(&parser->m_tempPool, XML_T('\0'))) - return XML_ERROR_NO_MEMORY; - parser->m_declAttributeType = parser->m_tempPool.start; - poolFinish(&parser->m_tempPool); - } - *eventEndPP = s; - parser->m_attlistDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, - parser->m_declAttributeId->name, parser->m_declAttributeType, - attVal, - role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); - poolClear(&parser->m_tempPool); - handleDefault = XML_FALSE; - } - } - break; - case XML_ROLE_ENTITY_VALUE: - if (dtd->keepProcessing) { - enum XML_Error result = storeEntityValue(parser, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (parser->m_declEntity) { - parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool); - parser->m_declEntity->textLen = (int)(poolLength(&dtd->entityValuePool)); - poolFinish(&dtd->entityValuePool); - if (parser->m_entityDeclHandler) { - *eventEndPP = s; - parser->m_entityDeclHandler(parser->m_handlerArg, - parser->m_declEntity->name, - parser->m_declEntity->is_param, - parser->m_declEntity->textPtr, - parser->m_declEntity->textLen, - parser->m_curBase, 0, 0, 0); - handleDefault = XML_FALSE; - } - } - else - poolDiscard(&dtd->entityValuePool); - if (result != XML_ERROR_NONE) - return result; - } - break; - case XML_ROLE_DOCTYPE_SYSTEM_ID: -#ifdef XML_DTD - parser->m_useForeignDTD = XML_FALSE; -#endif /* XML_DTD */ - dtd->hasParamEntityRefs = XML_TRUE; - if (parser->m_startDoctypeDeclHandler) { - parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (parser->m_doctypeSysid == NULL) - return XML_ERROR_NO_MEMORY; - poolFinish(&parser->m_tempPool); - handleDefault = XML_FALSE; - } -#ifdef XML_DTD - else - /* use externalSubsetName to make parser->m_doctypeSysid non-NULL - for the case where no parser->m_startDoctypeDeclHandler is set */ - parser->m_doctypeSysid = externalSubsetName; -#endif /* XML_DTD */ - if (!dtd->standalone -#ifdef XML_DTD - && !parser->m_paramEntityParsing -#endif /* XML_DTD */ - && parser->m_notStandaloneHandler - && !parser->m_notStandaloneHandler(parser->m_handlerArg)) - return XML_ERROR_NOT_STANDALONE; -#ifndef XML_DTD - break; -#else /* XML_DTD */ - if (!parser->m_declEntity) { - parser->m_declEntity = (ENTITY *)lookup(parser, - &dtd->paramEntities, - externalSubsetName, - sizeof(ENTITY)); - if (!parser->m_declEntity) - return XML_ERROR_NO_MEMORY; - parser->m_declEntity->publicId = NULL; - } - /* fall through */ -#endif /* XML_DTD */ - case XML_ROLE_ENTITY_SYSTEM_ID: - if (dtd->keepProcessing && parser->m_declEntity) { - parser->m_declEntity->systemId = poolStoreString(&dtd->pool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!parser->m_declEntity->systemId) - return XML_ERROR_NO_MEMORY; - parser->m_declEntity->base = parser->m_curBase; - poolFinish(&dtd->pool); - /* Don't suppress the default handler if we fell through from - * the XML_ROLE_DOCTYPE_SYSTEM_ID case. - */ - if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID) - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_ENTITY_COMPLETE: - if (dtd->keepProcessing && parser->m_declEntity && parser->m_entityDeclHandler) { - *eventEndPP = s; - parser->m_entityDeclHandler(parser->m_handlerArg, - parser->m_declEntity->name, - parser->m_declEntity->is_param, - 0,0, - parser->m_declEntity->base, - parser->m_declEntity->systemId, - parser->m_declEntity->publicId, - 0); - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_ENTITY_NOTATION_NAME: - if (dtd->keepProcessing && parser->m_declEntity) { - parser->m_declEntity->notation = poolStoreString(&dtd->pool, enc, s, next); - if (!parser->m_declEntity->notation) - return XML_ERROR_NO_MEMORY; - poolFinish(&dtd->pool); - if (parser->m_unparsedEntityDeclHandler) { - *eventEndPP = s; - parser->m_unparsedEntityDeclHandler(parser->m_handlerArg, - parser->m_declEntity->name, - parser->m_declEntity->base, - parser->m_declEntity->systemId, - parser->m_declEntity->publicId, - parser->m_declEntity->notation); - handleDefault = XML_FALSE; - } - else if (parser->m_entityDeclHandler) { - *eventEndPP = s; - parser->m_entityDeclHandler(parser->m_handlerArg, - parser->m_declEntity->name, - 0,0,0, - parser->m_declEntity->base, - parser->m_declEntity->systemId, - parser->m_declEntity->publicId, - parser->m_declEntity->notation); - handleDefault = XML_FALSE; - } - } - break; - case XML_ROLE_GENERAL_ENTITY_NAME: - { - if (XmlPredefinedEntityName(enc, s, next)) { - parser->m_declEntity = NULL; - break; - } - if (dtd->keepProcessing) { - const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); - if (!name) - return XML_ERROR_NO_MEMORY; - parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, - sizeof(ENTITY)); - if (!parser->m_declEntity) - return XML_ERROR_NO_MEMORY; - if (parser->m_declEntity->name != name) { - poolDiscard(&dtd->pool); - parser->m_declEntity = NULL; - } - else { - poolFinish(&dtd->pool); - parser->m_declEntity->publicId = NULL; - parser->m_declEntity->is_param = XML_FALSE; - /* if we have a parent parser or are reading an internal parameter - entity, then the entity declaration is not considered "internal" - */ - parser->m_declEntity->is_internal = !(parser->m_parentParser || parser->m_openInternalEntities); - if (parser->m_entityDeclHandler) - handleDefault = XML_FALSE; - } - } - else { - poolDiscard(&dtd->pool); - parser->m_declEntity = NULL; - } - } - break; - case XML_ROLE_PARAM_ENTITY_NAME: -#ifdef XML_DTD - if (dtd->keepProcessing) { - const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); - if (!name) - return XML_ERROR_NO_MEMORY; - parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities, - name, sizeof(ENTITY)); - if (!parser->m_declEntity) - return XML_ERROR_NO_MEMORY; - if (parser->m_declEntity->name != name) { - poolDiscard(&dtd->pool); - parser->m_declEntity = NULL; - } - else { - poolFinish(&dtd->pool); - parser->m_declEntity->publicId = NULL; - parser->m_declEntity->is_param = XML_TRUE; - /* if we have a parent parser or are reading an internal parameter - entity, then the entity declaration is not considered "internal" - */ - parser->m_declEntity->is_internal = !(parser->m_parentParser || parser->m_openInternalEntities); - if (parser->m_entityDeclHandler) - handleDefault = XML_FALSE; - } - } - else { - poolDiscard(&dtd->pool); - parser->m_declEntity = NULL; - } -#else /* not XML_DTD */ - parser->m_declEntity = NULL; -#endif /* XML_DTD */ - break; - case XML_ROLE_NOTATION_NAME: - parser->m_declNotationPublicId = NULL; - parser->m_declNotationName = NULL; - if (parser->m_notationDeclHandler) { - parser->m_declNotationName = poolStoreString(&parser->m_tempPool, enc, s, next); - if (!parser->m_declNotationName) - return XML_ERROR_NO_MEMORY; - poolFinish(&parser->m_tempPool); - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_NOTATION_PUBLIC_ID: - if (!XmlIsPublicId(enc, s, next, eventPP)) - return XML_ERROR_PUBLICID; - if (parser->m_declNotationName) { /* means m_notationDeclHandler != NULL */ - XML_Char *tem = poolStoreString(&parser->m_tempPool, - enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!tem) - return XML_ERROR_NO_MEMORY; - normalizePublicId(tem); - parser->m_declNotationPublicId = tem; - poolFinish(&parser->m_tempPool); - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_NOTATION_SYSTEM_ID: - if (parser->m_declNotationName && parser->m_notationDeclHandler) { - const XML_Char *systemId - = poolStoreString(&parser->m_tempPool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!systemId) - return XML_ERROR_NO_MEMORY; - *eventEndPP = s; - parser->m_notationDeclHandler(parser->m_handlerArg, - parser->m_declNotationName, - parser->m_curBase, - systemId, - parser->m_declNotationPublicId); - handleDefault = XML_FALSE; - } - poolClear(&parser->m_tempPool); - break; - case XML_ROLE_NOTATION_NO_SYSTEM_ID: - if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) { - *eventEndPP = s; - parser->m_notationDeclHandler(parser->m_handlerArg, - parser->m_declNotationName, - parser->m_curBase, - 0, - parser->m_declNotationPublicId); - handleDefault = XML_FALSE; - } - poolClear(&parser->m_tempPool); - break; - case XML_ROLE_ERROR: - switch (tok) { - case XML_TOK_PARAM_ENTITY_REF: - /* PE references in internal subset are - not allowed within declarations. */ - return XML_ERROR_PARAM_ENTITY_REF; - case XML_TOK_XML_DECL: - return XML_ERROR_MISPLACED_XML_PI; - default: - return XML_ERROR_SYNTAX; - } -#ifdef XML_DTD - case XML_ROLE_IGNORE_SECT: - { - enum XML_Error result; - if (parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - handleDefault = XML_FALSE; - result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); - if (result != XML_ERROR_NONE) - return result; - else if (!next) { - parser->m_processor = ignoreSectionProcessor; - return result; - } - } - break; -#endif /* XML_DTD */ - case XML_ROLE_GROUP_OPEN: - if (parser->m_prologState.level >= parser->m_groupSize) { - if (parser->m_groupSize) { - char *temp = (char *)REALLOC(parser, parser->m_groupConnector, parser->m_groupSize *= 2); - if (temp == NULL) { - parser->m_groupSize /= 2; - return XML_ERROR_NO_MEMORY; - } - parser->m_groupConnector = temp; - if (dtd->scaffIndex) { - int *temp = (int *)REALLOC(parser, dtd->scaffIndex, - parser->m_groupSize * sizeof(int)); - if (temp == NULL) - return XML_ERROR_NO_MEMORY; - dtd->scaffIndex = temp; - } - } - else { - parser->m_groupConnector = (char *)MALLOC(parser, parser->m_groupSize = 32); - if (!parser->m_groupConnector) { - parser->m_groupSize = 0; - return XML_ERROR_NO_MEMORY; - } - } - } - parser->m_groupConnector[parser->m_prologState.level] = 0; - if (dtd->in_eldecl) { - int myindex = nextScaffoldPart(parser); - if (myindex < 0) - return XML_ERROR_NO_MEMORY; - dtd->scaffIndex[dtd->scaffLevel] = myindex; - dtd->scaffLevel++; - dtd->scaffold[myindex].type = XML_CTYPE_SEQ; - if (parser->m_elementDeclHandler) - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_GROUP_SEQUENCE: - if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE) - return XML_ERROR_SYNTAX; - parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA; - if (dtd->in_eldecl && parser->m_elementDeclHandler) - handleDefault = XML_FALSE; - break; - case XML_ROLE_GROUP_CHOICE: - if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA) - return XML_ERROR_SYNTAX; - if (dtd->in_eldecl - && !parser->m_groupConnector[parser->m_prologState.level] - && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type - != XML_CTYPE_MIXED) - ) { - dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type - = XML_CTYPE_CHOICE; - if (parser->m_elementDeclHandler) - handleDefault = XML_FALSE; - } - parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE; - break; - case XML_ROLE_PARAM_ENTITY_REF: -#ifdef XML_DTD - case XML_ROLE_INNER_PARAM_ENTITY_REF: - dtd->hasParamEntityRefs = XML_TRUE; - if (!parser->m_paramEntityParsing) - dtd->keepProcessing = dtd->standalone; - else { - const XML_Char *name; - ENTITY *entity; - name = poolStoreString(&dtd->pool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) - return XML_ERROR_NO_MEMORY; - entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); - poolDiscard(&dtd->pool); - /* first, determine if a check for an existing declaration is needed; - if yes, check that the entity exists, and that it is internal, - otherwise call the skipped entity handler - */ - if (parser->m_prologState.documentEntity && - (dtd->standalone - ? !parser->m_openInternalEntities - : !dtd->hasParamEntityRefs)) { - if (!entity) - return XML_ERROR_UNDEFINED_ENTITY; - else if (!entity->is_internal) { - /* It's hard to exhaustively search the code to be sure, - * but there doesn't seem to be a way of executing the - * following line. There are two cases: - * - * If 'standalone' is false, the DTD must have no - * parameter entities or we wouldn't have passed the outer - * 'if' statement. That measn the only entity in the hash - * table is the external subset name "#" which cannot be - * given as a parameter entity name in XML syntax, so the - * lookup must have returned NULL and we don't even reach - * the test for an internal entity. - * - * If 'standalone' is true, it does not seem to be - * possible to create entities taking this code path that - * are not internal entities, so fail the test above. - * - * Because this analysis is very uncertain, the code is - * being left in place and merely removed from the - * coverage test statistics. - */ - return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */ - } - } - else if (!entity) { - dtd->keepProcessing = dtd->standalone; - /* cannot report skipped entities in declarations */ - if ((role == XML_ROLE_PARAM_ENTITY_REF) && parser->m_skippedEntityHandler) { - parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1); - handleDefault = XML_FALSE; - } - break; - } - if (entity->open) - return XML_ERROR_RECURSIVE_ENTITY_REF; - if (entity->textPtr) { - enum XML_Error result; - XML_Bool betweenDecl = - (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); - result = processInternalEntity(parser, entity, betweenDecl); - if (result != XML_ERROR_NONE) - return result; - handleDefault = XML_FALSE; - break; - } - if (parser->m_externalEntityRefHandler) { - dtd->paramEntityRead = XML_FALSE; - entity->open = XML_TRUE; - if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, - 0, - entity->base, - entity->systemId, - entity->publicId)) { - entity->open = XML_FALSE; - return XML_ERROR_EXTERNAL_ENTITY_HANDLING; - } - entity->open = XML_FALSE; - handleDefault = XML_FALSE; - if (!dtd->paramEntityRead) { - dtd->keepProcessing = dtd->standalone; - break; - } - } - else { - dtd->keepProcessing = dtd->standalone; - break; - } - } -#endif /* XML_DTD */ - if (!dtd->standalone && - parser->m_notStandaloneHandler && - !parser->m_notStandaloneHandler(parser->m_handlerArg)) - return XML_ERROR_NOT_STANDALONE; - break; - - /* Element declaration stuff */ - - case XML_ROLE_ELEMENT_NAME: - if (parser->m_elementDeclHandler) { - parser->m_declElementType = getElementType(parser, enc, s, next); - if (!parser->m_declElementType) - return XML_ERROR_NO_MEMORY; - dtd->scaffLevel = 0; - dtd->scaffCount = 0; - dtd->in_eldecl = XML_TRUE; - handleDefault = XML_FALSE; - } - break; - - case XML_ROLE_CONTENT_ANY: - case XML_ROLE_CONTENT_EMPTY: - if (dtd->in_eldecl) { - if (parser->m_elementDeclHandler) { - XML_Content * content = (XML_Content *) MALLOC(parser, sizeof(XML_Content)); - if (!content) - return XML_ERROR_NO_MEMORY; - content->quant = XML_CQUANT_NONE; - content->name = NULL; - content->numchildren = 0; - content->children = NULL; - content->type = ((role == XML_ROLE_CONTENT_ANY) ? - XML_CTYPE_ANY : - XML_CTYPE_EMPTY); - *eventEndPP = s; - parser->m_elementDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, content); - handleDefault = XML_FALSE; - } - dtd->in_eldecl = XML_FALSE; - } - break; - - case XML_ROLE_CONTENT_PCDATA: - if (dtd->in_eldecl) { - dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type - = XML_CTYPE_MIXED; - if (parser->m_elementDeclHandler) - handleDefault = XML_FALSE; - } - break; - - case XML_ROLE_CONTENT_ELEMENT: - quant = XML_CQUANT_NONE; - goto elementContent; - case XML_ROLE_CONTENT_ELEMENT_OPT: - quant = XML_CQUANT_OPT; - goto elementContent; - case XML_ROLE_CONTENT_ELEMENT_REP: - quant = XML_CQUANT_REP; - goto elementContent; - case XML_ROLE_CONTENT_ELEMENT_PLUS: - quant = XML_CQUANT_PLUS; - elementContent: - if (dtd->in_eldecl) { - ELEMENT_TYPE *el; - const XML_Char *name; - int nameLen; - const char *nxt = (quant == XML_CQUANT_NONE - ? next - : next - enc->minBytesPerChar); - int myindex = nextScaffoldPart(parser); - if (myindex < 0) - return XML_ERROR_NO_MEMORY; - dtd->scaffold[myindex].type = XML_CTYPE_NAME; - dtd->scaffold[myindex].quant = quant; - el = getElementType(parser, enc, s, nxt); - if (!el) - return XML_ERROR_NO_MEMORY; - name = el->name; - dtd->scaffold[myindex].name = name; - nameLen = 0; - for (; name[nameLen++]; ); - dtd->contentStringLen += nameLen; - if (parser->m_elementDeclHandler) - handleDefault = XML_FALSE; - } - break; - - case XML_ROLE_GROUP_CLOSE: - quant = XML_CQUANT_NONE; - goto closeGroup; - case XML_ROLE_GROUP_CLOSE_OPT: - quant = XML_CQUANT_OPT; - goto closeGroup; - case XML_ROLE_GROUP_CLOSE_REP: - quant = XML_CQUANT_REP; - goto closeGroup; - case XML_ROLE_GROUP_CLOSE_PLUS: - quant = XML_CQUANT_PLUS; - closeGroup: - if (dtd->in_eldecl) { - if (parser->m_elementDeclHandler) - handleDefault = XML_FALSE; - dtd->scaffLevel--; - dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; - if (dtd->scaffLevel == 0) { - if (!handleDefault) { - XML_Content *model = build_model(parser); - if (!model) - return XML_ERROR_NO_MEMORY; - *eventEndPP = s; - parser->m_elementDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, model); - } - dtd->in_eldecl = XML_FALSE; - dtd->contentStringLen = 0; - } - } - break; - /* End element declaration stuff */ - - case XML_ROLE_PI: - if (!reportProcessingInstruction(parser, enc, s, next)) - return XML_ERROR_NO_MEMORY; - handleDefault = XML_FALSE; - break; - case XML_ROLE_COMMENT: - if (!reportComment(parser, enc, s, next)) - return XML_ERROR_NO_MEMORY; - handleDefault = XML_FALSE; - break; - case XML_ROLE_NONE: - switch (tok) { - case XML_TOK_BOM: - handleDefault = XML_FALSE; - break; - } - break; - case XML_ROLE_DOCTYPE_NONE: - if (parser->m_startDoctypeDeclHandler) - handleDefault = XML_FALSE; - break; - case XML_ROLE_ENTITY_NONE: - if (dtd->keepProcessing && parser->m_entityDeclHandler) - handleDefault = XML_FALSE; - break; - case XML_ROLE_NOTATION_NONE: - if (parser->m_notationDeclHandler) - handleDefault = XML_FALSE; - break; - case XML_ROLE_ATTLIST_NONE: - if (dtd->keepProcessing && parser->m_attlistDeclHandler) - handleDefault = XML_FALSE; - break; - case XML_ROLE_ELEMENT_NONE: - if (parser->m_elementDeclHandler) - handleDefault = XML_FALSE; - break; - } /* end of big switch */ - - if (handleDefault && parser->m_defaultHandler) - reportDefault(parser, enc, s, next); - - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: - *nextPtr = next; - return XML_ERROR_NONE; - case XML_FINISHED: - return XML_ERROR_ABORTED; - default: - s = next; - tok = XmlPrologTok(enc, s, end, &next); - } - } - /* not reached */ -} - -static enum XML_Error PTRCALL -epilogProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - parser->m_processor = epilogProcessor; - parser->m_eventPtr = s; - for (;;) { - const char *next = NULL; - int tok = XmlPrologTok(parser->m_encoding, s, end, &next); - parser->m_eventEndPtr = next; - switch (tok) { - /* report partial linebreak - it might be the last token */ - case -XML_TOK_PROLOG_S: - if (parser->m_defaultHandler) { - reportDefault(parser, parser->m_encoding, s, next); - if (parser->m_parsingStatus.parsing == XML_FINISHED) - return XML_ERROR_ABORTED; - } - *nextPtr = next; - return XML_ERROR_NONE; - case XML_TOK_NONE: - *nextPtr = s; - return XML_ERROR_NONE; - case XML_TOK_PROLOG_S: - if (parser->m_defaultHandler) - reportDefault(parser, parser->m_encoding, s, next); - break; - case XML_TOK_PI: - if (!reportProcessingInstruction(parser, parser->m_encoding, s, next)) - return XML_ERROR_NO_MEMORY; - break; - case XML_TOK_COMMENT: - if (!reportComment(parser, parser->m_encoding, s, next)) - return XML_ERROR_NO_MEMORY; - break; - case XML_TOK_INVALID: - parser->m_eventPtr = next; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - if (!parser->m_parsingStatus.finalBuffer) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - if (!parser->m_parsingStatus.finalBuffer) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_PARTIAL_CHAR; - default: - return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; - } - parser->m_eventPtr = s = next; - switch (parser->m_parsingStatus.parsing) { - case XML_SUSPENDED: - *nextPtr = next; - return XML_ERROR_NONE; - case XML_FINISHED: - return XML_ERROR_ABORTED; - default: ; - } - } -} - -static enum XML_Error -processInternalEntity(XML_Parser parser, ENTITY *entity, - XML_Bool betweenDecl) -{ - const char *textStart, *textEnd; - const char *next; - enum XML_Error result; - OPEN_INTERNAL_ENTITY *openEntity; - - if (parser->m_freeInternalEntities) { - openEntity = parser->m_freeInternalEntities; - parser->m_freeInternalEntities = openEntity->next; - } - else { - openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY)); - if (!openEntity) - return XML_ERROR_NO_MEMORY; - } - entity->open = XML_TRUE; - entity->processed = 0; - openEntity->next = parser->m_openInternalEntities; - parser->m_openInternalEntities = openEntity; - openEntity->entity = entity; - openEntity->startTagLevel = parser->m_tagLevel; - openEntity->betweenDecl = betweenDecl; - openEntity->internalEventPtr = NULL; - openEntity->internalEventEndPtr = NULL; - textStart = (char *)entity->textPtr; - textEnd = (char *)(entity->textPtr + entity->textLen); - /* Set a safe default value in case 'next' does not get set */ - next = textStart; - -#ifdef XML_DTD - if (entity->is_param) { - int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); - result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok, - next, &next, XML_FALSE); - } - else -#endif /* XML_DTD */ - result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, textStart, - textEnd, &next, XML_FALSE); - - if (result == XML_ERROR_NONE) { - if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { - entity->processed = (int)(next - textStart); - parser->m_processor = internalEntityProcessor; - } - else { - entity->open = XML_FALSE; - parser->m_openInternalEntities = openEntity->next; - /* put openEntity back in list of free instances */ - openEntity->next = parser->m_freeInternalEntities; - parser->m_freeInternalEntities = openEntity; - } - } - return result; -} - -static enum XML_Error PTRCALL -internalEntityProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - ENTITY *entity; - const char *textStart, *textEnd; - const char *next; - enum XML_Error result; - OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities; - if (!openEntity) - return XML_ERROR_UNEXPECTED_STATE; - - entity = openEntity->entity; - textStart = ((char *)entity->textPtr) + entity->processed; - textEnd = (char *)(entity->textPtr + entity->textLen); - /* Set a safe default value in case 'next' does not get set */ - next = textStart; - -#ifdef XML_DTD - if (entity->is_param) { - int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); - result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok, - next, &next, XML_FALSE); - } - else -#endif /* XML_DTD */ - result = doContent(parser, openEntity->startTagLevel, parser->m_internalEncoding, - textStart, textEnd, &next, XML_FALSE); - - if (result != XML_ERROR_NONE) - return result; - else if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { - entity->processed = (int)(next - (char *)entity->textPtr); - return result; - } - else { - entity->open = XML_FALSE; - parser->m_openInternalEntities = openEntity->next; - /* put openEntity back in list of free instances */ - openEntity->next = parser->m_freeInternalEntities; - parser->m_freeInternalEntities = openEntity; - } - -#ifdef XML_DTD - if (entity->is_param) { - int tok; - parser->m_processor = prologProcessor; - tok = XmlPrologTok(parser->m_encoding, s, end, &next); - return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, - (XML_Bool)!parser->m_parsingStatus.finalBuffer); - } - else -#endif /* XML_DTD */ - { - parser->m_processor = contentProcessor; - /* see externalEntityContentProcessor vs contentProcessor */ - return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, s, end, - nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); - } -} - -static enum XML_Error PTRCALL -errorProcessor(XML_Parser parser, - const char *UNUSED_P(s), - const char *UNUSED_P(end), - const char **UNUSED_P(nextPtr)) -{ - return parser->m_errorCode; -} - -static enum XML_Error -storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, - const char *ptr, const char *end, - STRING_POOL *pool) -{ - enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, - end, pool); - if (result) - return result; - if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) - poolChop(pool); - if (!poolAppendChar(pool, XML_T('\0'))) - return XML_ERROR_NO_MEMORY; - return XML_ERROR_NONE; -} - -static enum XML_Error -appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, - const char *ptr, const char *end, - STRING_POOL *pool) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ - for (;;) { - const char *next; - int tok = XmlAttributeValueTok(enc, ptr, end, &next); - switch (tok) { - case XML_TOK_NONE: - return XML_ERROR_NONE; - case XML_TOK_INVALID: - if (enc == parser->m_encoding) - parser->m_eventPtr = next; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - if (enc == parser->m_encoding) - parser->m_eventPtr = ptr; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_CHAR_REF: - { - XML_Char buf[XML_ENCODE_MAX]; - int i; - int n = XmlCharRefNumber(enc, ptr); - if (n < 0) { - if (enc == parser->m_encoding) - parser->m_eventPtr = ptr; - return XML_ERROR_BAD_CHAR_REF; - } - if (!isCdata - && n == 0x20 /* space */ - && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) - break; - n = XmlEncode(n, (ICHAR *)buf); - /* The XmlEncode() functions can never return 0 here. That - * error return happens if the code point passed in is either - * negative or greater than or equal to 0x110000. The - * XmlCharRefNumber() functions will all return a number - * strictly less than 0x110000 or a negative value if an error - * occurred. The negative value is intercepted above, so - * XmlEncode() is never passed a value it might return an - * error for. - */ - for (i = 0; i < n; i++) { - if (!poolAppendChar(pool, buf[i])) - return XML_ERROR_NO_MEMORY; - } - } - break; - case XML_TOK_DATA_CHARS: - if (!poolAppend(pool, enc, ptr, next)) - return XML_ERROR_NO_MEMORY; - break; - case XML_TOK_TRAILING_CR: - next = ptr + enc->minBytesPerChar; - /* fall through */ - case XML_TOK_ATTRIBUTE_VALUE_S: - case XML_TOK_DATA_NEWLINE: - if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) - break; - if (!poolAppendChar(pool, 0x20)) - return XML_ERROR_NO_MEMORY; - break; - case XML_TOK_ENTITY_REF: - { - const XML_Char *name; - ENTITY *entity; - char checkEntityDecl; - XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, - ptr + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (ch) { - if (!poolAppendChar(pool, ch)) - return XML_ERROR_NO_MEMORY; - break; - } - name = poolStoreString(&parser->m_temp2Pool, enc, - ptr + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) - return XML_ERROR_NO_MEMORY; - entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); - poolDiscard(&parser->m_temp2Pool); - /* First, determine if a check for an existing declaration is needed; - if yes, check that the entity exists, and that it is internal. - */ - if (pool == &dtd->pool) /* are we called from prolog? */ - checkEntityDecl = -#ifdef XML_DTD - parser->m_prologState.documentEntity && -#endif /* XML_DTD */ - (dtd->standalone - ? !parser->m_openInternalEntities - : !dtd->hasParamEntityRefs); - else /* if (pool == &parser->m_tempPool): we are called from content */ - checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone; - if (checkEntityDecl) { - if (!entity) - return XML_ERROR_UNDEFINED_ENTITY; - else if (!entity->is_internal) - return XML_ERROR_ENTITY_DECLARED_IN_PE; - } - else if (!entity) { - /* Cannot report skipped entity here - see comments on - parser->m_skippedEntityHandler. - if (parser->m_skippedEntityHandler) - parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); - */ - /* Cannot call the default handler because this would be - out of sync with the call to the startElementHandler. - if ((pool == &parser->m_tempPool) && parser->m_defaultHandler) - reportDefault(parser, enc, ptr, next); - */ - break; - } - if (entity->open) { - if (enc == parser->m_encoding) { - /* It does not appear that this line can be executed. - * - * The "if (entity->open)" check catches recursive entity - * definitions. In order to be called with an open - * entity, it must have gone through this code before and - * been through the recursive call to - * appendAttributeValue() some lines below. That call - * sets the local encoding ("enc") to the parser's - * internal encoding (internal_utf8 or internal_utf16), - * which can never be the same as the principle encoding. - * It doesn't appear there is another code path that gets - * here with entity->open being TRUE. - * - * Since it is not certain that this logic is watertight, - * we keep the line and merely exclude it from coverage - * tests. - */ - parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */ - } - return XML_ERROR_RECURSIVE_ENTITY_REF; - } - if (entity->notation) { - if (enc == parser->m_encoding) - parser->m_eventPtr = ptr; - return XML_ERROR_BINARY_ENTITY_REF; - } - if (!entity->textPtr) { - if (enc == parser->m_encoding) - parser->m_eventPtr = ptr; - return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; - } - else { - enum XML_Error result; - const XML_Char *textEnd = entity->textPtr + entity->textLen; - entity->open = XML_TRUE; - result = appendAttributeValue(parser, parser->m_internalEncoding, isCdata, - (char *)entity->textPtr, - (char *)textEnd, pool); - entity->open = XML_FALSE; - if (result) - return result; - } - } - break; - default: - /* The only token returned by XmlAttributeValueTok() that does - * not have an explicit case here is XML_TOK_PARTIAL_CHAR. - * Getting that would require an entity name to contain an - * incomplete XML character (e.g. \xE2\x82); however previous - * tokenisers will have already recognised and rejected such - * names before XmlAttributeValueTok() gets a look-in. This - * default case should be retained as a safety net, but the code - * excluded from coverage tests. - * - * LCOV_EXCL_START - */ - if (enc == parser->m_encoding) - parser->m_eventPtr = ptr; - return XML_ERROR_UNEXPECTED_STATE; - /* LCOV_EXCL_STOP */ - } - ptr = next; - } - /* not reached */ -} - -static enum XML_Error -storeEntityValue(XML_Parser parser, - const ENCODING *enc, - const char *entityTextPtr, - const char *entityTextEnd) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ - STRING_POOL *pool = &(dtd->entityValuePool); - enum XML_Error result = XML_ERROR_NONE; -#ifdef XML_DTD - int oldInEntityValue = parser->m_prologState.inEntityValue; - parser->m_prologState.inEntityValue = 1; -#endif /* XML_DTD */ - /* never return Null for the value argument in EntityDeclHandler, - since this would indicate an external entity; therefore we - have to make sure that entityValuePool.start is not null */ - if (!pool->blocks) { - if (!poolGrow(pool)) - return XML_ERROR_NO_MEMORY; - } - - for (;;) { - const char *next; - int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); - switch (tok) { - case XML_TOK_PARAM_ENTITY_REF: -#ifdef XML_DTD - if (parser->m_isParamEntity || enc != parser->m_encoding) { - const XML_Char *name; - ENTITY *entity; - name = poolStoreString(&parser->m_tempPool, enc, - entityTextPtr + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) { - result = XML_ERROR_NO_MEMORY; - goto endEntityValue; - } - entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); - poolDiscard(&parser->m_tempPool); - if (!entity) { - /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ - /* cannot report skipped entity here - see comments on - parser->m_skippedEntityHandler - if (parser->m_skippedEntityHandler) - parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); - */ - dtd->keepProcessing = dtd->standalone; - goto endEntityValue; - } - if (entity->open) { - if (enc == parser->m_encoding) - parser->m_eventPtr = entityTextPtr; - result = XML_ERROR_RECURSIVE_ENTITY_REF; - goto endEntityValue; - } - if (entity->systemId) { - if (parser->m_externalEntityRefHandler) { - dtd->paramEntityRead = XML_FALSE; - entity->open = XML_TRUE; - if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, - 0, - entity->base, - entity->systemId, - entity->publicId)) { - entity->open = XML_FALSE; - result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; - goto endEntityValue; - } - entity->open = XML_FALSE; - if (!dtd->paramEntityRead) - dtd->keepProcessing = dtd->standalone; - } - else - dtd->keepProcessing = dtd->standalone; - } - else { - entity->open = XML_TRUE; - result = storeEntityValue(parser, - parser->m_internalEncoding, - (char *)entity->textPtr, - (char *)(entity->textPtr - + entity->textLen)); - entity->open = XML_FALSE; - if (result) - goto endEntityValue; - } - break; - } -#endif /* XML_DTD */ - /* In the internal subset, PE references are not legal - within markup declarations, e.g entity values in this case. */ - parser->m_eventPtr = entityTextPtr; - result = XML_ERROR_PARAM_ENTITY_REF; - goto endEntityValue; - case XML_TOK_NONE: - result = XML_ERROR_NONE; - goto endEntityValue; - case XML_TOK_ENTITY_REF: - case XML_TOK_DATA_CHARS: - if (!poolAppend(pool, enc, entityTextPtr, next)) { - result = XML_ERROR_NO_MEMORY; - goto endEntityValue; - } - break; - case XML_TOK_TRAILING_CR: - next = entityTextPtr + enc->minBytesPerChar; - /* fall through */ - case XML_TOK_DATA_NEWLINE: - if (pool->end == pool->ptr && !poolGrow(pool)) { - result = XML_ERROR_NO_MEMORY; - goto endEntityValue; - } - *(pool->ptr)++ = 0xA; - break; - case XML_TOK_CHAR_REF: - { - XML_Char buf[XML_ENCODE_MAX]; - int i; - int n = XmlCharRefNumber(enc, entityTextPtr); - if (n < 0) { - if (enc == parser->m_encoding) - parser->m_eventPtr = entityTextPtr; - result = XML_ERROR_BAD_CHAR_REF; - goto endEntityValue; - } - n = XmlEncode(n, (ICHAR *)buf); - /* The XmlEncode() functions can never return 0 here. That - * error return happens if the code point passed in is either - * negative or greater than or equal to 0x110000. The - * XmlCharRefNumber() functions will all return a number - * strictly less than 0x110000 or a negative value if an error - * occurred. The negative value is intercepted above, so - * XmlEncode() is never passed a value it might return an - * error for. - */ - for (i = 0; i < n; i++) { - if (pool->end == pool->ptr && !poolGrow(pool)) { - result = XML_ERROR_NO_MEMORY; - goto endEntityValue; - } - *(pool->ptr)++ = buf[i]; - } - } - break; - case XML_TOK_PARTIAL: - if (enc == parser->m_encoding) - parser->m_eventPtr = entityTextPtr; - result = XML_ERROR_INVALID_TOKEN; - goto endEntityValue; - case XML_TOK_INVALID: - if (enc == parser->m_encoding) - parser->m_eventPtr = next; - result = XML_ERROR_INVALID_TOKEN; - goto endEntityValue; - default: - /* This default case should be unnecessary -- all the tokens - * that XmlEntityValueTok() can return have their own explicit - * cases -- but should be retained for safety. We do however - * exclude it from the coverage statistics. - * - * LCOV_EXCL_START - */ - if (enc == parser->m_encoding) - parser->m_eventPtr = entityTextPtr; - result = XML_ERROR_UNEXPECTED_STATE; - goto endEntityValue; - /* LCOV_EXCL_STOP */ - } - entityTextPtr = next; - } -endEntityValue: -#ifdef XML_DTD - parser->m_prologState.inEntityValue = oldInEntityValue; -#endif /* XML_DTD */ - return result; -} - -static void FASTCALL -normalizeLines(XML_Char *s) -{ - XML_Char *p; - for (;; s++) { - if (*s == XML_T('\0')) - return; - if (*s == 0xD) - break; - } - p = s; - do { - if (*s == 0xD) { - *p++ = 0xA; - if (*++s == 0xA) - s++; - } - else - *p++ = *s++; - } while (*s); - *p = XML_T('\0'); -} - -static int -reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, - const char *start, const char *end) -{ - const XML_Char *target; - XML_Char *data; - const char *tem; - if (!parser->m_processingInstructionHandler) { - if (parser->m_defaultHandler) - reportDefault(parser, enc, start, end); - return 1; - } - start += enc->minBytesPerChar * 2; - tem = start + XmlNameLength(enc, start); - target = poolStoreString(&parser->m_tempPool, enc, start, tem); - if (!target) - return 0; - poolFinish(&parser->m_tempPool); - data = poolStoreString(&parser->m_tempPool, enc, - XmlSkipS(enc, tem), - end - enc->minBytesPerChar*2); - if (!data) - return 0; - normalizeLines(data); - parser->m_processingInstructionHandler(parser->m_handlerArg, target, data); - poolClear(&parser->m_tempPool); - return 1; -} - -static int -reportComment(XML_Parser parser, const ENCODING *enc, - const char *start, const char *end) -{ - XML_Char *data; - if (!parser->m_commentHandler) { - if (parser->m_defaultHandler) - reportDefault(parser, enc, start, end); - return 1; - } - data = poolStoreString(&parser->m_tempPool, - enc, - start + enc->minBytesPerChar * 4, - end - enc->minBytesPerChar * 3); - if (!data) - return 0; - normalizeLines(data); - parser->m_commentHandler(parser->m_handlerArg, data); - poolClear(&parser->m_tempPool); - return 1; -} - -static void -reportDefault(XML_Parser parser, const ENCODING *enc, - const char *s, const char *end) -{ - if (MUST_CONVERT(enc, s)) { - enum XML_Convert_Result convert_res; - const char **eventPP; - const char **eventEndPP; - if (enc == parser->m_encoding) { - eventPP = &parser->m_eventPtr; - eventEndPP = &parser->m_eventEndPtr; - } - else { - /* To get here, two things must be true; the parser must be - * using a character encoding that is not the same as the - * encoding passed in, and the encoding passed in must need - * conversion to the internal format (UTF-8 unless XML_UNICODE - * is defined). The only occasions on which the encoding passed - * in is not the same as the parser's encoding are when it is - * the internal encoding (e.g. a previously defined parameter - * entity, already converted to internal format). This by - * definition doesn't need conversion, so the whole branch never - * gets executed. - * - * For safety's sake we don't delete these lines and merely - * exclude them from coverage statistics. - * - * LCOV_EXCL_START - */ - eventPP = &(parser->m_openInternalEntities->internalEventPtr); - eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); - /* LCOV_EXCL_STOP */ - } - do { - ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; - convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); - *eventEndPP = s; - parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); - *eventPP = s; - } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE)); - } - else - parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s)); -} - - -static int -defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, - XML_Bool isId, const XML_Char *value, XML_Parser parser) -{ - DEFAULT_ATTRIBUTE *att; - if (value || isId) { - /* The handling of default attributes gets messed up if we have - a default which duplicates a non-default. */ - int i; - for (i = 0; i < type->nDefaultAtts; i++) - if (attId == type->defaultAtts[i].id) - return 1; - if (isId && !type->idAtt && !attId->xmlns) - type->idAtt = attId; - } - if (type->nDefaultAtts == type->allocDefaultAtts) { - if (type->allocDefaultAtts == 0) { - type->allocDefaultAtts = 8; - type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(parser, type->allocDefaultAtts - * sizeof(DEFAULT_ATTRIBUTE)); - if (!type->defaultAtts) { - type->allocDefaultAtts = 0; - return 0; - } - } - else { - DEFAULT_ATTRIBUTE *temp; - int count = type->allocDefaultAtts * 2; - temp = (DEFAULT_ATTRIBUTE *) - REALLOC(parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); - if (temp == NULL) - return 0; - type->allocDefaultAtts = count; - type->defaultAtts = temp; - } - } - att = type->defaultAtts + type->nDefaultAtts; - att->id = attId; - att->value = value; - att->isCdata = isCdata; - if (!isCdata) - attId->maybeTokenized = XML_TRUE; - type->nDefaultAtts += 1; - return 1; -} - -static int -setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ - const XML_Char *name; - for (name = elementType->name; *name; name++) { - if (*name == XML_T(ASCII_COLON)) { - PREFIX *prefix; - const XML_Char *s; - for (s = elementType->name; s != name; s++) { - if (!poolAppendChar(&dtd->pool, *s)) - return 0; - } - if (!poolAppendChar(&dtd->pool, XML_T('\0'))) - return 0; - prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool), - sizeof(PREFIX)); - if (!prefix) - return 0; - if (prefix->name == poolStart(&dtd->pool)) - poolFinish(&dtd->pool); - else - poolDiscard(&dtd->pool); - elementType->prefix = prefix; - - } - } - return 1; -} - -static ATTRIBUTE_ID * -getAttributeId(XML_Parser parser, const ENCODING *enc, - const char *start, const char *end) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ - ATTRIBUTE_ID *id; - const XML_Char *name; - if (!poolAppendChar(&dtd->pool, XML_T('\0'))) - return NULL; - name = poolStoreString(&dtd->pool, enc, start, end); - if (!name) - return NULL; - /* skip quotation mark - its storage will be re-used (like in name[-1]) */ - ++name; - id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID)); - if (!id) - return NULL; - if (id->name != name) - poolDiscard(&dtd->pool); - else { - poolFinish(&dtd->pool); - if (!parser->m_ns) - ; - else if (name[0] == XML_T(ASCII_x) - && name[1] == XML_T(ASCII_m) - && name[2] == XML_T(ASCII_l) - && name[3] == XML_T(ASCII_n) - && name[4] == XML_T(ASCII_s) - && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) { - if (name[5] == XML_T('\0')) - id->prefix = &dtd->defaultPrefix; - else - id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX)); - id->xmlns = XML_TRUE; - } - else { - int i; - for (i = 0; name[i]; i++) { - /* attributes without prefix are *not* in the default namespace */ - if (name[i] == XML_T(ASCII_COLON)) { - int j; - for (j = 0; j < i; j++) { - if (!poolAppendChar(&dtd->pool, name[j])) - return NULL; - } - if (!poolAppendChar(&dtd->pool, XML_T('\0'))) - return NULL; - id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool), - sizeof(PREFIX)); - if (!id->prefix) - return NULL; - if (id->prefix->name == poolStart(&dtd->pool)) - poolFinish(&dtd->pool); - else - poolDiscard(&dtd->pool); - break; - } - } - } - } - return id; -} - -#define CONTEXT_SEP XML_T(ASCII_FF) - -static const XML_Char * -getContext(XML_Parser parser) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ - HASH_TABLE_ITER iter; - XML_Bool needSep = XML_FALSE; - - if (dtd->defaultPrefix.binding) { - int i; - int len; - if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) - return NULL; - len = dtd->defaultPrefix.binding->uriLen; - if (parser->m_namespaceSeparator) - len--; - for (i = 0; i < len; i++) { - if (!poolAppendChar(&parser->m_tempPool, dtd->defaultPrefix.binding->uri[i])) { - /* Because of memory caching, I don't believe this line can be - * executed. - * - * This is part of a loop copying the default prefix binding - * URI into the parser's temporary string pool. Previously, - * that URI was copied into the same string pool, with a - * terminating NUL character, as part of setContext(). When - * the pool was cleared, that leaves a block definitely big - * enough to hold the URI on the free block list of the pool. - * The URI copy in getContext() therefore cannot run out of - * memory. - * - * If the pool is used between the setContext() and - * getContext() calls, the worst it can do is leave a bigger - * block on the front of the free list. Given that this is - * all somewhat inobvious and program logic can be changed, we - * don't delete the line but we do exclude it from the test - * coverage statistics. - */ - return NULL; /* LCOV_EXCL_LINE */ - } - } - needSep = XML_TRUE; - } - - hashTableIterInit(&iter, &(dtd->prefixes)); - for (;;) { - int i; - int len; - const XML_Char *s; - PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); - if (!prefix) - break; - if (!prefix->binding) { - /* This test appears to be (justifiable) paranoia. There does - * not seem to be a way of injecting a prefix without a binding - * that doesn't get errored long before this function is called. - * The test should remain for safety's sake, so we instead - * exclude the following line from the coverage statistics. - */ - continue; /* LCOV_EXCL_LINE */ - } - if (needSep && !poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) - return NULL; - for (s = prefix->name; *s; s++) - if (!poolAppendChar(&parser->m_tempPool, *s)) - return NULL; - if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) - return NULL; - len = prefix->binding->uriLen; - if (parser->m_namespaceSeparator) - len--; - for (i = 0; i < len; i++) - if (!poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i])) - return NULL; - needSep = XML_TRUE; - } - - - hashTableIterInit(&iter, &(dtd->generalEntities)); - for (;;) { - const XML_Char *s; - ENTITY *e = (ENTITY *)hashTableIterNext(&iter); - if (!e) - break; - if (!e->open) - continue; - if (needSep && !poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) - return NULL; - for (s = e->name; *s; s++) - if (!poolAppendChar(&parser->m_tempPool, *s)) - return 0; - needSep = XML_TRUE; - } - - if (!poolAppendChar(&parser->m_tempPool, XML_T('\0'))) - return NULL; - return parser->m_tempPool.start; -} - -static XML_Bool -setContext(XML_Parser parser, const XML_Char *context) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ - const XML_Char *s = context; - - while (*context != XML_T('\0')) { - if (*s == CONTEXT_SEP || *s == XML_T('\0')) { - ENTITY *e; - if (!poolAppendChar(&parser->m_tempPool, XML_T('\0'))) - return XML_FALSE; - e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&parser->m_tempPool), 0); - if (e) - e->open = XML_TRUE; - if (*s != XML_T('\0')) - s++; - context = s; - poolDiscard(&parser->m_tempPool); - } - else if (*s == XML_T(ASCII_EQUALS)) { - PREFIX *prefix; - if (poolLength(&parser->m_tempPool) == 0) - prefix = &dtd->defaultPrefix; - else { - if (!poolAppendChar(&parser->m_tempPool, XML_T('\0'))) - return XML_FALSE; - prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&parser->m_tempPool), - sizeof(PREFIX)); - if (!prefix) - return XML_FALSE; - if (prefix->name == poolStart(&parser->m_tempPool)) { - prefix->name = poolCopyString(&dtd->pool, prefix->name); - if (!prefix->name) - return XML_FALSE; - } - poolDiscard(&parser->m_tempPool); - } - for (context = s + 1; - *context != CONTEXT_SEP && *context != XML_T('\0'); - context++) - if (!poolAppendChar(&parser->m_tempPool, *context)) - return XML_FALSE; - if (!poolAppendChar(&parser->m_tempPool, XML_T('\0'))) - return XML_FALSE; - if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool), - &parser->m_inheritedBindings) != XML_ERROR_NONE) - return XML_FALSE; - poolDiscard(&parser->m_tempPool); - if (*context != XML_T('\0')) - ++context; - s = context; - } - else { - if (!poolAppendChar(&parser->m_tempPool, *s)) - return XML_FALSE; - s++; - } - } - return XML_TRUE; -} - -static void FASTCALL -normalizePublicId(XML_Char *publicId) -{ - XML_Char *p = publicId; - XML_Char *s; - for (s = publicId; *s; s++) { - switch (*s) { - case 0x20: - case 0xD: - case 0xA: - if (p != publicId && p[-1] != 0x20) - *p++ = 0x20; - break; - default: - *p++ = *s; - } - } - if (p != publicId && p[-1] == 0x20) - --p; - *p = XML_T('\0'); -} - -static DTD * -dtdCreate(const XML_Memory_Handling_Suite *ms) -{ - DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD)); - if (p == NULL) - return p; - poolInit(&(p->pool), ms); - poolInit(&(p->entityValuePool), ms); - hashTableInit(&(p->generalEntities), ms); - hashTableInit(&(p->elementTypes), ms); - hashTableInit(&(p->attributeIds), ms); - hashTableInit(&(p->prefixes), ms); -#ifdef XML_DTD - p->paramEntityRead = XML_FALSE; - hashTableInit(&(p->paramEntities), ms); -#endif /* XML_DTD */ - p->defaultPrefix.name = NULL; - p->defaultPrefix.binding = NULL; - - p->in_eldecl = XML_FALSE; - p->scaffIndex = NULL; - p->scaffold = NULL; - p->scaffLevel = 0; - p->scaffSize = 0; - p->scaffCount = 0; - p->contentStringLen = 0; - - p->keepProcessing = XML_TRUE; - p->hasParamEntityRefs = XML_FALSE; - p->standalone = XML_FALSE; - return p; -} - -static void -dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) -{ - HASH_TABLE_ITER iter; - hashTableIterInit(&iter, &(p->elementTypes)); - for (;;) { - ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); - if (!e) - break; - if (e->allocDefaultAtts != 0) - ms->free_fcn(e->defaultAtts); - } - hashTableClear(&(p->generalEntities)); -#ifdef XML_DTD - p->paramEntityRead = XML_FALSE; - hashTableClear(&(p->paramEntities)); -#endif /* XML_DTD */ - hashTableClear(&(p->elementTypes)); - hashTableClear(&(p->attributeIds)); - hashTableClear(&(p->prefixes)); - poolClear(&(p->pool)); - poolClear(&(p->entityValuePool)); - p->defaultPrefix.name = NULL; - p->defaultPrefix.binding = NULL; - - p->in_eldecl = XML_FALSE; - - ms->free_fcn(p->scaffIndex); - p->scaffIndex = NULL; - ms->free_fcn(p->scaffold); - p->scaffold = NULL; - - p->scaffLevel = 0; - p->scaffSize = 0; - p->scaffCount = 0; - p->contentStringLen = 0; - - p->keepProcessing = XML_TRUE; - p->hasParamEntityRefs = XML_FALSE; - p->standalone = XML_FALSE; -} - -static void -dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) -{ - HASH_TABLE_ITER iter; - hashTableIterInit(&iter, &(p->elementTypes)); - for (;;) { - ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); - if (!e) - break; - if (e->allocDefaultAtts != 0) - ms->free_fcn(e->defaultAtts); - } - hashTableDestroy(&(p->generalEntities)); -#ifdef XML_DTD - hashTableDestroy(&(p->paramEntities)); -#endif /* XML_DTD */ - hashTableDestroy(&(p->elementTypes)); - hashTableDestroy(&(p->attributeIds)); - hashTableDestroy(&(p->prefixes)); - poolDestroy(&(p->pool)); - poolDestroy(&(p->entityValuePool)); - if (isDocEntity) { - ms->free_fcn(p->scaffIndex); - ms->free_fcn(p->scaffold); - } - ms->free_fcn(p); -} - -/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise. - The new DTD has already been initialized. -*/ -static int -dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms) -{ - HASH_TABLE_ITER iter; - - /* Copy the prefix table. */ - - hashTableIterInit(&iter, &(oldDtd->prefixes)); - for (;;) { - const XML_Char *name; - const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); - if (!oldP) - break; - name = poolCopyString(&(newDtd->pool), oldP->name); - if (!name) - return 0; - if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX))) - return 0; - } - - hashTableIterInit(&iter, &(oldDtd->attributeIds)); - - /* Copy the attribute id table. */ - - for (;;) { - ATTRIBUTE_ID *newA; - const XML_Char *name; - const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); - - if (!oldA) - break; - /* Remember to allocate the scratch byte before the name. */ - if (!poolAppendChar(&(newDtd->pool), XML_T('\0'))) - return 0; - name = poolCopyString(&(newDtd->pool), oldA->name); - if (!name) - return 0; - ++name; - newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name, - sizeof(ATTRIBUTE_ID)); - if (!newA) - return 0; - newA->maybeTokenized = oldA->maybeTokenized; - if (oldA->prefix) { - newA->xmlns = oldA->xmlns; - if (oldA->prefix == &oldDtd->defaultPrefix) - newA->prefix = &newDtd->defaultPrefix; - else - newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), - oldA->prefix->name, 0); - } - } - - /* Copy the element type table. */ - - hashTableIterInit(&iter, &(oldDtd->elementTypes)); - - for (;;) { - int i; - ELEMENT_TYPE *newE; - const XML_Char *name; - const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); - if (!oldE) - break; - name = poolCopyString(&(newDtd->pool), oldE->name); - if (!name) - return 0; - newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name, - sizeof(ELEMENT_TYPE)); - if (!newE) - return 0; - if (oldE->nDefaultAtts) { - newE->defaultAtts = (DEFAULT_ATTRIBUTE *) - ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); - if (!newE->defaultAtts) { - return 0; - } - } - if (oldE->idAtt) - newE->idAtt = (ATTRIBUTE_ID *) - lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0); - newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; - if (oldE->prefix) - newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), - oldE->prefix->name, 0); - for (i = 0; i < newE->nDefaultAtts; i++) { - newE->defaultAtts[i].id = (ATTRIBUTE_ID *) - lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); - newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; - if (oldE->defaultAtts[i].value) { - newE->defaultAtts[i].value - = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); - if (!newE->defaultAtts[i].value) - return 0; - } - else - newE->defaultAtts[i].value = NULL; - } - } - - /* Copy the entity tables. */ - if (!copyEntityTable(oldParser, - &(newDtd->generalEntities), - &(newDtd->pool), - &(oldDtd->generalEntities))) - return 0; - -#ifdef XML_DTD - if (!copyEntityTable(oldParser, - &(newDtd->paramEntities), - &(newDtd->pool), - &(oldDtd->paramEntities))) - return 0; - newDtd->paramEntityRead = oldDtd->paramEntityRead; -#endif /* XML_DTD */ - - newDtd->keepProcessing = oldDtd->keepProcessing; - newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs; - newDtd->standalone = oldDtd->standalone; - - /* Don't want deep copying for scaffolding */ - newDtd->in_eldecl = oldDtd->in_eldecl; - newDtd->scaffold = oldDtd->scaffold; - newDtd->contentStringLen = oldDtd->contentStringLen; - newDtd->scaffSize = oldDtd->scaffSize; - newDtd->scaffLevel = oldDtd->scaffLevel; - newDtd->scaffIndex = oldDtd->scaffIndex; - - return 1; -} /* End dtdCopy */ - -static int -copyEntityTable(XML_Parser oldParser, - HASH_TABLE *newTable, - STRING_POOL *newPool, - const HASH_TABLE *oldTable) -{ - HASH_TABLE_ITER iter; - const XML_Char *cachedOldBase = NULL; - const XML_Char *cachedNewBase = NULL; - - hashTableIterInit(&iter, oldTable); - - for (;;) { - ENTITY *newE; - const XML_Char *name; - const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); - if (!oldE) - break; - name = poolCopyString(newPool, oldE->name); - if (!name) - return 0; - newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY)); - if (!newE) - return 0; - if (oldE->systemId) { - const XML_Char *tem = poolCopyString(newPool, oldE->systemId); - if (!tem) - return 0; - newE->systemId = tem; - if (oldE->base) { - if (oldE->base == cachedOldBase) - newE->base = cachedNewBase; - else { - cachedOldBase = oldE->base; - tem = poolCopyString(newPool, cachedOldBase); - if (!tem) - return 0; - cachedNewBase = newE->base = tem; - } - } - if (oldE->publicId) { - tem = poolCopyString(newPool, oldE->publicId); - if (!tem) - return 0; - newE->publicId = tem; - } - } - else { - const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, - oldE->textLen); - if (!tem) - return 0; - newE->textPtr = tem; - newE->textLen = oldE->textLen; - } - if (oldE->notation) { - const XML_Char *tem = poolCopyString(newPool, oldE->notation); - if (!tem) - return 0; - newE->notation = tem; - } - newE->is_param = oldE->is_param; - newE->is_internal = oldE->is_internal; - } - return 1; -} - -#define INIT_POWER 6 - -static XML_Bool FASTCALL -keyeq(KEY s1, KEY s2) -{ - for (; *s1 == *s2; s1++, s2++) - if (*s1 == 0) - return XML_TRUE; - return XML_FALSE; -} - -static size_t -keylen(KEY s) -{ - size_t len = 0; - for (; *s; s++, len++); - return len; -} - -static void -copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key) -{ - key->k[0] = 0; - key->k[1] = get_hash_secret_salt(parser); -} - -static unsigned long FASTCALL -hash(XML_Parser parser, KEY s) -{ - struct siphash state; - struct sipkey key; - (void)sip_tobin; - (void)sip24_valid; - copy_salt_to_sipkey(parser, &key); - sip24_init(&state, &key); - sip24_update(&state, s, keylen(s) * sizeof(XML_Char)); - return (unsigned long)sip24_final(&state); -} - -static NAMED * -lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) -{ - size_t i; - if (table->size == 0) { - size_t tsize; - if (!createSize) - return NULL; - table->power = INIT_POWER; - /* table->size is a power of 2 */ - table->size = (size_t)1 << INIT_POWER; - tsize = table->size * sizeof(NAMED *); - table->v = (NAMED **)table->mem->malloc_fcn(tsize); - if (!table->v) { - table->size = 0; - return NULL; - } - memset(table->v, 0, tsize); - i = hash(parser, name) & ((unsigned long)table->size - 1); - } - else { - unsigned long h = hash(parser, name); - unsigned long mask = (unsigned long)table->size - 1; - unsigned char step = 0; - i = h & mask; - while (table->v[i]) { - if (keyeq(name, table->v[i]->name)) - return table->v[i]; - if (!step) - step = PROBE_STEP(h, mask, table->power); - i < step ? (i += table->size - step) : (i -= step); - } - if (!createSize) - return NULL; - - /* check for overflow (table is half full) */ - if (table->used >> (table->power - 1)) { - unsigned char newPower = table->power + 1; - size_t newSize = (size_t)1 << newPower; - unsigned long newMask = (unsigned long)newSize - 1; - size_t tsize = newSize * sizeof(NAMED *); - NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize); - if (!newV) - return NULL; - memset(newV, 0, tsize); - for (i = 0; i < table->size; i++) - if (table->v[i]) { - unsigned long newHash = hash(parser, table->v[i]->name); - size_t j = newHash & newMask; - step = 0; - while (newV[j]) { - if (!step) - step = PROBE_STEP(newHash, newMask, newPower); - j < step ? (j += newSize - step) : (j -= step); - } - newV[j] = table->v[i]; - } - table->mem->free_fcn(table->v); - table->v = newV; - table->power = newPower; - table->size = newSize; - i = h & newMask; - step = 0; - while (table->v[i]) { - if (!step) - step = PROBE_STEP(h, newMask, newPower); - i < step ? (i += newSize - step) : (i -= step); - } - } - } - table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize); - if (!table->v[i]) - return NULL; - memset(table->v[i], 0, createSize); - table->v[i]->name = name; - (table->used)++; - return table->v[i]; -} - -static void FASTCALL -hashTableClear(HASH_TABLE *table) -{ - size_t i; - for (i = 0; i < table->size; i++) { - table->mem->free_fcn(table->v[i]); - table->v[i] = NULL; - } - table->used = 0; -} - -static void FASTCALL -hashTableDestroy(HASH_TABLE *table) -{ - size_t i; - for (i = 0; i < table->size; i++) - table->mem->free_fcn(table->v[i]); - table->mem->free_fcn(table->v); -} - -static void FASTCALL -hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) -{ - p->power = 0; - p->size = 0; - p->used = 0; - p->v = NULL; - p->mem = ms; -} - -static void FASTCALL -hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) -{ - iter->p = table->v; - iter->end = iter->p + table->size; -} - -static NAMED * FASTCALL -hashTableIterNext(HASH_TABLE_ITER *iter) -{ - while (iter->p != iter->end) { - NAMED *tem = *(iter->p)++; - if (tem) - return tem; - } - return NULL; -} - -static void FASTCALL -poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) -{ - pool->blocks = NULL; - pool->freeBlocks = NULL; - pool->start = NULL; - pool->ptr = NULL; - pool->end = NULL; - pool->mem = ms; -} - -static void FASTCALL -poolClear(STRING_POOL *pool) -{ - if (!pool->freeBlocks) - pool->freeBlocks = pool->blocks; - else { - BLOCK *p = pool->blocks; - while (p) { - BLOCK *tem = p->next; - p->next = pool->freeBlocks; - pool->freeBlocks = p; - p = tem; - } - } - pool->blocks = NULL; - pool->start = NULL; - pool->ptr = NULL; - pool->end = NULL; -} - -static void FASTCALL -poolDestroy(STRING_POOL *pool) -{ - BLOCK *p = pool->blocks; - while (p) { - BLOCK *tem = p->next; - pool->mem->free_fcn(p); - p = tem; - } - p = pool->freeBlocks; - while (p) { - BLOCK *tem = p->next; - pool->mem->free_fcn(p); - p = tem; - } -} - -static XML_Char * -poolAppend(STRING_POOL *pool, const ENCODING *enc, - const char *ptr, const char *end) -{ - if (!pool->ptr && !poolGrow(pool)) - return NULL; - for (;;) { - const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); - if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) - break; - if (!poolGrow(pool)) - return NULL; - } - return pool->start; -} - -static const XML_Char * FASTCALL -poolCopyString(STRING_POOL *pool, const XML_Char *s) -{ - do { - if (!poolAppendChar(pool, *s)) - return NULL; - } while (*s++); - s = pool->start; - poolFinish(pool); - return s; -} - -static const XML_Char * -poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) -{ - if (!pool->ptr && !poolGrow(pool)) { - /* The following line is unreachable given the current usage of - * poolCopyStringN(). Currently it is called from exactly one - * place to copy the text of a simple general entity. By that - * point, the name of the entity is already stored in the pool, so - * pool->ptr cannot be NULL. - * - * If poolCopyStringN() is used elsewhere as it well might be, - * this line may well become executable again. Regardless, this - * sort of check shouldn't be removed lightly, so we just exclude - * it from the coverage statistics. - */ - return NULL; /* LCOV_EXCL_LINE */ - } - for (; n > 0; --n, s++) { - if (!poolAppendChar(pool, *s)) - return NULL; - } - s = pool->start; - poolFinish(pool); - return s; -} - -static const XML_Char * FASTCALL -poolAppendString(STRING_POOL *pool, const XML_Char *s) -{ - while (*s) { - if (!poolAppendChar(pool, *s)) - return NULL; - s++; - } - return pool->start; -} - -static XML_Char * -poolStoreString(STRING_POOL *pool, const ENCODING *enc, - const char *ptr, const char *end) -{ - if (!poolAppend(pool, enc, ptr, end)) - return NULL; - if (pool->ptr == pool->end && !poolGrow(pool)) - return NULL; - *(pool->ptr)++ = 0; - return pool->start; -} - -static size_t -poolBytesToAllocateFor(int blockSize) -{ - /* Unprotected math would be: - ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); - ** - ** Detect overflow, avoiding _signed_ overflow undefined behavior - ** For a + b * c we check b * c in isolation first, so that addition of a - ** on top has no chance of making us accept a small non-negative number - */ - const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */ - - if (blockSize <= 0) - return 0; - - if (blockSize > (int)(INT_MAX / stretch)) - return 0; - - { - const int stretchedBlockSize = blockSize * (int)stretch; - const int bytesToAllocate = (int)( - offsetof(BLOCK, s) + (unsigned)stretchedBlockSize); - if (bytesToAllocate < 0) - return 0; - - return (size_t)bytesToAllocate; - } -} - -static XML_Bool FASTCALL -poolGrow(STRING_POOL *pool) -{ - if (pool->freeBlocks) { - if (pool->start == 0) { - pool->blocks = pool->freeBlocks; - pool->freeBlocks = pool->freeBlocks->next; - pool->blocks->next = NULL; - pool->start = pool->blocks->s; - pool->end = pool->start + pool->blocks->size; - pool->ptr = pool->start; - return XML_TRUE; - } - if (pool->end - pool->start < pool->freeBlocks->size) { - BLOCK *tem = pool->freeBlocks->next; - pool->freeBlocks->next = pool->blocks; - pool->blocks = pool->freeBlocks; - pool->freeBlocks = tem; - memcpy(pool->blocks->s, pool->start, - (pool->end - pool->start) * sizeof(XML_Char)); - pool->ptr = pool->blocks->s + (pool->ptr - pool->start); - pool->start = pool->blocks->s; - pool->end = pool->start + pool->blocks->size; - return XML_TRUE; - } - } - if (pool->blocks && pool->start == pool->blocks->s) { - BLOCK *temp; - int blockSize = (int)((unsigned)(pool->end - pool->start)*2U); - size_t bytesToAllocate; - - /* NOTE: Needs to be calculated prior to calling `realloc` - to avoid dangling pointers: */ - const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start; - - if (blockSize < 0) { - /* This condition traps a situation where either more than - * INT_MAX/2 bytes have already been allocated. This isn't - * readily testable, since it is unlikely that an average - * machine will have that much memory, so we exclude it from the - * coverage statistics. - */ - return XML_FALSE; /* LCOV_EXCL_LINE */ - } - - bytesToAllocate = poolBytesToAllocateFor(blockSize); - if (bytesToAllocate == 0) - return XML_FALSE; - - temp = (BLOCK *) - pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate); - if (temp == NULL) - return XML_FALSE; - pool->blocks = temp; - pool->blocks->size = blockSize; - pool->ptr = pool->blocks->s + offsetInsideBlock; - pool->start = pool->blocks->s; - pool->end = pool->start + blockSize; - } - else { - BLOCK *tem; - int blockSize = (int)(pool->end - pool->start); - size_t bytesToAllocate; - - if (blockSize < 0) { - /* This condition traps a situation where either more than - * INT_MAX bytes have already been allocated (which is prevented - * by various pieces of program logic, not least this one, never - * mind the unlikelihood of actually having that much memory) or - * the pool control fields have been corrupted (which could - * conceivably happen in an extremely buggy user handler - * function). Either way it isn't readily testable, so we - * exclude it from the coverage statistics. - */ - return XML_FALSE; /* LCOV_EXCL_LINE */ - } - - if (blockSize < INIT_BLOCK_SIZE) - blockSize = INIT_BLOCK_SIZE; - else { - /* Detect overflow, avoiding _signed_ overflow undefined behavior */ - if ((int)((unsigned)blockSize * 2U) < 0) { - return XML_FALSE; - } - blockSize *= 2; - } - - bytesToAllocate = poolBytesToAllocateFor(blockSize); - if (bytesToAllocate == 0) - return XML_FALSE; - - tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate); - if (!tem) - return XML_FALSE; - tem->size = blockSize; - tem->next = pool->blocks; - pool->blocks = tem; - if (pool->ptr != pool->start) - memcpy(tem->s, pool->start, - (pool->ptr - pool->start) * sizeof(XML_Char)); - pool->ptr = tem->s + (pool->ptr - pool->start); - pool->start = tem->s; - pool->end = tem->s + blockSize; - } - return XML_TRUE; -} - -static int FASTCALL -nextScaffoldPart(XML_Parser parser) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ - CONTENT_SCAFFOLD * me; - int next; - - if (!dtd->scaffIndex) { - dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int)); - if (!dtd->scaffIndex) - return -1; - dtd->scaffIndex[0] = 0; - } - - if (dtd->scaffCount >= dtd->scaffSize) { - CONTENT_SCAFFOLD *temp; - if (dtd->scaffold) { - temp = (CONTENT_SCAFFOLD *) - REALLOC(parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); - if (temp == NULL) - return -1; - dtd->scaffSize *= 2; - } - else { - temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS - * sizeof(CONTENT_SCAFFOLD)); - if (temp == NULL) - return -1; - dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS; - } - dtd->scaffold = temp; - } - next = dtd->scaffCount++; - me = &dtd->scaffold[next]; - if (dtd->scaffLevel) { - CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]]; - if (parent->lastchild) { - dtd->scaffold[parent->lastchild].nextsib = next; - } - if (!parent->childcnt) - parent->firstchild = next; - parent->lastchild = next; - parent->childcnt++; - } - me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0; - return next; -} - -static void -build_node(XML_Parser parser, - int src_node, - XML_Content *dest, - XML_Content **contpos, - XML_Char **strpos) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ - dest->type = dtd->scaffold[src_node].type; - dest->quant = dtd->scaffold[src_node].quant; - if (dest->type == XML_CTYPE_NAME) { - const XML_Char *src; - dest->name = *strpos; - src = dtd->scaffold[src_node].name; - for (;;) { - *(*strpos)++ = *src; - if (!*src) - break; - src++; - } - dest->numchildren = 0; - dest->children = NULL; - } - else { - unsigned int i; - int cn; - dest->numchildren = dtd->scaffold[src_node].childcnt; - dest->children = *contpos; - *contpos += dest->numchildren; - for (i = 0, cn = dtd->scaffold[src_node].firstchild; - i < dest->numchildren; - i++, cn = dtd->scaffold[cn].nextsib) { - build_node(parser, cn, &(dest->children[i]), contpos, strpos); - } - dest->name = NULL; - } -} - -static XML_Content * -build_model (XML_Parser parser) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ - XML_Content *ret; - XML_Content *cpos; - XML_Char * str; - int allocsize = (dtd->scaffCount * sizeof(XML_Content) - + (dtd->contentStringLen * sizeof(XML_Char))); - - ret = (XML_Content *)MALLOC(parser, allocsize); - if (!ret) - return NULL; - - str = (XML_Char *) (&ret[dtd->scaffCount]); - cpos = &ret[1]; - - build_node(parser, 0, ret, &cpos, &str); - return ret; -} - -static ELEMENT_TYPE * -getElementType(XML_Parser parser, - const ENCODING *enc, - const char *ptr, - const char *end) -{ - DTD * const dtd = parser->m_dtd; /* save one level of indirection */ - const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); - ELEMENT_TYPE *ret; - - if (!name) - return NULL; - ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); - if (!ret) - return NULL; - if (ret->name != name) - poolDiscard(&dtd->pool); - else { - poolFinish(&dtd->pool); - if (!setElementTypePrefix(parser, ret)) - return NULL; - } - return ret; -} - -static XML_Char * -copyString(const XML_Char *s, - const XML_Memory_Handling_Suite *memsuite) -{ - int charsRequired = 0; - XML_Char *result; - - /* First determine how long the string is */ - while (s[charsRequired] != 0) { - charsRequired++; - } - /* Include the terminator */ - charsRequired++; - - /* Now allocate space for the copy */ - result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char)); - if (result == NULL) - return NULL; - /* Copy the original into place */ - memcpy(result, s, charsRequired * sizeof(XML_Char)); - return result; -} diff --git a/tools/sdk/include/expat/xmlrole.c b/tools/sdk/include/expat/xmlrole.c deleted file mode 100644 index 708507d5..00000000 --- a/tools/sdk/include/expat/xmlrole.c +++ /dev/null @@ -1,1386 +0,0 @@ -/* - __ __ _ - ___\ \/ /_ __ __ _| |_ - / _ \\ /| '_ \ / _` | __| - | __// \| |_) | (_| | |_ - \___/_/\_\ .__/ \__,_|\__| - |_| XML parser - - Copyright (c) 1997-2000 Thai Open Source Software Center Ltd - Copyright (c) 2000-2017 Expat development team - Licensed under the MIT license: - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to permit - persons to whom the Software is furnished to do so, subject to the - following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN - NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include - -#ifdef _WIN32 -#include "winconfig.h" -#else -#ifdef HAVE_EXPAT_CONFIG_H -#include -#endif -#endif /* ndef _WIN32 */ - -#include "expat_external.h" -#include "internal.h" -#include "xmlrole.h" -#include "ascii.h" - -/* Doesn't check: - - that ,| are not mixed in a model group - content of literals - -*/ - -static const char KW_ANY[] = { - ASCII_A, ASCII_N, ASCII_Y, '\0' }; -static const char KW_ATTLIST[] = { - ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' }; -static const char KW_CDATA[] = { - ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; -static const char KW_DOCTYPE[] = { - ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' }; -static const char KW_ELEMENT[] = { - ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' }; -static const char KW_EMPTY[] = { - ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' }; -static const char KW_ENTITIES[] = { - ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, - '\0' }; -static const char KW_ENTITY[] = { - ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' }; -static const char KW_FIXED[] = { - ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' }; -static const char KW_ID[] = { - ASCII_I, ASCII_D, '\0' }; -static const char KW_IDREF[] = { - ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' }; -static const char KW_IDREFS[] = { - ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' }; -#ifdef XML_DTD -static const char KW_IGNORE[] = { - ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' }; -#endif -static const char KW_IMPLIED[] = { - ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' }; -#ifdef XML_DTD -static const char KW_INCLUDE[] = { - ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' }; -#endif -static const char KW_NDATA[] = { - ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; -static const char KW_NMTOKEN[] = { - ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' }; -static const char KW_NMTOKENS[] = { - ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, - '\0' }; -static const char KW_NOTATION[] = - { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, - '\0' }; -static const char KW_PCDATA[] = { - ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; -static const char KW_PUBLIC[] = { - ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' }; -static const char KW_REQUIRED[] = { - ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D, - '\0' }; -static const char KW_SYSTEM[] = { - ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' }; - -#ifndef MIN_BYTES_PER_CHAR -#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) -#endif - -#ifdef XML_DTD -#define setTopLevel(state) \ - ((state)->handler = ((state)->documentEntity \ - ? internalSubset \ - : externalSubset1)) -#else /* not XML_DTD */ -#define setTopLevel(state) ((state)->handler = internalSubset) -#endif /* not XML_DTD */ - -typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc); - -static PROLOG_HANDLER - prolog0, prolog1, prolog2, - doctype0, doctype1, doctype2, doctype3, doctype4, doctype5, - internalSubset, - entity0, entity1, entity2, entity3, entity4, entity5, entity6, - entity7, entity8, entity9, entity10, - notation0, notation1, notation2, notation3, notation4, - attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6, - attlist7, attlist8, attlist9, - element0, element1, element2, element3, element4, element5, element6, - element7, -#ifdef XML_DTD - externalSubset0, externalSubset1, - condSect0, condSect1, condSect2, -#endif /* XML_DTD */ - declClose, - error; - -static int FASTCALL common(PROLOG_STATE *state, int tok); - -static int PTRCALL -prolog0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - state->handler = prolog1; - return XML_ROLE_NONE; - case XML_TOK_XML_DECL: - state->handler = prolog1; - return XML_ROLE_XML_DECL; - case XML_TOK_PI: - state->handler = prolog1; - return XML_ROLE_PI; - case XML_TOK_COMMENT: - state->handler = prolog1; - return XML_ROLE_COMMENT; - case XML_TOK_BOM: - return XML_ROLE_NONE; - case XML_TOK_DECL_OPEN: - if (!XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_DOCTYPE)) - break; - state->handler = doctype0; - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_INSTANCE_START: - state->handler = error; - return XML_ROLE_INSTANCE_START; - } - return common(state, tok); -} - -static int PTRCALL -prolog1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_PI: - return XML_ROLE_PI; - case XML_TOK_COMMENT: - return XML_ROLE_COMMENT; - case XML_TOK_BOM: - /* This case can never arise. To reach this role function, the - * parse must have passed through prolog0 and therefore have had - * some form of input, even if only a space. At that point, a - * byte order mark is no longer a valid character (though - * technically it should be interpreted as a non-breaking space), - * so will be rejected by the tokenizing stages. - */ - return XML_ROLE_NONE; /* LCOV_EXCL_LINE */ - case XML_TOK_DECL_OPEN: - if (!XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_DOCTYPE)) - break; - state->handler = doctype0; - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_INSTANCE_START: - state->handler = error; - return XML_ROLE_INSTANCE_START; - } - return common(state, tok); -} - -static int PTRCALL -prolog2(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_PI: - return XML_ROLE_PI; - case XML_TOK_COMMENT: - return XML_ROLE_COMMENT; - case XML_TOK_INSTANCE_START: - state->handler = error; - return XML_ROLE_INSTANCE_START; - } - return common(state, tok); -} - -static int PTRCALL -doctype0(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = doctype1; - return XML_ROLE_DOCTYPE_NAME; - } - return common(state, tok); -} - -static int PTRCALL -doctype1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_OPEN_BRACKET: - state->handler = internalSubset; - return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; - case XML_TOK_DECL_CLOSE: - state->handler = prolog2; - return XML_ROLE_DOCTYPE_CLOSE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { - state->handler = doctype3; - return XML_ROLE_DOCTYPE_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { - state->handler = doctype2; - return XML_ROLE_DOCTYPE_NONE; - } - break; - } - return common(state, tok); -} - -static int PTRCALL -doctype2(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_LITERAL: - state->handler = doctype3; - return XML_ROLE_DOCTYPE_PUBLIC_ID; - } - return common(state, tok); -} - -static int PTRCALL -doctype3(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_LITERAL: - state->handler = doctype4; - return XML_ROLE_DOCTYPE_SYSTEM_ID; - } - return common(state, tok); -} - -static int PTRCALL -doctype4(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_OPEN_BRACKET: - state->handler = internalSubset; - return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; - case XML_TOK_DECL_CLOSE: - state->handler = prolog2; - return XML_ROLE_DOCTYPE_CLOSE; - } - return common(state, tok); -} - -static int PTRCALL -doctype5(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_DECL_CLOSE: - state->handler = prolog2; - return XML_ROLE_DOCTYPE_CLOSE; - } - return common(state, tok); -} - -static int PTRCALL -internalSubset(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_DECL_OPEN: - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_ENTITY)) { - state->handler = entity0; - return XML_ROLE_ENTITY_NONE; - } - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_ATTLIST)) { - state->handler = attlist0; - return XML_ROLE_ATTLIST_NONE; - } - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_ELEMENT)) { - state->handler = element0; - return XML_ROLE_ELEMENT_NONE; - } - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_NOTATION)) { - state->handler = notation0; - return XML_ROLE_NOTATION_NONE; - } - break; - case XML_TOK_PI: - return XML_ROLE_PI; - case XML_TOK_COMMENT: - return XML_ROLE_COMMENT; - case XML_TOK_PARAM_ENTITY_REF: - return XML_ROLE_PARAM_ENTITY_REF; - case XML_TOK_CLOSE_BRACKET: - state->handler = doctype5; - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_NONE: - return XML_ROLE_NONE; - } - return common(state, tok); -} - -#ifdef XML_DTD - -static int PTRCALL -externalSubset0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - state->handler = externalSubset1; - if (tok == XML_TOK_XML_DECL) - return XML_ROLE_TEXT_DECL; - return externalSubset1(state, tok, ptr, end, enc); -} - -static int PTRCALL -externalSubset1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_COND_SECT_OPEN: - state->handler = condSect0; - return XML_ROLE_NONE; - case XML_TOK_COND_SECT_CLOSE: - if (state->includeLevel == 0) - break; - state->includeLevel -= 1; - return XML_ROLE_NONE; - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_CLOSE_BRACKET: - break; - case XML_TOK_NONE: - if (state->includeLevel) - break; - return XML_ROLE_NONE; - default: - return internalSubset(state, tok, ptr, end, enc); - } - return common(state, tok); -} - -#endif /* XML_DTD */ - -static int PTRCALL -entity0(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_PERCENT: - state->handler = entity1; - return XML_ROLE_ENTITY_NONE; - case XML_TOK_NAME: - state->handler = entity2; - return XML_ROLE_GENERAL_ENTITY_NAME; - } - return common(state, tok); -} - -static int PTRCALL -entity1(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_NAME: - state->handler = entity7; - return XML_ROLE_PARAM_ENTITY_NAME; - } - return common(state, tok); -} - -static int PTRCALL -entity2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { - state->handler = entity4; - return XML_ROLE_ENTITY_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { - state->handler = entity3; - return XML_ROLE_ENTITY_NONE; - } - break; - case XML_TOK_LITERAL: - state->handler = declClose; - state->role_none = XML_ROLE_ENTITY_NONE; - return XML_ROLE_ENTITY_VALUE; - } - return common(state, tok); -} - -static int PTRCALL -entity3(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_LITERAL: - state->handler = entity4; - return XML_ROLE_ENTITY_PUBLIC_ID; - } - return common(state, tok); -} - -static int PTRCALL -entity4(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_LITERAL: - state->handler = entity5; - return XML_ROLE_ENTITY_SYSTEM_ID; - } - return common(state, tok); -} - -static int PTRCALL -entity5(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_DECL_CLOSE: - setTopLevel(state); - return XML_ROLE_ENTITY_COMPLETE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) { - state->handler = entity6; - return XML_ROLE_ENTITY_NONE; - } - break; - } - return common(state, tok); -} - -static int PTRCALL -entity6(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_NAME: - state->handler = declClose; - state->role_none = XML_ROLE_ENTITY_NONE; - return XML_ROLE_ENTITY_NOTATION_NAME; - } - return common(state, tok); -} - -static int PTRCALL -entity7(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { - state->handler = entity9; - return XML_ROLE_ENTITY_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { - state->handler = entity8; - return XML_ROLE_ENTITY_NONE; - } - break; - case XML_TOK_LITERAL: - state->handler = declClose; - state->role_none = XML_ROLE_ENTITY_NONE; - return XML_ROLE_ENTITY_VALUE; - } - return common(state, tok); -} - -static int PTRCALL -entity8(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_LITERAL: - state->handler = entity9; - return XML_ROLE_ENTITY_PUBLIC_ID; - } - return common(state, tok); -} - -static int PTRCALL -entity9(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_LITERAL: - state->handler = entity10; - return XML_ROLE_ENTITY_SYSTEM_ID; - } - return common(state, tok); -} - -static int PTRCALL -entity10(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_DECL_CLOSE: - setTopLevel(state); - return XML_ROLE_ENTITY_COMPLETE; - } - return common(state, tok); -} - -static int PTRCALL -notation0(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NOTATION_NONE; - case XML_TOK_NAME: - state->handler = notation1; - return XML_ROLE_NOTATION_NAME; - } - return common(state, tok); -} - -static int PTRCALL -notation1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NOTATION_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { - state->handler = notation3; - return XML_ROLE_NOTATION_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { - state->handler = notation2; - return XML_ROLE_NOTATION_NONE; - } - break; - } - return common(state, tok); -} - -static int PTRCALL -notation2(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NOTATION_NONE; - case XML_TOK_LITERAL: - state->handler = notation4; - return XML_ROLE_NOTATION_PUBLIC_ID; - } - return common(state, tok); -} - -static int PTRCALL -notation3(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NOTATION_NONE; - case XML_TOK_LITERAL: - state->handler = declClose; - state->role_none = XML_ROLE_NOTATION_NONE; - return XML_ROLE_NOTATION_SYSTEM_ID; - } - return common(state, tok); -} - -static int PTRCALL -notation4(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NOTATION_NONE; - case XML_TOK_LITERAL: - state->handler = declClose; - state->role_none = XML_ROLE_NOTATION_NONE; - return XML_ROLE_NOTATION_SYSTEM_ID; - case XML_TOK_DECL_CLOSE: - setTopLevel(state); - return XML_ROLE_NOTATION_NO_SYSTEM_ID; - } - return common(state, tok); -} - -static int PTRCALL -attlist0(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = attlist1; - return XML_ROLE_ATTLIST_ELEMENT_NAME; - } - return common(state, tok); -} - -static int PTRCALL -attlist1(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_DECL_CLOSE: - setTopLevel(state); - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = attlist2; - return XML_ROLE_ATTRIBUTE_NAME; - } - return common(state, tok); -} - -static int PTRCALL -attlist2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_NAME: - { - static const char * const types[] = { - KW_CDATA, - KW_ID, - KW_IDREF, - KW_IDREFS, - KW_ENTITY, - KW_ENTITIES, - KW_NMTOKEN, - KW_NMTOKENS, - }; - int i; - for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++) - if (XmlNameMatchesAscii(enc, ptr, end, types[i])) { - state->handler = attlist8; - return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; - } - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) { - state->handler = attlist5; - return XML_ROLE_ATTLIST_NONE; - } - break; - case XML_TOK_OPEN_PAREN: - state->handler = attlist3; - return XML_ROLE_ATTLIST_NONE; - } - return common(state, tok); -} - -static int PTRCALL -attlist3(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_NMTOKEN: - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = attlist4; - return XML_ROLE_ATTRIBUTE_ENUM_VALUE; - } - return common(state, tok); -} - -static int PTRCALL -attlist4(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_CLOSE_PAREN: - state->handler = attlist8; - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_OR: - state->handler = attlist3; - return XML_ROLE_ATTLIST_NONE; - } - return common(state, tok); -} - -static int PTRCALL -attlist5(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_OPEN_PAREN: - state->handler = attlist6; - return XML_ROLE_ATTLIST_NONE; - } - return common(state, tok); -} - -static int PTRCALL -attlist6(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_NAME: - state->handler = attlist7; - return XML_ROLE_ATTRIBUTE_NOTATION_VALUE; - } - return common(state, tok); -} - -static int PTRCALL -attlist7(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_CLOSE_PAREN: - state->handler = attlist8; - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_OR: - state->handler = attlist6; - return XML_ROLE_ATTLIST_NONE; - } - return common(state, tok); -} - -/* default value */ -static int PTRCALL -attlist8(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_POUND_NAME: - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, - KW_IMPLIED)) { - state->handler = attlist1; - return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; - } - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, - KW_REQUIRED)) { - state->handler = attlist1; - return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; - } - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, - KW_FIXED)) { - state->handler = attlist9; - return XML_ROLE_ATTLIST_NONE; - } - break; - case XML_TOK_LITERAL: - state->handler = attlist1; - return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE; - } - return common(state, tok); -} - -static int PTRCALL -attlist9(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_LITERAL: - state->handler = attlist1; - return XML_ROLE_FIXED_ATTRIBUTE_VALUE; - } - return common(state, tok); -} - -static int PTRCALL -element0(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = element1; - return XML_ROLE_ELEMENT_NAME; - } - return common(state, tok); -} - -static int PTRCALL -element1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) { - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - return XML_ROLE_CONTENT_EMPTY; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) { - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - return XML_ROLE_CONTENT_ANY; - } - break; - case XML_TOK_OPEN_PAREN: - state->handler = element2; - state->level = 1; - return XML_ROLE_GROUP_OPEN; - } - return common(state, tok); -} - -static int PTRCALL -element2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_POUND_NAME: - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, - KW_PCDATA)) { - state->handler = element3; - return XML_ROLE_CONTENT_PCDATA; - } - break; - case XML_TOK_OPEN_PAREN: - state->level = 2; - state->handler = element6; - return XML_ROLE_GROUP_OPEN; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT; - case XML_TOK_NAME_QUESTION: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_OPT; - case XML_TOK_NAME_ASTERISK: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_REP; - case XML_TOK_NAME_PLUS: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_PLUS; - } - return common(state, tok); -} - -static int PTRCALL -element3(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_CLOSE_PAREN: - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - return XML_ROLE_GROUP_CLOSE; - case XML_TOK_CLOSE_PAREN_ASTERISK: - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - return XML_ROLE_GROUP_CLOSE_REP; - case XML_TOK_OR: - state->handler = element4; - return XML_ROLE_ELEMENT_NONE; - } - return common(state, tok); -} - -static int PTRCALL -element4(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = element5; - return XML_ROLE_CONTENT_ELEMENT; - } - return common(state, tok); -} - -static int PTRCALL -element5(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_CLOSE_PAREN_ASTERISK: - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - return XML_ROLE_GROUP_CLOSE_REP; - case XML_TOK_OR: - state->handler = element4; - return XML_ROLE_ELEMENT_NONE; - } - return common(state, tok); -} - -static int PTRCALL -element6(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_OPEN_PAREN: - state->level += 1; - return XML_ROLE_GROUP_OPEN; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT; - case XML_TOK_NAME_QUESTION: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_OPT; - case XML_TOK_NAME_ASTERISK: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_REP; - case XML_TOK_NAME_PLUS: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_PLUS; - } - return common(state, tok); -} - -static int PTRCALL -element7(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_CLOSE_PAREN: - state->level -= 1; - if (state->level == 0) { - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - } - return XML_ROLE_GROUP_CLOSE; - case XML_TOK_CLOSE_PAREN_ASTERISK: - state->level -= 1; - if (state->level == 0) { - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - } - return XML_ROLE_GROUP_CLOSE_REP; - case XML_TOK_CLOSE_PAREN_QUESTION: - state->level -= 1; - if (state->level == 0) { - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - } - return XML_ROLE_GROUP_CLOSE_OPT; - case XML_TOK_CLOSE_PAREN_PLUS: - state->level -= 1; - if (state->level == 0) { - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - } - return XML_ROLE_GROUP_CLOSE_PLUS; - case XML_TOK_COMMA: - state->handler = element6; - return XML_ROLE_GROUP_SEQUENCE; - case XML_TOK_OR: - state->handler = element6; - return XML_ROLE_GROUP_CHOICE; - } - return common(state, tok); -} - -#ifdef XML_DTD - -static int PTRCALL -condSect0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) { - state->handler = condSect1; - return XML_ROLE_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) { - state->handler = condSect2; - return XML_ROLE_NONE; - } - break; - } - return common(state, tok); -} - -static int PTRCALL -condSect1(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_OPEN_BRACKET: - state->handler = externalSubset1; - state->includeLevel += 1; - return XML_ROLE_NONE; - } - return common(state, tok); -} - -static int PTRCALL -condSect2(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_OPEN_BRACKET: - state->handler = externalSubset1; - return XML_ROLE_IGNORE_SECT; - } - return common(state, tok); -} - -#endif /* XML_DTD */ - -static int PTRCALL -declClose(PROLOG_STATE *state, - int tok, - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return state->role_none; - case XML_TOK_DECL_CLOSE: - setTopLevel(state); - return state->role_none; - } - return common(state, tok); -} - -/* This function will only be invoked if the internal logic of the - * parser has broken down. It is used in two cases: - * - * 1: When the XML prolog has been finished. At this point the - * processor (the parser level above these role handlers) should - * switch from prologProcessor to contentProcessor and reinitialise - * the handler function. - * - * 2: When an error has been detected (via common() below). At this - * point again the processor should be switched to errorProcessor, - * which will never call a handler. - * - * The result of this is that error() can only be called if the - * processor switch failed to happen, which is an internal error and - * therefore we shouldn't be able to provoke it simply by using the - * library. It is a necessary backstop, however, so we merely exclude - * it from the coverage statistics. - * - * LCOV_EXCL_START - */ -static int PTRCALL -error(PROLOG_STATE *UNUSED_P(state), - int UNUSED_P(tok), - const char *UNUSED_P(ptr), - const char *UNUSED_P(end), - const ENCODING *UNUSED_P(enc)) -{ - return XML_ROLE_NONE; -} -/* LCOV_EXCL_STOP */ - -static int FASTCALL -common(PROLOG_STATE *state, int tok) -{ -#ifdef XML_DTD - if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) - return XML_ROLE_INNER_PARAM_ENTITY_REF; -#endif - state->handler = error; - return XML_ROLE_ERROR; -} - -void -XmlPrologStateInit(PROLOG_STATE *state) -{ - state->handler = prolog0; -#ifdef XML_DTD - state->documentEntity = 1; - state->includeLevel = 0; - state->inEntityValue = 0; -#endif /* XML_DTD */ -} - -#ifdef XML_DTD - -void -XmlPrologStateInitExternalEntity(PROLOG_STATE *state) -{ - state->handler = externalSubset0; - state->documentEntity = 0; - state->includeLevel = 0; -} - -#endif /* XML_DTD */ diff --git a/tools/sdk/include/expat/xmltok.c b/tools/sdk/include/expat/xmltok.c deleted file mode 100644 index 6b415d83..00000000 --- a/tools/sdk/include/expat/xmltok.c +++ /dev/null @@ -1,1806 +0,0 @@ -/* - __ __ _ - ___\ \/ /_ __ __ _| |_ - / _ \\ /| '_ \ / _` | __| - | __// \| |_) | (_| | |_ - \___/_/\_\ .__/ \__,_|\__| - |_| XML parser - - Copyright (c) 1997-2000 Thai Open Source Software Center Ltd - Copyright (c) 2000-2017 Expat development team - Licensed under the MIT license: - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to permit - persons to whom the Software is furnished to do so, subject to the - following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN - NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include -#include /* memcpy */ - -#if defined(_MSC_VER) && (_MSC_VER <= 1700) - /* for vs2012/11.0/1700 and earlier Visual Studio compilers */ -# define bool int -# define false 0 -# define true 1 -#else -# include -#endif - - -#ifdef _WIN32 -#include "winconfig.h" -#else -#ifdef HAVE_EXPAT_CONFIG_H -#include -#endif -#endif /* ndef _WIN32 */ - -#include "expat_external.h" -#include "internal.h" -#include "xmltok.h" -#include "nametab.h" - -#ifdef XML_DTD -#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok) -#else -#define IGNORE_SECTION_TOK_VTABLE /* as nothing */ -#endif - -#define VTABLE1 \ - { PREFIX(prologTok), PREFIX(contentTok), \ - PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \ - { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \ - PREFIX(nameMatchesAscii), \ - PREFIX(nameLength), \ - PREFIX(skipS), \ - PREFIX(getAtts), \ - PREFIX(charRefNumber), \ - PREFIX(predefinedEntityName), \ - PREFIX(updatePosition), \ - PREFIX(isPublicId) - -#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) - -#define UCS2_GET_NAMING(pages, hi, lo) \ - (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F))) - -/* A 2 byte UTF-8 representation splits the characters 11 bits between - the bottom 5 and 6 bits of the bytes. We need 8 bits to index into - pages, 3 bits to add to that index and 5 bits to generate the mask. -*/ -#define UTF8_GET_NAMING2(pages, byte) \ - (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ - + ((((byte)[0]) & 3) << 1) \ - + ((((byte)[1]) >> 5) & 1)] \ - & (1u << (((byte)[1]) & 0x1F))) - -/* A 3 byte UTF-8 representation splits the characters 16 bits between - the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index - into pages, 3 bits to add to that index and 5 bits to generate the - mask. -*/ -#define UTF8_GET_NAMING3(pages, byte) \ - (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \ - + ((((byte)[1]) >> 2) & 0xF)] \ - << 3) \ - + ((((byte)[1]) & 3) << 1) \ - + ((((byte)[2]) >> 5) & 1)] \ - & (1u << (((byte)[2]) & 0x1F))) - -#define UTF8_GET_NAMING(pages, p, n) \ - ((n) == 2 \ - ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \ - : ((n) == 3 \ - ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \ - : 0)) - -/* Detection of invalid UTF-8 sequences is based on Table 3.1B - of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/ - with the additional restriction of not allowing the Unicode - code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE). - Implementation details: - (A & 0x80) == 0 means A < 0x80 - and - (A & 0xC0) == 0xC0 means A > 0xBF -*/ - -#define UTF8_INVALID2(p) \ - ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0) - -#define UTF8_INVALID3(p) \ - (((p)[2] & 0x80) == 0 \ - || \ - ((*p) == 0xEF && (p)[1] == 0xBF \ - ? \ - (p)[2] > 0xBD \ - : \ - ((p)[2] & 0xC0) == 0xC0) \ - || \ - ((*p) == 0xE0 \ - ? \ - (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \ - : \ - ((p)[1] & 0x80) == 0 \ - || \ - ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0))) - -#define UTF8_INVALID4(p) \ - (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \ - || \ - ((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \ - || \ - ((*p) == 0xF0 \ - ? \ - (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \ - : \ - ((p)[1] & 0x80) == 0 \ - || \ - ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0))) - -static int PTRFASTCALL -isNever(const ENCODING *UNUSED_P(enc), const char *UNUSED_P(p)) -{ - return 0; -} - -static int PTRFASTCALL -utf8_isName2(const ENCODING *UNUSED_P(enc), const char *p) -{ - return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); -} - -static int PTRFASTCALL -utf8_isName3(const ENCODING *UNUSED_P(enc), const char *p) -{ - return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); -} - -#define utf8_isName4 isNever - -static int PTRFASTCALL -utf8_isNmstrt2(const ENCODING *UNUSED_P(enc), const char *p) -{ - return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); -} - -static int PTRFASTCALL -utf8_isNmstrt3(const ENCODING *UNUSED_P(enc), const char *p) -{ - return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); -} - -#define utf8_isNmstrt4 isNever - -static int PTRFASTCALL -utf8_isInvalid2(const ENCODING *UNUSED_P(enc), const char *p) -{ - return UTF8_INVALID2((const unsigned char *)p); -} - -static int PTRFASTCALL -utf8_isInvalid3(const ENCODING *UNUSED_P(enc), const char *p) -{ - return UTF8_INVALID3((const unsigned char *)p); -} - -static int PTRFASTCALL -utf8_isInvalid4(const ENCODING *UNUSED_P(enc), const char *p) -{ - return UTF8_INVALID4((const unsigned char *)p); -} - -struct normal_encoding { - ENCODING enc; - unsigned char type[256]; -#ifdef XML_MIN_SIZE - int (PTRFASTCALL *byteType)(const ENCODING *, const char *); - int (PTRFASTCALL *isNameMin)(const ENCODING *, const char *); - int (PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *); - int (PTRFASTCALL *byteToAscii)(const ENCODING *, const char *); - int (PTRCALL *charMatches)(const ENCODING *, const char *, int); -#endif /* XML_MIN_SIZE */ - int (PTRFASTCALL *isName2)(const ENCODING *, const char *); - int (PTRFASTCALL *isName3)(const ENCODING *, const char *); - int (PTRFASTCALL *isName4)(const ENCODING *, const char *); - int (PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *); - int (PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *); - int (PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *); - int (PTRFASTCALL *isInvalid2)(const ENCODING *, const char *); - int (PTRFASTCALL *isInvalid3)(const ENCODING *, const char *); - int (PTRFASTCALL *isInvalid4)(const ENCODING *, const char *); -}; - -#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *) (enc)) - -#ifdef XML_MIN_SIZE - -#define STANDARD_VTABLE(E) \ - E ## byteType, \ - E ## isNameMin, \ - E ## isNmstrtMin, \ - E ## byteToAscii, \ - E ## charMatches, - -#else - -#define STANDARD_VTABLE(E) /* as nothing */ - -#endif - -#define NORMAL_VTABLE(E) \ - E ## isName2, \ - E ## isName3, \ - E ## isName4, \ - E ## isNmstrt2, \ - E ## isNmstrt3, \ - E ## isNmstrt4, \ - E ## isInvalid2, \ - E ## isInvalid3, \ - E ## isInvalid4 - -#define NULL_VTABLE \ - /* isName2 */ NULL, \ - /* isName3 */ NULL, \ - /* isName4 */ NULL, \ - /* isNmstrt2 */ NULL, \ - /* isNmstrt3 */ NULL, \ - /* isNmstrt4 */ NULL, \ - /* isInvalid2 */ NULL, \ - /* isInvalid3 */ NULL, \ - /* isInvalid4 */ NULL - -static int FASTCALL checkCharRefNumber(int); - -#include "xmltok_impl.h" -#include "ascii.h" - -#ifdef XML_MIN_SIZE -#define sb_isNameMin isNever -#define sb_isNmstrtMin isNever -#endif - -#ifdef XML_MIN_SIZE -#define MINBPC(enc) ((enc)->minBytesPerChar) -#else -/* minimum bytes per character */ -#define MINBPC(enc) 1 -#endif - -#define SB_BYTE_TYPE(enc, p) \ - (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) - -#ifdef XML_MIN_SIZE -static int PTRFASTCALL -sb_byteType(const ENCODING *enc, const char *p) -{ - return SB_BYTE_TYPE(enc, p); -} -#define BYTE_TYPE(enc, p) \ - (AS_NORMAL_ENCODING(enc)->byteType(enc, p)) -#else -#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) -#endif - -#ifdef XML_MIN_SIZE -#define BYTE_TO_ASCII(enc, p) \ - (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p)) -static int PTRFASTCALL -sb_byteToAscii(const ENCODING *enc, const char *p) -{ - return *p; -} -#else -#define BYTE_TO_ASCII(enc, p) (*(p)) -#endif - -#define IS_NAME_CHAR(enc, p, n) \ - (AS_NORMAL_ENCODING(enc)->isName ## n(enc, p)) -#define IS_NMSTRT_CHAR(enc, p, n) \ - (AS_NORMAL_ENCODING(enc)->isNmstrt ## n(enc, p)) -#define IS_INVALID_CHAR(enc, p, n) \ - (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p)) - -#ifdef XML_MIN_SIZE -#define IS_NAME_CHAR_MINBPC(enc, p) \ - (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p)) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) \ - (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p)) -#else -#define IS_NAME_CHAR_MINBPC(enc, p) (0) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) -#endif - -#ifdef XML_MIN_SIZE -#define CHAR_MATCHES(enc, p, c) \ - (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c)) -static int PTRCALL -sb_charMatches(const ENCODING *enc, const char *p, int c) -{ - return *p == c; -} -#else -/* c is an ASCII character */ -#define CHAR_MATCHES(enc, p, c) (*(p) == c) -#endif - -#define PREFIX(ident) normal_ ## ident -#define XML_TOK_IMPL_C -#include "xmltok_impl.c" -#undef XML_TOK_IMPL_C - -#undef MINBPC -#undef BYTE_TYPE -#undef BYTE_TO_ASCII -#undef CHAR_MATCHES -#undef IS_NAME_CHAR -#undef IS_NAME_CHAR_MINBPC -#undef IS_NMSTRT_CHAR -#undef IS_NMSTRT_CHAR_MINBPC -#undef IS_INVALID_CHAR - -enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ - UTF8_cval1 = 0x00, - UTF8_cval2 = 0xc0, - UTF8_cval3 = 0xe0, - UTF8_cval4 = 0xf0 -}; - -void -_INTERNAL_trim_to_complete_utf8_characters(const char * from, const char ** fromLimRef) -{ - const char * fromLim = *fromLimRef; - size_t walked = 0; - for (; fromLim > from; fromLim--, walked++) { - const unsigned char prev = (unsigned char)fromLim[-1]; - if ((prev & 0xf8u) == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */ - if (walked + 1 >= 4) { - fromLim += 4 - 1; - break; - } else { - walked = 0; - } - } else if ((prev & 0xf0u) == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */ - if (walked + 1 >= 3) { - fromLim += 3 - 1; - break; - } else { - walked = 0; - } - } else if ((prev & 0xe0u) == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */ - if (walked + 1 >= 2) { - fromLim += 2 - 1; - break; - } else { - walked = 0; - } - } else if ((prev & 0x80u) == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */ - break; - } - } - *fromLimRef = fromLim; -} - -static enum XML_Convert_Result PTRCALL -utf8_toUtf8(const ENCODING *UNUSED_P(enc), - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ - bool input_incomplete = false; - bool output_exhausted = false; - - /* Avoid copying partial characters (due to limited space). */ - const ptrdiff_t bytesAvailable = fromLim - *fromP; - const ptrdiff_t bytesStorable = toLim - *toP; - if (bytesAvailable > bytesStorable) { - fromLim = *fromP + bytesStorable; - output_exhausted = true; - } - - /* Avoid copying partial characters (from incomplete input). */ - { - const char * const fromLimBefore = fromLim; - _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim); - if (fromLim < fromLimBefore) { - input_incomplete = true; - } - } - - { - const ptrdiff_t bytesToCopy = fromLim - *fromP; - memcpy(*toP, *fromP, bytesToCopy); - *fromP += bytesToCopy; - *toP += bytesToCopy; - } - - if (output_exhausted) /* needs to go first */ - return XML_CONVERT_OUTPUT_EXHAUSTED; - else if (input_incomplete) - return XML_CONVERT_INPUT_INCOMPLETE; - else - return XML_CONVERT_COMPLETED; -} - -static enum XML_Convert_Result PTRCALL -utf8_toUtf16(const ENCODING *enc, - const char **fromP, const char *fromLim, - unsigned short **toP, const unsigned short *toLim) -{ - enum XML_Convert_Result res = XML_CONVERT_COMPLETED; - unsigned short *to = *toP; - const char *from = *fromP; - while (from < fromLim && to < toLim) { - switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) { - case BT_LEAD2: - if (fromLim - from < 2) { - res = XML_CONVERT_INPUT_INCOMPLETE; - goto after; - } - *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); - from += 2; - break; - case BT_LEAD3: - if (fromLim - from < 3) { - res = XML_CONVERT_INPUT_INCOMPLETE; - goto after; - } - *to++ = (unsigned short)(((from[0] & 0xf) << 12) - | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f)); - from += 3; - break; - case BT_LEAD4: - { - unsigned long n; - if (toLim - to < 2) { - res = XML_CONVERT_OUTPUT_EXHAUSTED; - goto after; - } - if (fromLim - from < 4) { - res = XML_CONVERT_INPUT_INCOMPLETE; - goto after; - } - n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) - | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); - n -= 0x10000; - to[0] = (unsigned short)((n >> 10) | 0xD800); - to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); - to += 2; - from += 4; - } - break; - default: - *to++ = *from++; - break; - } - } - if (from < fromLim) - res = XML_CONVERT_OUTPUT_EXHAUSTED; -after: - *fromP = from; - *toP = to; - return res; -} - -#ifdef XML_NS -static const struct normal_encoding utf8_encoding_ns = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { -#include "asciitab.h" -#include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; -#endif - -static const struct normal_encoding utf8_encoding = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -#include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; - -#ifdef XML_NS - -static const struct normal_encoding internal_utf8_encoding_ns = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { -#include "iasciitab.h" -#include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; - -#endif - -static const struct normal_encoding internal_utf8_encoding = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { -#define BT_COLON BT_NMSTRT -#include "iasciitab.h" -#undef BT_COLON -#include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; - -static enum XML_Convert_Result PTRCALL -latin1_toUtf8(const ENCODING *UNUSED_P(enc), - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ - for (;;) { - unsigned char c; - if (*fromP == fromLim) - return XML_CONVERT_COMPLETED; - c = (unsigned char)**fromP; - if (c & 0x80) { - if (toLim - *toP < 2) - return XML_CONVERT_OUTPUT_EXHAUSTED; - *(*toP)++ = (char)((c >> 6) | UTF8_cval2); - *(*toP)++ = (char)((c & 0x3f) | 0x80); - (*fromP)++; - } - else { - if (*toP == toLim) - return XML_CONVERT_OUTPUT_EXHAUSTED; - *(*toP)++ = *(*fromP)++; - } - } -} - -static enum XML_Convert_Result PTRCALL -latin1_toUtf16(const ENCODING *UNUSED_P(enc), - const char **fromP, const char *fromLim, - unsigned short **toP, const unsigned short *toLim) -{ - while (*fromP < fromLim && *toP < toLim) - *(*toP)++ = (unsigned char)*(*fromP)++; - - if ((*toP == toLim) && (*fromP < fromLim)) - return XML_CONVERT_OUTPUT_EXHAUSTED; - else - return XML_CONVERT_COMPLETED; -} - -#ifdef XML_NS - -static const struct normal_encoding latin1_encoding_ns = { - { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, - { -#include "asciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(sb_) NULL_VTABLE -}; - -#endif - -static const struct normal_encoding latin1_encoding = { - { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(sb_) NULL_VTABLE -}; - -static enum XML_Convert_Result PTRCALL -ascii_toUtf8(const ENCODING *UNUSED_P(enc), - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ - while (*fromP < fromLim && *toP < toLim) - *(*toP)++ = *(*fromP)++; - - if ((*toP == toLim) && (*fromP < fromLim)) - return XML_CONVERT_OUTPUT_EXHAUSTED; - else - return XML_CONVERT_COMPLETED; -} - -#ifdef XML_NS - -static const struct normal_encoding ascii_encoding_ns = { - { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, - { -#include "asciitab.h" -/* BT_NONXML == 0 */ - }, - STANDARD_VTABLE(sb_) NULL_VTABLE -}; - -#endif - -static const struct normal_encoding ascii_encoding = { - { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -/* BT_NONXML == 0 */ - }, - STANDARD_VTABLE(sb_) NULL_VTABLE -}; - -static int PTRFASTCALL -unicode_byte_type(char hi, char lo) -{ - switch ((unsigned char)hi) { - case 0xD8: case 0xD9: case 0xDA: case 0xDB: - return BT_LEAD4; - case 0xDC: case 0xDD: case 0xDE: case 0xDF: - return BT_TRAIL; - case 0xFF: - switch ((unsigned char)lo) { - case 0xFF: - case 0xFE: - return BT_NONXML; - } - break; - } - return BT_NONASCII; -} - -#define DEFINE_UTF16_TO_UTF8(E) \ -static enum XML_Convert_Result PTRCALL \ -E ## toUtf8(const ENCODING *UNUSED_P(enc), \ - const char **fromP, const char *fromLim, \ - char **toP, const char *toLim) \ -{ \ - const char *from = *fromP; \ - fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \ - for (; from < fromLim; from += 2) { \ - int plane; \ - unsigned char lo2; \ - unsigned char lo = GET_LO(from); \ - unsigned char hi = GET_HI(from); \ - switch (hi) { \ - case 0: \ - if (lo < 0x80) { \ - if (*toP == toLim) { \ - *fromP = from; \ - return XML_CONVERT_OUTPUT_EXHAUSTED; \ - } \ - *(*toP)++ = lo; \ - break; \ - } \ - /* fall through */ \ - case 0x1: case 0x2: case 0x3: \ - case 0x4: case 0x5: case 0x6: case 0x7: \ - if (toLim - *toP < 2) { \ - *fromP = from; \ - return XML_CONVERT_OUTPUT_EXHAUSTED; \ - } \ - *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ - *(*toP)++ = ((lo & 0x3f) | 0x80); \ - break; \ - default: \ - if (toLim - *toP < 3) { \ - *fromP = from; \ - return XML_CONVERT_OUTPUT_EXHAUSTED; \ - } \ - /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ - *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ - *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ - *(*toP)++ = ((lo & 0x3f) | 0x80); \ - break; \ - case 0xD8: case 0xD9: case 0xDA: case 0xDB: \ - if (toLim - *toP < 4) { \ - *fromP = from; \ - return XML_CONVERT_OUTPUT_EXHAUSTED; \ - } \ - if (fromLim - from < 4) { \ - *fromP = from; \ - return XML_CONVERT_INPUT_INCOMPLETE; \ - } \ - plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ - *(*toP)++ = ((plane >> 2) | UTF8_cval4); \ - *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ - from += 2; \ - lo2 = GET_LO(from); \ - *(*toP)++ = (((lo & 0x3) << 4) \ - | ((GET_HI(from) & 0x3) << 2) \ - | (lo2 >> 6) \ - | 0x80); \ - *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ - break; \ - } \ - } \ - *fromP = from; \ - if (from < fromLim) \ - return XML_CONVERT_INPUT_INCOMPLETE; \ - else \ - return XML_CONVERT_COMPLETED; \ -} - -#define DEFINE_UTF16_TO_UTF16(E) \ -static enum XML_Convert_Result PTRCALL \ -E ## toUtf16(const ENCODING *UNUSED_P(enc), \ - const char **fromP, const char *fromLim, \ - unsigned short **toP, const unsigned short *toLim) \ -{ \ - enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \ - fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \ - /* Avoid copying first half only of surrogate */ \ - if (fromLim - *fromP > ((toLim - *toP) << 1) \ - && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \ - fromLim -= 2; \ - res = XML_CONVERT_INPUT_INCOMPLETE; \ - } \ - for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \ - *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ - if ((*toP == toLim) && (*fromP < fromLim)) \ - return XML_CONVERT_OUTPUT_EXHAUSTED; \ - else \ - return res; \ -} - -#define SET2(ptr, ch) \ - (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8))) -#define GET_LO(ptr) ((unsigned char)(ptr)[0]) -#define GET_HI(ptr) ((unsigned char)(ptr)[1]) - -DEFINE_UTF16_TO_UTF8(little2_) -DEFINE_UTF16_TO_UTF16(little2_) - -#undef SET2 -#undef GET_LO -#undef GET_HI - -#define SET2(ptr, ch) \ - (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF))) -#define GET_LO(ptr) ((unsigned char)(ptr)[1]) -#define GET_HI(ptr) ((unsigned char)(ptr)[0]) - -DEFINE_UTF16_TO_UTF8(big2_) -DEFINE_UTF16_TO_UTF16(big2_) - -#undef SET2 -#undef GET_LO -#undef GET_HI - -#define LITTLE2_BYTE_TYPE(enc, p) \ - ((p)[1] == 0 \ - ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \ - : unicode_byte_type((p)[1], (p)[0])) -#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1) -#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c) -#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \ - UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) -#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ - UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) - -#ifdef XML_MIN_SIZE - -static int PTRFASTCALL -little2_byteType(const ENCODING *enc, const char *p) -{ - return LITTLE2_BYTE_TYPE(enc, p); -} - -static int PTRFASTCALL -little2_byteToAscii(const ENCODING *enc, const char *p) -{ - return LITTLE2_BYTE_TO_ASCII(enc, p); -} - -static int PTRCALL -little2_charMatches(const ENCODING *enc, const char *p, int c) -{ - return LITTLE2_CHAR_MATCHES(enc, p, c); -} - -static int PTRFASTCALL -little2_isNameMin(const ENCODING *enc, const char *p) -{ - return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p); -} - -static int PTRFASTCALL -little2_isNmstrtMin(const ENCODING *enc, const char *p) -{ - return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p); -} - -#undef VTABLE -#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16 - -#else /* not XML_MIN_SIZE */ - -#undef PREFIX -#define PREFIX(ident) little2_ ## ident -#define MINBPC(enc) 2 -/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ -#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) -#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p) -#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c) -#define IS_NAME_CHAR(enc, p, n) 0 -#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) -#define IS_NMSTRT_CHAR(enc, p, n) (0) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) - -#define XML_TOK_IMPL_C -#include "xmltok_impl.c" -#undef XML_TOK_IMPL_C - -#undef MINBPC -#undef BYTE_TYPE -#undef BYTE_TO_ASCII -#undef CHAR_MATCHES -#undef IS_NAME_CHAR -#undef IS_NAME_CHAR_MINBPC -#undef IS_NMSTRT_CHAR -#undef IS_NMSTRT_CHAR_MINBPC -#undef IS_INVALID_CHAR - -#endif /* not XML_MIN_SIZE */ - -#ifdef XML_NS - -static const struct normal_encoding little2_encoding_ns = { - { VTABLE, 2, 0, -#if BYTEORDER == 1234 - 1 -#else - 0 -#endif - }, - { -#include "asciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) NULL_VTABLE -}; - -#endif - -static const struct normal_encoding little2_encoding = { - { VTABLE, 2, 0, -#if BYTEORDER == 1234 - 1 -#else - 0 -#endif - }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) NULL_VTABLE -}; - -#if BYTEORDER != 4321 - -#ifdef XML_NS - -static const struct normal_encoding internal_little2_encoding_ns = { - { VTABLE, 2, 0, 1 }, - { -#include "iasciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) NULL_VTABLE -}; - -#endif - -static const struct normal_encoding internal_little2_encoding = { - { VTABLE, 2, 0, 1 }, - { -#define BT_COLON BT_NMSTRT -#include "iasciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) NULL_VTABLE -}; - -#endif - - -#define BIG2_BYTE_TYPE(enc, p) \ - ((p)[0] == 0 \ - ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \ - : unicode_byte_type((p)[0], (p)[1])) -#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1) -#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c) -#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \ - UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) -#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ - UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) - -#ifdef XML_MIN_SIZE - -static int PTRFASTCALL -big2_byteType(const ENCODING *enc, const char *p) -{ - return BIG2_BYTE_TYPE(enc, p); -} - -static int PTRFASTCALL -big2_byteToAscii(const ENCODING *enc, const char *p) -{ - return BIG2_BYTE_TO_ASCII(enc, p); -} - -static int PTRCALL -big2_charMatches(const ENCODING *enc, const char *p, int c) -{ - return BIG2_CHAR_MATCHES(enc, p, c); -} - -static int PTRFASTCALL -big2_isNameMin(const ENCODING *enc, const char *p) -{ - return BIG2_IS_NAME_CHAR_MINBPC(enc, p); -} - -static int PTRFASTCALL -big2_isNmstrtMin(const ENCODING *enc, const char *p) -{ - return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p); -} - -#undef VTABLE -#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16 - -#else /* not XML_MIN_SIZE */ - -#undef PREFIX -#define PREFIX(ident) big2_ ## ident -#define MINBPC(enc) 2 -/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ -#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) -#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p) -#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c) -#define IS_NAME_CHAR(enc, p, n) 0 -#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p) -#define IS_NMSTRT_CHAR(enc, p, n) (0) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) - -#define XML_TOK_IMPL_C -#include "xmltok_impl.c" -#undef XML_TOK_IMPL_C - -#undef MINBPC -#undef BYTE_TYPE -#undef BYTE_TO_ASCII -#undef CHAR_MATCHES -#undef IS_NAME_CHAR -#undef IS_NAME_CHAR_MINBPC -#undef IS_NMSTRT_CHAR -#undef IS_NMSTRT_CHAR_MINBPC -#undef IS_INVALID_CHAR - -#endif /* not XML_MIN_SIZE */ - -#ifdef XML_NS - -static const struct normal_encoding big2_encoding_ns = { - { VTABLE, 2, 0, -#if BYTEORDER == 4321 - 1 -#else - 0 -#endif - }, - { -#include "asciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) NULL_VTABLE -}; - -#endif - -static const struct normal_encoding big2_encoding = { - { VTABLE, 2, 0, -#if BYTEORDER == 4321 - 1 -#else - 0 -#endif - }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) NULL_VTABLE -}; - -#if BYTEORDER != 1234 - -#ifdef XML_NS - -static const struct normal_encoding internal_big2_encoding_ns = { - { VTABLE, 2, 0, 1 }, - { -#include "iasciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) NULL_VTABLE -}; - -#endif - -static const struct normal_encoding internal_big2_encoding = { - { VTABLE, 2, 0, 1 }, - { -#define BT_COLON BT_NMSTRT -#include "iasciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) NULL_VTABLE -}; - -#endif - -#undef PREFIX - -static int FASTCALL -streqci(const char *s1, const char *s2) -{ - for (;;) { - char c1 = *s1++; - char c2 = *s2++; - if (ASCII_a <= c1 && c1 <= ASCII_z) - c1 += ASCII_A - ASCII_a; - if (ASCII_a <= c2 && c2 <= ASCII_z) - /* The following line will never get executed. streqci() is - * only called from two places, both of which guarantee to put - * upper-case strings into s2. - */ - c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */ - if (c1 != c2) - return 0; - if (!c1) - break; - } - return 1; -} - -static void PTRCALL -initUpdatePosition(const ENCODING *UNUSED_P(enc), const char *ptr, - const char *end, POSITION *pos) -{ - normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); -} - -static int -toAscii(const ENCODING *enc, const char *ptr, const char *end) -{ - char buf[1]; - char *p = buf; - XmlUtf8Convert(enc, &ptr, end, &p, p + 1); - if (p == buf) - return -1; - else - return buf[0]; -} - -static int FASTCALL -isSpace(int c) -{ - switch (c) { - case 0x20: - case 0xD: - case 0xA: - case 0x9: - return 1; - } - return 0; -} - -/* Return 1 if there's just optional white space or there's an S - followed by name=val. -*/ -static int -parsePseudoAttribute(const ENCODING *enc, - const char *ptr, - const char *end, - const char **namePtr, - const char **nameEndPtr, - const char **valPtr, - const char **nextTokPtr) -{ - int c; - char open; - if (ptr == end) { - *namePtr = NULL; - return 1; - } - if (!isSpace(toAscii(enc, ptr, end))) { - *nextTokPtr = ptr; - return 0; - } - do { - ptr += enc->minBytesPerChar; - } while (isSpace(toAscii(enc, ptr, end))); - if (ptr == end) { - *namePtr = NULL; - return 1; - } - *namePtr = ptr; - for (;;) { - c = toAscii(enc, ptr, end); - if (c == -1) { - *nextTokPtr = ptr; - return 0; - } - if (c == ASCII_EQUALS) { - *nameEndPtr = ptr; - break; - } - if (isSpace(c)) { - *nameEndPtr = ptr; - do { - ptr += enc->minBytesPerChar; - } while (isSpace(c = toAscii(enc, ptr, end))); - if (c != ASCII_EQUALS) { - *nextTokPtr = ptr; - return 0; - } - break; - } - ptr += enc->minBytesPerChar; - } - if (ptr == *namePtr) { - *nextTokPtr = ptr; - return 0; - } - ptr += enc->minBytesPerChar; - c = toAscii(enc, ptr, end); - while (isSpace(c)) { - ptr += enc->minBytesPerChar; - c = toAscii(enc, ptr, end); - } - if (c != ASCII_QUOT && c != ASCII_APOS) { - *nextTokPtr = ptr; - return 0; - } - open = (char)c; - ptr += enc->minBytesPerChar; - *valPtr = ptr; - for (;; ptr += enc->minBytesPerChar) { - c = toAscii(enc, ptr, end); - if (c == open) - break; - if (!(ASCII_a <= c && c <= ASCII_z) - && !(ASCII_A <= c && c <= ASCII_Z) - && !(ASCII_0 <= c && c <= ASCII_9) - && c != ASCII_PERIOD - && c != ASCII_MINUS - && c != ASCII_UNDERSCORE) { - *nextTokPtr = ptr; - return 0; - } - } - *nextTokPtr = ptr + enc->minBytesPerChar; - return 1; -} - -static const char KW_version[] = { - ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0' -}; - -static const char KW_encoding[] = { - ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0' -}; - -static const char KW_standalone[] = { - ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, - ASCII_n, ASCII_e, '\0' -}; - -static const char KW_yes[] = { - ASCII_y, ASCII_e, ASCII_s, '\0' -}; - -static const char KW_no[] = { - ASCII_n, ASCII_o, '\0' -}; - -static int -doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, - const char *, - const char *), - int isGeneralTextEntity, - const ENCODING *enc, - const char *ptr, - const char *end, - const char **badPtr, - const char **versionPtr, - const char **versionEndPtr, - const char **encodingName, - const ENCODING **encoding, - int *standalone) -{ - const char *val = NULL; - const char *name = NULL; - const char *nameEnd = NULL; - ptr += 5 * enc->minBytesPerChar; - end -= 2 * enc->minBytesPerChar; - if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) - || !name) { - *badPtr = ptr; - return 0; - } - if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) { - if (!isGeneralTextEntity) { - *badPtr = name; - return 0; - } - } - else { - if (versionPtr) - *versionPtr = val; - if (versionEndPtr) - *versionEndPtr = ptr; - if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { - *badPtr = ptr; - return 0; - } - if (!name) { - if (isGeneralTextEntity) { - /* a TextDecl must have an EncodingDecl */ - *badPtr = ptr; - return 0; - } - return 1; - } - } - if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) { - int c = toAscii(enc, val, end); - if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) { - *badPtr = val; - return 0; - } - if (encodingName) - *encodingName = val; - if (encoding) - *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); - if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { - *badPtr = ptr; - return 0; - } - if (!name) - return 1; - } - if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) - || isGeneralTextEntity) { - *badPtr = name; - return 0; - } - if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) { - if (standalone) - *standalone = 1; - } - else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) { - if (standalone) - *standalone = 0; - } - else { - *badPtr = val; - return 0; - } - while (isSpace(toAscii(enc, ptr, end))) - ptr += enc->minBytesPerChar; - if (ptr != end) { - *badPtr = ptr; - return 0; - } - return 1; -} - -static int FASTCALL -checkCharRefNumber(int result) -{ - switch (result >> 8) { - case 0xD8: case 0xD9: case 0xDA: case 0xDB: - case 0xDC: case 0xDD: case 0xDE: case 0xDF: - return -1; - case 0: - if (latin1_encoding.type[result] == BT_NONXML) - return -1; - break; - case 0xFF: - if (result == 0xFFFE || result == 0xFFFF) - return -1; - break; - } - return result; -} - -int FASTCALL -XmlUtf8Encode(int c, char *buf) -{ - enum { - /* minN is minimum legal resulting value for N byte sequence */ - min2 = 0x80, - min3 = 0x800, - min4 = 0x10000 - }; - - if (c < 0) - return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */ - if (c < min2) { - buf[0] = (char)(c | UTF8_cval1); - return 1; - } - if (c < min3) { - buf[0] = (char)((c >> 6) | UTF8_cval2); - buf[1] = (char)((c & 0x3f) | 0x80); - return 2; - } - if (c < min4) { - buf[0] = (char)((c >> 12) | UTF8_cval3); - buf[1] = (char)(((c >> 6) & 0x3f) | 0x80); - buf[2] = (char)((c & 0x3f) | 0x80); - return 3; - } - if (c < 0x110000) { - buf[0] = (char)((c >> 18) | UTF8_cval4); - buf[1] = (char)(((c >> 12) & 0x3f) | 0x80); - buf[2] = (char)(((c >> 6) & 0x3f) | 0x80); - buf[3] = (char)((c & 0x3f) | 0x80); - return 4; - } - return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */ -} - -int FASTCALL -XmlUtf16Encode(int charNum, unsigned short *buf) -{ - if (charNum < 0) - return 0; - if (charNum < 0x10000) { - buf[0] = (unsigned short)charNum; - return 1; - } - if (charNum < 0x110000) { - charNum -= 0x10000; - buf[0] = (unsigned short)((charNum >> 10) + 0xD800); - buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00); - return 2; - } - return 0; -} - -struct unknown_encoding { - struct normal_encoding normal; - CONVERTER convert; - void *userData; - unsigned short utf16[256]; - char utf8[256][4]; -}; - -#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *) (enc)) - -int -XmlSizeOfUnknownEncoding(void) -{ - return sizeof(struct unknown_encoding); -} - -static int PTRFASTCALL -unknown_isName(const ENCODING *enc, const char *p) -{ - const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); - int c = uenc->convert(uenc->userData, p); - if (c & ~0xFFFF) - return 0; - return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF); -} - -static int PTRFASTCALL -unknown_isNmstrt(const ENCODING *enc, const char *p) -{ - const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); - int c = uenc->convert(uenc->userData, p); - if (c & ~0xFFFF) - return 0; - return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF); -} - -static int PTRFASTCALL -unknown_isInvalid(const ENCODING *enc, const char *p) -{ - const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); - int c = uenc->convert(uenc->userData, p); - return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; -} - -static enum XML_Convert_Result PTRCALL -unknown_toUtf8(const ENCODING *enc, - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ - const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); - char buf[XML_UTF8_ENCODE_MAX]; - for (;;) { - const char *utf8; - int n; - if (*fromP == fromLim) - return XML_CONVERT_COMPLETED; - utf8 = uenc->utf8[(unsigned char)**fromP]; - n = *utf8++; - if (n == 0) { - int c = uenc->convert(uenc->userData, *fromP); - n = XmlUtf8Encode(c, buf); - if (n > toLim - *toP) - return XML_CONVERT_OUTPUT_EXHAUSTED; - utf8 = buf; - *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] - - (BT_LEAD2 - 2)); - } - else { - if (n > toLim - *toP) - return XML_CONVERT_OUTPUT_EXHAUSTED; - (*fromP)++; - } - memcpy(*toP, utf8, n); - *toP += n; - } -} - -static enum XML_Convert_Result PTRCALL -unknown_toUtf16(const ENCODING *enc, - const char **fromP, const char *fromLim, - unsigned short **toP, const unsigned short *toLim) -{ - const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); - while (*fromP < fromLim && *toP < toLim) { - unsigned short c = uenc->utf16[(unsigned char)**fromP]; - if (c == 0) { - c = (unsigned short) - uenc->convert(uenc->userData, *fromP); - *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] - - (BT_LEAD2 - 2)); - } - else - (*fromP)++; - *(*toP)++ = c; - } - - if ((*toP == toLim) && (*fromP < fromLim)) - return XML_CONVERT_OUTPUT_EXHAUSTED; - else - return XML_CONVERT_COMPLETED; -} - -ENCODING * -XmlInitUnknownEncoding(void *mem, - int *table, - CONVERTER convert, - void *userData) -{ - int i; - struct unknown_encoding *e = (struct unknown_encoding *)mem; - for (i = 0; i < (int)sizeof(struct normal_encoding); i++) - ((char *)mem)[i] = ((char *)&latin1_encoding)[i]; - for (i = 0; i < 128; i++) - if (latin1_encoding.type[i] != BT_OTHER - && latin1_encoding.type[i] != BT_NONXML - && table[i] != i) - return 0; - for (i = 0; i < 256; i++) { - int c = table[i]; - if (c == -1) { - e->normal.type[i] = BT_MALFORM; - /* This shouldn't really get used. */ - e->utf16[i] = 0xFFFF; - e->utf8[i][0] = 1; - e->utf8[i][1] = 0; - } - else if (c < 0) { - if (c < -4) - return 0; - /* Multi-byte sequences need a converter function */ - if (!convert) - return 0; - e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2)); - e->utf8[i][0] = 0; - e->utf16[i] = 0; - } - else if (c < 0x80) { - if (latin1_encoding.type[c] != BT_OTHER - && latin1_encoding.type[c] != BT_NONXML - && c != i) - return 0; - e->normal.type[i] = latin1_encoding.type[c]; - e->utf8[i][0] = 1; - e->utf8[i][1] = (char)c; - e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c); - } - else if (checkCharRefNumber(c) < 0) { - e->normal.type[i] = BT_NONXML; - /* This shouldn't really get used. */ - e->utf16[i] = 0xFFFF; - e->utf8[i][0] = 1; - e->utf8[i][1] = 0; - } - else { - if (c > 0xFFFF) - return 0; - if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) - e->normal.type[i] = BT_NMSTRT; - else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff)) - e->normal.type[i] = BT_NAME; - else - e->normal.type[i] = BT_OTHER; - e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1); - e->utf16[i] = (unsigned short)c; - } - } - e->userData = userData; - e->convert = convert; - if (convert) { - e->normal.isName2 = unknown_isName; - e->normal.isName3 = unknown_isName; - e->normal.isName4 = unknown_isName; - e->normal.isNmstrt2 = unknown_isNmstrt; - e->normal.isNmstrt3 = unknown_isNmstrt; - e->normal.isNmstrt4 = unknown_isNmstrt; - e->normal.isInvalid2 = unknown_isInvalid; - e->normal.isInvalid3 = unknown_isInvalid; - e->normal.isInvalid4 = unknown_isInvalid; - } - e->normal.enc.utf8Convert = unknown_toUtf8; - e->normal.enc.utf16Convert = unknown_toUtf16; - return &(e->normal.enc); -} - -/* If this enumeration is changed, getEncodingIndex and encodings -must also be changed. */ -enum { - UNKNOWN_ENC = -1, - ISO_8859_1_ENC = 0, - US_ASCII_ENC, - UTF_8_ENC, - UTF_16_ENC, - UTF_16BE_ENC, - UTF_16LE_ENC, - /* must match encodingNames up to here */ - NO_ENC -}; - -static const char KW_ISO_8859_1[] = { - ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, - ASCII_MINUS, ASCII_1, '\0' -}; -static const char KW_US_ASCII[] = { - ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, - '\0' -}; -static const char KW_UTF_8[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0' -}; -static const char KW_UTF_16[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0' -}; -static const char KW_UTF_16BE[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, - '\0' -}; -static const char KW_UTF_16LE[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, - '\0' -}; - -static int FASTCALL -getEncodingIndex(const char *name) -{ - static const char * const encodingNames[] = { - KW_ISO_8859_1, - KW_US_ASCII, - KW_UTF_8, - KW_UTF_16, - KW_UTF_16BE, - KW_UTF_16LE, - }; - int i; - if (name == NULL) - return NO_ENC; - for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++) - if (streqci(name, encodingNames[i])) - return i; - return UNKNOWN_ENC; -} - -/* For binary compatibility, we store the index of the encoding - specified at initialization in the isUtf16 member. -*/ - -#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16) -#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i) - -/* This is what detects the encoding. encodingTable maps from - encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of - the external (protocol) specified encoding; state is - XML_CONTENT_STATE if we're parsing an external text entity, and - XML_PROLOG_STATE otherwise. -*/ - - -static int -initScan(const ENCODING * const *encodingTable, - const INIT_ENCODING *enc, - int state, - const char *ptr, - const char *end, - const char **nextTokPtr) -{ - const ENCODING **encPtr; - - if (ptr >= end) - return XML_TOK_NONE; - encPtr = enc->encPtr; - if (ptr + 1 == end) { - /* only a single byte available for auto-detection */ -#ifndef XML_DTD /* FIXME */ - /* a well-formed document entity must have more than one byte */ - if (state != XML_CONTENT_STATE) - return XML_TOK_PARTIAL; -#endif - /* so we're parsing an external text entity... */ - /* if UTF-16 was externally specified, then we need at least 2 bytes */ - switch (INIT_ENC_INDEX(enc)) { - case UTF_16_ENC: - case UTF_16LE_ENC: - case UTF_16BE_ENC: - return XML_TOK_PARTIAL; - } - switch ((unsigned char)*ptr) { - case 0xFE: - case 0xFF: - case 0xEF: /* possibly first byte of UTF-8 BOM */ - if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC - && state == XML_CONTENT_STATE) - break; - /* fall through */ - case 0x00: - case 0x3C: - return XML_TOK_PARTIAL; - } - } - else { - switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { - case 0xFEFF: - if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC - && state == XML_CONTENT_STATE) - break; - *nextTokPtr = ptr + 2; - *encPtr = encodingTable[UTF_16BE_ENC]; - return XML_TOK_BOM; - /* 00 3C is handled in the default case */ - case 0x3C00: - if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC - || INIT_ENC_INDEX(enc) == UTF_16_ENC) - && state == XML_CONTENT_STATE) - break; - *encPtr = encodingTable[UTF_16LE_ENC]; - return XmlTok(*encPtr, state, ptr, end, nextTokPtr); - case 0xFFFE: - if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC - && state == XML_CONTENT_STATE) - break; - *nextTokPtr = ptr + 2; - *encPtr = encodingTable[UTF_16LE_ENC]; - return XML_TOK_BOM; - case 0xEFBB: - /* Maybe a UTF-8 BOM (EF BB BF) */ - /* If there's an explicitly specified (external) encoding - of ISO-8859-1 or some flavour of UTF-16 - and this is an external text entity, - don't look for the BOM, - because it might be a legal data. - */ - if (state == XML_CONTENT_STATE) { - int e = INIT_ENC_INDEX(enc); - if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC - || e == UTF_16LE_ENC || e == UTF_16_ENC) - break; - } - if (ptr + 2 == end) - return XML_TOK_PARTIAL; - if ((unsigned char)ptr[2] == 0xBF) { - *nextTokPtr = ptr + 3; - *encPtr = encodingTable[UTF_8_ENC]; - return XML_TOK_BOM; - } - break; - default: - if (ptr[0] == '\0') { - /* 0 isn't a legal data character. Furthermore a document - entity can only start with ASCII characters. So the only - way this can fail to be big-endian UTF-16 if it it's an - external parsed general entity that's labelled as - UTF-16LE. - */ - if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC) - break; - *encPtr = encodingTable[UTF_16BE_ENC]; - return XmlTok(*encPtr, state, ptr, end, nextTokPtr); - } - else if (ptr[1] == '\0') { - /* We could recover here in the case: - - parsing an external entity - - second byte is 0 - - no externally specified encoding - - no encoding declaration - by assuming UTF-16LE. But we don't, because this would mean when - presented just with a single byte, we couldn't reliably determine - whether we needed further bytes. - */ - if (state == XML_CONTENT_STATE) - break; - *encPtr = encodingTable[UTF_16LE_ENC]; - return XmlTok(*encPtr, state, ptr, end, nextTokPtr); - } - break; - } - } - *encPtr = encodingTable[INIT_ENC_INDEX(enc)]; - return XmlTok(*encPtr, state, ptr, end, nextTokPtr); -} - - -#define NS(x) x -#define ns(x) x -#define XML_TOK_NS_C -#include "xmltok_ns.c" -#undef XML_TOK_NS_C -#undef NS -#undef ns - -#ifdef XML_NS - -#define NS(x) x ## NS -#define ns(x) x ## _ns - -#define XML_TOK_NS_C -#include "xmltok_ns.c" -#undef XML_TOK_NS_C - -#undef NS -#undef ns - -ENCODING * -XmlInitUnknownEncodingNS(void *mem, - int *table, - CONVERTER convert, - void *userData) -{ - ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); - if (enc) - ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON; - return enc; -} - -#endif /* XML_NS */ diff --git a/tools/sdk/include/expat/xmltok_impl.c b/tools/sdk/include/expat/xmltok_impl.c deleted file mode 100644 index 0403dd3d..00000000 --- a/tools/sdk/include/expat/xmltok_impl.c +++ /dev/null @@ -1,1760 +0,0 @@ -/* This file is included! - __ __ _ - ___\ \/ /_ __ __ _| |_ - / _ \\ /| '_ \ / _` | __| - | __// \| |_) | (_| | |_ - \___/_/\_\ .__/ \__,_|\__| - |_| XML parser - - Copyright (c) 1997-2000 Thai Open Source Software Center Ltd - Copyright (c) 2000-2017 Expat development team - Licensed under the MIT license: - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to permit - persons to whom the Software is furnished to do so, subject to the - following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN - NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifdef XML_TOK_IMPL_C - -#ifndef IS_INVALID_CHAR -#define IS_INVALID_CHAR(enc, ptr, n) (0) -#endif - -#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (IS_INVALID_CHAR(enc, ptr, n)) { \ - *(nextTokPtr) = (ptr); \ - return XML_TOK_INVALID; \ - } \ - ptr += n; \ - break; - -#define INVALID_CASES(ptr, nextTokPtr) \ - INVALID_LEAD_CASE(2, ptr, nextTokPtr) \ - INVALID_LEAD_CASE(3, ptr, nextTokPtr) \ - INVALID_LEAD_CASE(4, ptr, nextTokPtr) \ - case BT_NONXML: \ - case BT_MALFORM: \ - case BT_TRAIL: \ - *(nextTokPtr) = (ptr); \ - return XML_TOK_INVALID; - -#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (!IS_NAME_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - ptr += n; \ - break; - -#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \ - case BT_NONASCII: \ - if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - case BT_NMSTRT: \ - case BT_HEX: \ - case BT_DIGIT: \ - case BT_NAME: \ - case BT_MINUS: \ - ptr += MINBPC(enc); \ - break; \ - CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \ - CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \ - CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr) - -#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - ptr += n; \ - break; - -#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \ - case BT_NONASCII: \ - if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - case BT_NMSTRT: \ - case BT_HEX: \ - ptr += MINBPC(enc); \ - break; \ - CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \ - CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \ - CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr) - -#ifndef PREFIX -#define PREFIX(ident) ident -#endif - - -#define HAS_CHARS(enc, ptr, end, count) \ - (end - ptr >= count * MINBPC(enc)) - -#define HAS_CHAR(enc, ptr, end) \ - HAS_CHARS(enc, ptr, end, 1) - -#define REQUIRE_CHARS(enc, ptr, end, count) \ - { \ - if (! HAS_CHARS(enc, ptr, end, count)) { \ - return XML_TOK_PARTIAL; \ - } \ - } - -#define REQUIRE_CHAR(enc, ptr, end) \ - REQUIRE_CHARS(enc, ptr, end, 1) - - -/* ptr points to character following " */ - switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { - case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - /* fall through */ - case BT_S: case BT_CR: case BT_LF: - *nextTokPtr = ptr; - return XML_TOK_DECL_OPEN; - case BT_NMSTRT: - case BT_HEX: - ptr += MINBPC(enc); - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return XML_TOK_PARTIAL; -} - -static int PTRCALL -PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr, - const char *end, int *tokPtr) -{ - int upper = 0; - *tokPtr = XML_TOK_PI; - if (end - ptr != MINBPC(enc)*3) - return 1; - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_x: - break; - case ASCII_X: - upper = 1; - break; - default: - return 1; - } - ptr += MINBPC(enc); - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_m: - break; - case ASCII_M: - upper = 1; - break; - default: - return 1; - } - ptr += MINBPC(enc); - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_l: - break; - case ASCII_L: - upper = 1; - break; - default: - return 1; - } - if (upper) - return 0; - *tokPtr = XML_TOK_XML_DECL; - return 1; -} - -/* ptr points to character following "= end) - return XML_TOK_NONE; - if (MINBPC(enc) > 1) { - size_t n = end - ptr; - if (n & (MINBPC(enc) - 1)) { - n &= ~(MINBPC(enc) - 1); - if (n == 0) - return XML_TOK_PARTIAL; - end = ptr + n; - } - } - switch (BYTE_TYPE(enc, ptr)) { - case BT_RSQB: - ptr += MINBPC(enc); - REQUIRE_CHAR(enc, ptr, end); - if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) - break; - ptr += MINBPC(enc); - REQUIRE_CHAR(enc, ptr, end); - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - ptr -= MINBPC(enc); - break; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CDATA_SECT_CLOSE; - case BT_CR: - ptr += MINBPC(enc); - REQUIRE_CHAR(enc, ptr, end); - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; - case BT_LF: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; - INVALID_CASES(ptr, nextTokPtr) - default: - ptr += MINBPC(enc); - break; - } - while (HAS_CHAR(enc, ptr, end)) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_DATA_CHARS; \ - } \ - ptr += n; \ - break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_NONXML: - case BT_MALFORM: - case BT_TRAIL: - case BT_CR: - case BT_LF: - case BT_RSQB: - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - default: - ptr += MINBPC(enc); - break; - } - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; -} - -/* ptr points to character following "= end) - return XML_TOK_NONE; - if (MINBPC(enc) > 1) { - size_t n = end - ptr; - if (n & (MINBPC(enc) - 1)) { - n &= ~(MINBPC(enc) - 1); - if (n == 0) - return XML_TOK_PARTIAL; - end = ptr + n; - } - } - switch (BYTE_TYPE(enc, ptr)) { - case BT_LT: - return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_AMP: - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_CR: - ptr += MINBPC(enc); - if (! HAS_CHAR(enc, ptr, end)) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; - case BT_LF: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; - case BT_RSQB: - ptr += MINBPC(enc); - if (! HAS_CHAR(enc, ptr, end)) - return XML_TOK_TRAILING_RSQB; - if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) - break; - ptr += MINBPC(enc); - if (! HAS_CHAR(enc, ptr, end)) - return XML_TOK_TRAILING_RSQB; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - ptr -= MINBPC(enc); - break; - } - *nextTokPtr = ptr; - return XML_TOK_INVALID; - INVALID_CASES(ptr, nextTokPtr) - default: - ptr += MINBPC(enc); - break; - } - while (HAS_CHAR(enc, ptr, end)) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_DATA_CHARS; \ - } \ - ptr += n; \ - break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_RSQB: - if (HAS_CHARS(enc, ptr, end, 2)) { - if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) { - ptr += MINBPC(enc); - break; - } - if (HAS_CHARS(enc, ptr, end, 3)) { - if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) { - ptr += MINBPC(enc); - break; - } - *nextTokPtr = ptr + 2*MINBPC(enc); - return XML_TOK_INVALID; - } - } - /* fall through */ - case BT_AMP: - case BT_LT: - case BT_NONXML: - case BT_MALFORM: - case BT_TRAIL: - case BT_CR: - case BT_LF: - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - default: - ptr += MINBPC(enc); - break; - } - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; -} - -/* ptr points to character following "%" */ - -static int PTRCALL -PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - REQUIRE_CHAR(enc, ptr, end); - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: - *nextTokPtr = ptr; - return XML_TOK_PERCENT; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - while (HAS_CHAR(enc, ptr, end)) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_SEMI: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_PARAM_ENTITY_REF; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return XML_TOK_PARTIAL; -} - -static int PTRCALL -PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - REQUIRE_CHAR(enc, ptr, end); - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - while (HAS_CHAR(enc, ptr, end)) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_CR: case BT_LF: case BT_S: - case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR: - *nextTokPtr = ptr; - return XML_TOK_POUND_NAME; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return -XML_TOK_POUND_NAME; -} - -static int PTRCALL -PREFIX(scanLit)(int open, const ENCODING *enc, - const char *ptr, const char *end, - const char **nextTokPtr) -{ - while (HAS_CHAR(enc, ptr, end)) { - int t = BYTE_TYPE(enc, ptr); - switch (t) { - INVALID_CASES(ptr, nextTokPtr) - case BT_QUOT: - case BT_APOS: - ptr += MINBPC(enc); - if (t != open) - break; - if (! HAS_CHAR(enc, ptr, end)) - return -XML_TOK_LITERAL; - *nextTokPtr = ptr; - switch (BYTE_TYPE(enc, ptr)) { - case BT_S: case BT_CR: case BT_LF: - case BT_GT: case BT_PERCNT: case BT_LSQB: - return XML_TOK_LITERAL; - default: - return XML_TOK_INVALID; - } - default: - ptr += MINBPC(enc); - break; - } - } - return XML_TOK_PARTIAL; -} - -static int PTRCALL -PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - int tok; - if (ptr >= end) - return XML_TOK_NONE; - if (MINBPC(enc) > 1) { - size_t n = end - ptr; - if (n & (MINBPC(enc) - 1)) { - n &= ~(MINBPC(enc) - 1); - if (n == 0) - return XML_TOK_PARTIAL; - end = ptr + n; - } - } - switch (BYTE_TYPE(enc, ptr)) { - case BT_QUOT: - return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_APOS: - return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_LT: - { - ptr += MINBPC(enc); - REQUIRE_CHAR(enc, ptr, end); - switch (BYTE_TYPE(enc, ptr)) { - case BT_EXCL: - return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_QUEST: - return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_NMSTRT: - case BT_HEX: - case BT_NONASCII: - case BT_LEAD2: - case BT_LEAD3: - case BT_LEAD4: - *nextTokPtr = ptr - MINBPC(enc); - return XML_TOK_INSTANCE_START; - } - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - case BT_CR: - if (ptr + MINBPC(enc) == end) { - *nextTokPtr = end; - /* indicate that this might be part of a CR/LF pair */ - return -XML_TOK_PROLOG_S; - } - /* fall through */ - case BT_S: case BT_LF: - for (;;) { - ptr += MINBPC(enc); - if (! HAS_CHAR(enc, ptr, end)) - break; - switch (BYTE_TYPE(enc, ptr)) { - case BT_S: case BT_LF: - break; - case BT_CR: - /* don't split CR/LF pair */ - if (ptr + MINBPC(enc) != end) - break; - /* fall through */ - default: - *nextTokPtr = ptr; - return XML_TOK_PROLOG_S; - } - } - *nextTokPtr = ptr; - return XML_TOK_PROLOG_S; - case BT_PERCNT: - return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_COMMA: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_COMMA; - case BT_LSQB: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_OPEN_BRACKET; - case BT_RSQB: - ptr += MINBPC(enc); - if (! HAS_CHAR(enc, ptr, end)) - return -XML_TOK_CLOSE_BRACKET; - if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { - REQUIRE_CHARS(enc, ptr, end, 2); - if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { - *nextTokPtr = ptr + 2*MINBPC(enc); - return XML_TOK_COND_SECT_CLOSE; - } - } - *nextTokPtr = ptr; - return XML_TOK_CLOSE_BRACKET; - case BT_LPAR: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_OPEN_PAREN; - case BT_RPAR: - ptr += MINBPC(enc); - if (! HAS_CHAR(enc, ptr, end)) - return -XML_TOK_CLOSE_PAREN; - switch (BYTE_TYPE(enc, ptr)) { - case BT_AST: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CLOSE_PAREN_ASTERISK; - case BT_QUEST: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CLOSE_PAREN_QUESTION; - case BT_PLUS: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CLOSE_PAREN_PLUS; - case BT_CR: case BT_LF: case BT_S: - case BT_GT: case BT_COMMA: case BT_VERBAR: - case BT_RPAR: - *nextTokPtr = ptr; - return XML_TOK_CLOSE_PAREN; - } - *nextTokPtr = ptr; - return XML_TOK_INVALID; - case BT_VERBAR: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_OR; - case BT_GT: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DECL_CLOSE; - case BT_NUM: - return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ - ptr += n; \ - tok = XML_TOK_NAME; \ - break; \ - } \ - if (IS_NAME_CHAR(enc, ptr, n)) { \ - ptr += n; \ - tok = XML_TOK_NMTOKEN; \ - break; \ - } \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_NMSTRT: - case BT_HEX: - tok = XML_TOK_NAME; - ptr += MINBPC(enc); - break; - case BT_DIGIT: - case BT_NAME: - case BT_MINUS: -#ifdef XML_NS - case BT_COLON: -#endif - tok = XML_TOK_NMTOKEN; - ptr += MINBPC(enc); - break; - case BT_NONASCII: - if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { - ptr += MINBPC(enc); - tok = XML_TOK_NAME; - break; - } - if (IS_NAME_CHAR_MINBPC(enc, ptr)) { - ptr += MINBPC(enc); - tok = XML_TOK_NMTOKEN; - break; - } - /* fall through */ - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - while (HAS_CHAR(enc, ptr, end)) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_GT: case BT_RPAR: case BT_COMMA: - case BT_VERBAR: case BT_LSQB: case BT_PERCNT: - case BT_S: case BT_CR: case BT_LF: - *nextTokPtr = ptr; - return tok; -#ifdef XML_NS - case BT_COLON: - ptr += MINBPC(enc); - switch (tok) { - case XML_TOK_NAME: - REQUIRE_CHAR(enc, ptr, end); - tok = XML_TOK_PREFIXED_NAME; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - default: - tok = XML_TOK_NMTOKEN; - break; - } - break; - case XML_TOK_PREFIXED_NAME: - tok = XML_TOK_NMTOKEN; - break; - } - break; -#endif - case BT_PLUS: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_PLUS; - case BT_AST: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_ASTERISK; - case BT_QUEST: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_QUESTION; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return -tok; -} - -static int PTRCALL -PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ - const char *start; - if (ptr >= end) - return XML_TOK_NONE; - else if (! HAS_CHAR(enc, ptr, end)) { - /* This line cannot be executed. The incoming data has already - * been tokenized once, so incomplete characters like this have - * already been eliminated from the input. Retaining the paranoia - * check is still valuable, however. - */ - return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */ - } - start = ptr; - while (HAS_CHAR(enc, ptr, end)) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: ptr += n; break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_AMP: - if (ptr == start) - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_LT: - /* this is for inside entity references */ - *nextTokPtr = ptr; - return XML_TOK_INVALID; - case BT_LF: - if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_CR: - if (ptr == start) { - ptr += MINBPC(enc); - if (! HAS_CHAR(enc, ptr, end)) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_S: - if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_ATTRIBUTE_VALUE_S; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - default: - ptr += MINBPC(enc); - break; - } - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; -} - -static int PTRCALL -PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ - const char *start; - if (ptr >= end) - return XML_TOK_NONE; - else if (! HAS_CHAR(enc, ptr, end)) { - /* This line cannot be executed. The incoming data has already - * been tokenized once, so incomplete characters like this have - * already been eliminated from the input. Retaining the paranoia - * check is still valuable, however. - */ - return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */ - } - start = ptr; - while (HAS_CHAR(enc, ptr, end)) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: ptr += n; break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_AMP: - if (ptr == start) - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_PERCNT: - if (ptr == start) { - int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc), - end, nextTokPtr); - return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_LF: - if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_CR: - if (ptr == start) { - ptr += MINBPC(enc); - if (! HAS_CHAR(enc, ptr, end)) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - default: - ptr += MINBPC(enc); - break; - } - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; -} - -#ifdef XML_DTD - -static int PTRCALL -PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ - int level = 0; - if (MINBPC(enc) > 1) { - size_t n = end - ptr; - if (n & (MINBPC(enc) - 1)) { - n &= ~(MINBPC(enc) - 1); - end = ptr + n; - } - } - while (HAS_CHAR(enc, ptr, end)) { - switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr) - case BT_LT: - ptr += MINBPC(enc); - REQUIRE_CHAR(enc, ptr, end); - if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) { - ptr += MINBPC(enc); - REQUIRE_CHAR(enc, ptr, end); - if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { - ++level; - ptr += MINBPC(enc); - } - } - break; - case BT_RSQB: - ptr += MINBPC(enc); - REQUIRE_CHAR(enc, ptr, end); - if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { - ptr += MINBPC(enc); - REQUIRE_CHAR(enc, ptr, end); - if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { - ptr += MINBPC(enc); - if (level == 0) { - *nextTokPtr = ptr; - return XML_TOK_IGNORE_SECT; - } - --level; - } - } - break; - default: - ptr += MINBPC(enc); - break; - } - } - return XML_TOK_PARTIAL; -} - -#endif /* XML_DTD */ - -static int PTRCALL -PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, - const char **badPtr) -{ - ptr += MINBPC(enc); - end -= MINBPC(enc); - for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { - switch (BYTE_TYPE(enc, ptr)) { - case BT_DIGIT: - case BT_HEX: - case BT_MINUS: - case BT_APOS: - case BT_LPAR: - case BT_RPAR: - case BT_PLUS: - case BT_COMMA: - case BT_SOL: - case BT_EQUALS: - case BT_QUEST: - case BT_CR: - case BT_LF: - case BT_SEMI: - case BT_EXCL: - case BT_AST: - case BT_PERCNT: - case BT_NUM: -#ifdef XML_NS - case BT_COLON: -#endif - break; - case BT_S: - if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) { - *badPtr = ptr; - return 0; - } - break; - case BT_NAME: - case BT_NMSTRT: - if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f)) - break; - default: - switch (BYTE_TO_ASCII(enc, ptr)) { - case 0x24: /* $ */ - case 0x40: /* @ */ - break; - default: - *badPtr = ptr; - return 0; - } - break; - } - } - return 1; -} - -/* This must only be called for a well-formed start-tag or empty - element tag. Returns the number of attributes. Pointers to the - first attsMax attributes are stored in atts. -*/ - -static int PTRCALL -PREFIX(getAtts)(const ENCODING *enc, const char *ptr, - int attsMax, ATTRIBUTE *atts) -{ - enum { other, inName, inValue } state = inName; - int nAtts = 0; - int open = 0; /* defined when state == inValue; - initialization just to shut up compilers */ - - for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { - switch (BYTE_TYPE(enc, ptr)) { -#define START_NAME \ - if (state == other) { \ - if (nAtts < attsMax) { \ - atts[nAtts].name = ptr; \ - atts[nAtts].normalized = 1; \ - } \ - state = inName; \ - } -#define LEAD_CASE(n) \ - case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_NONASCII: - case BT_NMSTRT: - case BT_HEX: - START_NAME - break; -#undef START_NAME - case BT_QUOT: - if (state != inValue) { - if (nAtts < attsMax) - atts[nAtts].valuePtr = ptr + MINBPC(enc); - state = inValue; - open = BT_QUOT; - } - else if (open == BT_QUOT) { - state = other; - if (nAtts < attsMax) - atts[nAtts].valueEnd = ptr; - nAtts++; - } - break; - case BT_APOS: - if (state != inValue) { - if (nAtts < attsMax) - atts[nAtts].valuePtr = ptr + MINBPC(enc); - state = inValue; - open = BT_APOS; - } - else if (open == BT_APOS) { - state = other; - if (nAtts < attsMax) - atts[nAtts].valueEnd = ptr; - nAtts++; - } - break; - case BT_AMP: - if (nAtts < attsMax) - atts[nAtts].normalized = 0; - break; - case BT_S: - if (state == inName) - state = other; - else if (state == inValue - && nAtts < attsMax - && atts[nAtts].normalized - && (ptr == atts[nAtts].valuePtr - || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE - || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE - || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) - atts[nAtts].normalized = 0; - break; - case BT_CR: case BT_LF: - /* This case ensures that the first attribute name is counted - Apart from that we could just change state on the quote. */ - if (state == inName) - state = other; - else if (state == inValue && nAtts < attsMax) - atts[nAtts].normalized = 0; - break; - case BT_GT: - case BT_SOL: - if (state != inValue) - return nAtts; - break; - default: - break; - } - } - /* not reached */ -} - -static int PTRFASTCALL -PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr) -{ - int result = 0; - /* skip &# */ - ptr += 2*MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_x)) { - for (ptr += MINBPC(enc); - !CHAR_MATCHES(enc, ptr, ASCII_SEMI); - ptr += MINBPC(enc)) { - int c = BYTE_TO_ASCII(enc, ptr); - switch (c) { - case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4: - case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9: - result <<= 4; - result |= (c - ASCII_0); - break; - case ASCII_A: case ASCII_B: case ASCII_C: - case ASCII_D: case ASCII_E: case ASCII_F: - result <<= 4; - result += 10 + (c - ASCII_A); - break; - case ASCII_a: case ASCII_b: case ASCII_c: - case ASCII_d: case ASCII_e: case ASCII_f: - result <<= 4; - result += 10 + (c - ASCII_a); - break; - } - if (result >= 0x110000) - return -1; - } - } - else { - for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { - int c = BYTE_TO_ASCII(enc, ptr); - result *= 10; - result += (c - ASCII_0); - if (result >= 0x110000) - return -1; - } - } - return checkCharRefNumber(result); -} - -static int PTRCALL -PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr, - const char *end) -{ - switch ((end - ptr)/MINBPC(enc)) { - case 2: - if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) { - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_l: - return ASCII_LT; - case ASCII_g: - return ASCII_GT; - } - } - break; - case 3: - if (CHAR_MATCHES(enc, ptr, ASCII_a)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_m)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_p)) - return ASCII_AMP; - } - } - break; - case 4: - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_q: - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_u)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_o)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_t)) - return ASCII_QUOT; - } - } - break; - case ASCII_a: - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_p)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_o)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_s)) - return ASCII_APOS; - } - } - break; - } - } - return 0; -} - -static int PTRCALL -PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1, - const char *end1, const char *ptr2) -{ - for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { - if (end1 - ptr1 < MINBPC(enc)) { - /* This line cannot be executed. THe incoming data has already - * been tokenized once, so imcomplete characters like this have - * already been eliminated from the input. Retaining the - * paranoia check is still valuable, however. - */ - return 0; /* LCOV_EXCL_LINE */ - } - if (!CHAR_MATCHES(enc, ptr1, *ptr2)) - return 0; - } - return ptr1 == end1; -} - -static int PTRFASTCALL -PREFIX(nameLength)(const ENCODING *enc, const char *ptr) -{ - const char *start = ptr; - for (;;) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: ptr += n; break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_NONASCII: - case BT_NMSTRT: -#ifdef XML_NS - case BT_COLON: -#endif - case BT_HEX: - case BT_DIGIT: - case BT_NAME: - case BT_MINUS: - ptr += MINBPC(enc); - break; - default: - return (int)(ptr - start); - } - } -} - -static const char * PTRFASTCALL -PREFIX(skipS)(const ENCODING *enc, const char *ptr) -{ - for (;;) { - switch (BYTE_TYPE(enc, ptr)) { - case BT_LF: - case BT_CR: - case BT_S: - ptr += MINBPC(enc); - break; - default: - return ptr; - } - } -} - -static void PTRCALL -PREFIX(updatePosition)(const ENCODING *enc, - const char *ptr, - const char *end, - POSITION *pos) -{ - while (HAS_CHAR(enc, ptr, end)) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - ptr += n; \ - break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_LF: - pos->columnNumber = (XML_Size)-1; - pos->lineNumber++; - ptr += MINBPC(enc); - break; - case BT_CR: - pos->lineNumber++; - ptr += MINBPC(enc); - if (HAS_CHAR(enc, ptr, end) && BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - pos->columnNumber = (XML_Size)-1; - break; - default: - ptr += MINBPC(enc); - break; - } - pos->columnNumber++; - } -} - -#undef DO_LEAD_CASE -#undef MULTIBYTE_CASES -#undef INVALID_CASES -#undef CHECK_NAME_CASE -#undef CHECK_NAME_CASES -#undef CHECK_NMSTRT_CASE -#undef CHECK_NMSTRT_CASES - -#endif /* XML_TOK_IMPL_C */ diff --git a/tools/sdk/include/expat/xmltok_ns.c b/tools/sdk/include/expat/xmltok_ns.c deleted file mode 100644 index 23d31e8e..00000000 --- a/tools/sdk/include/expat/xmltok_ns.c +++ /dev/null @@ -1,142 +0,0 @@ -/* This file is included! - __ __ _ - ___\ \/ /_ __ __ _| |_ - / _ \\ /| '_ \ / _` | __| - | __// \| |_) | (_| | |_ - \___/_/\_\ .__/ \__,_|\__| - |_| XML parser - - Copyright (c) 1997-2000 Thai Open Source Software Center Ltd - Copyright (c) 2000-2017 Expat development team - Licensed under the MIT license: - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to permit - persons to whom the Software is furnished to do so, subject to the - following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN - NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifdef XML_TOK_NS_C - -const ENCODING * -NS(XmlGetUtf8InternalEncoding)(void) -{ - return &ns(internal_utf8_encoding).enc; -} - -const ENCODING * -NS(XmlGetUtf16InternalEncoding)(void) -{ -#if BYTEORDER == 1234 - return &ns(internal_little2_encoding).enc; -#elif BYTEORDER == 4321 - return &ns(internal_big2_encoding).enc; -#else - const short n = 1; - return (*(const char *)&n - ? &ns(internal_little2_encoding).enc - : &ns(internal_big2_encoding).enc); -#endif -} - -static const ENCODING * const NS(encodings)[] = { - &ns(latin1_encoding).enc, - &ns(ascii_encoding).enc, - &ns(utf8_encoding).enc, - &ns(big2_encoding).enc, - &ns(big2_encoding).enc, - &ns(little2_encoding).enc, - &ns(utf8_encoding).enc /* NO_ENC */ -}; - -static int PTRCALL -NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - return initScan(NS(encodings), (const INIT_ENCODING *)enc, - XML_PROLOG_STATE, ptr, end, nextTokPtr); -} - -static int PTRCALL -NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - return initScan(NS(encodings), (const INIT_ENCODING *)enc, - XML_CONTENT_STATE, ptr, end, nextTokPtr); -} - -int -NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, - const char *name) -{ - int i = getEncodingIndex(name); - if (i == UNKNOWN_ENC) - return 0; - SET_INIT_ENC_INDEX(p, i); - p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog); - p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent); - p->initEnc.updatePosition = initUpdatePosition; - p->encPtr = encPtr; - *encPtr = &(p->initEnc); - return 1; -} - -static const ENCODING * -NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) -{ -#define ENCODING_MAX 128 - char buf[ENCODING_MAX]; - char *p = buf; - int i; - XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); - if (ptr != end) - return 0; - *p = 0; - if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2) - return enc; - i = getEncodingIndex(buf); - if (i == UNKNOWN_ENC) - return 0; - return NS(encodings)[i]; -} - -int -NS(XmlParseXmlDecl)(int isGeneralTextEntity, - const ENCODING *enc, - const char *ptr, - const char *end, - const char **badPtr, - const char **versionPtr, - const char **versionEndPtr, - const char **encodingName, - const ENCODING **encoding, - int *standalone) -{ - return doParseXmlDecl(NS(findEncoding), - isGeneralTextEntity, - enc, - ptr, - end, - badPtr, - versionPtr, - versionEndPtr, - encodingName, - encoding, - standalone); -} - -#endif /* XML_TOK_NS_C */ diff --git a/tools/sdk/include/fatfs/ffconf.h b/tools/sdk/include/fatfs/ffconf.h index 1b1cf8c8..bf0e1a8e 100644 --- a/tools/sdk/include/fatfs/ffconf.h +++ b/tools/sdk/include/fatfs/ffconf.h @@ -52,7 +52,7 @@ /* This option switches f_expand function. (0:Disable or 1:Enable) */ -#define FF_USE_CHMOD 0 +#define FF_USE_CHMOD 1 /* This option switches attribute manipulation functions, f_chmod() and f_utime(). / (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */ diff --git a/tools/sdk/include/freemodbus/mb.h b/tools/sdk/include/freemodbus/mb.h new file mode 100644 index 00000000..8d6be7b4 --- /dev/null +++ b/tools/sdk/include/freemodbus/mb.h @@ -0,0 +1,417 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * File: $Id: mb.h,v 1.17 2006/12/07 22:10:34 wolti Exp $ + */ + +#ifndef _MB_H +#define _MB_H + +#include "port.h" + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif + +#include "mbport.h" +#include "mbproto.h" + +/*! \defgroup modbus Modbus + * \code #include "mb.h" \endcode + * + * This module defines the interface for the application. It contains + * the basic functions and types required to use the Modbus protocol stack. + * A typical application will want to call eMBInit() first. If the device + * is ready to answer network requests it must then call eMBEnable() to activate + * the protocol stack. In the main loop the function eMBPoll() must be called + * periodically. The time interval between pooling depends on the configured + * Modbus timeout. If an RTOS is available a separate task should be created + * and the task should always call the function eMBPoll(). + * + * \code + * // Initialize protocol stack in RTU mode for a slave with address 10 = 0x0A + * eMBInit( MB_RTU, 0x0A, 38400, MB_PAR_EVEN ); + * // Enable the Modbus Protocol Stack. + * eMBEnable( ); + * for( ;; ) + * { + * // Call the main polling loop of the Modbus protocol stack. + * eMBPoll( ); + * ... + * } + * \endcode + */ + +/* ----------------------- Defines ------------------------------------------*/ + +/*! \ingroup modbus + * \brief Use the default Modbus TCP port (502) + */ +#define MB_TCP_PORT_USE_DEFAULT 0 + +/* ----------------------- Type definitions ---------------------------------*/ + +/*! \ingroup modbus + * \brief Modbus serial transmission modes (RTU/ASCII). + * + * Modbus serial supports two transmission modes. Either ASCII or RTU. RTU + * is faster but has more hardware requirements and requires a network with + * a low jitter. ASCII is slower and more reliable on slower links (E.g. modems) + */ + typedef enum +{ + MB_RTU, /*!< RTU transmission mode. */ + MB_ASCII, /*!< ASCII transmission mode. */ + MB_TCP /*!< TCP mode. */ +} eMBMode; + +/*! \ingroup modbus + * \brief If register should be written or read. + * + * This value is passed to the callback functions which support either + * reading or writing register values. Writing means that the application + * registers should be updated and reading means that the modbus protocol + * stack needs to know the current register values. + * + * \see eMBRegHoldingCB( ), eMBRegCoilsCB( ), eMBRegDiscreteCB( ) and + * eMBRegInputCB( ). + */ +typedef enum +{ + MB_REG_READ, /*!< Read register values and pass to protocol stack. */ + MB_REG_WRITE /*!< Update register values. */ +} eMBRegisterMode; + +/*! \ingroup modbus + * \brief Errorcodes used by all function in the protocol stack. + */ +typedef enum +{ + MB_ENOERR, /*!< no error. */ + MB_ENOREG, /*!< illegal register address. */ + MB_EINVAL, /*!< illegal argument. */ + MB_EPORTERR, /*!< porting layer error. */ + MB_ENORES, /*!< insufficient resources. */ + MB_EIO, /*!< I/O error. */ + MB_EILLSTATE, /*!< protocol stack in illegal state. */ + MB_ETIMEDOUT /*!< timeout error occurred. */ +} eMBErrorCode; + + +/* ----------------------- Function prototypes ------------------------------*/ +/*! \ingroup modbus + * \brief Initialize the Modbus protocol stack. + * + * This functions initializes the ASCII or RTU module and calls the + * init functions of the porting layer to prepare the hardware. Please + * note that the receiver is still disabled and no Modbus frames are + * processed until eMBEnable( ) has been called. + * + * \param eMode If ASCII or RTU mode should be used. + * \param ucSlaveAddress The slave address. Only frames sent to this + * address or to the broadcast address are processed. + * \param ucPort The port to use. E.g. 1 for COM1 on windows. This value + * is platform dependent and some ports simply choose to ignore it. + * \param ulBaudRate The baudrate. E.g. 19200. Supported baudrates depend + * on the porting layer. + * \param eParity Parity used for serial transmission. + * + * \return If no error occurs the function returns eMBErrorCode::MB_ENOERR. + * The protocol is then in the disabled state and ready for activation + * by calling eMBEnable( ). Otherwise one of the following error codes + * is returned: + * - eMBErrorCode::MB_EINVAL If the slave address was not valid. Valid + * slave addresses are in the range 1 - 247. + * - eMBErrorCode::MB_EPORTERR IF the porting layer returned an error. + */ +eMBErrorCode eMBInit( eMBMode eMode, UCHAR ucSlaveAddress, + UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity ); + +/*! \ingroup modbus + * \brief Initialize the Modbus protocol stack for Modbus TCP. + * + * This function initializes the Modbus TCP Module. Please note that + * frame processing is still disabled until eMBEnable( ) is called. + * + * \param usTCPPort The TCP port to listen on. + * \return If the protocol stack has been initialized correctly the function + * returns eMBErrorCode::MB_ENOERR. Otherwise one of the following error + * codes is returned: + * - eMBErrorCode::MB_EINVAL If the slave address was not valid. Valid + * slave addresses are in the range 1 - 247. + * - eMBErrorCode::MB_EPORTERR IF the porting layer returned an error. + */ +eMBErrorCode eMBTCPInit( USHORT usTCPPort ); + +/*! \ingroup modbus + * \brief Release resources used by the protocol stack. + * + * This function disables the Modbus protocol stack and release all + * hardware resources. It must only be called when the protocol stack + * is disabled. + * + * \note Note all ports implement this function. A port which wants to + * get an callback must define the macro MB_PORT_HAS_CLOSE to 1. + * + * \return If the resources where released it return eMBErrorCode::MB_ENOERR. + * If the protocol stack is not in the disabled state it returns + * eMBErrorCode::MB_EILLSTATE. + */ +eMBErrorCode eMBClose( void ); + +/*! \ingroup modbus + * \brief Enable the Modbus protocol stack. + * + * This function enables processing of Modbus frames. Enabling the protocol + * stack is only possible if it is in the disabled state. + * + * \return If the protocol stack is now in the state enabled it returns + * eMBErrorCode::MB_ENOERR. If it was not in the disabled state it + * return eMBErrorCode::MB_EILLSTATE. + */ +eMBErrorCode eMBEnable( void ); + +/*! \ingroup modbus + * \brief Disable the Modbus protocol stack. + * + * This function disables processing of Modbus frames. + * + * \return If the protocol stack has been disabled it returns + * eMBErrorCode::MB_ENOERR. If it was not in the enabled state it returns + * eMBErrorCode::MB_EILLSTATE. + */ +eMBErrorCode eMBDisable( void ); + +/*! \ingroup modbus + * \brief The main pooling loop of the Modbus protocol stack. + * + * This function must be called periodically. The timer interval required + * is given by the application dependent Modbus slave timeout. Internally the + * function calls xMBPortEventGet() and waits for an event from the receiver or + * transmitter state machines. + * + * \return If the protocol stack is not in the enabled state the function + * returns eMBErrorCode::MB_EILLSTATE. Otherwise it returns + * eMBErrorCode::MB_ENOERR. + */ +eMBErrorCode eMBPoll( void ); + +/*! \ingroup modbus + * \brief Configure the slave id of the device. + * + * This function should be called when the Modbus function Report Slave ID + * is enabled ( By defining MB_FUNC_OTHER_REP_SLAVEID_ENABLED in mbconfig.h ). + * + * \param ucSlaveID Values is returned in the Slave ID byte of the + * Report Slave ID response. + * \param xIsRunning If TRUE the Run Indicator Status byte is set to 0xFF. + * otherwise the Run Indicator Status is 0x00. + * \param pucAdditional Values which should be returned in the Additional + * bytes of the Report Slave ID response. + * \param usAdditionalLen Length of the buffer pucAdditonal. + * + * \return If the static buffer defined by MB_FUNC_OTHER_REP_SLAVEID_BUF in + * mbconfig.h is to small it returns eMBErrorCode::MB_ENORES. Otherwise + * it returns eMBErrorCode::MB_ENOERR. + */ +eMBErrorCode eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning, + UCHAR const *pucAdditional, + USHORT usAdditionalLen ); + +/*! \ingroup modbus + * \brief Registers a callback handler for a given function code. + * + * This function registers a new callback handler for a given function code. + * The callback handler supplied is responsible for interpreting the Modbus PDU and + * the creation of an appropriate response. In case of an error it should return + * one of the possible Modbus exceptions which results in a Modbus exception frame + * sent by the protocol stack. + * + * \param ucFunctionCode The Modbus function code for which this handler should + * be registers. Valid function codes are in the range 1 to 127. + * \param pxHandler The function handler which should be called in case + * such a frame is received. If \c NULL a previously registered function handler + * for this function code is removed. + * + * \return eMBErrorCode::MB_ENOERR if the handler has been installed. If no + * more resources are available it returns eMBErrorCode::MB_ENORES. In this + * case the values in mbconfig.h should be adjusted. If the argument was not + * valid it returns eMBErrorCode::MB_EINVAL. + */ +eMBErrorCode eMBRegisterCB( UCHAR ucFunctionCode, + pxMBFunctionHandler pxHandler ); + +/* ----------------------- Callback -----------------------------------------*/ + +/*! \defgroup modbus_registers Modbus Registers + * \code #include "mb.h" \endcode + * The protocol stack does not internally allocate any memory for the + * registers. This makes the protocol stack very small and also usable on + * low end targets. In addition the values don't have to be in the memory + * and could for example be stored in a flash.
+ * Whenever the protocol stack requires a value it calls one of the callback + * function with the register address and the number of registers to read + * as an argument. The application should then read the actual register values + * (for example the ADC voltage) and should store the result in the supplied + * buffer.
+ * If the protocol stack wants to update a register value because a write + * register function was received a buffer with the new register values is + * passed to the callback function. The function should then use these values + * to update the application register values. + */ + +/*! \ingroup modbus_registers + * \brief Callback function used if the value of a Input Register + * is required by the protocol stack. The starting register address is given + * by \c usAddress and the last register is given by usAddress + + * usNRegs - 1. + * + * \param pucRegBuffer A buffer where the callback function should write + * the current value of the modbus registers to. + * \param usAddress The starting address of the register. Input registers + * are in the range 1 - 65535. + * \param usNRegs Number of registers the callback function must supply. + * + * \return The function must return one of the following error codes: + * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal + * Modbus response is sent. + * - eMBErrorCode::MB_ENOREG If the application can not supply values + * for registers within this range. In this case a + * ILLEGAL DATA ADDRESS exception frame is sent as a response. + * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is + * currently not available and the application dependent response + * timeout would be violated. In this case a SLAVE DEVICE BUSY + * exception is sent as a response. + * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case + * a SLAVE DEVICE FAILURE exception is sent as a response. + */ +eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, + USHORT usNRegs ); + +/*! \ingroup modbus_registers + * \brief Callback function used if a Holding Register value is + * read or written by the protocol stack. The starting register address + * is given by \c usAddress and the last register is given by + * usAddress + usNRegs - 1. + * + * \param pucRegBuffer If the application registers values should be updated the + * buffer points to the new registers values. If the protocol stack needs + * to now the current values the callback function should write them into + * this buffer. + * \param usAddress The starting address of the register. + * \param usNRegs Number of registers to read or write. + * \param eMode If eMBRegisterMode::MB_REG_WRITE the application register + * values should be updated from the values in the buffer. For example + * this would be the case when the Modbus master has issued an + * WRITE SINGLE REGISTER command. + * If the value eMBRegisterMode::MB_REG_READ the application should copy + * the current values into the buffer \c pucRegBuffer. + * + * \return The function must return one of the following error codes: + * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal + * Modbus response is sent. + * - eMBErrorCode::MB_ENOREG If the application can not supply values + * for registers within this range. In this case a + * ILLEGAL DATA ADDRESS exception frame is sent as a response. + * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is + * currently not available and the application dependent response + * timeout would be violated. In this case a SLAVE DEVICE BUSY + * exception is sent as a response. + * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case + * a SLAVE DEVICE FAILURE exception is sent as a response. + */ +eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, + USHORT usNRegs, eMBRegisterMode eMode ); + +/*! \ingroup modbus_registers + * \brief Callback function used if a Coil Register value is + * read or written by the protocol stack. If you are going to use + * this function you might use the functions xMBUtilSetBits( ) and + * xMBUtilGetBits( ) for working with bitfields. + * + * \param pucRegBuffer The bits are packed in bytes where the first coil + * starting at address \c usAddress is stored in the LSB of the + * first byte in the buffer pucRegBuffer. + * If the buffer should be written by the callback function unused + * coil values (I.e. if not a multiple of eight coils is used) should be set + * to zero. + * \param usAddress The first coil number. + * \param usNCoils Number of coil values requested. + * \param eMode If eMBRegisterMode::MB_REG_WRITE the application values should + * be updated from the values supplied in the buffer \c pucRegBuffer. + * If eMBRegisterMode::MB_REG_READ the application should store the current + * values in the buffer \c pucRegBuffer. + * + * \return The function must return one of the following error codes: + * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal + * Modbus response is sent. + * - eMBErrorCode::MB_ENOREG If the application does not map an coils + * within the requested address range. In this case a + * ILLEGAL DATA ADDRESS is sent as a response. + * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is + * currently not available and the application dependent response + * timeout would be violated. In this case a SLAVE DEVICE BUSY + * exception is sent as a response. + * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case + * a SLAVE DEVICE FAILURE exception is sent as a response. + */ +eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, + USHORT usNCoils, eMBRegisterMode eMode ); + +/*! \ingroup modbus_registers + * \brief Callback function used if a Input Discrete Register value is + * read by the protocol stack. + * + * If you are going to use his function you might use the functions + * xMBUtilSetBits( ) and xMBUtilGetBits( ) for working with bitfields. + * + * \param pucRegBuffer The buffer should be updated with the current + * coil values. The first discrete input starting at \c usAddress must be + * stored at the LSB of the first byte in the buffer. If the requested number + * is not a multiple of eight the remaining bits should be set to zero. + * \param usAddress The starting address of the first discrete input. + * \param usNDiscrete Number of discrete input values. + * \return The function must return one of the following error codes: + * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal + * Modbus response is sent. + * - eMBErrorCode::MB_ENOREG If no such discrete inputs exists. + * In this case a ILLEGAL DATA ADDRESS exception frame is sent + * as a response. + * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is + * currently not available and the application dependent response + * timeout would be violated. In this case a SLAVE DEVICE BUSY + * exception is sent as a response. + * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case + * a SLAVE DEVICE FAILURE exception is sent as a response. + */ +eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, + USHORT usNDiscrete ); + +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif diff --git a/tools/sdk/include/freemodbus/mbconfig.h b/tools/sdk/include/freemodbus/mbconfig.h new file mode 100644 index 00000000..54194de2 --- /dev/null +++ b/tools/sdk/include/freemodbus/mbconfig.h @@ -0,0 +1,132 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * File: $Id: mbconfig.h,v 1.15 2010/06/06 13:54:40 wolti Exp $ + */ + +#ifndef _MB_CONFIG_H +#define _MB_CONFIG_H + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif +/* ----------------------- Defines ------------------------------------------*/ +/*! \defgroup modbus_cfg Modbus Configuration + * + * Most modules in the protocol stack are completly optional and can be + * excluded. This is specially important if target resources are very small + * and program memory space should be saved.
+ * + * All of these settings are available in the file mbconfig.h + */ +/*! \addtogroup modbus_cfg + * @{ + */ +/*! \brief If Modbus ASCII support is enabled. */ +#define MB_ASCII_ENABLED ( 0 ) + +/*! \brief If Modbus RTU support is enabled. */ +#define MB_RTU_ENABLED ( 1 ) + +/*! \brief If Modbus TCP support is enabled. */ +#define MB_TCP_ENABLED ( 0 ) + +/*! \brief The character timeout value for Modbus ASCII. + * + * The character timeout value is not fixed for Modbus ASCII and is therefore + * a configuration option. It should be set to the maximum expected delay + * time of the network. + */ +#define MB_ASCII_TIMEOUT_SEC ( 1 ) + +/*! \brief Timeout to wait in ASCII prior to enabling transmitter. + * + * If defined the function calls vMBPortSerialDelay with the argument + * MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS to allow for a delay before + * the serial transmitter is enabled. This is required because some + * targets are so fast that there is no time between receiving and + * transmitting the frame. If the master is to slow with enabling its + * receiver then he will not receive the response correctly. + */ +#ifndef MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS +#define MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS ( 0 ) +#endif + +/*! \brief Maximum number of Modbus functions codes the protocol stack + * should support. + * + * The maximum number of supported Modbus functions must be greater than + * the sum of all enabled functions in this file and custom function + * handlers. If set to small adding more functions will fail. + */ +#define MB_FUNC_HANDLERS_MAX ( 16 ) + +/*! \brief Number of bytes which should be allocated for the Report Slave ID + * command. + * + * This number limits the maximum size of the additional segment in the + * report slave id function. See eMBSetSlaveID( ) for more information on + * how to set this value. It is only used if MB_FUNC_OTHER_REP_SLAVEID_ENABLED + * is set to 1. + */ +#define MB_FUNC_OTHER_REP_SLAVEID_BUF ( 32 ) + +/*! \brief If the Report Slave ID function should be enabled. */ +#define MB_FUNC_OTHER_REP_SLAVEID_ENABLED ( CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT ) + +/*! \brief If the Read Input Registers function should be enabled. */ +#define MB_FUNC_READ_INPUT_ENABLED ( 1 ) + +/*! \brief If the Read Holding Registers function should be enabled. */ +#define MB_FUNC_READ_HOLDING_ENABLED ( 1 ) + +/*! \brief If the Write Single Register function should be enabled. */ +#define MB_FUNC_WRITE_HOLDING_ENABLED ( 1 ) + +/*! \brief If the Write Multiple registers function should be enabled. */ +#define MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED ( 1 ) + +/*! \brief If the Read Coils function should be enabled. */ +#define MB_FUNC_READ_COILS_ENABLED ( 1 ) + +/*! \brief If the Write Coils function should be enabled. */ +#define MB_FUNC_WRITE_COIL_ENABLED ( 1 ) + +/*! \brief If the Write Multiple Coils function should be enabled. */ +#define MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED ( 1 ) + +/*! \brief If the Read Discrete Inputs function should be enabled. */ +#define MB_FUNC_READ_DISCRETE_INPUTS_ENABLED ( 1 ) + +/*! \brief If the Read/Write Multiple Registers function should be enabled. */ +#define MB_FUNC_READWRITE_HOLDING_ENABLED ( 1 ) + +/*! @} */ +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif diff --git a/tools/sdk/include/freemodbus/mbcontroller.h b/tools/sdk/include/freemodbus/mbcontroller.h new file mode 100644 index 00000000..b6b206e2 --- /dev/null +++ b/tools/sdk/include/freemodbus/mbcontroller.h @@ -0,0 +1,186 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// mbcontroller.h +// Implementation of the MbController + +#ifndef _MODBUS_CONTROLLER +#define _MODBUS_CONTROLLER + +#include // for standard int types definition +#include // for NULL and std defines +#include "soc/soc.h" // for BITN definitions +#include "sdkconfig.h" // for KConfig options +#include "driver/uart.h" // for uart port number defines + +/* ----------------------- Defines ------------------------------------------*/ +#define MB_INST_MIN_SIZE (2) // The minimal size of Modbus registers area in bytes +#define MB_INST_MAX_SIZE (2048) // The maximum size of Modbus area in bytes + +#define MB_CONTROLLER_STACK_SIZE (CONFIG_MB_CONTROLLER_STACK_SIZE) // Stack size for Modbus controller +#define MB_CONTROLLER_PRIORITY (CONFIG_MB_SERIAL_TASK_PRIO - 1) // priority of MB controller task +#define MB_CONTROLLER_NOTIFY_QUEUE_SIZE (CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE) // Number of messages in parameter notification queue +#define MB_CONTROLLER_NOTIFY_TIMEOUT (pdMS_TO_TICKS(CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT)) // notification timeout + +// Default port defines +#define MB_DEVICE_ADDRESS (1) // Default slave device address in Modbus +#define MB_DEVICE_SPEED (115200) // Default Modbus speed for now hard defined +#define MB_UART_PORT (UART_NUM_2) // Default UART port number +#define MB_PAR_INFO_TOUT (10) // Timeout for get parameter info +#define MB_PARITY_NONE (UART_PARITY_DISABLE) + +/** + * @brief Event group for parameters notification + */ +typedef enum +{ + MB_EVENT_NO_EVENTS = 0x00, + MB_EVENT_HOLDING_REG_WR = BIT0, /*!< Modbus Event Write Holding registers. */ + MB_EVENT_HOLDING_REG_RD = BIT1, /*!< Modbus Event Read Holding registers. */ + MB_EVENT_INPUT_REG_RD = BIT3, /*!< Modbus Event Read Input registers. */ + MB_EVENT_COILS_WR = BIT4, /*!< Modbus Event Write Coils. */ + MB_EVENT_COILS_RD = BIT5, /*!< Modbus Event Read Coils. */ + MB_EVENT_DISCRETE_RD = BIT6, /*!< Modbus Event Read Discrete bits. */ + MB_EVENT_STACK_STARTED = BIT7 /*!< Modbus Event Stack started */ +} mb_event_group_t; + +/** + * @brief Type of Modbus parameter + */ +typedef enum +{ + MB_PARAM_HOLDING, /*!< Modbus Holding register. */ + MB_PARAM_INPUT, /*!< Modbus Input register. */ + MB_PARAM_COIL, /*!< Modbus Coils. */ + MB_PARAM_DISCRETE, /*!< Modbus Discrete bits. */ + MB_PARAM_COUNT, + MB_PARAM_UNKNOWN = 0xFF +} mb_param_type_t; + +/*! + * \brief Modbus serial transmission modes (RTU/ASCII). + */ +typedef enum +{ + MB_MODE_RTU, /*!< RTU transmission mode. */ + MB_MODE_ASCII, /*!< ASCII transmission mode. */ + MB_MODE_TCP /*!< TCP mode. */ +} mb_mode_type_t; + +/** + * @brief Parameter access event information type + */ +typedef struct { + uint32_t time_stamp; /*!< Timestamp of Modbus Event (uS)*/ + uint16_t mb_offset; /*!< Modbus register offset */ + mb_event_group_t type; /*!< Modbus event type */ + uint8_t* address; /*!< Modbus data storage address */ + size_t size; /*!< Modbus event register size (number of registers)*/ +} mb_param_info_t; + +/** + * @brief Parameter storage area descriptor + */ +typedef struct { + uint16_t start_offset; /*!< Modbus start address for area descriptor */ + mb_param_type_t type; /*!< Type of storage area descriptor */ + void* address; /*!< Instance address for storage area descriptor */ + size_t size; /*!< Instance size for area descriptor (bytes) */ +} mb_register_area_descriptor_t; + +/** + * @brief Device communication parameters + */ +typedef struct { + mb_mode_type_t mode; /*!< Modbus communication mode */ + uint8_t slave_addr; /*!< Modbus Slave Address */ + uart_port_t port; /*!< Modbus communication port (UART) number */ + uint32_t baudrate; /*!< Modbus baudrate */ + uart_parity_t parity; /*!< Modbus UART parity settings */ +} mb_communication_info_t; + +/** + * @brief Initialize modbus controller and stack + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t mbcontroller_init(void); + +/** + * @brief Destroy Modbus controller and stack + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t mbcontroller_destroy(void); + +/** + * @brief Start Modbus communication stack + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Modbus stack start error + */ +esp_err_t mbcontroller_start(void); + +/** + * @brief Set Modbus communication parameters for the controller + * + * @param comm_info Communication parameters structure. + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Incorrect parameter data + */ +esp_err_t mbcontroller_setup(mb_communication_info_t comm_info); + +/** + * @brief Wait for specific event on parameter change. + * + * @param group Group event bit mask to wait for change + * + * @return + * - mb_event_group_t event bits triggered + */ +mb_event_group_t mbcontroller_check_event(mb_event_group_t group); + +/** + * @brief Get parameter information + * + * @param[out] reg_info parameter info structure + * @param timeout Timeout in milliseconds to read information from + * parameter queue + * @return + * - ESP_OK Success + * - ESP_ERR_TIMEOUT Can not get data from parameter queue + * or queue overflow + */ +esp_err_t mbcontroller_get_param_info(mb_param_info_t* reg_info, uint32_t timeout); + +/** + * @brief Set Modbus area descriptor + * + * @param descr_data Modbus registers area descriptor structure + * + * @return + * - ESP_OK: The appropriate descriptor is set + * - ESP_ERR_INVALID_ARG: The argument is incorrect + */ +esp_err_t mbcontroller_set_descriptor(mb_register_area_descriptor_t descr_data); + +#endif + diff --git a/tools/sdk/include/freemodbus/mbframe.h b/tools/sdk/include/freemodbus/mbframe.h new file mode 100644 index 00000000..99d59c61 --- /dev/null +++ b/tools/sdk/include/freemodbus/mbframe.h @@ -0,0 +1,87 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * File: $Id: mbframe.h,v 1.9 2006/12/07 22:10:34 wolti Exp $ + */ + +#ifndef _MB_FRAME_H +#define _MB_FRAME_H + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif + +/*! + * Constants which defines the format of a modbus frame. The example is + * shown for a Modbus RTU/ASCII frame. Note that the Modbus PDU is not + * dependent on the underlying transport. + * + * + * <------------------------ MODBUS SERIAL LINE PDU (1) -------------------> + * <----------- MODBUS PDU (1') ----------------> + * +-----------+---------------+----------------------------+-------------+ + * | Address | Function Code | Data | CRC/LRC | + * +-----------+---------------+----------------------------+-------------+ + * | | | | + * (2) (3/2') (3') (4) + * + * (1) ... MB_SER_PDU_SIZE_MAX = 256 + * (2) ... MB_SER_PDU_ADDR_OFF = 0 + * (3) ... MB_SER_PDU_PDU_OFF = 1 + * (4) ... MB_SER_PDU_SIZE_CRC = 2 + * + * (1') ... MB_PDU_SIZE_MAX = 253 + * (2') ... MB_PDU_FUNC_OFF = 0 + * (3') ... MB_PDU_DATA_OFF = 1 + * + */ + +/* ----------------------- Defines ------------------------------------------*/ +#define MB_PDU_SIZE_MAX 253 /*!< Maximum size of a PDU. */ +#define MB_PDU_SIZE_MIN 1 /*!< Function Code */ +#define MB_PDU_FUNC_OFF 0 /*!< Offset of function code in PDU. */ +#define MB_PDU_DATA_OFF 1 /*!< Offset for response data in PDU. */ + +/* ----------------------- Prototypes 0-------------------------------------*/ +typedef void ( *pvMBFrameStart ) ( void ); + +typedef void ( *pvMBFrameStop ) ( void ); + +typedef eMBErrorCode( *peMBFrameReceive ) ( UCHAR * pucRcvAddress, + UCHAR ** pucFrame, + USHORT * pusLength ); + +typedef eMBErrorCode( *peMBFrameSend ) ( UCHAR slaveAddress, + const UCHAR * pucFrame, + USHORT usLength ); + +typedef void( *pvMBFrameClose ) ( void ); + +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif diff --git a/tools/sdk/include/freemodbus/mbfunc.h b/tools/sdk/include/freemodbus/mbfunc.h new file mode 100644 index 00000000..aea14f75 --- /dev/null +++ b/tools/sdk/include/freemodbus/mbfunc.h @@ -0,0 +1,80 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * File: $Id: mbfunc.h,v 1.12 2006/12/07 22:10:34 wolti Exp $ + */ + +#ifndef _MB_FUNC_H +#define _MB_FUNC_H + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif +#if MB_FUNC_OTHER_REP_SLAVEID_BUF > 0 + eMBException eMBFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_READ_INPUT_ENABLED > 0 +eMBException eMBFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_READ_HOLDING_ENABLED > 0 +eMBException eMBFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_WRITE_HOLDING_ENABLED > 0 +eMBException eMBFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0 +eMBException eMBFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_READ_COILS_ENABLED > 0 +eMBException eMBFuncReadCoils( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_WRITE_COIL_ENABLED > 0 +eMBException eMBFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0 +eMBException eMBFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_READ_DISCRETE_INPUTS_ENABLED > 0 +eMBException eMBFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0 +eMBException eMBFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif diff --git a/tools/sdk/include/freemodbus/mbport.h b/tools/sdk/include/freemodbus/mbport.h new file mode 100644 index 00000000..8d334d0e --- /dev/null +++ b/tools/sdk/include/freemodbus/mbport.h @@ -0,0 +1,130 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * File: $Id: mbport.h,v 1.19 2010/06/06 13:54:40 wolti Exp $ + */ + +#ifndef _MB_PORT_H +#define _MB_PORT_H + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif + +/* ----------------------- Type definitions ---------------------------------*/ + +typedef enum +{ + EV_READY, /*!< Startup finished. */ + EV_FRAME_RECEIVED, /*!< Frame received. */ + EV_EXECUTE, /*!< Execute function. */ + EV_FRAME_SENT /*!< Frame sent. */ +} eMBEventType; + +/*! \ingroup modbus + * \brief Parity used for characters in serial mode. + * + * The parity which should be applied to the characters sent over the serial + * link. Please note that this values are actually passed to the porting + * layer and therefore not all parity modes might be available. + */ +typedef enum +{ + MB_PAR_NONE, /*!< No parity. */ + MB_PAR_ODD, /*!< Odd parity. */ + MB_PAR_EVEN /*!< Even parity. */ +} eMBParity; + +/* ----------------------- Supporting functions -----------------------------*/ +BOOL xMBPortEventInit( void ); + +BOOL xMBPortEventPost( eMBEventType eEvent ); + +BOOL xMBPortEventGet( /*@out@ */ eMBEventType * eEvent ); + +/* ----------------------- Serial port functions ----------------------------*/ + +BOOL xMBPortSerialInit( UCHAR ucPort, ULONG ulBaudRate, + UCHAR ucDataBits, eMBParity eParity ); + +void vMBPortClose( void ); + +void xMBPortSerialClose( void ); + +void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable ); + +BOOL xMBPortSerialGetByte( CHAR * pucByte ); + +BOOL xMBPortSerialPutByte( CHAR ucByte ); + +/* ----------------------- Timers functions ---------------------------------*/ +BOOL xMBPortTimersInit( USHORT usTimeOut50us ); + +void xMBPortTimersClose( void ); + +void vMBPortTimersEnable( void ); + +void vMBPortTimersDisable( void ); + +void vMBPortTimersDelay( USHORT usTimeOutMS ); + +/* ----------------------- Callback for the protocol stack ------------------*/ +/*! + * \brief Callback function for the porting layer when a new byte is + * available. + * + * Depending upon the mode this callback function is used by the RTU or + * ASCII transmission layers. In any case a call to xMBPortSerialGetByte() + * must immediately return a new character. + * + * \return TRUE if a event was posted to the queue because + * a new byte was received. The port implementation should wake up the + * tasks which are currently blocked on the eventqueue. + */ +extern BOOL( *pxMBFrameCBByteReceived ) ( void ); + +extern BOOL( *pxMBFrameCBTransmitterEmpty ) ( void ); + +extern BOOL( *pxMBPortCBTimerExpired ) ( void ); + +/* ----------------------- TCP port functions -------------------------------*/ +#if MB_TCP_ENABLED == 1 +BOOL xMBTCPPortInit( USHORT usTCPPort ); + +void vMBTCPPortClose( void ); + +void vMBTCPPortDisable( void ); + +BOOL xMBTCPPortGetRequest( UCHAR **ppucMBTCPFrame, USHORT * usTCPLength ); + +BOOL xMBTCPPortSendResponse( const UCHAR *pucMBTCPFrame, USHORT usTCPLength ); +#endif + +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif diff --git a/tools/sdk/include/freemodbus/mbproto.h b/tools/sdk/include/freemodbus/mbproto.h new file mode 100644 index 00000000..786aaf40 --- /dev/null +++ b/tools/sdk/include/freemodbus/mbproto.h @@ -0,0 +1,83 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * File: $Id: mbproto.h,v 1.14 2006/12/07 22:10:34 wolti Exp $ + */ + +#ifndef _MB_PROTO_H +#define _MB_PROTO_H + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif +/* ----------------------- Defines ------------------------------------------*/ +#define MB_ADDRESS_BROADCAST ( 0 ) /*! Modbus broadcast address. */ +#define MB_ADDRESS_MIN ( 1 ) /*! Smallest possible slave address. */ +#define MB_ADDRESS_MAX ( 247 ) /*! Biggest possible slave address. */ +#define MB_FUNC_NONE ( 0 ) +#define MB_FUNC_READ_COILS ( 1 ) +#define MB_FUNC_READ_DISCRETE_INPUTS ( 2 ) +#define MB_FUNC_WRITE_SINGLE_COIL ( 5 ) +#define MB_FUNC_WRITE_MULTIPLE_COILS ( 15 ) +#define MB_FUNC_READ_HOLDING_REGISTER ( 3 ) +#define MB_FUNC_READ_INPUT_REGISTER ( 4 ) +#define MB_FUNC_WRITE_REGISTER ( 6 ) +#define MB_FUNC_WRITE_MULTIPLE_REGISTERS ( 16 ) +#define MB_FUNC_READWRITE_MULTIPLE_REGISTERS ( 23 ) +#define MB_FUNC_DIAG_READ_EXCEPTION ( 7 ) +#define MB_FUNC_DIAG_DIAGNOSTIC ( 8 ) +#define MB_FUNC_DIAG_GET_COM_EVENT_CNT ( 11 ) +#define MB_FUNC_DIAG_GET_COM_EVENT_LOG ( 12 ) +#define MB_FUNC_OTHER_REPORT_SLAVEID ( 17 ) +#define MB_FUNC_ERROR ( 128 ) +/* ----------------------- Type definitions ---------------------------------*/ + typedef enum +{ + MB_EX_NONE = 0x00, + MB_EX_ILLEGAL_FUNCTION = 0x01, + MB_EX_ILLEGAL_DATA_ADDRESS = 0x02, + MB_EX_ILLEGAL_DATA_VALUE = 0x03, + MB_EX_SLAVE_DEVICE_FAILURE = 0x04, + MB_EX_ACKNOWLEDGE = 0x05, + MB_EX_SLAVE_BUSY = 0x06, + MB_EX_MEMORY_PARITY_ERROR = 0x08, + MB_EX_GATEWAY_PATH_FAILED = 0x0A, + MB_EX_GATEWAY_TGT_FAILED = 0x0B +} eMBException; + +typedef eMBException( *pxMBFunctionHandler ) ( UCHAR * pucFrame, USHORT * pusLength ); + +typedef struct +{ + UCHAR ucFunctionCode; + pxMBFunctionHandler pxHandler; +} xMBFunctionHandler; + +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif diff --git a/tools/sdk/include/freemodbus/mbutils.h b/tools/sdk/include/freemodbus/mbutils.h new file mode 100644 index 00000000..61495751 --- /dev/null +++ b/tools/sdk/include/freemodbus/mbutils.h @@ -0,0 +1,108 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * File: $Id: mbutils.h,v 1.5 2006/12/07 22:10:34 wolti Exp $ + */ + +#ifndef _MB_UTILS_H +#define _MB_UTILS_H + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif +/*! \defgroup modbus_utils Utilities + * + * This module contains some utility functions which can be used by + * the application. It includes some special functions for working with + * bitfields backed by a character array buffer. + * + */ +/*! \addtogroup modbus_utils + * @{ + */ +/*! \brief Function to set bits in a byte buffer. + * + * This function allows the efficient use of an array to implement bitfields. + * The array used for storing the bits must always be a multiple of two + * bytes. Up to eight bits can be set or cleared in one operation. + * + * \param ucByteBuf A buffer where the bit values are stored. Must be a + * multiple of 2 bytes. No length checking is performed and if + * usBitOffset / 8 is greater than the size of the buffer memory contents + * is overwritten. + * \param usBitOffset The starting address of the bits to set. The first + * bit has the offset 0. + * \param ucNBits Number of bits to modify. The value must always be smaller + * than 8. + * \param ucValues Thew new values for the bits. The value for the first bit + * starting at usBitOffset is the LSB of the value + * ucValues + * + * \code + * ucBits[2] = {0, 0}; + * + * // Set bit 4 to 1 (read: set 1 bit starting at bit offset 4 to value 1) + * xMBUtilSetBits( ucBits, 4, 1, 1 ); + * + * // Set bit 7 to 1 and bit 8 to 0. + * xMBUtilSetBits( ucBits, 7, 2, 0x01 ); + * + * // Set bits 8 - 11 to 0x05 and bits 12 - 15 to 0x0A; + * xMBUtilSetBits( ucBits, 8, 8, 0x5A); + * \endcode + */ +void xMBUtilSetBits( UCHAR * ucByteBuf, USHORT usBitOffset, + UCHAR ucNBits, UCHAR ucValues ); + +/*! \brief Function to read bits in a byte buffer. + * + * This function is used to extract up bit values from an array. Up to eight + * bit values can be extracted in one step. + * + * \param ucByteBuf A buffer where the bit values are stored. + * \param usBitOffset The starting address of the bits to set. The first + * bit has the offset 0. + * \param ucNBits Number of bits to modify. The value must always be smaller + * than 8. + * + * \code + * UCHAR ucBits[2] = {0, 0}; + * UCHAR ucResult; + * + * // Extract the bits 3 - 10. + * ucResult = xMBUtilGetBits( ucBits, 3, 8 ); + * \endcode + */ +UCHAR xMBUtilGetBits( UCHAR * ucByteBuf, USHORT usBitOffset, + UCHAR ucNBits ); + +/*! @} */ + +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif diff --git a/tools/sdk/include/freertos/freertos/FreeRTOSConfig.h b/tools/sdk/include/freertos/freertos/FreeRTOSConfig.h index aa33917e..80185f9e 100644 --- a/tools/sdk/include/freertos/freertos/FreeRTOSConfig.h +++ b/tools/sdk/include/freertos/freertos/FreeRTOSConfig.h @@ -300,7 +300,12 @@ extern void vPortCleanUpTCB ( void *pxTCB ); #define configXT_BOARD 1 /* Board mode */ #define configXT_SIMULATOR 0 -#define configENABLE_TASK_SNAPSHOT 1 +#if CONFIG_ESP32_ENABLE_COREDUMP +#define configENABLE_TASK_SNAPSHOT 1 +#endif +#ifndef configENABLE_TASK_SNAPSHOT +#define configENABLE_TASK_SNAPSHOT 1 +#endif #if CONFIG_SYSVIEW_ENABLE #ifndef __ASSEMBLER__ diff --git a/tools/sdk/include/freertos/freertos/task.h b/tools/sdk/include/freertos/freertos/task.h index 31df0bdd..3fc06d9e 100644 --- a/tools/sdk/include/freertos/freertos/task.h +++ b/tools/sdk/include/freertos/freertos/task.h @@ -93,6 +93,9 @@ extern "C" { #define tskKERNEL_VERSION_MINOR 2 #define tskKERNEL_VERSION_BUILD 0 +/** + * @brief Argument of xTaskCreatePinnedToCore indicating that task has no affinity + */ #define tskNO_AFFINITY INT_MAX /** @@ -305,9 +308,7 @@ is used in assert() statements. */ * is 16. * * @param usStackDepth The size of the task stack specified as the number of - * variables the stack can hold - not the number of bytes. For example, if - * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes - * will be allocated for stack storage. + * bytes. Note that this differs from vanilla FreeRTOS. * * @param pvParameters Pointer that will be used as the parameter for the task * being created. @@ -372,9 +373,7 @@ is used in assert() statements. */ * is 16. * * @param usStackDepth The size of the task stack specified as the number of - * variables the stack can hold - not the number of bytes. For example, if - * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes - * will be allocated for stack storage. + * bytes. Note that this differs from vanilla FreeRTOS. * * @param pvParameters Pointer that will be used as the parameter for the task * being created. @@ -460,9 +459,7 @@ is used in assert() statements. */ * configMAX_TASK_NAME_LEN in FreeRTOSConfig.h. * * @param ulStackDepth The size of the task stack specified as the number of - * variables the stack can hold - not the number of bytes. For example, if - * the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes - * will be allocated for stack storage. + * bytes. Note that this differs from vanilla FreeRTOS. * * @param pvParameters Pointer that will be used as the parameter for the task * being created. @@ -522,9 +519,7 @@ is used in assert() statements. */ * configMAX_TASK_NAME_LEN in FreeRTOSConfig.h. * * @param ulStackDepth The size of the task stack specified as the number of - * variables the stack can hold - not the number of bytes. For example, if - * the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes - * will be allocated for stack storage. + * bytes. Note that this differs from vanilla FreeRTOS. * * @param pvParameters Pointer that will be used as the parameter for the task * being created. @@ -551,9 +546,8 @@ is used in assert() statements. */ * @code{c} * * // Dimensions the buffer that the task being created will use as its stack. - * // NOTE: This is the number of words the stack will hold, not the number of - * // bytes. For example, if each stack item is 32-bits, and this is set to 100, - * // then 400 bytes (100 * 32-bits) will be allocated. + * // NOTE: This is the number of bytes the stack will hold, not the number of + * // words as found in vanilla FreeRTOS. * #define STACK_SIZE 200 * * // Structure that will hold the TCB of the task being created. @@ -586,7 +580,7 @@ is used in assert() statements. */ * xHandle = xTaskCreateStatic( * vTaskCode, // Function that implements the task. * "NAME", // Text name for the task. - * STACK_SIZE, // Stack size in words, not bytes. + * STACK_SIZE, // Stack size in bytes, not words. * ( void * ) 1, // Parameter passed into the task. * tskIDLE_PRIORITY,// Priority at which the task is created. * xStack, // Array to use as the task's stack. @@ -642,7 +636,7 @@ is used in assert() statements. */ * { * vATask, // pvTaskCode - the function that implements the task. * "ATask", // pcName - just a text name for the task to assist debugging. - * 100, // usStackDepth - the stack size DEFINED IN WORDS. + * 100, // usStackDepth - the stack size DEFINED IN BYTES. * NULL, // pvParameters - passed into the task function as the function parameters. * ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state. * cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack. @@ -1339,15 +1333,15 @@ char *pcTaskGetTaskName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for * this function to be available. * - * High water mark is the minimum free stack space there has been (in words, - * so on a 32 bit machine a value of 1 means 4 bytes) since the task started. + * High water mark is the minimum free stack space there has been (in bytes + * rather than words as found in vanilla FreeRTOS) since the task started. * The smaller the returned number the closer the task has come to overflowing its stack. * * @param xTask Handle of the task associated with the stack to be checked. * Set xTask to NULL to check the stack of the calling task. * - * @return The smallest amount of free stack space there has been (in words, so - * actual spaces on the stack rather than bytes) since the task referenced by + * @return The smallest amount of free stack space there has been (in bytes + * rather than words as found in vanilla FreeRTOS) since the task referenced by * xTask was created. */ UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; diff --git a/tools/sdk/include/idf_test/idf_performance.h b/tools/sdk/include/idf_test/idf_performance.h new file mode 100644 index 00000000..3e7c841d --- /dev/null +++ b/tools/sdk/include/idf_test/idf_performance.h @@ -0,0 +1,24 @@ +#pragma once + +/* declare the performance here */ +#define IDF_PERFORMANCE_MAX_HTTPS_REQUEST_BIN_SIZE 800 +#define IDF_PERFORMANCE_MAX_FREERTOS_SPINLOCK_CYCLES_PER_OP 200 +#define IDF_PERFORMANCE_MAX_FREERTOS_SPINLOCK_CYCLES_PER_OP_PSRAM 300 +#define IDF_PERFORMANCE_MAX_FREERTOS_SPINLOCK_CYCLES_PER_OP_UNICORE 130 +#define IDF_PERFORMANCE_MAX_ESP_TIMER_GET_TIME_PER_CALL 1000 +#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 30 +#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 27 +#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 15 +#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 15 +/* Due to code size & linker layout differences interacting with cache, VFS + microbenchmark currently runs slower with PSRAM enabled. */ +#define IDF_PERFORMANCE_MAX_VFS_OPEN_WRITE_CLOSE_TIME 50000 +#define IDF_PERFORMANCE_MAX_VFS_OPEN_WRITE_CLOSE_TIME_PSRAM 40000 +// throughput performance by iperf +#define IDF_PERFORMANCE_MIN_TCP_RX_THROUGHPUT 50 +#define IDF_PERFORMANCE_MIN_TCP_TX_THROUGHPUT 40 +#define IDF_PERFORMANCE_MIN_UDP_RX_THROUGHPUT 80 +#define IDF_PERFORMANCE_MIN_UDP_TX_THROUGHPUT 50 +// events dispatched per second by event loop library +#define IDF_PERFORMANCE_MIN_EVENT_DISPATCH 25000 +#define IDF_PERFORMANCE_MIN_EVENT_DISPATCH_PSRAM 21000 diff --git a/tools/sdk/include/json/tests/common.h b/tools/sdk/include/json/tests/common.h new file mode 100644 index 00000000..4db6bf8c --- /dev/null +++ b/tools/sdk/include/json/tests/common.h @@ -0,0 +1,122 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef CJSON_TESTS_COMMON_H +#define CJSON_TESTS_COMMON_H + +#include "../cJSON.c" + +void reset(cJSON *item); +void reset(cJSON *item) { + if ((item != NULL) && (item->child != NULL)) + { + cJSON_Delete(item->child); + } + if ((item->valuestring != NULL) && !(item->type & cJSON_IsReference)) + { + global_hooks.deallocate(item->valuestring); + } + if ((item->string != NULL) && !(item->type & cJSON_StringIsConst)) + { + global_hooks.deallocate(item->string); + } + + memset(item, 0, sizeof(cJSON)); +} + +char* read_file(const char *filename); +char* read_file(const char *filename) { + FILE *file = NULL; + long length = 0; + char *content = NULL; + size_t read_chars = 0; + + /* open in read binary mode */ + file = fopen(filename, "rb"); + if (file == NULL) + { + goto cleanup; + } + + /* get the length */ + if (fseek(file, 0, SEEK_END) != 0) + { + goto cleanup; + } + length = ftell(file); + if (length < 0) + { + goto cleanup; + } + if (fseek(file, 0, SEEK_SET) != 0) + { + goto cleanup; + } + + /* allocate content buffer */ + content = (char*)malloc((size_t)length + sizeof("")); + if (content == NULL) + { + goto cleanup; + } + + /* read the file into memory */ + read_chars = fread(content, sizeof(char), (size_t)length, file); + if ((long)read_chars != length) + { + free(content); + content = NULL; + goto cleanup; + } + content[read_chars] = '\0'; + + +cleanup: + if (file != NULL) + { + fclose(file); + } + + return content; +} + +/* assertion helper macros */ +#define assert_has_type(item, item_type) TEST_ASSERT_BITS_MESSAGE(0xFF, item_type, item->type, "Item doesn't have expected type.") +#define assert_has_no_reference(item) TEST_ASSERT_BITS_MESSAGE(cJSON_IsReference, 0, item->type, "Item should not have a string as reference.") +#define assert_has_no_const_string(item) TEST_ASSERT_BITS_MESSAGE(cJSON_StringIsConst, 0, item->type, "Item should not have a const string.") +#define assert_has_valuestring(item) TEST_ASSERT_NOT_NULL_MESSAGE(item->valuestring, "Valuestring is NULL.") +#define assert_has_no_valuestring(item) TEST_ASSERT_NULL_MESSAGE(item->valuestring, "Valuestring is not NULL.") +#define assert_has_string(item) TEST_ASSERT_NOT_NULL_MESSAGE(item->string, "String is NULL") +#define assert_has_no_string(item) TEST_ASSERT_NULL_MESSAGE(item->string, "String is not NULL.") +#define assert_not_in_list(item) \ + TEST_ASSERT_NULL_MESSAGE(item->next, "Linked list next pointer is not NULL.");\ + TEST_ASSERT_NULL_MESSAGE(item->prev, "Linked list previous pointer is not NULL.") +#define assert_has_child(item) TEST_ASSERT_NOT_NULL_MESSAGE(item->child, "Item doesn't have a child.") +#define assert_has_no_child(item) TEST_ASSERT_NULL_MESSAGE(item->child, "Item has a child.") +#define assert_is_invalid(item) \ + assert_has_type(item, cJSON_Invalid);\ + assert_not_in_list(item);\ + assert_has_no_child(item);\ + assert_has_no_string(item);\ + assert_has_no_valuestring(item) + +#endif diff --git a/tools/sdk/include/json/tests/unity/examples/example_1/src/ProductionCode.h b/tools/sdk/include/json/tests/unity/examples/example_1/src/ProductionCode.h new file mode 100644 index 00000000..250ca0dc --- /dev/null +++ b/tools/sdk/include/json/tests/unity/examples/example_1/src/ProductionCode.h @@ -0,0 +1,3 @@ + +int FindFunction_WhichIsBroken(int NumberToFind); +int FunctionWhichReturnsLocalVariable(void); diff --git a/tools/sdk/include/json/tests/unity/examples/example_1/src/ProductionCode2.h b/tools/sdk/include/json/tests/unity/examples/example_1/src/ProductionCode2.h new file mode 100644 index 00000000..34ae980d --- /dev/null +++ b/tools/sdk/include/json/tests/unity/examples/example_1/src/ProductionCode2.h @@ -0,0 +1,2 @@ + +char* ThisFunctionHasNotBeenTested(int Poor, char* LittleFunction); diff --git a/tools/sdk/include/json/tests/unity/examples/example_2/src/ProductionCode.h b/tools/sdk/include/json/tests/unity/examples/example_2/src/ProductionCode.h new file mode 100644 index 00000000..250ca0dc --- /dev/null +++ b/tools/sdk/include/json/tests/unity/examples/example_2/src/ProductionCode.h @@ -0,0 +1,3 @@ + +int FindFunction_WhichIsBroken(int NumberToFind); +int FunctionWhichReturnsLocalVariable(void); diff --git a/tools/sdk/include/json/tests/unity/examples/example_2/src/ProductionCode2.h b/tools/sdk/include/json/tests/unity/examples/example_2/src/ProductionCode2.h new file mode 100644 index 00000000..34ae980d --- /dev/null +++ b/tools/sdk/include/json/tests/unity/examples/example_2/src/ProductionCode2.h @@ -0,0 +1,2 @@ + +char* ThisFunctionHasNotBeenTested(int Poor, char* LittleFunction); diff --git a/tools/sdk/include/json/tests/unity/examples/example_3/helper/UnityHelper.h b/tools/sdk/include/json/tests/unity/examples/example_3/helper/UnityHelper.h new file mode 100644 index 00000000..15161115 --- /dev/null +++ b/tools/sdk/include/json/tests/unity/examples/example_3/helper/UnityHelper.h @@ -0,0 +1,12 @@ +#ifndef _TESTHELPER_H +#define _TESTHELPER_H + +#include "Types.h" + +void AssertEqualExampleStruct(const EXAMPLE_STRUCT_T expected, const EXAMPLE_STRUCT_T actual, const unsigned short line); + +#define UNITY_TEST_ASSERT_EQUAL_EXAMPLE_STRUCT_T(expected, actual, line, message) AssertEqualExampleStruct(expected, actual, line); + +#define TEST_ASSERT_EQUAL_EXAMPLE_STRUCT_T(expected, actual) UNITY_TEST_ASSERT_EQUAL_EXAMPLE_STRUCT_T(expected, actual, __LINE__, NULL); + +#endif // _TESTHELPER_H diff --git a/tools/sdk/include/json/tests/unity/examples/example_3/src/ProductionCode.h b/tools/sdk/include/json/tests/unity/examples/example_3/src/ProductionCode.h new file mode 100644 index 00000000..250ca0dc --- /dev/null +++ b/tools/sdk/include/json/tests/unity/examples/example_3/src/ProductionCode.h @@ -0,0 +1,3 @@ + +int FindFunction_WhichIsBroken(int NumberToFind); +int FunctionWhichReturnsLocalVariable(void); diff --git a/tools/sdk/include/json/tests/unity/examples/example_3/src/ProductionCode2.h b/tools/sdk/include/json/tests/unity/examples/example_3/src/ProductionCode2.h new file mode 100644 index 00000000..34ae980d --- /dev/null +++ b/tools/sdk/include/json/tests/unity/examples/example_3/src/ProductionCode2.h @@ -0,0 +1,2 @@ + +char* ThisFunctionHasNotBeenTested(int Poor, char* LittleFunction); diff --git a/tools/sdk/include/json/tests/unity/examples/unity_config.h b/tools/sdk/include/json/tests/unity/examples/unity_config.h new file mode 100644 index 00000000..a2f161a7 --- /dev/null +++ b/tools/sdk/include/json/tests/unity/examples/unity_config.h @@ -0,0 +1,239 @@ +/* Unity Configuration + * As of May 11th, 2016 at ThrowTheSwitch/Unity commit 837c529 + * Update: December 29th, 2016 + * See Also: Unity/docs/UnityConfigurationGuide.pdf + * + * Unity is designed to run on almost anything that is targeted by a C compiler. + * It would be awesome if this could be done with zero configuration. While + * there are some targets that come close to this dream, it is sadly not + * universal. It is likely that you are going to need at least a couple of the + * configuration options described in this document. + * + * All of Unity's configuration options are `#defines`. Most of these are simple + * definitions. A couple are macros with arguments. They live inside the + * unity_internals.h header file. We don't necessarily recommend opening that + * file unless you really need to. That file is proof that a cross-platform + * library is challenging to build. From a more positive perspective, it is also + * proof that a great deal of complexity can be centralized primarily to one + * place in order to provide a more consistent and simple experience elsewhere. + * + * Using These Options + * It doesn't matter if you're using a target-specific compiler and a simulator + * or a native compiler. In either case, you've got a couple choices for + * configuring these options: + * + * 1. Because these options are specified via C defines, you can pass most of + * these options to your compiler through command line compiler flags. Even + * if you're using an embedded target that forces you to use their + * overbearing IDE for all configuration, there will be a place somewhere in + * your project to configure defines for your compiler. + * 2. You can create a custom `unity_config.h` configuration file (present in + * your toolchain's search paths). In this file, you will list definitions + * and macros specific to your target. All you must do is define + * `UNITY_INCLUDE_CONFIG_H` and Unity will rely on `unity_config.h` for any + * further definitions it may need. + */ + +#ifndef UNITY_CONFIG_H +#define UNITY_CONFIG_H + +/* ************************* AUTOMATIC INTEGER TYPES *************************** + * C's concept of an integer varies from target to target. The C Standard has + * rules about the `int` matching the register size of the target + * microprocessor. It has rules about the `int` and how its size relates to + * other integer types. An `int` on one target might be 16 bits while on another + * target it might be 64. There are more specific types in compilers compliant + * with C99 or later, but that's certainly not every compiler you are likely to + * encounter. Therefore, Unity has a number of features for helping to adjust + * itself to match your required integer sizes. It starts off by trying to do it + * automatically. + **************************************************************************** */ + +/* The first attempt to guess your types is to check `limits.h`. Some compilers + * that don't support `stdint.h` could include `limits.h`. If you don't + * want Unity to check this file, define this to make it skip the inclusion. + * Unity looks at UINT_MAX & ULONG_MAX, which were available since C89. + */ +/* #define UNITY_EXCLUDE_LIMITS_H */ + +/* The second thing that Unity does to guess your types is check `stdint.h`. + * This file defines `UINTPTR_MAX`, since C99, that Unity can make use of to + * learn about your system. It's possible you don't want it to do this or it's + * possible that your system doesn't support `stdint.h`. If that's the case, + * you're going to want to define this. That way, Unity will know to skip the + * inclusion of this file and you won't be left with a compiler error. + */ +/* #define UNITY_EXCLUDE_STDINT_H */ + +/* ********************** MANUAL INTEGER TYPE DEFINITION *********************** + * If you've disabled all of the automatic options above, you're going to have + * to do the configuration yourself. There are just a handful of defines that + * you are going to specify if you don't like the defaults. + **************************************************************************** */ + + /* Define this to be the number of bits an `int` takes up on your system. The + * default, if not auto-detected, is 32 bits. + * + * Example: + */ +/* #define UNITY_INT_WIDTH 16 */ + +/* Define this to be the number of bits a `long` takes up on your system. The + * default, if not autodetected, is 32 bits. This is used to figure out what + * kind of 64-bit support your system can handle. Does it need to specify a + * `long` or a `long long` to get a 64-bit value. On 16-bit systems, this option + * is going to be ignored. + * + * Example: + */ +/* #define UNITY_LONG_WIDTH 16 */ + +/* Define this to be the number of bits a pointer takes up on your system. The + * default, if not autodetected, is 32-bits. If you're getting ugly compiler + * warnings about casting from pointers, this is the one to look at. + * + * Example: + */ +/* #define UNITY_POINTER_WIDTH 64 */ + +/* Unity will automatically include 64-bit support if it auto-detects it, or if + * your `int`, `long`, or pointer widths are greater than 32-bits. Define this + * to enable 64-bit support if none of the other options already did it for you. + * There can be a significant size and speed impact to enabling 64-bit support + * on small targets, so don't define it if you don't need it. + */ +/* #define UNITY_INCLUDE_64 */ + + +/* *************************** FLOATING POINT TYPES **************************** + * In the embedded world, it's not uncommon for targets to have no support for + * floating point operations at all or to have support that is limited to only + * single precision. We are able to guess integer sizes on the fly because + * integers are always available in at least one size. Floating point, on the + * other hand, is sometimes not available at all. Trying to include `float.h` on + * these platforms would result in an error. This leaves manual configuration as + * the only option. + **************************************************************************** */ + + /* By default, Unity guesses that you will want single precision floating point + * support, but not double precision. It's easy to change either of these using + * the include and exclude options here. You may include neither, just float, + * or both, as suits your needs. + */ +/* #define UNITY_EXCLUDE_FLOAT */ +#define UNITY_INCLUDE_DOUBLE +/* #define UNITY_EXCLUDE_DOUBLE */ + +/* For features that are enabled, the following floating point options also + * become available. + */ + +/* Unity aims for as small of a footprint as possible and avoids most standard + * library calls (some embedded platforms don't have a standard library!). + * Because of this, its routines for printing integer values are minimalist and + * hand-coded. To keep Unity universal, though, we eventually chose to develop + * our own floating point print routines. Still, the display of floating point + * values during a failure are optional. By default, Unity will print the + * actual results of floating point assertion failures. So a failed assertion + * will produce a message like "Expected 4.0 Was 4.25". If you would like less + * verbose failure messages for floating point assertions, use this option to + * give a failure message `"Values Not Within Delta"` and trim the binary size. + */ +/* #define UNITY_EXCLUDE_FLOAT_PRINT */ + +/* If enabled, Unity assumes you want your `FLOAT` asserts to compare standard C + * floats. If your compiler supports a specialty floating point type, you can + * always override this behavior by using this definition. + * + * Example: + */ +/* #define UNITY_FLOAT_TYPE float16_t */ + +/* If enabled, Unity assumes you want your `DOUBLE` asserts to compare standard + * C doubles. If you would like to change this, you can specify something else + * by using this option. For example, defining `UNITY_DOUBLE_TYPE` to `long + * double` could enable gargantuan floating point types on your 64-bit processor + * instead of the standard `double`. + * + * Example: + */ +/* #define UNITY_DOUBLE_TYPE long double */ + +/* If you look up `UNITY_ASSERT_EQUAL_FLOAT` and `UNITY_ASSERT_EQUAL_DOUBLE` as + * documented in the Unity Assertion Guide, you will learn that they are not + * really asserting that two values are equal but rather that two values are + * "close enough" to equal. "Close enough" is controlled by these precision + * configuration options. If you are working with 32-bit floats and/or 64-bit + * doubles (the normal on most processors), you should have no need to change + * these options. They are both set to give you approximately 1 significant bit + * in either direction. The float precision is 0.00001 while the double is + * 10^-12. For further details on how this works, see the appendix of the Unity + * Assertion Guide. + * + * Example: + */ +/* #define UNITY_FLOAT_PRECISION 0.001f */ +/* #define UNITY_DOUBLE_PRECISION 0.001f */ + + +/* *************************** TOOLSET CUSTOMIZATION *************************** + * In addition to the options listed above, there are a number of other options + * which will come in handy to customize Unity's behavior for your specific + * toolchain. It is possible that you may not need to touch any of these but + * certain platforms, particularly those running in simulators, may need to jump + * through extra hoops to operate properly. These macros will help in those + * situations. + **************************************************************************** */ + +/* By default, Unity prints its results to `stdout` as it runs. This works + * perfectly fine in most situations where you are using a native compiler for + * testing. It works on some simulators as well so long as they have `stdout` + * routed back to the command line. There are times, however, where the + * simulator will lack support for dumping results or you will want to route + * results elsewhere for other reasons. In these cases, you should define the + * `UNITY_OUTPUT_CHAR` macro. This macro accepts a single character at a time + * (as an `int`, since this is the parameter type of the standard C `putchar` + * function most commonly used). You may replace this with whatever function + * call you like. + * + * Example: + * Say you are forced to run your test suite on an embedded processor with no + * `stdout` option. You decide to route your test result output to a custom + * serial `RS232_putc()` function you wrote like thus: + */ +/* #define UNITY_OUTPUT_CHAR(a) RS232_putc(a) */ +/* #define UNITY_OUTPUT_CHAR_HEADER_DECLARATION RS232_putc(int) */ +/* #define UNITY_OUTPUT_FLUSH() RS232_flush() */ +/* #define UNITY_OUTPUT_FLUSH_HEADER_DECLARATION RS232_flush(void) */ +/* #define UNITY_OUTPUT_START() RS232_config(115200,1,8,0) */ +/* #define UNITY_OUTPUT_COMPLETE() RS232_close() */ + +/* For some targets, Unity can make the otherwise required `setUp()` and + * `tearDown()` functions optional. This is a nice convenience for test writers + * since `setUp` and `tearDown` don't often actually _do_ anything. If you're + * using gcc or clang, this option is automatically defined for you. Other + * compilers can also support this behavior, if they support a C feature called + * weak functions. A weak function is a function that is compiled into your + * executable _unless_ a non-weak version of the same function is defined + * elsewhere. If a non-weak version is found, the weak version is ignored as if + * it never existed. If your compiler supports this feature, you can let Unity + * know by defining `UNITY_SUPPORT_WEAK` as the function attributes that would + * need to be applied to identify a function as weak. If your compiler lacks + * support for weak functions, you will always need to define `setUp` and + * `tearDown` functions (though they can be and often will be just empty). The + * most common options for this feature are: + */ +/* #define UNITY_SUPPORT_WEAK weak */ +/* #define UNITY_SUPPORT_WEAK __attribute__((weak)) */ +/* #define UNITY_NO_WEAK */ + +/* Some compilers require a custom attribute to be assigned to pointers, like + * `near` or `far`. In these cases, you can give Unity a safe default for these + * by defining this option with the attribute you would like. + * + * Example: + */ +/* #define UNITY_PTR_ATTRIBUTE __attribute__((far)) */ +/* #define UNITY_PTR_ATTRIBUTE near */ + +#endif /* UNITY_CONFIG_H */ diff --git a/tools/sdk/include/json/tests/unity/extras/fixture/src/unity_fixture.h b/tools/sdk/include/json/tests/unity/extras/fixture/src/unity_fixture.h new file mode 100644 index 00000000..6f8d6234 --- /dev/null +++ b/tools/sdk/include/json/tests/unity/extras/fixture/src/unity_fixture.h @@ -0,0 +1,83 @@ +/* Copyright (c) 2010 James Grenning and Contributed to Unity Project + * ========================================== + * Unity Project - A Test Framework for C + * Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + * [Released under MIT License. Please refer to license.txt for details] + * ========================================== */ + +#ifndef UNITY_FIXTURE_H_ +#define UNITY_FIXTURE_H_ + +#include "unity.h" +#include "unity_internals.h" +#include "unity_fixture_malloc_overrides.h" +#include "unity_fixture_internals.h" + +int UnityMain(int argc, const char* argv[], void (*runAllTests)(void)); + + +#define TEST_GROUP(group)\ + static const char* TEST_GROUP_##group = #group + +#define TEST_SETUP(group) void TEST_##group##_SETUP(void);\ + void TEST_##group##_SETUP(void) + +#define TEST_TEAR_DOWN(group) void TEST_##group##_TEAR_DOWN(void);\ + void TEST_##group##_TEAR_DOWN(void) + + +#define TEST(group, name) \ + void TEST_##group##_##name##_(void);\ + void TEST_##group##_##name##_run(void);\ + void TEST_##group##_##name##_run(void)\ + {\ + UnityTestRunner(TEST_##group##_SETUP,\ + TEST_##group##_##name##_,\ + TEST_##group##_TEAR_DOWN,\ + "TEST(" #group ", " #name ")",\ + TEST_GROUP_##group, #name,\ + __FILE__, __LINE__);\ + }\ + void TEST_##group##_##name##_(void) + +#define IGNORE_TEST(group, name) \ + void TEST_##group##_##name##_(void);\ + void TEST_##group##_##name##_run(void);\ + void TEST_##group##_##name##_run(void)\ + {\ + UnityIgnoreTest("IGNORE_TEST(" #group ", " #name ")", TEST_GROUP_##group, #name);\ + }\ + void TEST_##group##_##name##_(void) + +/* Call this for each test, insider the group runner */ +#define RUN_TEST_CASE(group, name) \ + { void TEST_##group##_##name##_run(void);\ + TEST_##group##_##name##_run(); } + +/* This goes at the bottom of each test file or in a separate c file */ +#define TEST_GROUP_RUNNER(group)\ + void TEST_##group##_GROUP_RUNNER(void);\ + void TEST_##group##_GROUP_RUNNER(void) + +/* Call this from main */ +#define RUN_TEST_GROUP(group)\ + { void TEST_##group##_GROUP_RUNNER(void);\ + TEST_##group##_GROUP_RUNNER(); } + +/* CppUTest Compatibility Macros */ +#ifndef UNITY_EXCLUDE_CPPUTEST_ASSERTS +/* Sets a pointer and automatically restores it to its old value after teardown */ +#define UT_PTR_SET(ptr, newPointerValue) UnityPointer_Set((void**)&(ptr), (void*)(newPointerValue), __LINE__) +#define TEST_ASSERT_POINTERS_EQUAL(expected, actual) TEST_ASSERT_EQUAL_PTR((expected), (actual)) +#define TEST_ASSERT_BYTES_EQUAL(expected, actual) TEST_ASSERT_EQUAL_HEX8(0xff & (expected), 0xff & (actual)) +#define FAIL(message) TEST_FAIL_MESSAGE((message)) +#define CHECK(condition) TEST_ASSERT_TRUE((condition)) +#define LONGS_EQUAL(expected, actual) TEST_ASSERT_EQUAL_INT((expected), (actual)) +#define STRCMP_EQUAL(expected, actual) TEST_ASSERT_EQUAL_STRING((expected), (actual)) +#define DOUBLES_EQUAL(expected, actual, delta) TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual)) +#endif + +/* You must compile with malloc replacement, as defined in unity_fixture_malloc_overrides.h */ +void UnityMalloc_MakeMallocFailAfterCount(int count); + +#endif /* UNITY_FIXTURE_H_ */ diff --git a/tools/sdk/include/json/tests/unity/extras/fixture/src/unity_fixture_internals.h b/tools/sdk/include/json/tests/unity/extras/fixture/src/unity_fixture_internals.h new file mode 100644 index 00000000..aa0d9e7c --- /dev/null +++ b/tools/sdk/include/json/tests/unity/extras/fixture/src/unity_fixture_internals.h @@ -0,0 +1,51 @@ +/* Copyright (c) 2010 James Grenning and Contributed to Unity Project + * ========================================== + * Unity Project - A Test Framework for C + * Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + * [Released under MIT License. Please refer to license.txt for details] + * ========================================== */ + +#ifndef UNITY_FIXTURE_INTERNALS_H_ +#define UNITY_FIXTURE_INTERNALS_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct UNITY_FIXTURE_T +{ + int Verbose; + unsigned int RepeatCount; + const char* NameFilter; + const char* GroupFilter; +}; +extern struct UNITY_FIXTURE_T UnityFixture; + +typedef void unityfunction(void); +void UnityTestRunner(unityfunction* setup, + unityfunction* body, + unityfunction* teardown, + const char* printableName, + const char* group, + const char* name, + const char* file, unsigned int line); + +void UnityIgnoreTest(const char* printableName, const char* group, const char* name); +void UnityMalloc_StartTest(void); +void UnityMalloc_EndTest(void); +int UnityGetCommandLineOptions(int argc, const char* argv[]); +void UnityConcludeFixtureTest(void); + +void UnityPointer_Set(void** ptr, void* newValue, UNITY_LINE_TYPE line); +void UnityPointer_UndoAllSets(void); +void UnityPointer_Init(void); +#ifndef UNITY_MAX_POINTERS +#define UNITY_MAX_POINTERS 5 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* UNITY_FIXTURE_INTERNALS_H_ */ diff --git a/tools/sdk/include/json/tests/unity/extras/fixture/src/unity_fixture_malloc_overrides.h b/tools/sdk/include/json/tests/unity/extras/fixture/src/unity_fixture_malloc_overrides.h new file mode 100644 index 00000000..7daba50a --- /dev/null +++ b/tools/sdk/include/json/tests/unity/extras/fixture/src/unity_fixture_malloc_overrides.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2010 James Grenning and Contributed to Unity Project + * ========================================== + * Unity Project - A Test Framework for C + * Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + * [Released under MIT License. Please refer to license.txt for details] + * ========================================== */ + +#ifndef UNITY_FIXTURE_MALLOC_OVERRIDES_H_ +#define UNITY_FIXTURE_MALLOC_OVERRIDES_H_ + +#include + +#ifdef UNITY_EXCLUDE_STDLIB_MALLOC +/* Define this macro to remove the use of stdlib.h, malloc, and free. + * Many embedded systems do not have a heap or malloc/free by default. + * This internal unity_malloc() provides allocated memory deterministically from + * the end of an array only, unity_free() only releases from end-of-array, + * blocks are not coalesced, and memory not freed in LIFO order is stranded. */ + #ifndef UNITY_INTERNAL_HEAP_SIZE_BYTES + #define UNITY_INTERNAL_HEAP_SIZE_BYTES 256 + #endif +#endif + +/* These functions are used by the Unity Fixture to allocate and release memory + * on the heap and can be overridden with platform-specific implementations. + * For example, when using FreeRTOS UNITY_FIXTURE_MALLOC becomes pvPortMalloc() + * and UNITY_FIXTURE_FREE becomes vPortFree(). */ +#if !defined(UNITY_FIXTURE_MALLOC) || !defined(UNITY_FIXTURE_FREE) + #include + #define UNITY_FIXTURE_MALLOC(size) malloc(size) + #define UNITY_FIXTURE_FREE(ptr) free(ptr) +#else + extern void* UNITY_FIXTURE_MALLOC(size_t size); + extern void UNITY_FIXTURE_FREE(void* ptr); +#endif + +#define malloc unity_malloc +#define calloc unity_calloc +#define realloc unity_realloc +#define free unity_free + +void* unity_malloc(size_t size); +void* unity_calloc(size_t num, size_t size); +void* unity_realloc(void * oldMem, size_t size); +void unity_free(void * mem); + +#endif /* UNITY_FIXTURE_MALLOC_OVERRIDES_H_ */ diff --git a/tools/sdk/include/json/tests/unity/extras/fixture/test/unity_output_Spy.h b/tools/sdk/include/json/tests/unity/extras/fixture/test/unity_output_Spy.h new file mode 100644 index 00000000..b30a7f13 --- /dev/null +++ b/tools/sdk/include/json/tests/unity/extras/fixture/test/unity_output_Spy.h @@ -0,0 +1,17 @@ +/* Copyright (c) 2010 James Grenning and Contributed to Unity Project + * ========================================== + * Unity Project - A Test Framework for C + * Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + * [Released under MIT License. Please refer to license.txt for details] + * ========================================== */ + +#ifndef D_unity_output_Spy_H +#define D_unity_output_Spy_H + +void UnityOutputCharSpy_Create(int s); +void UnityOutputCharSpy_Destroy(void); +void UnityOutputCharSpy_OutputChar(int c); +const char * UnityOutputCharSpy_Get(void); +void UnityOutputCharSpy_Enable(int enable); + +#endif diff --git a/tools/sdk/include/json/tests/unity/src/unity.h b/tools/sdk/include/json/tests/unity/src/unity.h new file mode 100644 index 00000000..32ff0e6d --- /dev/null +++ b/tools/sdk/include/json/tests/unity/src/unity.h @@ -0,0 +1,503 @@ +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_FRAMEWORK_H +#define UNITY_FRAMEWORK_H +#define UNITY + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "unity_internals.h" + +/*------------------------------------------------------- + * Test Setup / Teardown + *-------------------------------------------------------*/ + +/* These functions are intended to be called before and after each test. */ +void setUp(void); +void tearDown(void); + +/* These functions are intended to be called at the beginning and end of an + * entire test suite. suiteTearDown() is passed the number of tests that + * failed, and its return value becomes the exit code of main(). */ +void suiteSetUp(void); +int suiteTearDown(int num_failures); + +/* If the compiler supports it, the following block provides stub + * implementations of the above functions as weak symbols. Note that on + * some platforms (MinGW for example), weak function implementations need + * to be in the same translation unit they are called from. This can be + * achieved by defining UNITY_INCLUDE_SETUP_STUBS before including unity.h. */ +#ifdef UNITY_INCLUDE_SETUP_STUBS + #ifdef UNITY_WEAK_ATTRIBUTE + UNITY_WEAK_ATTRIBUTE void setUp(void) { } + UNITY_WEAK_ATTRIBUTE void tearDown(void) { } + UNITY_WEAK_ATTRIBUTE void suiteSetUp(void) { } + UNITY_WEAK_ATTRIBUTE int suiteTearDown(int num_failures) { return num_failures; } + #elif defined(UNITY_WEAK_PRAGMA) + #pragma weak setUp + void setUp(void) { } + #pragma weak tearDown + void tearDown(void) { } + #pragma weak suiteSetUp + void suiteSetUp(void) { } + #pragma weak suiteTearDown + int suiteTearDown(int num_failures) { return num_failures; } + #endif +#endif + +/*------------------------------------------------------- + * Configuration Options + *------------------------------------------------------- + * All options described below should be passed as a compiler flag to all files using Unity. If you must add #defines, place them BEFORE the #include above. + + * Integers/longs/pointers + * - Unity attempts to automatically discover your integer sizes + * - define UNITY_EXCLUDE_STDINT_H to stop attempting to look in + * - define UNITY_EXCLUDE_LIMITS_H to stop attempting to look in + * - If you cannot use the automatic methods above, you can force Unity by using these options: + * - define UNITY_SUPPORT_64 + * - set UNITY_INT_WIDTH + * - set UNITY_LONG_WIDTH + * - set UNITY_POINTER_WIDTH + + * Floats + * - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons + * - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT + * - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats + * - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons + * - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default) + * - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE + * - define UNITY_DOUBLE_TYPE to specify something other than double + * - define UNITY_EXCLUDE_FLOAT_PRINT to trim binary size, won't print floating point values in errors + + * Output + * - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired + * - define UNITY_DIFFERENTIATE_FINAL_FAIL to print FAILED (vs. FAIL) at test end summary - for automated search for failure + + * Optimization + * - by default, line numbers are stored in unsigned shorts. Define UNITY_LINE_TYPE with a different type if your files are huge + * - by default, test and failure counters are unsigned shorts. Define UNITY_COUNTER_TYPE with a different type if you want to save space or have more than 65535 Tests. + + * Test Cases + * - define UNITY_SUPPORT_TEST_CASES to include the TEST_CASE macro, though really it's mostly about the runner generator script + + * Parameterized Tests + * - you'll want to create a define of TEST_CASE(...) which basically evaluates to nothing + + * Tests with Arguments + * - you'll want to define UNITY_USE_COMMAND_LINE_ARGS if you have the test runner passing arguments to Unity + + *------------------------------------------------------- + * Basic Fail and Ignore + *-------------------------------------------------------*/ + +#define TEST_FAIL_MESSAGE(message) UNITY_TEST_FAIL(__LINE__, (message)) +#define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL) +#define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, (message)) +#define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL) +#define TEST_ONLY() + +/* It is not necessary for you to call PASS. A PASS condition is assumed if nothing fails. + * This method allows you to abort a test immediately with a PASS state, ignoring the remainder of the test. */ +#define TEST_PASS() TEST_ABORT() + +/* This macro does nothing, but it is useful for build tools (like Ceedling) to make use of this to figure out + * which files should be linked to in order to perform a test. Use it like TEST_FILE("sandwiches.c") */ +#define TEST_FILE(a) + +/*------------------------------------------------------- + * Test Asserts (simple) + *-------------------------------------------------------*/ + +/* Boolean */ +#define TEST_ASSERT(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expression Evaluated To FALSE") +#define TEST_ASSERT_TRUE(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expected TRUE Was FALSE") +#define TEST_ASSERT_UNLESS(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expression Evaluated To TRUE") +#define TEST_ASSERT_FALSE(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expected FALSE Was TRUE") +#define TEST_ASSERT_NULL(pointer) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, " Expected NULL") +#define TEST_ASSERT_NOT_NULL(pointer) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, " Expected Non-NULL") + +/* Integers (of all sizes) */ +#define TEST_ASSERT_EQUAL_INT(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal") +#define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(-1), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(0), (actual), __LINE__, NULL) +#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, NULL) +#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, NULL) + +/* Integer Greater Than/ Less Than (of all sizes) */ +#define TEST_ASSERT_GREATER_THAN(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, NULL) + +#define TEST_ASSERT_LESS_THAN(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, NULL) + +#define TEST_ASSERT_GREATER_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL) + +#define TEST_ASSERT_LESS_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL) + +/* Integer Ranges (of all sizes) */ +#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, NULL) + +/* Structs and Strings */ +#define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING(expected, actual) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, NULL) + +/* Arrays */ +#define TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, NULL) + +/* Arrays Compared To Single Value */ +#define TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, NULL) + +/* Floating Point (If Enabled) */ +#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, NULL) + +/* Double (If Enabled) */ +#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, NULL) + +/*------------------------------------------------------- + * Test Asserts (with additional messages) + *-------------------------------------------------------*/ + +/* Boolean */ +#define TEST_ASSERT_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message)) +#define TEST_ASSERT_TRUE_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message)) +#define TEST_ASSERT_UNLESS_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message)) +#define TEST_ASSERT_FALSE_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message)) +#define TEST_ASSERT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, (message)) +#define TEST_ASSERT_NOT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, (message)) + +/* Integers (of all sizes) */ +#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(-1), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(0), (actual), __LINE__, (message)) +#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, (message)) +#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, (message)) + +/* Integer Greater Than/ Less Than (of all sizes) */ +#define TEST_ASSERT_GREATER_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, (message)) + +#define TEST_ASSERT_LESS_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, (message)) + +#define TEST_ASSERT_GREATER_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message)) + +#define TEST_ASSERT_LESS_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, (message)) + +/* Integer Ranges (of all sizes) */ +#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, (message)) + +/* Structs and Strings */ +#define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_LEN_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, (message)) + +/* Arrays */ +#define TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, (message)) + +/* Arrays Compared To Single Value*/ +#define TEST_ASSERT_EACH_EQUAL_INT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_PTR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_STRING_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_MEMORY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, (message)) + +/* Floating Point (If Enabled) */ +#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_FLOAT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, (message)) + +/* Double (If Enabled) */ +#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_DOUBLE_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, (message)) + +/* end of UNITY_FRAMEWORK_H */ +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/sdk/include/json/tests/unity/src/unity_internals.h b/tools/sdk/include/json/tests/unity/src/unity_internals.h new file mode 100644 index 00000000..f78cebac --- /dev/null +++ b/tools/sdk/include/json/tests/unity/src/unity_internals.h @@ -0,0 +1,870 @@ +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_INTERNALS_H +#define UNITY_INTERNALS_H + +#include "../examples/unity_config.h" + +#ifndef UNITY_EXCLUDE_SETJMP_H +#include +#endif + +#ifndef UNITY_EXCLUDE_MATH_H +#include +#endif + +/* Unity Attempts to Auto-Detect Integer Types + * Attempt 1: UINT_MAX, ULONG_MAX in , or default to 32 bits + * Attempt 2: UINTPTR_MAX in , or default to same size as long + * The user may override any of these derived constants: + * UNITY_INT_WIDTH, UNITY_LONG_WIDTH, UNITY_POINTER_WIDTH */ +#ifndef UNITY_EXCLUDE_STDINT_H +#include +#endif + +#ifndef UNITY_EXCLUDE_LIMITS_H +#include +#endif + +/*------------------------------------------------------- + * Guess Widths If Not Specified + *-------------------------------------------------------*/ + +/* Determine the size of an int, if not already specified. + * We cannot use sizeof(int), because it is not yet defined + * at this stage in the translation of the C program. + * Therefore, infer it from UINT_MAX if possible. */ +#ifndef UNITY_INT_WIDTH + #ifdef UINT_MAX + #if (UINT_MAX == 0xFFFF) + #define UNITY_INT_WIDTH (16) + #elif (UINT_MAX == 0xFFFFFFFF) + #define UNITY_INT_WIDTH (32) + #elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF) + #define UNITY_INT_WIDTH (64) + #endif + #else /* Set to default */ + #define UNITY_INT_WIDTH (32) + #endif /* UINT_MAX */ +#endif + +/* Determine the size of a long, if not already specified. */ +#ifndef UNITY_LONG_WIDTH + #ifdef ULONG_MAX + #if (ULONG_MAX == 0xFFFF) + #define UNITY_LONG_WIDTH (16) + #elif (ULONG_MAX == 0xFFFFFFFF) + #define UNITY_LONG_WIDTH (32) + #elif (ULONG_MAX == 0xFFFFFFFFFFFFFFFF) + #define UNITY_LONG_WIDTH (64) + #endif + #else /* Set to default */ + #define UNITY_LONG_WIDTH (32) + #endif /* ULONG_MAX */ +#endif + +/* Determine the size of a pointer, if not already specified. */ +#ifndef UNITY_POINTER_WIDTH + #ifdef UINTPTR_MAX + #if (UINTPTR_MAX <= 0xFFFF) + #define UNITY_POINTER_WIDTH (16) + #elif (UINTPTR_MAX <= 0xFFFFFFFF) + #define UNITY_POINTER_WIDTH (32) + #elif (UINTPTR_MAX <= 0xFFFFFFFFFFFFFFFF) + #define UNITY_POINTER_WIDTH (64) + #endif + #else /* Set to default */ + #define UNITY_POINTER_WIDTH UNITY_LONG_WIDTH + #endif /* UINTPTR_MAX */ +#endif + +/*------------------------------------------------------- + * Int Support (Define types based on detected sizes) + *-------------------------------------------------------*/ + +#if (UNITY_INT_WIDTH == 32) + typedef unsigned char UNITY_UINT8; + typedef unsigned short UNITY_UINT16; + typedef unsigned int UNITY_UINT32; + typedef signed char UNITY_INT8; + typedef signed short UNITY_INT16; + typedef signed int UNITY_INT32; +#elif (UNITY_INT_WIDTH == 16) + typedef unsigned char UNITY_UINT8; + typedef unsigned int UNITY_UINT16; + typedef unsigned long UNITY_UINT32; + typedef signed char UNITY_INT8; + typedef signed int UNITY_INT16; + typedef signed long UNITY_INT32; +#else + #error Invalid UNITY_INT_WIDTH specified! (16 or 32 are supported) +#endif + +/*------------------------------------------------------- + * 64-bit Support + *-------------------------------------------------------*/ + +#ifndef UNITY_SUPPORT_64 + #if UNITY_LONG_WIDTH == 64 || UNITY_POINTER_WIDTH == 64 + #define UNITY_SUPPORT_64 + #endif +#endif + +#ifndef UNITY_SUPPORT_64 + /* No 64-bit Support */ + typedef UNITY_UINT32 UNITY_UINT; + typedef UNITY_INT32 UNITY_INT; +#else + + /* 64-bit Support */ + #if (UNITY_LONG_WIDTH == 32) + typedef unsigned long long UNITY_UINT64; + typedef signed long long UNITY_INT64; + #elif (UNITY_LONG_WIDTH == 64) + typedef unsigned long UNITY_UINT64; + typedef signed long UNITY_INT64; + #else + #error Invalid UNITY_LONG_WIDTH specified! (32 or 64 are supported) + #endif + typedef UNITY_UINT64 UNITY_UINT; + typedef UNITY_INT64 UNITY_INT; + +#endif + +/*------------------------------------------------------- + * Pointer Support + *-------------------------------------------------------*/ + +#if (UNITY_POINTER_WIDTH == 32) +#define UNITY_PTR_TO_INT UNITY_INT32 +#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX32 +#elif (UNITY_POINTER_WIDTH == 64) +#define UNITY_PTR_TO_INT UNITY_INT64 +#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX64 +#elif (UNITY_POINTER_WIDTH == 16) +#define UNITY_PTR_TO_INT UNITY_INT16 +#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX16 +#else + #error Invalid UNITY_POINTER_WIDTH specified! (16, 32 or 64 are supported) +#endif + +#ifndef UNITY_PTR_ATTRIBUTE +#define UNITY_PTR_ATTRIBUTE +#endif + +#ifndef UNITY_INTERNAL_PTR +#define UNITY_INTERNAL_PTR UNITY_PTR_ATTRIBUTE const void* +#endif + +/*------------------------------------------------------- + * Float Support + *-------------------------------------------------------*/ + +#ifdef UNITY_EXCLUDE_FLOAT + +/* No Floating Point Support */ +#ifndef UNITY_EXCLUDE_DOUBLE +#define UNITY_EXCLUDE_DOUBLE /* Remove double when excluding float support */ +#endif +#ifndef UNITY_EXCLUDE_FLOAT_PRINT +#define UNITY_EXCLUDE_FLOAT_PRINT +#endif + +#else + +/* Floating Point Support */ +#ifndef UNITY_FLOAT_PRECISION +#define UNITY_FLOAT_PRECISION (0.00001f) +#endif +#ifndef UNITY_FLOAT_TYPE +#define UNITY_FLOAT_TYPE float +#endif +typedef UNITY_FLOAT_TYPE UNITY_FLOAT; + +/* isinf & isnan macros should be provided by math.h */ +#ifndef isinf +/* The value of Inf - Inf is NaN */ +#define isinf(n) (isnan((n) - (n)) && !isnan(n)) +#endif + +#ifndef isnan +/* NaN is the only floating point value that does NOT equal itself. + * Therefore if n != n, then it is NaN. */ +#define isnan(n) ((n != n) ? 1 : 0) +#endif + +#endif + +/*------------------------------------------------------- + * Double Float Support + *-------------------------------------------------------*/ + +/* unlike float, we DON'T include by default */ +#if defined(UNITY_EXCLUDE_DOUBLE) || !defined(UNITY_INCLUDE_DOUBLE) + + /* No Floating Point Support */ + #ifndef UNITY_EXCLUDE_DOUBLE + #define UNITY_EXCLUDE_DOUBLE + #else + #undef UNITY_INCLUDE_DOUBLE + #endif + + #ifndef UNITY_EXCLUDE_FLOAT + #ifndef UNITY_DOUBLE_TYPE + #define UNITY_DOUBLE_TYPE double + #endif + typedef UNITY_FLOAT UNITY_DOUBLE; + /* For parameter in UnityPrintFloat(UNITY_DOUBLE), which aliases to double or float */ + #endif + +#else + + /* Double Floating Point Support */ + #ifndef UNITY_DOUBLE_PRECISION + #define UNITY_DOUBLE_PRECISION (1e-12) + #endif + + #ifndef UNITY_DOUBLE_TYPE + #define UNITY_DOUBLE_TYPE double + #endif + typedef UNITY_DOUBLE_TYPE UNITY_DOUBLE; + +#endif + +/*------------------------------------------------------- + * Output Method: stdout (DEFAULT) + *-------------------------------------------------------*/ +#ifndef UNITY_OUTPUT_CHAR +/* Default to using putchar, which is defined in stdio.h */ +#include +#define UNITY_OUTPUT_CHAR(a) (void)putchar(a) +#else + /* If defined as something else, make sure we declare it here so it's ready for use */ + #ifdef UNITY_OUTPUT_CHAR_HEADER_DECLARATION +extern void UNITY_OUTPUT_CHAR_HEADER_DECLARATION; + #endif +#endif + +#ifndef UNITY_OUTPUT_FLUSH +#ifdef UNITY_USE_FLUSH_STDOUT +/* We want to use the stdout flush utility */ +#include +#define UNITY_OUTPUT_FLUSH() (void)fflush(stdout) +#else +/* We've specified nothing, therefore flush should just be ignored */ +#define UNITY_OUTPUT_FLUSH() +#endif +#else +/* We've defined flush as something else, so make sure we declare it here so it's ready for use */ +#ifdef UNITY_OUTPUT_FLUSH_HEADER_DECLARATION +extern void UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION; +#endif +#endif + +#ifndef UNITY_OUTPUT_FLUSH +#define UNITY_FLUSH_CALL() +#else +#define UNITY_FLUSH_CALL() UNITY_OUTPUT_FLUSH() +#endif + +#ifndef UNITY_PRINT_EOL +#define UNITY_PRINT_EOL() UNITY_OUTPUT_CHAR('\n') +#endif + +#ifndef UNITY_OUTPUT_START +#define UNITY_OUTPUT_START() +#endif + +#ifndef UNITY_OUTPUT_COMPLETE +#define UNITY_OUTPUT_COMPLETE() +#endif + +/*------------------------------------------------------- + * Footprint + *-------------------------------------------------------*/ + +#ifndef UNITY_LINE_TYPE +#define UNITY_LINE_TYPE UNITY_UINT +#endif + +#ifndef UNITY_COUNTER_TYPE +#define UNITY_COUNTER_TYPE UNITY_UINT +#endif + +/*------------------------------------------------------- + * Language Features Available + *-------------------------------------------------------*/ +#if !defined(UNITY_WEAK_ATTRIBUTE) && !defined(UNITY_WEAK_PRAGMA) +# if defined(__GNUC__) || defined(__ghs__) /* __GNUC__ includes clang */ +# if !(defined(__WIN32__) && defined(__clang__)) && !defined(__TMS470__) +# define UNITY_WEAK_ATTRIBUTE __attribute__((weak)) +# endif +# endif +#endif + +#ifdef UNITY_NO_WEAK +# undef UNITY_WEAK_ATTRIBUTE +# undef UNITY_WEAK_PRAGMA +#endif + + +/*------------------------------------------------------- + * Internal Structs Needed + *-------------------------------------------------------*/ + +typedef void (*UnityTestFunction)(void); + +#define UNITY_DISPLAY_RANGE_INT (0x10) +#define UNITY_DISPLAY_RANGE_UINT (0x20) +#define UNITY_DISPLAY_RANGE_HEX (0x40) + +typedef enum +{ +UNITY_DISPLAY_STYLE_INT = sizeof(int)+ UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT8 = 1 + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT16 = 2 + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT32 = 4 + UNITY_DISPLAY_RANGE_INT, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_INT64 = 8 + UNITY_DISPLAY_RANGE_INT, +#endif + +UNITY_DISPLAY_STYLE_UINT = sizeof(unsigned) + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT8 = 1 + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT16 = 2 + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT32 = 4 + UNITY_DISPLAY_RANGE_UINT, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_UINT64 = 8 + UNITY_DISPLAY_RANGE_UINT, +#endif + + UNITY_DISPLAY_STYLE_HEX8 = 1 + UNITY_DISPLAY_RANGE_HEX, + UNITY_DISPLAY_STYLE_HEX16 = 2 + UNITY_DISPLAY_RANGE_HEX, + UNITY_DISPLAY_STYLE_HEX32 = 4 + UNITY_DISPLAY_RANGE_HEX, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_HEX64 = 8 + UNITY_DISPLAY_RANGE_HEX, +#endif + + UNITY_DISPLAY_STYLE_UNKNOWN +} UNITY_DISPLAY_STYLE_T; + +typedef enum +{ + UNITY_EQUAL_TO = 1, + UNITY_GREATER_THAN = 2, + UNITY_GREATER_OR_EQUAL = 2 + UNITY_EQUAL_TO, + UNITY_SMALLER_THAN = 4, + UNITY_SMALLER_OR_EQUAL = 4 + UNITY_EQUAL_TO +} UNITY_COMPARISON_T; + +#ifndef UNITY_EXCLUDE_FLOAT +typedef enum UNITY_FLOAT_TRAIT +{ + UNITY_FLOAT_IS_NOT_INF = 0, + UNITY_FLOAT_IS_INF, + UNITY_FLOAT_IS_NOT_NEG_INF, + UNITY_FLOAT_IS_NEG_INF, + UNITY_FLOAT_IS_NOT_NAN, + UNITY_FLOAT_IS_NAN, + UNITY_FLOAT_IS_NOT_DET, + UNITY_FLOAT_IS_DET, + UNITY_FLOAT_INVALID_TRAIT +} UNITY_FLOAT_TRAIT_T; +#endif + +typedef enum +{ + UNITY_ARRAY_TO_VAL = 0, + UNITY_ARRAY_TO_ARRAY +} UNITY_FLAGS_T; + +struct UNITY_STORAGE_T +{ + const char* TestFile; + const char* CurrentTestName; +#ifndef UNITY_EXCLUDE_DETAILS + const char* CurrentDetail1; + const char* CurrentDetail2; +#endif + UNITY_LINE_TYPE CurrentTestLineNumber; + UNITY_COUNTER_TYPE NumberOfTests; + UNITY_COUNTER_TYPE TestFailures; + UNITY_COUNTER_TYPE TestIgnores; + UNITY_COUNTER_TYPE CurrentTestFailed; + UNITY_COUNTER_TYPE CurrentTestIgnored; +#ifndef UNITY_EXCLUDE_SETJMP_H + jmp_buf AbortFrame; +#endif +}; + +extern struct UNITY_STORAGE_T Unity; + +/*------------------------------------------------------- + * Test Suite Management + *-------------------------------------------------------*/ + +void UnityBegin(const char* filename); +int UnityEnd(void); +void UnityConcludeTest(void); +void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum); + +/*------------------------------------------------------- + * Details Support + *-------------------------------------------------------*/ + +#ifdef UNITY_EXCLUDE_DETAILS +#define UNITY_CLR_DETAILS() +#define UNITY_SET_DETAIL(d1) +#define UNITY_SET_DETAILS(d1,d2) +#else +#define UNITY_CLR_DETAILS() { Unity.CurrentDetail1 = 0; Unity.CurrentDetail2 = 0; } +#define UNITY_SET_DETAIL(d1) { Unity.CurrentDetail1 = d1; Unity.CurrentDetail2 = 0; } +#define UNITY_SET_DETAILS(d1,d2) { Unity.CurrentDetail1 = d1; Unity.CurrentDetail2 = d2; } + +#ifndef UNITY_DETAIL1_NAME +#define UNITY_DETAIL1_NAME "Function" +#endif + +#ifndef UNITY_DETAIL2_NAME +#define UNITY_DETAIL2_NAME "Argument" +#endif +#endif + +/*------------------------------------------------------- + * Test Output + *-------------------------------------------------------*/ + +void UnityPrint(const char* string); +void UnityPrintLen(const char* string, const UNITY_UINT32 length); +void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number); +void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style); +void UnityPrintNumber(const UNITY_INT number); +void UnityPrintNumberUnsigned(const UNITY_UINT number); +void UnityPrintNumberHex(const UNITY_UINT number, const char nibbles); + +#ifndef UNITY_EXCLUDE_FLOAT_PRINT +void UnityPrintFloat(const UNITY_DOUBLE input_number); +#endif + +/*------------------------------------------------------- + * Test Assertion Functions + *------------------------------------------------------- + * Use the macros below this section instead of calling + * these directly. The macros have a consistent naming + * convention and will pull in file and line information + * for you. */ + +void UnityAssertEqualNumber(const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold, + const UNITY_INT actual, + const UNITY_COMPARISON_T compare, + const char *msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style, + const UNITY_FLAGS_T flags); + +void UnityAssertBits(const UNITY_INT mask, + const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualString(const char* expected, + const char* actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualStringLen(const char* expected, + const char* actual, + const UNITY_UINT32 length, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualStringArray( UNITY_INTERNAL_PTR expected, + const char** actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertEqualMemory( UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 length, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertNumbersWithin(const UNITY_UINT delta, + const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityFail(const char* message, const UNITY_LINE_TYPE line); + +void UnityIgnore(const char* message, const UNITY_LINE_TYPE line); + +#ifndef UNITY_EXCLUDE_FLOAT +void UnityAssertFloatsWithin(const UNITY_FLOAT delta, + const UNITY_FLOAT expected, + const UNITY_FLOAT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected, + UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertFloatSpecial(const UNITY_FLOAT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style); +#endif + +#ifndef UNITY_EXCLUDE_DOUBLE +void UnityAssertDoublesWithin(const UNITY_DOUBLE delta, + const UNITY_DOUBLE expected, + const UNITY_DOUBLE actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expected, + UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style); +#endif + +/*------------------------------------------------------- + * Helpers + *-------------------------------------------------------*/ + +UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size); +#ifndef UNITY_EXCLUDE_FLOAT +UNITY_INTERNAL_PTR UnityFloatToPtr(const float num); +#endif +#ifndef UNITY_EXCLUDE_DOUBLE +UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num); +#endif + +/*------------------------------------------------------- + * Error Strings We Might Need + *-------------------------------------------------------*/ + +extern const char UnityStrErrFloat[]; +extern const char UnityStrErrDouble[]; +extern const char UnityStrErr64[]; + +/*------------------------------------------------------- + * Test Running Macros + *-------------------------------------------------------*/ + +#ifndef UNITY_EXCLUDE_SETJMP_H +#define TEST_PROTECT() (setjmp(Unity.AbortFrame) == 0) +#define TEST_ABORT() longjmp(Unity.AbortFrame, 1) +#else +#define TEST_PROTECT() 1 +#define TEST_ABORT() return +#endif + +/* This tricky series of macros gives us an optional line argument to treat it as RUN_TEST(func, num=__LINE__) */ +#ifndef RUN_TEST +#ifdef __STDC_VERSION__ +#if __STDC_VERSION__ >= 199901L +#define RUN_TEST(...) UnityDefaultTestRun(RUN_TEST_FIRST(__VA_ARGS__), RUN_TEST_SECOND(__VA_ARGS__)) +#define RUN_TEST_FIRST(...) RUN_TEST_FIRST_HELPER(__VA_ARGS__, throwaway) +#define RUN_TEST_FIRST_HELPER(first, ...) (first), #first +#define RUN_TEST_SECOND(...) RUN_TEST_SECOND_HELPER(__VA_ARGS__, __LINE__, throwaway) +#define RUN_TEST_SECOND_HELPER(first, second, ...) (second) +#endif +#endif +#endif + +/* If we can't do the tricky version, we'll just have to require them to always include the line number */ +#ifndef RUN_TEST +#ifdef CMOCK +#define RUN_TEST(func, num) UnityDefaultTestRun(func, #func, num) +#else +#define RUN_TEST(func) UnityDefaultTestRun(func, #func, __LINE__) +#endif +#endif + +#define TEST_LINE_NUM (Unity.CurrentTestLineNumber) +#define TEST_IS_IGNORED (Unity.CurrentTestIgnored) +#define UNITY_NEW_TEST(a) \ + Unity.CurrentTestName = (a); \ + Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)(__LINE__); \ + Unity.NumberOfTests++; + +#ifndef UNITY_BEGIN +#define UNITY_BEGIN() UnityBegin(__FILE__) +#endif + +#ifndef UNITY_END +#define UNITY_END() UnityEnd() +#endif + +/*----------------------------------------------- + * Command Line Argument Support + *-----------------------------------------------*/ + +#ifdef UNITY_USE_COMMAND_LINE_ARGS +int UnityParseOptions(int argc, char** argv); +int UnityTestMatches(void); +#endif + +/*------------------------------------------------------- + * Basic Fail and Ignore + *-------------------------------------------------------*/ + +#define UNITY_TEST_FAIL(line, message) UnityFail( (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_IGNORE(line, message) UnityIgnore( (message), (UNITY_LINE_TYPE)(line)) + +/*------------------------------------------------------- + * Test Asserts + *-------------------------------------------------------*/ + +#define UNITY_TEST_ASSERT(condition, line, message) if (condition) {} else {UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), (message));} +#define UNITY_TEST_ASSERT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) == NULL), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_NOT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) != NULL), (UNITY_LINE_TYPE)(line), (message)) + +#define UNITY_TEST_ASSERT_EQUAL_INT(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_EQUAL_INT8(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_EQUAL_INT16(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT16)(expected), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_EQUAL_INT32(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT32)(expected), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_EQUAL_UINT(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_EQUAL_UINT8(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_UINT8 )(expected), (UNITY_INT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_EQUAL_UINT16(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_UINT16)(expected), (UNITY_INT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_EQUAL_UINT32(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_UINT32)(expected), (UNITY_INT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_EQUAL_HEX8(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_EQUAL_HEX16(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT16)(expected), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_EQUAL_HEX32(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT32)(expected), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_BITS(mask, expected, actual, line, message) UnityAssertBits((UNITY_INT)(mask), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line)) + +#define UNITY_TEST_ASSERT_GREATER_THAN_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) + +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) + +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) + +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) + +#define UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_INT16)(expected), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_INT32)(expected), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_UINT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_UINT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_UINT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) + +#define UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, line, message) UnityAssertEqualNumber((UNITY_PTR_TO_INT)(expected), (UNITY_PTR_TO_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER) +#define UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, line, message) UnityAssertEqualString((const char*)(expected), (const char*)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len, line, message) UnityAssertEqualStringLen((const char*)(expected), (const char*)(actual), (UNITY_UINT32)(len), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), 1, (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) + +#define UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((UNITY_INTERNAL_PTR)(expected), (const char**)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) + +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT) expected, sizeof(int)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )expected, 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT16 )expected, 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT32 )expected, 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT) expected, sizeof(unsigned int)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT8 )expected, 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT16)expected, 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT32)expected, 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )expected, 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT16 )expected, 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT32 )expected, 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_PTR_TO_INT) expected, sizeof(int*)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((UNITY_INTERNAL_PTR)(expected), (const char**)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) + +#ifdef UNITY_SUPPORT_64 +#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#else +#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#endif + +#ifdef UNITY_EXCLUDE_FLOAT +#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#else +#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UnityAssertFloatsWithin((UNITY_FLOAT)(delta), (UNITY_FLOAT)(expected), (UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((UNITY_FLOAT)(expected) * (UNITY_FLOAT)UNITY_FLOAT_PRECISION, (UNITY_FLOAT)(expected), (UNITY_FLOAT)(actual), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray((UNITY_FLOAT*)(expected), (UNITY_FLOAT*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray(UnityFloatToPtr(expected), (UNITY_FLOAT*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) +#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_DET) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NEG_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NAN) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET) +#endif + +#ifdef UNITY_EXCLUDE_DOUBLE +#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#else +#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((UNITY_DOUBLE)(delta), (UNITY_DOUBLE)(expected), (UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)line) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((UNITY_DOUBLE)(expected) * (UNITY_DOUBLE)UNITY_DOUBLE_PRECISION, (UNITY_DOUBLE)expected, (UNITY_DOUBLE)actual, (UNITY_LINE_TYPE)(line), message) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray((UNITY_DOUBLE*)(expected), (UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray(UnityDoubleToPtr(expected), (UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) +#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_DET) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NEG_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NAN) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET) +#endif + +/* End of UNITY_INTERNALS_H */ +#endif diff --git a/tools/sdk/include/json/tests/unity/test/expectdata/testsample_head1.h b/tools/sdk/include/json/tests/unity/test/expectdata/testsample_head1.h new file mode 100644 index 00000000..da6b7ab2 --- /dev/null +++ b/tools/sdk/include/json/tests/unity/test/expectdata/testsample_head1.h @@ -0,0 +1,15 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ +#ifndef _TESTSAMPLE_HEAD1_H +#define _TESTSAMPLE_HEAD1_H + +#include "unity.h" +#include "funky.h" +#include "stanky.h" +#include + +void test_TheFirstThingToTest(void); +void test_TheSecondThingToTest(void); +void test_TheThirdThingToTest(void); +void test_TheFourthThingToTest(void); +#endif + diff --git a/tools/sdk/include/json/tests/unity/test/expectdata/testsample_mock_head1.h b/tools/sdk/include/json/tests/unity/test/expectdata/testsample_mock_head1.h new file mode 100644 index 00000000..30c509ad --- /dev/null +++ b/tools/sdk/include/json/tests/unity/test/expectdata/testsample_mock_head1.h @@ -0,0 +1,13 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ +#ifndef _TESTSAMPLE_MOCK_HEAD1_H +#define _TESTSAMPLE_MOCK_HEAD1_H + +#include "unity.h" +#include "cmock.h" +#include "funky.h" +#include + +void test_TheFirstThingToTest(void); +void test_TheSecondThingToTest(void); +#endif + diff --git a/tools/sdk/include/json/tests/unity/test/testdata/CException.h b/tools/sdk/include/json/tests/unity/test/testdata/CException.h new file mode 100644 index 00000000..91ad3e1b --- /dev/null +++ b/tools/sdk/include/json/tests/unity/test/testdata/CException.h @@ -0,0 +1,11 @@ +#ifndef CEXCEPTION_H +#define CEXCEPTION_H + +#define CEXCEPTION_BEING_USED 1 + +#define CEXCEPTION_NONE 0 +#define CEXCEPTION_T int e = 1; (void) +#define Try if (e) +#define Catch(a) if (!a) + +#endif //CEXCEPTION_H diff --git a/tools/sdk/include/json/tests/unity/test/testdata/Defs.h b/tools/sdk/include/json/tests/unity/test/testdata/Defs.h new file mode 100644 index 00000000..d3a90c0d --- /dev/null +++ b/tools/sdk/include/json/tests/unity/test/testdata/Defs.h @@ -0,0 +1,8 @@ +#ifndef DEF_H +#define DEF_H + +#define EXTERN_DECL + +extern int CounterSuiteSetup; + +#endif //DEF_H diff --git a/tools/sdk/include/json/tests/unity/test/testdata/cmock.h b/tools/sdk/include/json/tests/unity/test/testdata/cmock.h new file mode 100644 index 00000000..c6149be1 --- /dev/null +++ b/tools/sdk/include/json/tests/unity/test/testdata/cmock.h @@ -0,0 +1,14 @@ +#ifndef CMOCK_H +#define CMOCK_H + +int CMockMemFreeFinalCounter = 0; +int mockMock_Init_Counter = 0; +int mockMock_Verify_Counter = 0; +int mockMock_Destroy_Counter = 0; + +void CMock_Guts_MemFreeFinal(void) { CMockMemFreeFinalCounter++; } +void mockMock_Init(void) { mockMock_Init_Counter++; } +void mockMock_Verify(void) { mockMock_Verify_Counter++; } +void mockMock_Destroy(void) { mockMock_Destroy_Counter++; } + +#endif //CMOCK_H diff --git a/tools/sdk/include/json/tests/unity/test/testdata/mockMock.h b/tools/sdk/include/json/tests/unity/test/testdata/mockMock.h new file mode 100644 index 00000000..0a2c616f --- /dev/null +++ b/tools/sdk/include/json/tests/unity/test/testdata/mockMock.h @@ -0,0 +1,13 @@ +#ifndef MOCK_MOCK_H +#define MOCK_MOCK_H + +extern int mockMock_Init_Counter; +extern int mockMock_Verify_Counter; +extern int mockMock_Destroy_Counter; +extern int CMockMemFreeFinalCounter; + +void mockMock_Init(void); +void mockMock_Verify(void); +void mockMock_Destroy(void); + +#endif //MOCK_MOCK_H diff --git a/tools/sdk/include/libsodium/sodium.h b/tools/sdk/include/libsodium/sodium.h new file mode 100644 index 00000000..d0bb25c8 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium.h @@ -0,0 +1,68 @@ + +#ifndef sodium_H +#define sodium_H + +#include "sodium/version.h" + +#include "sodium/core.h" +#include "sodium/crypto_aead_aes256gcm.h" +#include "sodium/crypto_aead_chacha20poly1305.h" +#include "sodium/crypto_aead_xchacha20poly1305.h" +#include "sodium/crypto_auth.h" +#include "sodium/crypto_auth_hmacsha256.h" +#include "sodium/crypto_auth_hmacsha512.h" +#include "sodium/crypto_auth_hmacsha512256.h" +#include "sodium/crypto_box.h" +#include "sodium/crypto_box_curve25519xsalsa20poly1305.h" +#include "sodium/crypto_core_hsalsa20.h" +#include "sodium/crypto_core_hchacha20.h" +#include "sodium/crypto_core_salsa20.h" +#include "sodium/crypto_core_salsa2012.h" +#include "sodium/crypto_core_salsa208.h" +#include "sodium/crypto_generichash.h" +#include "sodium/crypto_generichash_blake2b.h" +#include "sodium/crypto_hash.h" +#include "sodium/crypto_hash_sha256.h" +#include "sodium/crypto_hash_sha512.h" +#include "sodium/crypto_kdf.h" +#include "sodium/crypto_kdf_blake2b.h" +#include "sodium/crypto_kx.h" +#include "sodium/crypto_onetimeauth.h" +#include "sodium/crypto_onetimeauth_poly1305.h" +#include "sodium/crypto_pwhash.h" +#include "sodium/crypto_pwhash_argon2i.h" +#include "sodium/crypto_pwhash_scryptsalsa208sha256.h" +#include "sodium/crypto_scalarmult.h" +#include "sodium/crypto_scalarmult_curve25519.h" +#include "sodium/crypto_secretbox.h" +#include "sodium/crypto_secretbox_xsalsa20poly1305.h" +#include "sodium/crypto_shorthash.h" +#include "sodium/crypto_shorthash_siphash24.h" +#include "sodium/crypto_sign.h" +#include "sodium/crypto_sign_ed25519.h" +#include "sodium/crypto_stream.h" +#include "sodium/crypto_stream_chacha20.h" +#include "sodium/crypto_stream_salsa20.h" +#include "sodium/crypto_stream_xsalsa20.h" +#include "sodium/crypto_verify_16.h" +#include "sodium/crypto_verify_32.h" +#include "sodium/crypto_verify_64.h" +#include "sodium/randombytes.h" +#ifdef __native_client__ +# include "sodium/randombytes_nativeclient.h" +#endif +#include "sodium/randombytes_salsa20_random.h" +#include "sodium/randombytes_sysrandom.h" +#include "sodium/runtime.h" +#include "sodium/utils.h" + +#ifndef SODIUM_LIBRARY_MINIMAL +# include "sodium/crypto_box_curve25519xchacha20poly1305.h" +# include "sodium/crypto_secretbox_xchacha20poly1305.h" +# include "sodium/crypto_stream_aes128ctr.h" +# include "sodium/crypto_stream_salsa2012.h" +# include "sodium/crypto_stream_salsa208.h" +# include "sodium/crypto_stream_xchacha20.h" +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/core.h b/tools/sdk/include/libsodium/sodium/core.h new file mode 100644 index 00000000..3ca44762 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/core.h @@ -0,0 +1,19 @@ + +#ifndef sodium_core_H +#define sodium_core_H + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +int sodium_init(void) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_aead_aes256gcm.h b/tools/sdk/include/libsodium/sodium/crypto_aead_aes256gcm.h new file mode 100644 index 00000000..972df54f --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_aead_aes256gcm.h @@ -0,0 +1,145 @@ +#ifndef crypto_aead_aes256gcm_H +#define crypto_aead_aes256gcm_H + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +SODIUM_EXPORT +int crypto_aead_aes256gcm_is_available(void); + +#define crypto_aead_aes256gcm_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_keybytes(void); + +#define crypto_aead_aes256gcm_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_nsecbytes(void); + +#define crypto_aead_aes256gcm_NPUBBYTES 12U +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_npubbytes(void); + +#define crypto_aead_aes256gcm_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_abytes(void); + +typedef CRYPTO_ALIGN(16) unsigned char crypto_aead_aes256gcm_state[512]; + +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_statebytes(void); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +/* -- Precomputation interface -- */ + +SODIUM_EXPORT +int crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +void crypto_aead_aes256gcm_keygen(unsigned char k[crypto_aead_aes256gcm_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_aead_chacha20poly1305.h b/tools/sdk/include/libsodium/sodium/crypto_aead_chacha20poly1305.h new file mode 100644 index 00000000..0bbc6885 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_aead_chacha20poly1305.h @@ -0,0 +1,162 @@ +#ifndef crypto_aead_chacha20poly1305_H +#define crypto_aead_chacha20poly1305_H + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +/* -- IETF ChaCha20-Poly1305 construction with a 96-bit nonce and a 32-bit internal counter -- */ + +#define crypto_aead_chacha20poly1305_ietf_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_ietf_keybytes(void); + +#define crypto_aead_chacha20poly1305_ietf_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_ietf_nsecbytes(void); + +#define crypto_aead_chacha20poly1305_ietf_NPUBBYTES 12U + +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_ietf_npubbytes(void); + +#define crypto_aead_chacha20poly1305_ietf_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_ietf_abytes(void); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_ietf_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_ietf_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_ietf_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_ietf_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +void crypto_aead_chacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_chacha20poly1305_ietf_KEYBYTES]); + +/* -- Original ChaCha20-Poly1305 construction with a 64-bit nonce and a 64-bit internal counter -- */ + +#define crypto_aead_chacha20poly1305_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_keybytes(void); + +#define crypto_aead_chacha20poly1305_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_nsecbytes(void); + +#define crypto_aead_chacha20poly1305_NPUBBYTES 8U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_npubbytes(void); + +#define crypto_aead_chacha20poly1305_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_abytes(void); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +void crypto_aead_chacha20poly1305_keygen(unsigned char k[crypto_aead_chacha20poly1305_KEYBYTES]); + +/* Aliases */ + +#define crypto_aead_chacha20poly1305_IETF_KEYBYTES crypto_aead_chacha20poly1305_ietf_KEYBYTES +#define crypto_aead_chacha20poly1305_IETF_NSECBYTES crypto_aead_chacha20poly1305_ietf_NSECBYTES +#define crypto_aead_chacha20poly1305_IETF_NPUBBYTES crypto_aead_chacha20poly1305_ietf_NPUBBYTES +#define crypto_aead_chacha20poly1305_IETF_ABYTES crypto_aead_chacha20poly1305_ietf_ABYTES + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_aead_xchacha20poly1305.h b/tools/sdk/include/libsodium/sodium/crypto_aead_xchacha20poly1305.h new file mode 100644 index 00000000..f863ce88 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_aead_xchacha20poly1305.h @@ -0,0 +1,91 @@ +#ifndef crypto_aead_xchacha20poly1305_H +#define crypto_aead_xchacha20poly1305_H + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_aead_xchacha20poly1305_ietf_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_keybytes(void); + +#define crypto_aead_xchacha20poly1305_ietf_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_nsecbytes(void); + +#define crypto_aead_xchacha20poly1305_ietf_NPUBBYTES 24U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_npubbytes(void); + +#define crypto_aead_xchacha20poly1305_ietf_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_abytes(void); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_ietf_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +void crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES]); + +/* Aliases */ + +#define crypto_aead_xchacha20poly1305_IETF_KEYBYTES crypto_aead_xchacha20poly1305_ietf_KEYBYTES +#define crypto_aead_xchacha20poly1305_IETF_NSECBYTES crypto_aead_xchacha20poly1305_ietf_NSECBYTES +#define crypto_aead_xchacha20poly1305_IETF_NPUBBYTES crypto_aead_xchacha20poly1305_ietf_NPUBBYTES +#define crypto_aead_xchacha20poly1305_IETF_ABYTES crypto_aead_xchacha20poly1305_ietf_ABYTES + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_auth.h b/tools/sdk/include/libsodium/sodium/crypto_auth.h new file mode 100644 index 00000000..7174e7bc --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_auth.h @@ -0,0 +1,44 @@ +#ifndef crypto_auth_H +#define crypto_auth_H + +#include + +#include "crypto_auth_hmacsha512256.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_auth_BYTES crypto_auth_hmacsha512256_BYTES +SODIUM_EXPORT +size_t crypto_auth_bytes(void); + +#define crypto_auth_KEYBYTES crypto_auth_hmacsha512256_KEYBYTES +SODIUM_EXPORT +size_t crypto_auth_keybytes(void); + +#define crypto_auth_PRIMITIVE "hmacsha512256" +SODIUM_EXPORT +const char *crypto_auth_primitive(void); + +SODIUM_EXPORT +int crypto_auth(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); + +SODIUM_EXPORT +int crypto_auth_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +void crypto_auth_keygen(unsigned char k[crypto_auth_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_auth_hmacsha256.h b/tools/sdk/include/libsodium/sodium/crypto_auth_hmacsha256.h new file mode 100644 index 00000000..deec5266 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_auth_hmacsha256.h @@ -0,0 +1,68 @@ +#ifndef crypto_auth_hmacsha256_H +#define crypto_auth_hmacsha256_H + +#include +#include "crypto_hash_sha256.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_auth_hmacsha256_BYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha256_bytes(void); + +#define crypto_auth_hmacsha256_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha256_keybytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha256(unsigned char *out, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_auth_hmacsha256_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +/* ------------------------------------------------------------------------- */ + +typedef struct crypto_auth_hmacsha256_state { + crypto_hash_sha256_state ictx; + crypto_hash_sha256_state octx; +} crypto_auth_hmacsha256_state; + +SODIUM_EXPORT +size_t crypto_auth_hmacsha256_statebytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state, + const unsigned char *key, + size_t keylen); + +SODIUM_EXPORT +int crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state, + unsigned char *out); + + +SODIUM_EXPORT +void crypto_auth_hmacsha256_keygen(unsigned char k[crypto_auth_hmacsha256_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_auth_hmacsha512.h b/tools/sdk/include/libsodium/sodium/crypto_auth_hmacsha512.h new file mode 100644 index 00000000..77a55fbc --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_auth_hmacsha512.h @@ -0,0 +1,67 @@ +#ifndef crypto_auth_hmacsha512_H +#define crypto_auth_hmacsha512_H + +#include +#include "crypto_hash_sha512.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_auth_hmacsha512_BYTES 64U +SODIUM_EXPORT +size_t crypto_auth_hmacsha512_bytes(void); + +#define crypto_auth_hmacsha512_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha512_keybytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha512(unsigned char *out, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_auth_hmacsha512_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +/* ------------------------------------------------------------------------- */ + +typedef struct crypto_auth_hmacsha512_state { + crypto_hash_sha512_state ictx; + crypto_hash_sha512_state octx; +} crypto_auth_hmacsha512_state; + +SODIUM_EXPORT +size_t crypto_auth_hmacsha512_statebytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state *state, + const unsigned char *key, + size_t keylen); + +SODIUM_EXPORT +int crypto_auth_hmacsha512_update(crypto_auth_hmacsha512_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state *state, + unsigned char *out); + +SODIUM_EXPORT +void crypto_auth_hmacsha512_keygen(unsigned char k[crypto_auth_hmacsha512_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_auth_hmacsha512256.h b/tools/sdk/include/libsodium/sodium/crypto_auth_hmacsha512256.h new file mode 100644 index 00000000..4842f3de --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_auth_hmacsha512256.h @@ -0,0 +1,62 @@ +#ifndef crypto_auth_hmacsha512256_H +#define crypto_auth_hmacsha512256_H + +#include +#include "crypto_auth_hmacsha512.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_auth_hmacsha512256_BYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha512256_bytes(void); + +#define crypto_auth_hmacsha512256_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha512256_keybytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256(unsigned char *out, const unsigned char *in, + unsigned long long inlen,const unsigned char *k); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +/* ------------------------------------------------------------------------- */ + +typedef crypto_auth_hmacsha512_state crypto_auth_hmacsha512256_state; + +SODIUM_EXPORT +size_t crypto_auth_hmacsha512256_statebytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256_init(crypto_auth_hmacsha512256_state *state, + const unsigned char *key, + size_t keylen); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256_update(crypto_auth_hmacsha512256_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256_final(crypto_auth_hmacsha512256_state *state, + unsigned char *out); + +SODIUM_EXPORT +void crypto_auth_hmacsha512256_keygen(unsigned char k[crypto_auth_hmacsha512256_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_box.h b/tools/sdk/include/libsodium/sodium/crypto_box.h new file mode 100644 index 00000000..614cd1e0 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_box.h @@ -0,0 +1,169 @@ +#ifndef crypto_box_H +#define crypto_box_H + +/* + * THREAD SAFETY: crypto_box_keypair() is thread-safe, + * provided that sodium_init() was called before. + * + * Other functions are always thread-safe. + */ + +#include + +#include "crypto_box_curve25519xsalsa20poly1305.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_box_SEEDBYTES crypto_box_curve25519xsalsa20poly1305_SEEDBYTES +SODIUM_EXPORT +size_t crypto_box_seedbytes(void); + +#define crypto_box_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES +SODIUM_EXPORT +size_t crypto_box_publickeybytes(void); + +#define crypto_box_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES +SODIUM_EXPORT +size_t crypto_box_secretkeybytes(void); + +#define crypto_box_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES +SODIUM_EXPORT +size_t crypto_box_noncebytes(void); + +#define crypto_box_MACBYTES crypto_box_curve25519xsalsa20poly1305_MACBYTES +SODIUM_EXPORT +size_t crypto_box_macbytes(void); + +#define crypto_box_PRIMITIVE "curve25519xsalsa20poly1305" +SODIUM_EXPORT +const char *crypto_box_primitive(void); + +SODIUM_EXPORT +int crypto_box_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed); + +SODIUM_EXPORT +int crypto_box_keypair(unsigned char *pk, unsigned char *sk); + +SODIUM_EXPORT +int crypto_box_easy(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_open_easy(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_detached(unsigned char *c, unsigned char *mac, + const unsigned char *m, unsigned long long mlen, + const unsigned char *n, const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_open_detached(unsigned char *m, const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +/* -- Precomputation interface -- */ + +#define crypto_box_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES +SODIUM_EXPORT +size_t crypto_box_beforenmbytes(void); + +SODIUM_EXPORT +int crypto_box_beforenm(unsigned char *k, const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_easy_afternm(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_box_open_easy_afternm(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_detached_afternm(unsigned char *c, unsigned char *mac, + const unsigned char *m, unsigned long long mlen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_box_open_detached_afternm(unsigned char *m, const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +/* -- Ephemeral SK interface -- */ + +#define crypto_box_SEALBYTES (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) +SODIUM_EXPORT +size_t crypto_box_sealbytes(void); + +SODIUM_EXPORT +int crypto_box_seal(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *pk); + +SODIUM_EXPORT +int crypto_box_seal_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +/* -- NaCl compatibility interface ; Requires padding -- */ + +#define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES +SODIUM_EXPORT +size_t crypto_box_zerobytes(void); + +#define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES +SODIUM_EXPORT +size_t crypto_box_boxzerobytes(void); + +SODIUM_EXPORT +int crypto_box(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_afternm(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_box_open_afternm(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_box_curve25519xchacha20poly1305.h b/tools/sdk/include/libsodium/sodium/crypto_box_curve25519xchacha20poly1305.h new file mode 100644 index 00000000..29c9b255 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_box_curve25519xchacha20poly1305.h @@ -0,0 +1,130 @@ + +#ifndef crypto_box_curve25519xchacha20poly1305_H +#define crypto_box_curve25519xchacha20poly1305_H + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_box_curve25519xchacha20poly1305_SEEDBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_seedbytes(void); + +#define crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_publickeybytes(void); + +#define crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_secretkeybytes(void); + +#define crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_beforenmbytes(void); + +#define crypto_box_curve25519xchacha20poly1305_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_noncebytes(void); + +#define crypto_box_curve25519xchacha20poly1305_MACBYTES 16U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_macbytes(void); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_seed_keypair(unsigned char *pk, + unsigned char *sk, + const unsigned char *seed); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_keypair(unsigned char *pk, + unsigned char *sk); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_easy(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_open_easy(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_detached(unsigned char *c, + unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_open_detached(unsigned char *m, + const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +/* -- Precomputation interface -- */ + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_beforenm(unsigned char *k, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_easy_afternm(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_open_easy_afternm(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_detached_afternm(unsigned char *c, + unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_open_detached_afternm(unsigned char *m, + const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_box_curve25519xsalsa20poly1305.h b/tools/sdk/include/libsodium/sodium/crypto_box_curve25519xsalsa20poly1305.h new file mode 100644 index 00000000..9b5a39c3 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_box_curve25519xsalsa20poly1305.h @@ -0,0 +1,100 @@ +#ifndef crypto_box_curve25519xsalsa20poly1305_H +#define crypto_box_curve25519xsalsa20poly1305_H + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_box_curve25519xsalsa20poly1305_SEEDBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_seedbytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_publickeybytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_secretkeybytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_beforenmbytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_noncebytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_MACBYTES 16U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_macbytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES 16U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_boxzerobytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES \ + (crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES + \ + crypto_box_curve25519xsalsa20poly1305_MACBYTES) +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_zerobytes(void); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_open(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_seed_keypair(unsigned char *pk, + unsigned char *sk, + const unsigned char *seed); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_keypair(unsigned char *pk, + unsigned char *sk); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_beforenm(unsigned char *k, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_afternm(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_open_afternm(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_core_hchacha20.h b/tools/sdk/include/libsodium/sodium/crypto_core_hchacha20.h new file mode 100644 index 00000000..05e5670c --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_core_hchacha20.h @@ -0,0 +1,35 @@ +#ifndef crypto_core_hchacha20_H +#define crypto_core_hchacha20_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_hchacha20_OUTPUTBYTES 32U +SODIUM_EXPORT +size_t crypto_core_hchacha20_outputbytes(void); + +#define crypto_core_hchacha20_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_hchacha20_inputbytes(void); + +#define crypto_core_hchacha20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_hchacha20_keybytes(void); + +#define crypto_core_hchacha20_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_hchacha20_constbytes(void); + +SODIUM_EXPORT +int crypto_core_hchacha20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_core_hsalsa20.h b/tools/sdk/include/libsodium/sodium/crypto_core_hsalsa20.h new file mode 100644 index 00000000..82e475b8 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_core_hsalsa20.h @@ -0,0 +1,35 @@ +#ifndef crypto_core_hsalsa20_H +#define crypto_core_hsalsa20_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_hsalsa20_OUTPUTBYTES 32U +SODIUM_EXPORT +size_t crypto_core_hsalsa20_outputbytes(void); + +#define crypto_core_hsalsa20_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_hsalsa20_inputbytes(void); + +#define crypto_core_hsalsa20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_hsalsa20_keybytes(void); + +#define crypto_core_hsalsa20_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_hsalsa20_constbytes(void); + +SODIUM_EXPORT +int crypto_core_hsalsa20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_core_salsa20.h b/tools/sdk/include/libsodium/sodium/crypto_core_salsa20.h new file mode 100644 index 00000000..160cc56d --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_core_salsa20.h @@ -0,0 +1,35 @@ +#ifndef crypto_core_salsa20_H +#define crypto_core_salsa20_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_salsa20_OUTPUTBYTES 64U +SODIUM_EXPORT +size_t crypto_core_salsa20_outputbytes(void); + +#define crypto_core_salsa20_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa20_inputbytes(void); + +#define crypto_core_salsa20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_salsa20_keybytes(void); + +#define crypto_core_salsa20_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa20_constbytes(void); + +SODIUM_EXPORT +int crypto_core_salsa20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_core_salsa2012.h b/tools/sdk/include/libsodium/sodium/crypto_core_salsa2012.h new file mode 100644 index 00000000..bdd5f9fd --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_core_salsa2012.h @@ -0,0 +1,35 @@ +#ifndef crypto_core_salsa2012_H +#define crypto_core_salsa2012_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_salsa2012_OUTPUTBYTES 64U +SODIUM_EXPORT +size_t crypto_core_salsa2012_outputbytes(void); + +#define crypto_core_salsa2012_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa2012_inputbytes(void); + +#define crypto_core_salsa2012_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_salsa2012_keybytes(void); + +#define crypto_core_salsa2012_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa2012_constbytes(void); + +SODIUM_EXPORT +int crypto_core_salsa2012(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_core_salsa208.h b/tools/sdk/include/libsodium/sodium/crypto_core_salsa208.h new file mode 100644 index 00000000..3c13efa4 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_core_salsa208.h @@ -0,0 +1,35 @@ +#ifndef crypto_core_salsa208_H +#define crypto_core_salsa208_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_salsa208_OUTPUTBYTES 64U +SODIUM_EXPORT +size_t crypto_core_salsa208_outputbytes(void); + +#define crypto_core_salsa208_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa208_inputbytes(void); + +#define crypto_core_salsa208_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_salsa208_keybytes(void); + +#define crypto_core_salsa208_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa208_constbytes(void); + +SODIUM_EXPORT +int crypto_core_salsa208(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_generichash.h b/tools/sdk/include/libsodium/sodium/crypto_generichash.h new file mode 100644 index 00000000..2398fb9d --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_generichash.h @@ -0,0 +1,75 @@ +#ifndef crypto_generichash_H +#define crypto_generichash_H + +#include + +#include "crypto_generichash_blake2b.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_generichash_BYTES_MIN crypto_generichash_blake2b_BYTES_MIN +SODIUM_EXPORT +size_t crypto_generichash_bytes_min(void); + +#define crypto_generichash_BYTES_MAX crypto_generichash_blake2b_BYTES_MAX +SODIUM_EXPORT +size_t crypto_generichash_bytes_max(void); + +#define crypto_generichash_BYTES crypto_generichash_blake2b_BYTES +SODIUM_EXPORT +size_t crypto_generichash_bytes(void); + +#define crypto_generichash_KEYBYTES_MIN crypto_generichash_blake2b_KEYBYTES_MIN +SODIUM_EXPORT +size_t crypto_generichash_keybytes_min(void); + +#define crypto_generichash_KEYBYTES_MAX crypto_generichash_blake2b_KEYBYTES_MAX +SODIUM_EXPORT +size_t crypto_generichash_keybytes_max(void); + +#define crypto_generichash_KEYBYTES crypto_generichash_blake2b_KEYBYTES +SODIUM_EXPORT +size_t crypto_generichash_keybytes(void); + +#define crypto_generichash_PRIMITIVE "blake2b" +SODIUM_EXPORT +const char *crypto_generichash_primitive(void); + +typedef crypto_generichash_blake2b_state crypto_generichash_state; + +SODIUM_EXPORT +size_t crypto_generichash_statebytes(void); + +SODIUM_EXPORT +int crypto_generichash(unsigned char *out, size_t outlen, + const unsigned char *in, unsigned long long inlen, + const unsigned char *key, size_t keylen); + +SODIUM_EXPORT +int crypto_generichash_init(crypto_generichash_state *state, + const unsigned char *key, + const size_t keylen, const size_t outlen); + +SODIUM_EXPORT +int crypto_generichash_update(crypto_generichash_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_generichash_final(crypto_generichash_state *state, + unsigned char *out, const size_t outlen); + +SODIUM_EXPORT +void crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_generichash_blake2b.h b/tools/sdk/include/libsodium/sodium/crypto_generichash_blake2b.h new file mode 100644 index 00000000..7b0c0820 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_generichash_blake2b.h @@ -0,0 +1,121 @@ +#ifndef crypto_generichash_blake2b_H +#define crypto_generichash_blake2b_H + +#include +#include +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# pragma pack(1) +#else +# pragma pack(push, 1) +#endif + +typedef CRYPTO_ALIGN(64) struct crypto_generichash_blake2b_state { + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[2 * 128]; + size_t buflen; + uint8_t last_node; +} crypto_generichash_blake2b_state; + +#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# pragma pack() +#else +# pragma pack(pop) +#endif + +#define crypto_generichash_blake2b_BYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_bytes_min(void); + +#define crypto_generichash_blake2b_BYTES_MAX 64U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_bytes_max(void); + +#define crypto_generichash_blake2b_BYTES 32U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_bytes(void); + +#define crypto_generichash_blake2b_KEYBYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_keybytes_min(void); + +#define crypto_generichash_blake2b_KEYBYTES_MAX 64U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_keybytes_max(void); + +#define crypto_generichash_blake2b_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_keybytes(void); + +#define crypto_generichash_blake2b_SALTBYTES 16U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_saltbytes(void); + +#define crypto_generichash_blake2b_PERSONALBYTES 16U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_personalbytes(void); + +SODIUM_EXPORT +size_t crypto_generichash_blake2b_statebytes(void); + +SODIUM_EXPORT +int crypto_generichash_blake2b(unsigned char *out, size_t outlen, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *key, size_t keylen); + +SODIUM_EXPORT +int crypto_generichash_blake2b_salt_personal(unsigned char *out, size_t outlen, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *key, + size_t keylen, + const unsigned char *salt, + const unsigned char *personal); + +SODIUM_EXPORT +int crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state, + const unsigned char *key, + const size_t keylen, const size_t outlen); + +SODIUM_EXPORT +int crypto_generichash_blake2b_init_salt_personal(crypto_generichash_blake2b_state *state, + const unsigned char *key, + const size_t keylen, const size_t outlen, + const unsigned char *salt, + const unsigned char *personal); + +SODIUM_EXPORT +int crypto_generichash_blake2b_update(crypto_generichash_blake2b_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_generichash_blake2b_final(crypto_generichash_blake2b_state *state, + unsigned char *out, + const size_t outlen); + +SODIUM_EXPORT +void crypto_generichash_blake2b_keygen(unsigned char k[crypto_generichash_blake2b_KEYBYTES]); + +/* ------------------------------------------------------------------------- */ + +int _crypto_generichash_blake2b_pick_best_implementation(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_hash.h b/tools/sdk/include/libsodium/sodium/crypto_hash.h new file mode 100644 index 00000000..302ed5c5 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_hash.h @@ -0,0 +1,40 @@ +#ifndef crypto_hash_H +#define crypto_hash_H + +/* + * WARNING: Unless you absolutely need to use SHA512 for interoperatibility, + * purposes, you might want to consider crypto_generichash() instead. + * Unlike SHA512, crypto_generichash() is not vulnerable to length + * extension attacks. + */ + +#include + +#include "crypto_hash_sha512.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_hash_BYTES crypto_hash_sha512_BYTES +SODIUM_EXPORT +size_t crypto_hash_bytes(void); + +SODIUM_EXPORT +int crypto_hash(unsigned char *out, const unsigned char *in, + unsigned long long inlen); + +#define crypto_hash_PRIMITIVE "sha512" +SODIUM_EXPORT +const char *crypto_hash_primitive(void) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_hash_sha256.h b/tools/sdk/include/libsodium/sodium/crypto_hash_sha256.h new file mode 100644 index 00000000..f64d16e0 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_hash_sha256.h @@ -0,0 +1,57 @@ +#ifndef crypto_hash_sha256_H +#define crypto_hash_sha256_H + +/* + * WARNING: Unless you absolutely need to use SHA256 for interoperatibility, + * purposes, you might want to consider crypto_generichash() instead. + * Unlike SHA256, crypto_generichash() is not vulnerable to length + * extension attacks. + */ + +#include +#include +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef struct crypto_hash_sha256_state { + uint32_t state[8]; + uint64_t count; + uint8_t buf[64]; +} crypto_hash_sha256_state; + +SODIUM_EXPORT +size_t crypto_hash_sha256_statebytes(void); + +#define crypto_hash_sha256_BYTES 32U +SODIUM_EXPORT +size_t crypto_hash_sha256_bytes(void); + +SODIUM_EXPORT +int crypto_hash_sha256(unsigned char *out, const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_hash_sha256_init(crypto_hash_sha256_state *state); + +SODIUM_EXPORT +int crypto_hash_sha256_update(crypto_hash_sha256_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_hash_sha256_final(crypto_hash_sha256_state *state, + unsigned char *out); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_hash_sha512.h b/tools/sdk/include/libsodium/sodium/crypto_hash_sha512.h new file mode 100644 index 00000000..6b0330f1 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_hash_sha512.h @@ -0,0 +1,57 @@ +#ifndef crypto_hash_sha512_H +#define crypto_hash_sha512_H + +/* + * WARNING: Unless you absolutely need to use SHA512 for interoperatibility, + * purposes, you might want to consider crypto_generichash() instead. + * Unlike SHA512, crypto_generichash() is not vulnerable to length + * extension attacks. + */ + +#include +#include +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef struct crypto_hash_sha512_state { + uint64_t state[8]; + uint64_t count[2]; + uint8_t buf[128]; +} crypto_hash_sha512_state; + +SODIUM_EXPORT +size_t crypto_hash_sha512_statebytes(void); + +#define crypto_hash_sha512_BYTES 64U +SODIUM_EXPORT +size_t crypto_hash_sha512_bytes(void); + +SODIUM_EXPORT +int crypto_hash_sha512(unsigned char *out, const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_hash_sha512_init(crypto_hash_sha512_state *state); + +SODIUM_EXPORT +int crypto_hash_sha512_update(crypto_hash_sha512_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_hash_sha512_final(crypto_hash_sha512_state *state, + unsigned char *out); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_kdf.h b/tools/sdk/include/libsodium/sodium/crypto_kdf.h new file mode 100644 index 00000000..52e496a7 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_kdf.h @@ -0,0 +1,51 @@ +#ifndef crypto_kdf_H +#define crypto_kdf_H + +#include +#include + +#include "crypto_kdf_blake2b.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_kdf_BYTES_MIN crypto_kdf_blake2b_BYTES_MIN +SODIUM_EXPORT +size_t crypto_kdf_bytes_min(void); + +#define crypto_kdf_BYTES_MAX crypto_kdf_blake2b_BYTES_MAX +SODIUM_EXPORT +size_t crypto_kdf_bytes_max(void); + +#define crypto_kdf_CONTEXTBYTES crypto_kdf_blake2b_CONTEXTBYTES +SODIUM_EXPORT +size_t crypto_kdf_contextbytes(void); + +#define crypto_kdf_KEYBYTES crypto_kdf_blake2b_KEYBYTES +SODIUM_EXPORT +size_t crypto_kdf_keybytes(void); + +#define crypto_kdf_PRIMITIVE "blake2b" +SODIUM_EXPORT +const char *crypto_kdf_primitive(void) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_kdf_derive_from_key(unsigned char *subkey, size_t subkey_len, + uint64_t subkey_id, + const char ctx[crypto_kdf_CONTEXTBYTES], + const unsigned char key[crypto_kdf_KEYBYTES]); + +SODIUM_EXPORT +void crypto_kdf_keygen(unsigned char k[crypto_kdf_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_kdf_blake2b.h b/tools/sdk/include/libsodium/sodium/crypto_kdf_blake2b.h new file mode 100644 index 00000000..5480ebe8 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_kdf_blake2b.h @@ -0,0 +1,42 @@ +#ifndef crypto_kdf_blake2b_H +#define crypto_kdf_blake2b_H + +#include +#include + +#include "crypto_kdf_blake2b.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_kdf_blake2b_BYTES_MIN 16 +SODIUM_EXPORT +size_t crypto_kdf_blake2b_bytes_min(void); + +#define crypto_kdf_blake2b_BYTES_MAX 64 +SODIUM_EXPORT +size_t crypto_kdf_blake2b_bytes_max(void); + +#define crypto_kdf_blake2b_CONTEXTBYTES 8 +SODIUM_EXPORT +size_t crypto_kdf_blake2b_contextbytes(void); + +#define crypto_kdf_blake2b_KEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kdf_blake2b_keybytes(void); + +SODIUM_EXPORT +int crypto_kdf_blake2b_derive_from_key(unsigned char *subkey, size_t subkey_len, + uint64_t subkey_id, + const char ctx[crypto_kdf_blake2b_CONTEXTBYTES], + const unsigned char key[crypto_kdf_blake2b_KEYBYTES]); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_kx.h b/tools/sdk/include/libsodium/sodium/crypto_kx.h new file mode 100644 index 00000000..d1fce90d --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_kx.h @@ -0,0 +1,64 @@ +#ifndef crypto_kx_H +#define crypto_kx_H + +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_kx_PUBLICKEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_publickeybytes(void); + +#define crypto_kx_SECRETKEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_secretkeybytes(void); + +#define crypto_kx_SEEDBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_seedbytes(void); + +#define crypto_kx_SESSIONKEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_sessionkeybytes(void); + +#define crypto_kx_PRIMITIVE "x25519blake2b" +SODIUM_EXPORT +const char *crypto_kx_primitive(void); + +SODIUM_EXPORT +int crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], + unsigned char sk[crypto_kx_SECRETKEYBYTES], + const unsigned char seed[crypto_kx_SEEDBYTES]); + +SODIUM_EXPORT +int crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], + unsigned char sk[crypto_kx_SECRETKEYBYTES]); + +SODIUM_EXPORT +int crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], + unsigned char tx[crypto_kx_SESSIONKEYBYTES], + const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES], + const unsigned char client_sk[crypto_kx_SECRETKEYBYTES], + const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES]) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], + unsigned char tx[crypto_kx_SESSIONKEYBYTES], + const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES], + const unsigned char server_sk[crypto_kx_SECRETKEYBYTES], + const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES]) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_onetimeauth.h b/tools/sdk/include/libsodium/sodium/crypto_onetimeauth.h new file mode 100644 index 00000000..5951c5b8 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_onetimeauth.h @@ -0,0 +1,62 @@ +#ifndef crypto_onetimeauth_H +#define crypto_onetimeauth_H + +#include + +#include "crypto_onetimeauth_poly1305.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef crypto_onetimeauth_poly1305_state crypto_onetimeauth_state; + +SODIUM_EXPORT +size_t crypto_onetimeauth_statebytes(void); + +#define crypto_onetimeauth_BYTES crypto_onetimeauth_poly1305_BYTES +SODIUM_EXPORT +size_t crypto_onetimeauth_bytes(void); + +#define crypto_onetimeauth_KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES +SODIUM_EXPORT +size_t crypto_onetimeauth_keybytes(void); + +#define crypto_onetimeauth_PRIMITIVE "poly1305" +SODIUM_EXPORT +const char *crypto_onetimeauth_primitive(void); + +SODIUM_EXPORT +int crypto_onetimeauth(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); + +SODIUM_EXPORT +int crypto_onetimeauth_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_onetimeauth_init(crypto_onetimeauth_state *state, + const unsigned char *key); + +SODIUM_EXPORT +int crypto_onetimeauth_update(crypto_onetimeauth_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_onetimeauth_final(crypto_onetimeauth_state *state, + unsigned char *out); + +SODIUM_EXPORT +void crypto_onetimeauth_keygen(unsigned char k[crypto_onetimeauth_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_onetimeauth_poly1305.h b/tools/sdk/include/libsodium/sodium/crypto_onetimeauth_poly1305.h new file mode 100644 index 00000000..479e923d --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_onetimeauth_poly1305.h @@ -0,0 +1,71 @@ +#ifndef crypto_onetimeauth_poly1305_H +#define crypto_onetimeauth_poly1305_H + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#include +#include +#include + +#include + +#include "export.h" + +typedef CRYPTO_ALIGN(16) struct crypto_onetimeauth_poly1305_state { + unsigned char opaque[256]; +} crypto_onetimeauth_poly1305_state; + +SODIUM_EXPORT +size_t crypto_onetimeauth_poly1305_statebytes(void); + +#define crypto_onetimeauth_poly1305_BYTES 16U +SODIUM_EXPORT +size_t crypto_onetimeauth_poly1305_bytes(void); + +#define crypto_onetimeauth_poly1305_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_onetimeauth_poly1305_keybytes(void); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305(unsigned char *out, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305_init(crypto_onetimeauth_poly1305_state *state, + const unsigned char *key); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305_update(crypto_onetimeauth_poly1305_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305_final(crypto_onetimeauth_poly1305_state *state, + unsigned char *out); + +SODIUM_EXPORT +void crypto_onetimeauth_poly1305_keygen(unsigned char k[crypto_onetimeauth_poly1305_KEYBYTES]); + +/* ------------------------------------------------------------------------- */ + +int _crypto_onetimeauth_poly1305_pick_best_implementation(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_pwhash.h b/tools/sdk/include/libsodium/sodium/crypto_pwhash.h new file mode 100644 index 00000000..56eca068 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_pwhash.h @@ -0,0 +1,121 @@ +#ifndef crypto_pwhash_H +#define crypto_pwhash_H + +#include + +#include "crypto_pwhash_argon2i.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_pwhash_ALG_ARGON2I13 crypto_pwhash_argon2i_ALG_ARGON2I13 +SODIUM_EXPORT +int crypto_pwhash_alg_argon2i13(void); + +#define crypto_pwhash_ALG_DEFAULT crypto_pwhash_ALG_ARGON2I13 +SODIUM_EXPORT +int crypto_pwhash_alg_default(void); + +#define crypto_pwhash_BYTES_MIN crypto_pwhash_argon2i_BYTES_MIN +SODIUM_EXPORT +size_t crypto_pwhash_bytes_min(void); + +#define crypto_pwhash_BYTES_MAX crypto_pwhash_argon2i_BYTES_MAX +SODIUM_EXPORT +size_t crypto_pwhash_bytes_max(void); + +#define crypto_pwhash_PASSWD_MIN crypto_pwhash_argon2i_PASSWD_MIN +SODIUM_EXPORT +size_t crypto_pwhash_passwd_min(void); + +#define crypto_pwhash_PASSWD_MAX crypto_pwhash_argon2i_PASSWD_MAX +SODIUM_EXPORT +size_t crypto_pwhash_passwd_max(void); + +#define crypto_pwhash_SALTBYTES crypto_pwhash_argon2i_SALTBYTES +SODIUM_EXPORT +size_t crypto_pwhash_saltbytes(void); + +#define crypto_pwhash_STRBYTES crypto_pwhash_argon2i_STRBYTES +SODIUM_EXPORT +size_t crypto_pwhash_strbytes(void); + +#define crypto_pwhash_STRPREFIX crypto_pwhash_argon2i_STRPREFIX +SODIUM_EXPORT +const char *crypto_pwhash_strprefix(void); + +#define crypto_pwhash_OPSLIMIT_MIN crypto_pwhash_argon2i_OPSLIMIT_MIN +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_min(void); + +#define crypto_pwhash_OPSLIMIT_MAX crypto_pwhash_argon2i_OPSLIMIT_MAX +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_max(void); + +#define crypto_pwhash_MEMLIMIT_MIN crypto_pwhash_argon2i_MEMLIMIT_MIN +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_min(void); + +#define crypto_pwhash_MEMLIMIT_MAX crypto_pwhash_argon2i_MEMLIMIT_MAX +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_max(void); + +#define crypto_pwhash_OPSLIMIT_INTERACTIVE crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_interactive(void); + +#define crypto_pwhash_MEMLIMIT_INTERACTIVE crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_interactive(void); + +#define crypto_pwhash_OPSLIMIT_MODERATE crypto_pwhash_argon2i_OPSLIMIT_MODERATE +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_moderate(void); + +#define crypto_pwhash_MEMLIMIT_MODERATE crypto_pwhash_argon2i_MEMLIMIT_MODERATE +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_moderate(void); + +#define crypto_pwhash_OPSLIMIT_SENSITIVE crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_sensitive(void); + +#define crypto_pwhash_MEMLIMIT_SENSITIVE crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_sensitive(void); + +SODIUM_EXPORT +int crypto_pwhash(unsigned char * const out, unsigned long long outlen, + const char * const passwd, unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, size_t memlimit, int alg) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_str(char out[crypto_pwhash_STRBYTES], + const char * const passwd, unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) + __attribute__ ((warn_unused_result)); + +#define crypto_pwhash_PRIMITIVE "argon2i" +SODIUM_EXPORT +const char *crypto_pwhash_primitive(void) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/tools/sdk/include/libsodium/sodium/crypto_pwhash_argon2i.h b/tools/sdk/include/libsodium/sodium/crypto_pwhash_argon2i.h new file mode 100644 index 00000000..d414b939 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_pwhash_argon2i.h @@ -0,0 +1,120 @@ +#ifndef crypto_pwhash_argon2i_H +#define crypto_pwhash_argon2i_H + +#include +#include +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_pwhash_argon2i_ALG_ARGON2I13 1 +SODIUM_EXPORT +int crypto_pwhash_argon2i_alg_argon2i13(void); + +#define crypto_pwhash_argon2i_BYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_bytes_min(void); + +#define crypto_pwhash_argon2i_BYTES_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_bytes_max(void); + +#define crypto_pwhash_argon2i_PASSWD_MIN 0U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_passwd_min(void); + +#define crypto_pwhash_argon2i_PASSWD_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_passwd_max(void); + +#define crypto_pwhash_argon2i_SALTBYTES 16U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_saltbytes(void); + +#define crypto_pwhash_argon2i_STRBYTES 128U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_strbytes(void); + +#define crypto_pwhash_argon2i_STRPREFIX "$argon2i$" +SODIUM_EXPORT +const char *crypto_pwhash_argon2i_strprefix(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_MIN 3U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_min(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_max(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_MIN 1U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_min(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_MAX ((SIZE_MAX >= 1ULL << 48) ? 4398046510080U : (SIZE_MAX >= 1ULL << 32) ? 2147483648U : 32768U) +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_max(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE 4U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_interactive(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE 33554432U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_interactive(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_MODERATE 6U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_moderate(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_MODERATE 134217728U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_moderate(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE 8U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_sensitive(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE 536870912U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_sensitive(void); + +SODIUM_EXPORT +int crypto_pwhash_argon2i(unsigned char * const out, + unsigned long long outlen, + const char * const passwd, + unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, size_t memlimit, + int alg) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES], + const char * const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) + __attribute__ ((warn_unused_result)); + +/* ------------------------------------------------------------------------- */ + +int _crypto_pwhash_argon2i_pick_best_implementation(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_pwhash_scryptsalsa208sha256.h b/tools/sdk/include/libsodium/sodium/crypto_pwhash_scryptsalsa208sha256.h new file mode 100644 index 00000000..9f693e54 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_pwhash_scryptsalsa208sha256.h @@ -0,0 +1,112 @@ +#ifndef crypto_pwhash_scryptsalsa208sha256_H +#define crypto_pwhash_scryptsalsa208sha256_H + +#include +#include +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_pwhash_scryptsalsa208sha256_BYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_bytes_min(void); + +#define crypto_pwhash_scryptsalsa208sha256_BYTES_MAX SIZE_MAX +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_bytes_max(void); + +#define crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN 0U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_passwd_min(void); + +#define crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX SIZE_MAX +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_passwd_max(void); + +#define crypto_pwhash_scryptsalsa208sha256_SALTBYTES 32U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_saltbytes(void); + +#define crypto_pwhash_scryptsalsa208sha256_STRBYTES 102U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_strbytes(void); + +#define crypto_pwhash_scryptsalsa208sha256_STRPREFIX "$7$" +SODIUM_EXPORT +const char *crypto_pwhash_scryptsalsa208sha256_strprefix(void); + +#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN 32768U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_opslimit_min(void); + +#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_opslimit_max(void); + +#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN 16777216U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_memlimit_min(void); + +#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX ((SIZE_MAX >= 68719476736U) ? 68719476736U : SIZE_MAX) +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_memlimit_max(void); + +#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE 524288U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void); + +#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE 16777216U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void); + +#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE 33554432U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void); + +#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE 1073741824U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void); + +SODIUM_EXPORT +int crypto_pwhash_scryptsalsa208sha256(unsigned char * const out, + unsigned long long outlen, + const char * const passwd, + unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, + size_t memlimit) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + const char * const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, + size_t memlimit) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd, size_t passwdlen, + const uint8_t * salt, size_t saltlen, + uint64_t N, uint32_t r, uint32_t p, + uint8_t * buf, size_t buflen) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_scalarmult.h b/tools/sdk/include/libsodium/sodium/crypto_scalarmult.h new file mode 100644 index 00000000..830c10f6 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_scalarmult.h @@ -0,0 +1,37 @@ +#ifndef crypto_scalarmult_H +#define crypto_scalarmult_H + +#include + +#include "crypto_scalarmult_curve25519.h" +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES +SODIUM_EXPORT +size_t crypto_scalarmult_bytes(void); + +#define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES +SODIUM_EXPORT +size_t crypto_scalarmult_scalarbytes(void); + +#define crypto_scalarmult_PRIMITIVE "curve25519" +SODIUM_EXPORT +const char *crypto_scalarmult_primitive(void); + +SODIUM_EXPORT +int crypto_scalarmult_base(unsigned char *q, const unsigned char *n); + +SODIUM_EXPORT +int crypto_scalarmult(unsigned char *q, const unsigned char *n, + const unsigned char *p) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_scalarmult_curve25519.h b/tools/sdk/include/libsodium/sodium/crypto_scalarmult_curve25519.h new file mode 100644 index 00000000..953f8923 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_scalarmult_curve25519.h @@ -0,0 +1,36 @@ +#ifndef crypto_scalarmult_curve25519_H +#define crypto_scalarmult_curve25519_H + +#include + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_scalarmult_curve25519_BYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_curve25519_bytes(void); + +#define crypto_scalarmult_curve25519_SCALARBYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_curve25519_scalarbytes(void); + +SODIUM_EXPORT +int crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n, + const unsigned char *p) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_scalarmult_curve25519_base(unsigned char *q, const unsigned char *n); + +/* ------------------------------------------------------------------------- */ + +int _crypto_scalarmult_curve25519_pick_best_implementation(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_secretbox.h b/tools/sdk/include/libsodium/sodium/crypto_secretbox.h new file mode 100644 index 00000000..9b098200 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_secretbox.h @@ -0,0 +1,87 @@ +#ifndef crypto_secretbox_H +#define crypto_secretbox_H + +#include + +#include "crypto_secretbox_xsalsa20poly1305.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_secretbox_KEYBYTES crypto_secretbox_xsalsa20poly1305_KEYBYTES +SODIUM_EXPORT +size_t crypto_secretbox_keybytes(void); + +#define crypto_secretbox_NONCEBYTES crypto_secretbox_xsalsa20poly1305_NONCEBYTES +SODIUM_EXPORT +size_t crypto_secretbox_noncebytes(void); + +#define crypto_secretbox_MACBYTES crypto_secretbox_xsalsa20poly1305_MACBYTES +SODIUM_EXPORT +size_t crypto_secretbox_macbytes(void); + +#define crypto_secretbox_PRIMITIVE "xsalsa20poly1305" +SODIUM_EXPORT +const char *crypto_secretbox_primitive(void); + +SODIUM_EXPORT +int crypto_secretbox_easy(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_secretbox_detached(unsigned char *c, unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_secretbox_open_detached(unsigned char *m, + const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +void crypto_secretbox_keygen(unsigned char k[crypto_secretbox_KEYBYTES]); + +/* -- NaCl compatibility interface ; Requires padding -- */ + +#define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES +SODIUM_EXPORT +size_t crypto_secretbox_zerobytes(void); + +#define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES +SODIUM_EXPORT +size_t crypto_secretbox_boxzerobytes(void); + +SODIUM_EXPORT +int crypto_secretbox(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_secretbox_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_secretbox_xchacha20poly1305.h b/tools/sdk/include/libsodium/sodium/crypto_secretbox_xchacha20poly1305.h new file mode 100644 index 00000000..7a61a091 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_secretbox_xchacha20poly1305.h @@ -0,0 +1,62 @@ +#ifndef crypto_secretbox_xchacha20poly1305_H +#define crypto_secretbox_xchacha20poly1305_H + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_secretbox_xchacha20poly1305_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_secretbox_xchacha20poly1305_keybytes(void); + +#define crypto_secretbox_xchacha20poly1305_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_secretbox_xchacha20poly1305_noncebytes(void); + +#define crypto_secretbox_xchacha20poly1305_MACBYTES 16U +SODIUM_EXPORT +size_t crypto_secretbox_xchacha20poly1305_macbytes(void); + +SODIUM_EXPORT +int crypto_secretbox_xchacha20poly1305_easy(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_secretbox_xchacha20poly1305_open_easy(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_secretbox_xchacha20poly1305_detached(unsigned char *c, + unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_secretbox_xchacha20poly1305_open_detached(unsigned char *m, + const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_secretbox_xsalsa20poly1305.h b/tools/sdk/include/libsodium/sodium/crypto_secretbox_xsalsa20poly1305.h new file mode 100644 index 00000000..5aa30805 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_secretbox_xsalsa20poly1305.h @@ -0,0 +1,58 @@ +#ifndef crypto_secretbox_xsalsa20poly1305_H +#define crypto_secretbox_xsalsa20poly1305_H + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_secretbox_xsalsa20poly1305_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_keybytes(void); + +#define crypto_secretbox_xsalsa20poly1305_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_noncebytes(void); + +#define crypto_secretbox_xsalsa20poly1305_MACBYTES 16U +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_macbytes(void); + +#define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES 16U +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_boxzerobytes(void); + +#define crypto_secretbox_xsalsa20poly1305_ZEROBYTES \ + (crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES + \ + crypto_secretbox_xsalsa20poly1305_MACBYTES) +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_zerobytes(void); + +SODIUM_EXPORT +int crypto_secretbox_xsalsa20poly1305(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_secretbox_xsalsa20poly1305_open(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +void crypto_secretbox_xsalsa20poly1305_keygen(unsigned char k[crypto_secretbox_xsalsa20poly1305_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_shorthash.h b/tools/sdk/include/libsodium/sodium/crypto_shorthash.h new file mode 100644 index 00000000..a4988082 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_shorthash.h @@ -0,0 +1,39 @@ +#ifndef crypto_shorthash_H +#define crypto_shorthash_H + +#include + +#include "crypto_shorthash_siphash24.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_shorthash_BYTES crypto_shorthash_siphash24_BYTES +SODIUM_EXPORT +size_t crypto_shorthash_bytes(void); + +#define crypto_shorthash_KEYBYTES crypto_shorthash_siphash24_KEYBYTES +SODIUM_EXPORT +size_t crypto_shorthash_keybytes(void); + +#define crypto_shorthash_PRIMITIVE "siphash24" +SODIUM_EXPORT +const char *crypto_shorthash_primitive(void); + +SODIUM_EXPORT +int crypto_shorthash(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); + +SODIUM_EXPORT +void crypto_shorthash_keygen(unsigned char k[crypto_shorthash_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_shorthash_siphash24.h b/tools/sdk/include/libsodium/sodium/crypto_shorthash_siphash24.h new file mode 100644 index 00000000..745ed48f --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_shorthash_siphash24.h @@ -0,0 +1,48 @@ +#ifndef crypto_shorthash_siphash24_H +#define crypto_shorthash_siphash24_H + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +/* -- 64-bit output -- */ + +#define crypto_shorthash_siphash24_BYTES 8U +SODIUM_EXPORT +size_t crypto_shorthash_siphash24_bytes(void); + +#define crypto_shorthash_siphash24_KEYBYTES 16U +SODIUM_EXPORT +size_t crypto_shorthash_siphash24_keybytes(void); + +SODIUM_EXPORT +int crypto_shorthash_siphash24(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); + +#ifndef SODIUM_LIBRARY_MINIMAL +/* -- 128-bit output -- */ + +#define crypto_shorthash_siphashx24_BYTES 16U +SODIUM_EXPORT +size_t crypto_shorthash_siphashx24_bytes(void); + +#define crypto_shorthash_siphashx24_KEYBYTES 16U +SODIUM_EXPORT +size_t crypto_shorthash_siphashx24_keybytes(void); + +SODIUM_EXPORT +int crypto_shorthash_siphashx24(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_sign.h b/tools/sdk/include/libsodium/sodium/crypto_sign.h new file mode 100644 index 00000000..b0335bf2 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_sign.h @@ -0,0 +1,99 @@ +#ifndef crypto_sign_H +#define crypto_sign_H + +/* + * THREAD SAFETY: crypto_sign_keypair() is thread-safe, + * provided that sodium_init() was called before. + * + * Other functions, including crypto_sign_seed_keypair() are always thread-safe. + */ + +#include + +#include "crypto_sign_ed25519.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef crypto_sign_ed25519ph_state crypto_sign_state; + +SODIUM_EXPORT +size_t crypto_sign_statebytes(void); + +#define crypto_sign_BYTES crypto_sign_ed25519_BYTES +SODIUM_EXPORT +size_t crypto_sign_bytes(void); + +#define crypto_sign_SEEDBYTES crypto_sign_ed25519_SEEDBYTES +SODIUM_EXPORT +size_t crypto_sign_seedbytes(void); + +#define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES +SODIUM_EXPORT +size_t crypto_sign_publickeybytes(void); + +#define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES +SODIUM_EXPORT +size_t crypto_sign_secretkeybytes(void); + +#define crypto_sign_PRIMITIVE "ed25519" +SODIUM_EXPORT +const char *crypto_sign_primitive(void); + +SODIUM_EXPORT +int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed); + +SODIUM_EXPORT +int crypto_sign_keypair(unsigned char *pk, unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign(unsigned char *sm, unsigned long long *smlen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_open(unsigned char *m, unsigned long long *mlen_p, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_sign_detached(unsigned char *sig, unsigned long long *siglen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_verify_detached(const unsigned char *sig, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_sign_init(crypto_sign_state *state); + +SODIUM_EXPORT +int crypto_sign_update(crypto_sign_state *state, + const unsigned char *m, unsigned long long mlen); + +SODIUM_EXPORT +int crypto_sign_final_create(crypto_sign_state *state, unsigned char *sig, + unsigned long long *siglen_p, + const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_final_verify(crypto_sign_state *state, unsigned char *sig, + const unsigned char *pk) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_sign_ed25519.h b/tools/sdk/include/libsodium/sodium/crypto_sign_ed25519.h new file mode 100644 index 00000000..17c150f2 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_sign_ed25519.h @@ -0,0 +1,110 @@ +#ifndef crypto_sign_ed25519_H +#define crypto_sign_ed25519_H + +#include +#include "crypto_hash_sha512.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef struct crypto_sign_ed25519ph_state { + crypto_hash_sha512_state hs; +} crypto_sign_ed25519ph_state; + +SODIUM_EXPORT +size_t crypto_sign_ed25519ph_statebytes(void); + +#define crypto_sign_ed25519_BYTES 64U +SODIUM_EXPORT +size_t crypto_sign_ed25519_bytes(void); + +#define crypto_sign_ed25519_SEEDBYTES 32U +SODIUM_EXPORT +size_t crypto_sign_ed25519_seedbytes(void); + +#define crypto_sign_ed25519_PUBLICKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_sign_ed25519_publickeybytes(void); + +#define crypto_sign_ed25519_SECRETKEYBYTES (32U + 32U) +SODIUM_EXPORT +size_t crypto_sign_ed25519_secretkeybytes(void); + +SODIUM_EXPORT +int crypto_sign_ed25519(unsigned char *sm, unsigned long long *smlen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_ed25519_open(unsigned char *m, unsigned long long *mlen_p, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_sign_ed25519_detached(unsigned char *sig, + unsigned long long *siglen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_ed25519_verify_detached(const unsigned char *sig, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_sign_ed25519_keypair(unsigned char *pk, unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_ed25519_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed); + +SODIUM_EXPORT +int crypto_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk, + const unsigned char *ed25519_pk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk, + const unsigned char *ed25519_sk); + +SODIUM_EXPORT +int crypto_sign_ed25519_sk_to_seed(unsigned char *seed, + const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_ed25519ph_init(crypto_sign_ed25519ph_state *state); + +SODIUM_EXPORT +int crypto_sign_ed25519ph_update(crypto_sign_ed25519ph_state *state, + const unsigned char *m, + unsigned long long mlen); + +SODIUM_EXPORT +int crypto_sign_ed25519ph_final_create(crypto_sign_ed25519ph_state *state, + unsigned char *sig, + unsigned long long *siglen_p, + const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_ed25519ph_final_verify(crypto_sign_ed25519ph_state *state, + unsigned char *sig, + const unsigned char *pk) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_sign_edwards25519sha512batch.h b/tools/sdk/include/libsodium/sodium/crypto_sign_edwards25519sha512batch.h new file mode 100644 index 00000000..2224a94e --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_sign_edwards25519sha512batch.h @@ -0,0 +1,54 @@ +#ifndef crypto_sign_edwards25519sha512batch_H +#define crypto_sign_edwards25519sha512batch_H + +/* + * WARNING: This construction was a prototype, which should not be used + * any more in new projects. + * + * crypto_sign_edwards25519sha512batch is provided for applications + * initially built with NaCl, but as recommended by the author of this + * construction, new applications should use ed25519 instead. + * + * In Sodium, you should use the high-level crypto_sign_*() functions instead. + */ + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_sign_edwards25519sha512batch_BYTES 64U +#define crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES 32U +#define crypto_sign_edwards25519sha512batch_SECRETKEYBYTES (32U + 32U) + +SODIUM_EXPORT +int crypto_sign_edwards25519sha512batch(unsigned char *sm, + unsigned long long *smlen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *sk) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +int crypto_sign_edwards25519sha512batch_open(unsigned char *m, + unsigned long long *mlen_p, + const unsigned char *sm, + unsigned long long smlen, + const unsigned char *pk) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +int crypto_sign_edwards25519sha512batch_keypair(unsigned char *pk, + unsigned char *sk) + __attribute__ ((deprecated)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_stream.h b/tools/sdk/include/libsodium/sodium/crypto_stream.h new file mode 100644 index 00000000..22de6ff5 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_stream.h @@ -0,0 +1,52 @@ +#ifndef crypto_stream_H +#define crypto_stream_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include + +#include "crypto_stream_xsalsa20.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_KEYBYTES crypto_stream_xsalsa20_KEYBYTES +SODIUM_EXPORT +size_t crypto_stream_keybytes(void); + +#define crypto_stream_NONCEBYTES crypto_stream_xsalsa20_NONCEBYTES +SODIUM_EXPORT +size_t crypto_stream_noncebytes(void); + +#define crypto_stream_PRIMITIVE "xsalsa20" +SODIUM_EXPORT +const char *crypto_stream_primitive(void); + +SODIUM_EXPORT +int crypto_stream(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_keygen(unsigned char k[crypto_stream_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_stream_aes128ctr.h b/tools/sdk/include/libsodium/sodium/crypto_stream_aes128ctr.h new file mode 100644 index 00000000..33ee1b89 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_stream_aes128ctr.h @@ -0,0 +1,65 @@ +#ifndef crypto_stream_aes128ctr_H +#define crypto_stream_aes128ctr_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_aes128ctr_KEYBYTES 16U +SODIUM_EXPORT +size_t crypto_stream_aes128ctr_keybytes(void); + +#define crypto_stream_aes128ctr_NONCEBYTES 16U +SODIUM_EXPORT +size_t crypto_stream_aes128ctr_noncebytes(void); + +#define crypto_stream_aes128ctr_BEFORENMBYTES 1408U +SODIUM_EXPORT +size_t crypto_stream_aes128ctr_beforenmbytes(void); + +SODIUM_EXPORT +int crypto_stream_aes128ctr(unsigned char *out, unsigned long long outlen, + const unsigned char *n, const unsigned char *k) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +int crypto_stream_aes128ctr_xor(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +int crypto_stream_aes128ctr_beforenm(unsigned char *c, const unsigned char *k) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +int crypto_stream_aes128ctr_afternm(unsigned char *out, unsigned long long len, + const unsigned char *nonce, const unsigned char *c) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +int crypto_stream_aes128ctr_xor_afternm(unsigned char *out, const unsigned char *in, + unsigned long long len, + const unsigned char *nonce, + const unsigned char *c) + __attribute__ ((deprecated)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_stream_chacha20.h b/tools/sdk/include/libsodium/sodium/crypto_stream_chacha20.h new file mode 100644 index 00000000..cf3ffe89 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_stream_chacha20.h @@ -0,0 +1,92 @@ +#ifndef crypto_stream_chacha20_H +#define crypto_stream_chacha20_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_chacha20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_chacha20_keybytes(void); + +#define crypto_stream_chacha20_NONCEBYTES 8U +SODIUM_EXPORT +size_t crypto_stream_chacha20_noncebytes(void); + +/* ChaCha20 with a 64-bit nonce and a 64-bit counter, as originally designed */ + +SODIUM_EXPORT +int crypto_stream_chacha20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_chacha20_keygen(unsigned char k[crypto_stream_chacha20_KEYBYTES]); + +/* ChaCha20 with a 96-bit nonce and a 32-bit counter (IETF) */ + +#define crypto_stream_chacha20_ietf_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_chacha20_ietf_keybytes(void); + +#define crypto_stream_chacha20_ietf_NONCEBYTES 12U +SODIUM_EXPORT +size_t crypto_stream_chacha20_ietf_noncebytes(void); + +SODIUM_EXPORT +int crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint32_t ic, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_chacha20_ietf_keygen(unsigned char k[crypto_stream_chacha20_ietf_KEYBYTES]); + +/* ------------------------------------------------------------------------- */ + +int _crypto_stream_chacha20_pick_best_implementation(void); + +/* Aliases */ + +#define crypto_stream_chacha20_IETF_KEYBYTES crypto_stream_chacha20_ietf_KEYBYTES +#define crypto_stream_chacha20_IETF_NONCEBYTES crypto_stream_chacha20_ietf_NONCEBYTES + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_stream_salsa20.h b/tools/sdk/include/libsodium/sodium/crypto_stream_salsa20.h new file mode 100644 index 00000000..741140eb --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_stream_salsa20.h @@ -0,0 +1,57 @@ +#ifndef crypto_stream_salsa20_H +#define crypto_stream_salsa20_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_salsa20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_salsa20_keybytes(void); + +#define crypto_stream_salsa20_NONCEBYTES 8U +SODIUM_EXPORT +size_t crypto_stream_salsa20_noncebytes(void); + +SODIUM_EXPORT +int crypto_stream_salsa20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_salsa20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_salsa20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_salsa20_keygen(unsigned char k[crypto_stream_salsa20_KEYBYTES]); + +/* ------------------------------------------------------------------------- */ + +int _crypto_stream_salsa20_pick_best_implementation(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_stream_salsa2012.h b/tools/sdk/include/libsodium/sodium/crypto_stream_salsa2012.h new file mode 100644 index 00000000..d5c44282 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_stream_salsa2012.h @@ -0,0 +1,46 @@ +#ifndef crypto_stream_salsa2012_H +#define crypto_stream_salsa2012_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_salsa2012_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_salsa2012_keybytes(void); + +#define crypto_stream_salsa2012_NONCEBYTES 8U +SODIUM_EXPORT +size_t crypto_stream_salsa2012_noncebytes(void); + +SODIUM_EXPORT +int crypto_stream_salsa2012(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_salsa2012_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_salsa2012_keygen(unsigned char k[crypto_stream_salsa2012_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_stream_salsa208.h b/tools/sdk/include/libsodium/sodium/crypto_stream_salsa208.h new file mode 100644 index 00000000..02b4166e --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_stream_salsa208.h @@ -0,0 +1,46 @@ +#ifndef crypto_stream_salsa208_H +#define crypto_stream_salsa208_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_salsa208_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_salsa208_keybytes(void); + +#define crypto_stream_salsa208_NONCEBYTES 8U +SODIUM_EXPORT +size_t crypto_stream_salsa208_noncebytes(void); + +SODIUM_EXPORT +int crypto_stream_salsa208(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_salsa208_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_salsa208_keygen(unsigned char k[crypto_stream_salsa208_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_stream_xchacha20.h b/tools/sdk/include/libsodium/sodium/crypto_stream_xchacha20.h new file mode 100644 index 00000000..f884798e --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_stream_xchacha20.h @@ -0,0 +1,53 @@ +#ifndef crypto_stream_xchacha20_H +#define crypto_stream_xchacha20_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_xchacha20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_xchacha20_keybytes(void); + +#define crypto_stream_xchacha20_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_stream_xchacha20_noncebytes(void); + +SODIUM_EXPORT +int crypto_stream_xchacha20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_xchacha20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_xchacha20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_xchacha20_keygen(unsigned char k[crypto_stream_xchacha20_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_stream_xsalsa20.h b/tools/sdk/include/libsodium/sodium/crypto_stream_xsalsa20.h new file mode 100644 index 00000000..ed5ae3c3 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_stream_xsalsa20.h @@ -0,0 +1,53 @@ +#ifndef crypto_stream_xsalsa20_H +#define crypto_stream_xsalsa20_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_xsalsa20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_xsalsa20_keybytes(void); + +#define crypto_stream_xsalsa20_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_stream_xsalsa20_noncebytes(void); + +SODIUM_EXPORT +int crypto_stream_xsalsa20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_xsalsa20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_xsalsa20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_xsalsa20_keygen(unsigned char k[crypto_stream_xsalsa20_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_verify_16.h b/tools/sdk/include/libsodium/sodium/crypto_verify_16.h new file mode 100644 index 00000000..5e9eeabe --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_verify_16.h @@ -0,0 +1,23 @@ +#ifndef crypto_verify_16_H +#define crypto_verify_16_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_verify_16_BYTES 16U +SODIUM_EXPORT +size_t crypto_verify_16_bytes(void); + +SODIUM_EXPORT +int crypto_verify_16(const unsigned char *x, const unsigned char *y) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_verify_32.h b/tools/sdk/include/libsodium/sodium/crypto_verify_32.h new file mode 100644 index 00000000..281b5a1b --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_verify_32.h @@ -0,0 +1,23 @@ +#ifndef crypto_verify_32_H +#define crypto_verify_32_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_verify_32_BYTES 32U +SODIUM_EXPORT +size_t crypto_verify_32_bytes(void); + +SODIUM_EXPORT +int crypto_verify_32(const unsigned char *x, const unsigned char *y) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/crypto_verify_64.h b/tools/sdk/include/libsodium/sodium/crypto_verify_64.h new file mode 100644 index 00000000..0dc7c304 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/crypto_verify_64.h @@ -0,0 +1,23 @@ +#ifndef crypto_verify_64_H +#define crypto_verify_64_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_verify_64_BYTES 64U +SODIUM_EXPORT +size_t crypto_verify_64_bytes(void); + +SODIUM_EXPORT +int crypto_verify_64(const unsigned char *x, const unsigned char *y) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/export.h b/tools/sdk/include/libsodium/sodium/export.h new file mode 100644 index 00000000..c33bced8 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/export.h @@ -0,0 +1,44 @@ + +#ifndef sodium_export_H +#define sodium_export_H + +#ifndef __GNUC__ +# ifdef __attribute__ +# undef __attribute__ +# endif +# define __attribute__(a) +#endif + +#ifdef SODIUM_STATIC +# define SODIUM_EXPORT +#else +# if defined(_MSC_VER) +# ifdef SODIUM_DLL_EXPORT +# define SODIUM_EXPORT __declspec(dllexport) +# else +# define SODIUM_EXPORT __declspec(dllimport) +# endif +# else +# if defined(__SUNPRO_C) +# ifndef __GNU_C__ +# define SODIUM_EXPORT __attribute__ (visibility(__global)) +# else +# define SODIUM_EXPORT __attribute__ __global +# endif +# elif defined(_MSG_VER) +# define SODIUM_EXPORT extern __declspec(dllexport) +# else +# define SODIUM_EXPORT __attribute__ ((visibility ("default"))) +# endif +# endif +#endif + +#ifndef CRYPTO_ALIGN +# if defined(__INTEL_COMPILER) || defined(_MSC_VER) +# define CRYPTO_ALIGN(x) __declspec(align(x)) +# else +# define CRYPTO_ALIGN(x) __attribute__ ((aligned(x))) +# endif +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/private/common.h b/tools/sdk/include/libsodium/sodium/private/common.h new file mode 100644 index 00000000..5e27e574 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/private/common.h @@ -0,0 +1,217 @@ +#ifndef common_H +#define common_H 1 + +#include +#include +#include + +#define COMPILER_ASSERT(X) (void) sizeof(char[(X) ? 1 : -1]) + +#define ROTL32(X, B) rotl32((X), (B)) +static inline uint32_t +rotl32(const uint32_t x, const int b) +{ + return (x << b) | (x >> (32 - b)); +} + +#define ROTL64(X, B) rotl64((X), (B)) +static inline uint64_t +rotl64(const uint64_t x, const int b) +{ + return (x << b) | (x >> (64 - b)); +} + +#define ROTR32(X, B) rotr32((X), (B)) +static inline uint32_t +rotr32(const uint32_t x, const int b) +{ + return (x >> b) | (x << (32 - b)); +} + +#define ROTR64(X, B) rotr64((X), (B)) +static inline uint64_t +rotr64(const uint64_t x, const int b) +{ + return (x >> b) | (x << (64 - b)); +} + +#define LOAD64_LE(SRC) load64_le(SRC) +static inline uint64_t +load64_le(const uint8_t src[8]) +{ +#ifdef NATIVE_LITTLE_ENDIAN + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint64_t w = (uint64_t) src[0]; + w |= (uint64_t) src[1] << 8; + w |= (uint64_t) src[2] << 16; + w |= (uint64_t) src[3] << 24; + w |= (uint64_t) src[4] << 32; + w |= (uint64_t) src[5] << 40; + w |= (uint64_t) src[6] << 48; + w |= (uint64_t) src[7] << 56; + return w; +#endif +} + +#define STORE64_LE(DST, W) store64_le((DST), (W)) +static inline void +store64_le(uint8_t dst[8], uint64_t w) +{ +#ifdef NATIVE_LITTLE_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[0] = (uint8_t) w; w >>= 8; + dst[1] = (uint8_t) w; w >>= 8; + dst[2] = (uint8_t) w; w >>= 8; + dst[3] = (uint8_t) w; w >>= 8; + dst[4] = (uint8_t) w; w >>= 8; + dst[5] = (uint8_t) w; w >>= 8; + dst[6] = (uint8_t) w; w >>= 8; + dst[7] = (uint8_t) w; +#endif +} + +#define LOAD32_LE(SRC) load32_le(SRC) +static inline uint32_t +load32_le(const uint8_t src[4]) +{ +#ifdef NATIVE_LITTLE_ENDIAN + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint32_t w = (uint32_t) src[0]; + w |= (uint32_t) src[1] << 8; + w |= (uint32_t) src[2] << 16; + w |= (uint32_t) src[3] << 24; + return w; +#endif +} + +#define STORE32_LE(DST, W) store32_le((DST), (W)) +static inline void +store32_le(uint8_t dst[4], uint32_t w) +{ +#ifdef NATIVE_LITTLE_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[0] = (uint8_t) w; w >>= 8; + dst[1] = (uint8_t) w; w >>= 8; + dst[2] = (uint8_t) w; w >>= 8; + dst[3] = (uint8_t) w; +#endif +} + +/* ----- */ + +#define LOAD64_BE(SRC) load64_be(SRC) +static inline uint64_t +load64_be(const uint8_t src[8]) +{ +#ifdef NATIVE_BIG_ENDIAN + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint64_t w = (uint64_t) src[7]; + w |= (uint64_t) src[6] << 8; + w |= (uint64_t) src[5] << 16; + w |= (uint64_t) src[4] << 24; + w |= (uint64_t) src[3] << 32; + w |= (uint64_t) src[2] << 40; + w |= (uint64_t) src[1] << 48; + w |= (uint64_t) src[0] << 56; + return w; +#endif +} + +#define STORE64_BE(DST, W) store64_be((DST), (W)) +static inline void +store64_be(uint8_t dst[8], uint64_t w) +{ +#ifdef NATIVE_BIG_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[7] = (uint8_t) w; w >>= 8; + dst[6] = (uint8_t) w; w >>= 8; + dst[5] = (uint8_t) w; w >>= 8; + dst[4] = (uint8_t) w; w >>= 8; + dst[3] = (uint8_t) w; w >>= 8; + dst[2] = (uint8_t) w; w >>= 8; + dst[1] = (uint8_t) w; w >>= 8; + dst[0] = (uint8_t) w; +#endif +} + +#define LOAD32_BE(SRC) load32_be(SRC) +static inline uint32_t +load32_be(const uint8_t src[4]) +{ +#ifdef NATIVE_BIG_ENDIAN + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint32_t w = (uint32_t) src[3]; + w |= (uint32_t) src[2] << 8; + w |= (uint32_t) src[1] << 16; + w |= (uint32_t) src[0] << 24; + return w; +#endif +} + +#define STORE32_BE(DST, W) store32_be((DST), (W)) +static inline void +store32_be(uint8_t dst[4], uint32_t w) +{ +#ifdef NATIVE_BIG_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[3] = (uint8_t) w; w >>= 8; + dst[2] = (uint8_t) w; w >>= 8; + dst[1] = (uint8_t) w; w >>= 8; + dst[0] = (uint8_t) w; +#endif +} + +#ifndef __GNUC__ +# ifdef __attribute__ +# undef __attribute__ +# endif +# define __attribute__(a) +#endif + +#ifndef CRYPTO_ALIGN +# if defined(__INTEL_COMPILER) || defined(_MSC_VER) +# define CRYPTO_ALIGN(x) __declspec(align(x)) +# else +# define CRYPTO_ALIGN(x) __attribute__ ((aligned(x))) +# endif +#endif + +#if defined(_MSC_VER) && \ + (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86)) + +# include + +# define HAVE_INTRIN_H 1 +# define HAVE_MMINTRIN_H 1 +# define HAVE_EMMINTRIN_H 1 +# define HAVE_PMMINTRIN_H 1 +# define HAVE_TMMINTRIN_H 1 +# define HAVE_SMMINTRIN_H 1 +# define HAVE_AVXINTRIN_H 1 +# if _MSC_VER >= 1600 +# define HAVE_WMMINTRIN_H 1 +# endif +# if _MSC_VER >= 1700 && defined(_M_X64) +# define HAVE_AVX2INTRIN_H 1 +# endif +#elif defined(HAVE_INTRIN_H) +# include +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/private/curve25519_ref10.h b/tools/sdk/include/libsodium/sodium/private/curve25519_ref10.h new file mode 100644 index 00000000..2b9caeb1 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/private/curve25519_ref10.h @@ -0,0 +1,160 @@ +#ifndef curve25519_ref10_H +#define curve25519_ref10_H + +#include +#include + +#define fe crypto_core_curve25519_ref10_fe +typedef int32_t fe[10]; + +/* + fe means field element. + Here the field is \Z/(2^255-19). + An element t, entries t[0]...t[9], represents the integer + t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. + Bounds on each t[i] vary depending on context. + */ + +#define fe_frombytes crypto_core_curve25519_ref10_fe_frombytes +#define fe_tobytes crypto_core_curve25519_ref10_fe_tobytes +#define fe_copy crypto_core_curve25519_ref10_fe_copy +#define fe_isnonzero crypto_core_curve25519_ref10_fe_isnonzero +#define fe_isnegative crypto_core_curve25519_ref10_fe_isnegative +#define fe_0 crypto_core_curve25519_ref10_fe_0 +#define fe_1 crypto_core_curve25519_ref10_fe_1 +#define fe_cmov crypto_core_curve25519_ref10_fe_cmov +#define fe_add crypto_core_curve25519_ref10_fe_add +#define fe_sub crypto_core_curve25519_ref10_fe_sub +#define fe_neg crypto_core_curve25519_ref10_fe_neg +#define fe_mul crypto_core_curve25519_ref10_fe_mul +#define fe_sq crypto_core_curve25519_ref10_fe_sq +#define fe_sq2 crypto_core_curve25519_ref10_fe_sq2 +#define fe_invert crypto_core_curve25519_ref10_fe_invert +#define fe_pow22523 crypto_core_curve25519_ref10_fe_pow22523 + +extern void fe_frombytes(fe,const unsigned char *); +extern void fe_tobytes(unsigned char *,const fe); + +extern void fe_copy(fe,const fe); +extern int fe_isnonzero(const fe); +extern int fe_isnegative(const fe); +extern void fe_0(fe); +extern void fe_1(fe); +extern void fe_cmov(fe,const fe,unsigned int); +extern void fe_add(fe,const fe,const fe); +extern void fe_sub(fe,const fe,const fe); +extern void fe_neg(fe,const fe); +extern void fe_mul(fe,const fe,const fe); +extern void fe_sq(fe,const fe); +extern void fe_sq2(fe,const fe); +extern void fe_invert(fe,const fe); +extern void fe_pow22523(fe,const fe); + +/* + ge means group element. + * + Here the group is the set of pairs (x,y) of field elements (see fe.h) + satisfying -x^2 + y^2 = 1 + d x^2y^2 + where d = -121665/121666. + * + Representations: + ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z + ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT + ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T + ge_precomp (Duif): (y+x,y-x,2dxy) + */ + +#define ge_p2 crypto_core_curve25519_ref10_ge_p2 +typedef struct { + fe X; + fe Y; + fe Z; +} ge_p2; + +#define ge_p3 crypto_core_curve25519_ref10_ge_p3 +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p3; + +#define ge_p1p1 crypto_core_curve25519_ref10_ge_p1p1 +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p1p1; + +#define ge_precomp crypto_core_curve25519_ref10_ge_precomp +typedef struct { + fe yplusx; + fe yminusx; + fe xy2d; +} ge_precomp; + +#define ge_cached crypto_core_curve25519_ref10_ge_cached +typedef struct { + fe YplusX; + fe YminusX; + fe Z; + fe T2d; +} ge_cached; + +#define ge_frombytes_negate_vartime crypto_core_curve25519_ref10_ge_frombytes_negate_vartime +#define ge_tobytes crypto_core_curve25519_ref10_ge_tobytes +#define ge_p3_tobytes crypto_core_curve25519_ref10_ge_p3_tobytes + +#define ge_p2_0 crypto_core_curve25519_ref10_ge_p2_0 +#define ge_p3_0 crypto_core_curve25519_ref10_ge_p3_0 +#define ge_precomp_0 crypto_core_curve25519_ref10_ge_precomp_0 +#define ge_p3_to_p2 crypto_core_curve25519_ref10_ge_p3_to_p2 +#define ge_p3_to_cached crypto_core_curve25519_ref10_ge_p3_to_cached +#define ge_p1p1_to_p2 crypto_core_curve25519_ref10_ge_p1p1_to_p2 +#define ge_p1p1_to_p3 crypto_core_curve25519_ref10_ge_p1p1_to_p3 +#define ge_p2_dbl crypto_core_curve25519_ref10_ge_p2_dbl +#define ge_p3_dbl crypto_core_curve25519_ref10_ge_p3_dbl + +#define ge_madd crypto_core_curve25519_ref10_ge_madd +#define ge_msub crypto_core_curve25519_ref10_ge_msub +#define ge_add crypto_core_curve25519_ref10_ge_add +#define ge_sub crypto_core_curve25519_ref10_ge_sub +#define ge_scalarmult_base crypto_core_curve25519_ref10_ge_scalarmult_base +#define ge_double_scalarmult_vartime crypto_core_curve25519_ref10_ge_double_scalarmult_vartime +#define ge_scalarmult_vartime crypto_core_curve25519_ref10_ge_scalarmult_vartime + +extern void ge_tobytes(unsigned char *,const ge_p2 *); +extern void ge_p3_tobytes(unsigned char *,const ge_p3 *); +extern int ge_frombytes_negate_vartime(ge_p3 *,const unsigned char *); + +extern void ge_p2_0(ge_p2 *); +extern void ge_p3_0(ge_p3 *); +extern void ge_precomp_0(ge_precomp *); +extern void ge_p3_to_p2(ge_p2 *,const ge_p3 *); +extern void ge_p3_to_cached(ge_cached *,const ge_p3 *); +extern void ge_p1p1_to_p2(ge_p2 *,const ge_p1p1 *); +extern void ge_p1p1_to_p3(ge_p3 *,const ge_p1p1 *); +extern void ge_p2_dbl(ge_p1p1 *,const ge_p2 *); +extern void ge_p3_dbl(ge_p1p1 *,const ge_p3 *); + +extern void ge_madd(ge_p1p1 *,const ge_p3 *,const ge_precomp *); +extern void ge_msub(ge_p1p1 *,const ge_p3 *,const ge_precomp *); +extern void ge_add(ge_p1p1 *,const ge_p3 *,const ge_cached *); +extern void ge_sub(ge_p1p1 *,const ge_p3 *,const ge_cached *); +extern void ge_scalarmult_base(ge_p3 *,const unsigned char *); +extern void ge_double_scalarmult_vartime(ge_p2 *,const unsigned char *,const ge_p3 *,const unsigned char *); +extern void ge_scalarmult_vartime(ge_p3 *,const unsigned char *,const ge_p3 *); + +/* + The set of scalars is \Z/l + where l = 2^252 + 27742317777372353535851937790883648493. + */ + +#define sc_reduce crypto_core_curve25519_ref10_sc_reduce +#define sc_muladd crypto_core_curve25519_ref10_sc_muladd + +extern void sc_reduce(unsigned char *); +extern void sc_muladd(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *); + +#endif diff --git a/tools/sdk/include/libsodium/sodium/private/mutex.h b/tools/sdk/include/libsodium/sodium/private/mutex.h new file mode 100644 index 00000000..322b6742 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/private/mutex.h @@ -0,0 +1,7 @@ +#ifndef mutex_H +#define mutex_H 1 + +extern int sodium_crit_enter(void); +extern int sodium_crit_leave(void); + +#endif diff --git a/tools/sdk/include/libsodium/sodium/private/sse2_64_32.h b/tools/sdk/include/libsodium/sodium/private/sse2_64_32.h new file mode 100644 index 00000000..d0455b41 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/private/sse2_64_32.h @@ -0,0 +1,50 @@ +#ifndef sse2_64_32_H +#define sse2_64_32_H 1 + +#include "common.h" + +#ifdef HAVE_INTRIN_H +# include +#endif + +#if defined(HAVE_EMMINTRIN_H) && \ + !(defined(__amd64) || defined(__amd64__) || defined(__x86_64__) || \ + defined(_M_X64) || defined(_M_AMD64)) + +# include +# include + +# ifndef _mm_set_epi64x +# define _mm_set_epi64x(Q0, Q1) sodium__mm_set_epi64x((Q0), (Q1)) +static inline __m128i +sodium__mm_set_epi64x(int64_t q1, int64_t q0) +{ + union { int64_t as64; int32_t as32[2]; } x0, x1; + x0.as64 = q0; x1.as64 = q1; + return _mm_set_epi32(x1.as32[1], x1.as32[0], x0.as32[1], x0.as32[0]); +} +# endif + +# ifndef _mm_set1_epi64x +# define _mm_set1_epi64x(Q) sodium__mm_set1_epi64x(Q) +static inline __m128i +sodium__mm_set1_epi64x(int64_t q) +{ + return _mm_set_epi64x(q, q); +} +# endif + +# ifndef _mm_cvtsi64_si128 +# define _mm_cvtsi64_si128(Q) sodium__mm_cvtsi64_si128(Q) +static inline __m128i +sodium__mm_cvtsi64_si128(int64_t q) +{ + union { int64_t as64; int32_t as32[2]; } x; + x.as64 = q; + return _mm_setr_epi32(x.as32[0], x.as32[1], 0, 0); +} +# endif + +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/randombytes.h b/tools/sdk/include/libsodium/sodium/randombytes.h new file mode 100644 index 00000000..d112fb29 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/randombytes.h @@ -0,0 +1,66 @@ + +#ifndef randombytes_H +#define randombytes_H + +#include +#include + +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef struct randombytes_implementation { + const char *(*implementation_name)(void); /* required */ + uint32_t (*random)(void); /* required */ + void (*stir)(void); /* optional */ + uint32_t (*uniform)(const uint32_t upper_bound); /* optional, a default implementation will be used if NULL */ + void (*buf)(void * const buf, const size_t size); /* required */ + int (*close)(void); /* optional */ +} randombytes_implementation; + +#define randombytes_SEEDBYTES 32U +SODIUM_EXPORT +size_t randombytes_seedbytes(void); + +SODIUM_EXPORT +void randombytes_buf(void * const buf, const size_t size); + +SODIUM_EXPORT +void randombytes_buf_deterministic(void * const buf, const size_t size, + const unsigned char seed[randombytes_SEEDBYTES]); + +SODIUM_EXPORT +uint32_t randombytes_random(void); + +SODIUM_EXPORT +uint32_t randombytes_uniform(const uint32_t upper_bound); + +SODIUM_EXPORT +void randombytes_stir(void); + +SODIUM_EXPORT +int randombytes_close(void); + +SODIUM_EXPORT +int randombytes_set_implementation(randombytes_implementation *impl); + +SODIUM_EXPORT +const char *randombytes_implementation_name(void); + +/* -- NaCl compatibility interface -- */ + +SODIUM_EXPORT +void randombytes(unsigned char * const buf, const unsigned long long buf_len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/randombytes_nativeclient.h b/tools/sdk/include/libsodium/sodium/randombytes_nativeclient.h new file mode 100644 index 00000000..5158d8c3 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/randombytes_nativeclient.h @@ -0,0 +1,23 @@ + +#ifndef randombytes_nativeclient_H +#define randombytes_nativeclient_H + +#ifdef __native_client__ + +# include "export.h" +# include "randombytes.h" + +# ifdef __cplusplus +extern "C" { +# endif + +SODIUM_EXPORT +extern struct randombytes_implementation randombytes_nativeclient_implementation; + +# ifdef __cplusplus +} +# endif + +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/randombytes_salsa20_random.h b/tools/sdk/include/libsodium/sodium/randombytes_salsa20_random.h new file mode 100644 index 00000000..4deae15b --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/randombytes_salsa20_random.h @@ -0,0 +1,19 @@ + +#ifndef randombytes_salsa20_random_H +#define randombytes_salsa20_random_H + +#include "export.h" +#include "randombytes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +extern struct randombytes_implementation randombytes_salsa20_implementation; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/randombytes_sysrandom.h b/tools/sdk/include/libsodium/sodium/randombytes_sysrandom.h new file mode 100644 index 00000000..9e27b674 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/randombytes_sysrandom.h @@ -0,0 +1,19 @@ + +#ifndef randombytes_sysrandom_H +#define randombytes_sysrandom_H + +#include "export.h" +#include "randombytes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +extern struct randombytes_implementation randombytes_sysrandom_implementation; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/runtime.h b/tools/sdk/include/libsodium/sodium/runtime.h new file mode 100644 index 00000000..76859ea0 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/runtime.h @@ -0,0 +1,46 @@ + +#ifndef sodium_runtime_H +#define sodium_runtime_H + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +int sodium_runtime_has_neon(void); + +SODIUM_EXPORT +int sodium_runtime_has_sse2(void); + +SODIUM_EXPORT +int sodium_runtime_has_sse3(void); + +SODIUM_EXPORT +int sodium_runtime_has_ssse3(void); + +SODIUM_EXPORT +int sodium_runtime_has_sse41(void); + +SODIUM_EXPORT +int sodium_runtime_has_avx(void); + +SODIUM_EXPORT +int sodium_runtime_has_avx2(void); + +SODIUM_EXPORT +int sodium_runtime_has_pclmul(void); + +SODIUM_EXPORT +int sodium_runtime_has_aesni(void); + +/* ------------------------------------------------------------------------- */ + +int _sodium_runtime_get_cpu_features(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/utils.h b/tools/sdk/include/libsodium/sodium/utils.h new file mode 100644 index 00000000..0a7aadb4 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/utils.h @@ -0,0 +1,131 @@ + +#ifndef sodium_utils_H +#define sodium_utils_H + +#include + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SODIUM_C99 +# if defined(__cplusplus) || !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L +# define SODIUM_C99(X) +# else +# define SODIUM_C99(X) X +# endif +#endif + +SODIUM_EXPORT +void sodium_memzero(void * const pnt, const size_t len); + +/* + * WARNING: sodium_memcmp() must be used to verify if two secret keys + * are equal, in constant time. + * It returns 0 if the keys are equal, and -1 if they differ. + * This function is not designed for lexicographical comparisons. + */ +SODIUM_EXPORT +int sodium_memcmp(const void * const b1_, const void * const b2_, size_t len) + __attribute__ ((warn_unused_result)); + +/* + * sodium_compare() returns -1 if b1_ < b2_, 1 if b1_ > b2_ and 0 if b1_ == b2_ + * It is suitable for lexicographical comparisons, or to compare nonces + * and counters stored in little-endian format. + * However, it is slower than sodium_memcmp(). + */ +SODIUM_EXPORT +int sodium_compare(const unsigned char *b1_, const unsigned char *b2_, + size_t len) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int sodium_is_zero(const unsigned char *n, const size_t nlen); + +SODIUM_EXPORT +void sodium_increment(unsigned char *n, const size_t nlen); + +SODIUM_EXPORT +void sodium_add(unsigned char *a, const unsigned char *b, const size_t len); + +SODIUM_EXPORT +char *sodium_bin2hex(char * const hex, const size_t hex_maxlen, + const unsigned char * const bin, const size_t bin_len); + +SODIUM_EXPORT +int sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen, + const char * const hex, const size_t hex_len, + const char * const ignore, size_t * const bin_len, + const char ** const hex_end); + +SODIUM_EXPORT +int sodium_mlock(void * const addr, const size_t len); + +SODIUM_EXPORT +int sodium_munlock(void * const addr, const size_t len); + +/* WARNING: sodium_malloc() and sodium_allocarray() are not general-purpose + * allocation functions. + * + * They return a pointer to a region filled with 0xd0 bytes, immediately + * followed by a guard page. + * As a result, accessing a single byte after the requested allocation size + * will intentionally trigger a segmentation fault. + * + * A canary and an additional guard page placed before the beginning of the + * region may also kill the process if a buffer underflow is detected. + * + * The memory layout is: + * [unprotected region size (read only)][guard page (no access)][unprotected pages (read/write)][guard page (no access)] + * With the layout of the unprotected pages being: + * [optional padding][16-bytes canary][user region] + * + * However: + * - These functions are significantly slower than standard functions + * - Each allocation requires 3 or 4 additional pages + * - The returned address will not be aligned if the allocation size is not + * a multiple of the required alignment. For this reason, these functions + * are designed to store data, such as secret keys and messages. + * + * sodium_malloc() can be used to allocate any libsodium data structure. + * + * The crypto_generichash_state structure is packed and its length is + * either 357 or 361 bytes. For this reason, when using sodium_malloc() to + * allocate a crypto_generichash_state structure, padding must be added in + * order to ensure proper alignment. crypto_generichash_statebytes() + * returns the rounded up structure size, and should be prefered to sizeof(): + * state = sodium_malloc(crypto_generichash_statebytes()); + */ + +SODIUM_EXPORT +void *sodium_malloc(const size_t size) + __attribute__ ((malloc)); + +SODIUM_EXPORT +void *sodium_allocarray(size_t count, size_t size) + __attribute__ ((malloc)); + +SODIUM_EXPORT +void sodium_free(void *ptr); + +SODIUM_EXPORT +int sodium_mprotect_noaccess(void *ptr); + +SODIUM_EXPORT +int sodium_mprotect_readonly(void *ptr); + +SODIUM_EXPORT +int sodium_mprotect_readwrite(void *ptr); + +/* -------- */ + +int _sodium_alloc_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/libsodium/sodium/version.h b/tools/sdk/include/libsodium/sodium/version.h new file mode 100644 index 00000000..c0bf5869 --- /dev/null +++ b/tools/sdk/include/libsodium/sodium/version.h @@ -0,0 +1,35 @@ + +#ifndef sodium_version_H +#define sodium_version_H + +#include + +/* IMPORTANT: As we don't use autotools, these version are not automatically + updated if we change submodules. They need to be changed manually. +*/ + +#define SODIUM_VERSION_STRING "1.0.12-idf" + +/* Note: these are not the same as the overall version, see + configure.ac for the relevant macros */ +#define SODIUM_LIBRARY_VERSION_MAJOR 9 +#define SODIUM_LIBRARY_VERSION_MINOR 4 + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +const char *sodium_version_string(void); + +SODIUM_EXPORT +int sodium_library_version_major(void); + +SODIUM_EXPORT +int sodium_library_version_minor(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/lwip/apps/sntp/sntp.h b/tools/sdk/include/lwip/apps/sntp/sntp.h new file mode 100644 index 00000000..3db0fba1 --- /dev/null +++ b/tools/sdk/include/lwip/apps/sntp/sntp.h @@ -0,0 +1,3 @@ +#pragma once +#warning "This header file is deprecated, please include lwip/apps/sntp.h instead." +#include "lwip/apps/sntp.h" diff --git a/tools/sdk/include/lwip/arch/sys_arch.h b/tools/sdk/include/lwip/arch/sys_arch.h index b13d7d1f..bfa2ad6c 100644 --- a/tools/sdk/include/lwip/arch/sys_arch.h +++ b/tools/sdk/include/lwip/arch/sys_arch.h @@ -50,8 +50,7 @@ typedef xTaskHandle sys_thread_t; typedef struct sys_mbox_s { xQueueHandle os_mbox; - sys_mutex_t lock; - uint8_t alive; + void *owner; }* sys_mbox_t; diff --git a/tools/sdk/include/lwip/ping/esp_ping.h b/tools/sdk/include/lwip/esp_ping.h similarity index 90% rename from tools/sdk/include/lwip/ping/esp_ping.h rename to tools/sdk/include/lwip/esp_ping.h index d83c5b36..9abb883c 100644 --- a/tools/sdk/include/lwip/ping/esp_ping.h +++ b/tools/sdk/include/lwip/esp_ping.h @@ -21,6 +21,9 @@ extern "C" { #endif +// gen_esp_err_to_name.py: include this as "esp_ping.h" because "components/lwip/include/apps/" is in the compiler path +// and not "components/lwip/include" + #define ESP_ERR_PING_BASE 0x6000 #define ESP_ERR_PING_INVALID_PARAMS ESP_ERR_PING_BASE + 0x01 @@ -49,7 +52,9 @@ typedef enum { PING_TARGET_DELAY_TIME = 53, /**< delay time in milliseconds */ PING_TARGET_ID = 54, /**< identifier */ PING_TARGET_RES_FN = 55, /**< ping result callback function */ - PING_TARGET_RES_RESET = 56 /**< ping result statistic reset */ + PING_TARGET_RES_RESET = 56, /**< ping result statistic reset */ + PING_TARGET_DATA_LEN = 57, /**< ping data length*/ + PING_TARGET_IP_TOS = 58 /**< ping QOS*/ } ping_target_id_t; typedef enum { diff --git a/tools/sdk/include/lwip/lwip/api.h b/tools/sdk/include/lwip/lwip/api.h index a4fed9bb..5ad6235e 100644 --- a/tools/sdk/include/lwip/lwip/api.h +++ b/tools/sdk/include/lwip/lwip/api.h @@ -233,6 +233,15 @@ struct netconn { by the application thread */ sys_mbox_t acceptmbox; #endif /* LWIP_TCP */ + +#if ESP_THREAD_SAFE + /** point to the same mbox as recvmbox */ + sys_mbox_t recvmbox_ref; +#if LWIP_TCP + /** point to the same mbox as acceptmbox */ + sys_mbox_t acceptmbox_ref; +#endif +#endif /** only used for socket layer */ #if LWIP_SOCKET int socket; diff --git a/tools/sdk/include/lwip/lwip/apps/FILES b/tools/sdk/include/lwip/lwip/apps/FILES deleted file mode 100644 index adfc0f33..00000000 --- a/tools/sdk/include/lwip/lwip/apps/FILES +++ /dev/null @@ -1,2 +0,0 @@ -This directory contains application headers. -Every application shall provide one api file APP.h and optionally one options file APP_opts.h diff --git a/tools/sdk/include/lwip/lwip/autoip.h b/tools/sdk/include/lwip/lwip/autoip.h index 82a69b46..1d85bccf 100644 --- a/tools/sdk/include/lwip/lwip/autoip.h +++ b/tools/sdk/include/lwip/lwip/autoip.h @@ -57,26 +57,6 @@ extern "C" { #define AUTOIP_TMR_INTERVAL 100 #define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL) -#if ESP_LWIP -/* RFC 3927 Constants */ -#define PROBE_WAIT 1 /* second (initial random delay) */ -#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */ -#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */ -#define PROBE_NUM 3 /* (number of probe packets) */ -#define ANNOUNCE_NUM 2 /* (number of announcement packets) */ -#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */ -#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */ -#define MAX_CONFLICTS LWIP_AUTOIP_MAX_CONFLICTS /* (max conflicts before rate limiting) */ -#define RATE_LIMIT_INTERVAL LWIP_AUTOIP_RATE_LIMIT_INTERVAL /* seconds (delay between successive attempts) */ -#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */ - -/* AutoIP client states */ -#define AUTOIP_STATE_OFF 0 -#define AUTOIP_STATE_PROBING 1 -#define AUTOIP_STATE_ANNOUNCING 2 -#define AUTOIP_STATE_BOUND 3 -#endif - /** AutoIP state information per netif */ struct autoip { diff --git a/tools/sdk/include/lwip/lwip/sys.h b/tools/sdk/include/lwip/lwip/sys.h index f229e407..695cae49 100644 --- a/tools/sdk/include/lwip/lwip/sys.h +++ b/tools/sdk/include/lwip/lwip/sys.h @@ -275,6 +275,17 @@ err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg); * The returned time has to be accurate to prevent timer jitter! */ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout); + +#if ESP_THREAD_SAFE +/** + * @ingroup sys_mbox + * Set the owner of the mbox + * @param mbox mbox to set the owner + * @param owner the owner of the mbox, it's a pointer to struct netconn + */ +void sys_mbox_set_owner(sys_mbox_t *mbox, void *owner); +#endif + /* Allow port to override with a macro, e.g. special timeout for sys_arch_mbox_fetch() */ #ifndef sys_arch_mbox_tryfetch /** diff --git a/tools/sdk/include/lwip/sys_arch.h b/tools/sdk/include/lwip/sys_arch.h index b13d7d1f..bfa2ad6c 100644 --- a/tools/sdk/include/lwip/sys_arch.h +++ b/tools/sdk/include/lwip/sys_arch.h @@ -50,8 +50,7 @@ typedef xTaskHandle sys_thread_t; typedef struct sys_mbox_s { xQueueHandle os_mbox; - sys_mutex_t lock; - uint8_t alive; + void *owner; }* sys_mbox_t; diff --git a/tools/sdk/include/mbedtls/.gitignore b/tools/sdk/include/mbedtls/.gitignore deleted file mode 100644 index bf67d02e..00000000 --- a/tools/sdk/include/mbedtls/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -Makefile -*.sln -*.vcxproj -mbedtls/check_config diff --git a/tools/sdk/include/mbedtls/CMakeLists.txt b/tools/sdk/include/mbedtls/CMakeLists.txt deleted file mode 100644 index 1b581a54..00000000 --- a/tools/sdk/include/mbedtls/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -option(INSTALL_MBEDTLS_HEADERS "Install mbed TLS headers." ON) - -if(INSTALL_MBEDTLS_HEADERS) - - file(GLOB headers "mbedtls/*.h") - - install(FILES ${headers} - DESTINATION include/mbedtls - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) - -endif(INSTALL_MBEDTLS_HEADERS) - -# Make config.h available in an out-of-source build. ssl-opt.sh requires it. -if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) - link_to_source(mbedtls) -endif() diff --git a/tools/sdk/include/mbedtls_port/aes_alt.h b/tools/sdk/include/mbedtls/aes_alt.h similarity index 81% rename from tools/sdk/include/mbedtls_port/aes_alt.h rename to tools/sdk/include/mbedtls/aes_alt.h index 5c143f2c..cf87ea5c 100644 --- a/tools/sdk/include/mbedtls_port/aes_alt.h +++ b/tools/sdk/include/mbedtls/aes_alt.h @@ -47,6 +47,14 @@ typedef esp_aes_context mbedtls_aes_context; #if defined(MBEDTLS_CIPHER_MODE_CTR) #define mbedtls_aes_crypt_ctr esp_aes_crypt_ctr #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) +typedef esp_aes_xts_context mbedtls_aes_xts_context; +#define mbedtls_aes_xts_init esp_aes_xts_init +#define mbedtls_aes_xts_free esp_aes_xts_free +#define mbedtls_aes_xts_setkey_enc esp_aes_xts_setkey_enc +#define mbedtls_aes_xts_setkey_dec esp_aes_xts_setkey_dec +#define mbedtls_aes_crypt_xts esp_aes_crypt_xts +#endif #define mbedtls_internal_aes_encrypt esp_internal_aes_encrypt #define mbedtls_internal_aes_decrypt esp_internal_aes_decrypt #endif /* MBEDTLS_AES_ALT */ diff --git a/tools/sdk/include/bluedroid/btc/btc_alarm.h b/tools/sdk/include/mbedtls/esp_mem.h similarity index 62% rename from tools/sdk/include/bluedroid/btc/btc_alarm.h rename to tools/sdk/include/mbedtls/esp_mem.h index 39348f0f..da740830 100644 --- a/tools/sdk/include/bluedroid/btc/btc_alarm.h +++ b/tools/sdk/include/mbedtls/esp_mem.h @@ -1,9 +1,9 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software @@ -12,19 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +#pragma once -#ifndef __BTC_ALARM_H__ -#define __BTC_ALARM_H__ +#include -#include -#include "osi/alarm.h" - -/* btc_alarm_args_t */ -typedef struct { - osi_alarm_callback_t cb; - void *cb_data; -} btc_alarm_args_t; - -void btc_alarm_handler(btc_msg_t *msg); - -#endif /* __BTC_ALARM_H__ */ +void *esp_mbedtls_mem_calloc(size_t n, size_t size); +void esp_mbedtls_mem_free(void *ptr); diff --git a/tools/sdk/include/mbedtls/mbedtls/aes.h b/tools/sdk/include/mbedtls/mbedtls/aes.h index f6603d59..4c8dab31 100644 --- a/tools/sdk/include/mbedtls/mbedtls/aes.h +++ b/tools/sdk/include/mbedtls/mbedtls/aes.h @@ -79,7 +79,7 @@ extern "C" { /** * \brief The AES context-type definition. */ -typedef struct +typedef struct mbedtls_aes_context { int nr; /*!< The number of rounds. */ uint32_t *rk; /*!< AES round keys. */ @@ -98,7 +98,7 @@ mbedtls_aes_context; /** * \brief The AES XTS context-type definition. */ -typedef struct +typedef struct mbedtls_aes_xts_context { mbedtls_aes_context crypt; /*!< The AES context to use for AES block encryption or decryption. */ diff --git a/tools/sdk/include/mbedtls/mbedtls/arc4.h b/tools/sdk/include/mbedtls/mbedtls/arc4.h index f11fc5be..83a7461f 100644 --- a/tools/sdk/include/mbedtls/mbedtls/arc4.h +++ b/tools/sdk/include/mbedtls/mbedtls/arc4.h @@ -53,7 +53,7 @@ extern "C" { * security risk. We recommend considering stronger ciphers instead. * */ -typedef struct +typedef struct mbedtls_arc4_context { int x; /*!< permutation index */ int y; /*!< permutation index */ diff --git a/tools/sdk/include/mbedtls/mbedtls/aria.h b/tools/sdk/include/mbedtls/mbedtls/aria.h index bae0621b..4a79c138 100644 --- a/tools/sdk/include/mbedtls/mbedtls/aria.h +++ b/tools/sdk/include/mbedtls/mbedtls/aria.h @@ -62,7 +62,7 @@ extern "C" { /** * \brief The ARIA context-type definition. */ -typedef struct +typedef struct mbedtls_aria_context { unsigned char nr; /*!< The number of rounds (12, 14 or 16) */ /*! The ARIA round keys. */ diff --git a/tools/sdk/include/mbedtls/mbedtls/bignum.h b/tools/sdk/include/mbedtls/mbedtls/bignum.h index 0f319a5c..b267b23e 100644 --- a/tools/sdk/include/mbedtls/mbedtls/bignum.h +++ b/tools/sdk/include/mbedtls/mbedtls/bignum.h @@ -179,7 +179,7 @@ extern "C" { /** * \brief MPI structure */ -typedef struct +typedef struct mbedtls_mpi { int s; /*!< integer sign */ size_t n; /*!< total # of limbs */ diff --git a/tools/sdk/include/mbedtls/mbedtls/blowfish.h b/tools/sdk/include/mbedtls/mbedtls/blowfish.h index 985faa43..eea6882f 100644 --- a/tools/sdk/include/mbedtls/mbedtls/blowfish.h +++ b/tools/sdk/include/mbedtls/mbedtls/blowfish.h @@ -55,7 +55,7 @@ extern "C" { /** * \brief Blowfish context structure */ -typedef struct +typedef struct mbedtls_blowfish_context { uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2]; /*!< Blowfish round keys */ uint32_t S[4][256]; /*!< key dependent S-boxes */ diff --git a/tools/sdk/include/mbedtls/mbedtls/camellia.h b/tools/sdk/include/mbedtls/mbedtls/camellia.h index 7e4721af..fa1e05ee 100644 --- a/tools/sdk/include/mbedtls/mbedtls/camellia.h +++ b/tools/sdk/include/mbedtls/mbedtls/camellia.h @@ -51,7 +51,7 @@ extern "C" { /** * \brief CAMELLIA context structure */ -typedef struct +typedef struct mbedtls_camellia_context { int nr; /*!< number of rounds */ uint32_t rk[68]; /*!< CAMELLIA round keys */ diff --git a/tools/sdk/include/mbedtls/mbedtls/ccm.h b/tools/sdk/include/mbedtls/mbedtls/ccm.h index 5d727e7c..e1dc124b 100644 --- a/tools/sdk/include/mbedtls/mbedtls/ccm.h +++ b/tools/sdk/include/mbedtls/mbedtls/ccm.h @@ -68,7 +68,8 @@ extern "C" { * \brief The CCM context-type definition. The CCM context is passed * to the APIs called. */ -typedef struct { +typedef struct mbedtls_ccm_context +{ mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ } mbedtls_ccm_context; diff --git a/tools/sdk/include/mbedtls/mbedtls/chacha20.h b/tools/sdk/include/mbedtls/mbedtls/chacha20.h index 47bd7d38..cfea40a5 100644 --- a/tools/sdk/include/mbedtls/mbedtls/chacha20.h +++ b/tools/sdk/include/mbedtls/mbedtls/chacha20.h @@ -52,7 +52,7 @@ extern "C" { #if !defined(MBEDTLS_CHACHA20_ALT) -typedef struct +typedef struct mbedtls_chacha20_context { uint32_t state[16]; /*! The state (before round operations). */ uint8_t keystream8[64]; /*! Leftover keystream bytes. */ diff --git a/tools/sdk/include/mbedtls/mbedtls/chachapoly.h b/tools/sdk/include/mbedtls/mbedtls/chachapoly.h index 42b2b230..7de6f4e8 100644 --- a/tools/sdk/include/mbedtls/mbedtls/chachapoly.h +++ b/tools/sdk/include/mbedtls/mbedtls/chachapoly.h @@ -60,7 +60,7 @@ mbedtls_chachapoly_mode_t; #include "chacha20.h" -typedef struct +typedef struct mbedtls_chachapoly_context { mbedtls_chacha20_context chacha20_ctx; /**< The ChaCha20 context. */ mbedtls_poly1305_context poly1305_ctx; /**< The Poly1305 context. */ diff --git a/tools/sdk/include/mbedtls/mbedtls/cipher.h b/tools/sdk/include/mbedtls/mbedtls/cipher.h index ea0ce983..dfb15411 100644 --- a/tools/sdk/include/mbedtls/mbedtls/cipher.h +++ b/tools/sdk/include/mbedtls/mbedtls/cipher.h @@ -45,7 +45,8 @@ #define MBEDTLS_CIPHER_MODE_WITH_PADDING #endif -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) +#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ + defined(MBEDTLS_CHACHA20_C) #define MBEDTLS_CIPHER_MODE_STREAM #endif @@ -235,7 +236,8 @@ typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t; * Cipher information. Allows calling cipher functions * in a generic way. */ -typedef struct { +typedef struct mbedtls_cipher_info_t +{ /** Full cipher identifier. For example, * MBEDTLS_CIPHER_AES_256_CBC. */ @@ -276,7 +278,8 @@ typedef struct { /** * Generic cipher context. */ -typedef struct { +typedef struct mbedtls_cipher_context_t +{ /** Information about the associated cipher. */ const mbedtls_cipher_info_t *cipher_info; diff --git a/tools/sdk/include/mbedtls/mbedtls/config.h b/tools/sdk/include/mbedtls/mbedtls/config.h index 70820be5..81438c5b 100644 --- a/tools/sdk/include/mbedtls/mbedtls/config.h +++ b/tools/sdk/include/mbedtls/mbedtls/config.h @@ -137,12 +137,21 @@ /** * \def MBEDTLS_HAVE_TIME_DATE * - * System has time.h and time(), gmtime() and the clock is correct. + * System has time.h, time(), and an implementation for + * mbedtls_platform_gmtime_r() (see below). * The time needs to be correct (not necesarily very accurate, but at least * the date should be correct). This is used to verify the validity period of * X.509 certificates. * * Comment if your system does not have a correct clock. + * + * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that + * behaves similarly to the gmtime_r() function from the C standard. Refer to + * the documentation for mbedtls_platform_gmtime_r() for more information. + * + * \note It is possible to configure an implementation for + * mbedtls_platform_gmtime_r() at compile-time by using the macro + * MBEDTLS_PLATFORM_GMTIME_R_ALT. */ #define MBEDTLS_HAVE_TIME_DATE @@ -3010,6 +3019,23 @@ */ //#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 +/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING + * + * Maximum number of heap-allocated bytes for the purpose of + * DTLS handshake message reassembly and future message buffering. + * + * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN + * to account for a reassembled handshake message of maximum size, + * together with its reassembly bitmap. + * + * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default) + * should be sufficient for all practical situations as it allows + * to reassembly a large handshake message (such as a certificate) + * while buffering multiple smaller handshake messages. + * + */ +//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 + //#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ //#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ //#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ @@ -3083,6 +3109,25 @@ */ //#define MBEDTLS_PLATFORM_ZEROIZE_ALT +/** + * Uncomment the macro to let Mbed TLS use your alternate implementation of + * mbedtls_platform_gmtime_r(). This replaces the default implementation in + * platform_util.c. + * + * gmtime() is not a thread-safe function as defined in the C standard. The + * library will try to use safer implementations of this function, such as + * gmtime_r() when available. However, if Mbed TLS cannot identify the target + * system, the implementation of mbedtls_platform_gmtime_r() will default to + * using the standard gmtime(). In this case, calls from the library to + * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex + * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the + * library are also guarded with this mutex to avoid race conditions. However, + * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will + * unconditionally use the implementation for mbedtls_platform_gmtime_r() + * supplied at compile time. + */ +//#define MBEDTLS_PLATFORM_GMTIME_R_ALT + /* \} name SECTION: Customisation configuration options */ /* Target and application specific configurations */ diff --git a/tools/sdk/include/mbedtls/mbedtls/ctr_drbg.h b/tools/sdk/include/mbedtls/mbedtls/ctr_drbg.h index 3835d729..3a4b7f3f 100644 --- a/tools/sdk/include/mbedtls/mbedtls/ctr_drbg.h +++ b/tools/sdk/include/mbedtls/mbedtls/ctr_drbg.h @@ -108,7 +108,7 @@ extern "C" { /** * \brief The CTR_DRBG context structure. */ -typedef struct +typedef struct mbedtls_ctr_drbg_context { unsigned char counter[16]; /*!< The counter (V). */ int reseed_counter; /*!< The reseed counter. */ diff --git a/tools/sdk/include/mbedtls/mbedtls/des.h b/tools/sdk/include/mbedtls/mbedtls/des.h index 6eb7d03b..91d16b6f 100644 --- a/tools/sdk/include/mbedtls/mbedtls/des.h +++ b/tools/sdk/include/mbedtls/mbedtls/des.h @@ -61,7 +61,7 @@ extern "C" { * security risk. We recommend considering stronger ciphers * instead. */ -typedef struct +typedef struct mbedtls_des_context { uint32_t sk[32]; /*!< DES subkeys */ } @@ -70,7 +70,7 @@ mbedtls_des_context; /** * \brief Triple-DES context structure */ -typedef struct +typedef struct mbedtls_des3_context { uint32_t sk[96]; /*!< 3DES subkeys */ } diff --git a/tools/sdk/include/mbedtls/mbedtls/dhm.h b/tools/sdk/include/mbedtls/mbedtls/dhm.h index 75317a8e..3e117894 100644 --- a/tools/sdk/include/mbedtls/mbedtls/dhm.h +++ b/tools/sdk/include/mbedtls/mbedtls/dhm.h @@ -96,7 +96,7 @@ extern "C" { /** * \brief The DHM context structure. */ -typedef struct +typedef struct mbedtls_dhm_context { size_t len; /*!< The size of \p P in Bytes. */ mbedtls_mpi P; /*!< The prime modulus. */ diff --git a/tools/sdk/include/mbedtls/mbedtls/ecdh.h b/tools/sdk/include/mbedtls/mbedtls/ecdh.h index 5fdf55a8..95f39805 100644 --- a/tools/sdk/include/mbedtls/mbedtls/ecdh.h +++ b/tools/sdk/include/mbedtls/mbedtls/ecdh.h @@ -52,7 +52,7 @@ typedef enum /** * \brief The ECDH context structure. */ -typedef struct +typedef struct mbedtls_ecdh_context { mbedtls_ecp_group grp; /*!< The elliptic curve used. */ mbedtls_mpi d; /*!< The private key. */ diff --git a/tools/sdk/include/mbedtls/mbedtls/ecjpake.h b/tools/sdk/include/mbedtls/mbedtls/ecjpake.h index cc2b316f..59d12f08 100644 --- a/tools/sdk/include/mbedtls/mbedtls/ecjpake.h +++ b/tools/sdk/include/mbedtls/mbedtls/ecjpake.h @@ -68,7 +68,7 @@ typedef enum { * convetion from the Thread v1.0 spec. Correspondance is indicated in the * description as a pair C: client name, S: server name */ -typedef struct +typedef struct mbedtls_ecjpake_context { const mbedtls_md_info_t *md_info; /**< Hash to use */ mbedtls_ecp_group grp; /**< Elliptic curve */ diff --git a/tools/sdk/include/mbedtls/mbedtls/ecp.h b/tools/sdk/include/mbedtls/mbedtls/ecp.h index 3a407986..ed1b9d73 100644 --- a/tools/sdk/include/mbedtls/mbedtls/ecp.h +++ b/tools/sdk/include/mbedtls/mbedtls/ecp.h @@ -92,7 +92,7 @@ typedef enum /** * Curve information, for use by other modules. */ -typedef struct +typedef struct mbedtls_ecp_curve_info { mbedtls_ecp_group_id grp_id; /*!< An internal identifier. */ uint16_t tls_id; /*!< The TLS NamedCurve identifier. */ @@ -111,7 +111,7 @@ typedef struct * Otherwise, \p X and \p Y are its standard (affine) * coordinates. */ -typedef struct +typedef struct mbedtls_ecp_point { mbedtls_mpi X; /*!< The X coordinate of the ECP point. */ mbedtls_mpi Y; /*!< The Y coordinate of the ECP point. */ @@ -156,7 +156,7 @@ mbedtls_ecp_point; * reduction. It must return 0 on success and non-zero on failure. * */ -typedef struct +typedef struct mbedtls_ecp_group { mbedtls_ecp_group_id id; /*!< An internal group identifier. */ mbedtls_mpi P; /*!< The prime modulus of the base field. */ @@ -251,7 +251,7 @@ mbedtls_ecp_group; * \note Members are deliberately in the same order as in the * ::mbedtls_ecdsa_context structure. */ -typedef struct +typedef struct mbedtls_ecp_keypair { mbedtls_ecp_group grp; /*!< Elliptic curve and base point */ mbedtls_mpi d; /*!< our secret value */ diff --git a/tools/sdk/include/mbedtls/mbedtls/entropy.h b/tools/sdk/include/mbedtls/mbedtls/entropy.h index a5cb05a5..ca06dc3c 100644 --- a/tools/sdk/include/mbedtls/mbedtls/entropy.h +++ b/tools/sdk/include/mbedtls/mbedtls/entropy.h @@ -107,7 +107,7 @@ typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, s /** * \brief Entropy source state */ -typedef struct +typedef struct mbedtls_entropy_source_state { mbedtls_entropy_f_source_ptr f_source; /**< The entropy source callback */ void * p_source; /**< The callback data pointer */ @@ -120,7 +120,7 @@ mbedtls_entropy_source_state; /** * \brief Entropy context structure */ -typedef struct +typedef struct mbedtls_entropy_context { int accumulator_started; #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) diff --git a/tools/sdk/include/mbedtls_port/mbedtls/esp_config.h b/tools/sdk/include/mbedtls/mbedtls/esp_config.h similarity index 97% rename from tools/sdk/include/mbedtls_port/mbedtls/esp_config.h rename to tools/sdk/include/mbedtls/mbedtls/esp_config.h index 561ff723..89cdef89 100644 --- a/tools/sdk/include/mbedtls_port/mbedtls/esp_config.h +++ b/tools/sdk/include/mbedtls/mbedtls/esp_config.h @@ -114,8 +114,13 @@ * * Enable this layer to allow use of alternative memory allocators. */ -#ifdef CONFIG_MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_PLATFORM_MEMORY + +/** Override calloc(), free() except for case where memory allocation scheme is not set to custom */ +#ifndef CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC +#include "esp_mem.h" +#define MBEDTLS_PLATFORM_STD_CALLOC esp_mbedtls_mem_calloc +#define MBEDTLS_PLATFORM_STD_FREE esp_mbedtls_mem_free #endif /** @@ -357,6 +362,13 @@ */ #define MBEDTLS_CIPHER_MODE_CTR +/** + * \def MBEDTLS_CIPHER_MODE_XTS + * + * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. + */ +#define MBEDTLS_CIPHER_MODE_XTS + /** * \def MBEDTLS_CIPHER_NULL_CIPHER * @@ -2611,8 +2623,46 @@ //#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ /* SSL options */ +#ifndef CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN #define MBEDTLS_SSL_MAX_CONTENT_LEN CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */ + +#else + +/** \def MBEDTLS_SSL_IN_CONTENT_LEN + * + * Maximum incoming fragment length in bytes. + * + * Uncomment to set the size of the inward TLS buffer independently of the + * outward buffer. + */ +#define MBEDTLS_SSL_IN_CONTENT_LEN CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN + +/** \def MBEDTLS_SSL_OUT_CONTENT_LEN + * + * Maximum outgoing fragment length in bytes. + * + * Uncomment to set the size of the outward TLS buffer independently of the + * inward buffer. + * + * It is possible to save RAM by setting a smaller outward buffer, while keeping + * the default inward 16384 byte buffer to conform to the TLS specification. + * + * The minimum required outward buffer size is determined by the handshake + * protocol's usage. Handshaking will fail if the outward buffer is too small. + * The specific size requirement depends on the configured ciphers and any + * certificate data which is sent during the handshake. + * + * For absolute minimum RAM usage, it's best to enable + * MBEDTLS_SSL_MAX_FRAGMENT_LENGTH and reduce MBEDTLS_SSL_MAX_CONTENT_LEN. This + * reduces both incoming and outgoing buffer sizes. However this is only + * guaranteed if the other end of the connection also supports the TLS + * max_fragment_len extension. Otherwise the connection may fail. + */ +#define MBEDTLS_SSL_OUT_CONTENT_LEN CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN + +#endif /* !CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN */ + //#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ //#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ //#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ diff --git a/tools/sdk/include/mbedtls_port/mbedtls/esp_debug.h b/tools/sdk/include/mbedtls/mbedtls/esp_debug.h similarity index 100% rename from tools/sdk/include/mbedtls_port/mbedtls/esp_debug.h rename to tools/sdk/include/mbedtls/mbedtls/esp_debug.h diff --git a/tools/sdk/include/mbedtls/mbedtls/gcm.h b/tools/sdk/include/mbedtls/mbedtls/gcm.h index 87535ab9..d2098eb9 100644 --- a/tools/sdk/include/mbedtls/mbedtls/gcm.h +++ b/tools/sdk/include/mbedtls/mbedtls/gcm.h @@ -53,7 +53,8 @@ extern "C" { /** * \brief The GCM context structure. */ -typedef struct { +typedef struct mbedtls_gcm_context +{ mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ uint64_t HL[16]; /*!< Precalculated HTable low. */ uint64_t HH[16]; /*!< Precalculated HTable high. */ diff --git a/tools/sdk/include/mbedtls/mbedtls/havege.h b/tools/sdk/include/mbedtls/mbedtls/havege.h index d4cb3ed3..57e8c409 100644 --- a/tools/sdk/include/mbedtls/mbedtls/havege.h +++ b/tools/sdk/include/mbedtls/mbedtls/havege.h @@ -35,7 +35,7 @@ extern "C" { /** * \brief HAVEGE state structure */ -typedef struct +typedef struct mbedtls_havege_state { int PT1, PT2, offset[2]; int pool[MBEDTLS_HAVEGE_COLLECT_SIZE]; diff --git a/tools/sdk/include/mbedtls/mbedtls/hkdf.h b/tools/sdk/include/mbedtls/mbedtls/hkdf.h index 6833e727..e6ed7cde 100644 --- a/tools/sdk/include/mbedtls/mbedtls/hkdf.h +++ b/tools/sdk/include/mbedtls/mbedtls/hkdf.h @@ -73,6 +73,11 @@ int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt, * \brief Take the input keying material \p ikm and extract from it a * fixed-length pseudorandom key \p prk. * + * \warning This function should only be used if the security of it has been + * studied and established in that particular context (eg. TLS 1.3 + * key schedule). For standard HKDF security guarantees use + * \c mbedtls_hkdf instead. + * * \param md A hash function; md.size denotes the length of the * hash function output in bytes. * \param salt An optional salt value (a non-secret random value); @@ -97,10 +102,15 @@ int mbedtls_hkdf_extract( const mbedtls_md_info_t *md, * \brief Expand the supplied \p prk into several additional pseudorandom * keys, which is the output of the HKDF. * + * \warning This function should only be used if the security of it has been + * studied and established in that particular context (eg. TLS 1.3 + * key schedule). For standard HKDF security guarantees use + * \c mbedtls_hkdf instead. + * * \param md A hash function; md.size denotes the length of the hash * function output in bytes. - * \param prk A pseudorandom key of at least md.size bytes. \p prk is usually, - * the output from the HKDF extract step. + * \param prk A pseudorandom key of at least md.size bytes. \p prk is + * usually the output from the HKDF extract step. * \param prk_len The length in bytes of \p prk. * \param info An optional context and application specific information * string. This can be a zero-length string. diff --git a/tools/sdk/include/mbedtls/mbedtls/hmac_drbg.h b/tools/sdk/include/mbedtls/mbedtls/hmac_drbg.h index 2608de85..3bc675ec 100644 --- a/tools/sdk/include/mbedtls/mbedtls/hmac_drbg.h +++ b/tools/sdk/include/mbedtls/mbedtls/hmac_drbg.h @@ -74,7 +74,7 @@ extern "C" { /** * HMAC_DRBG context. */ -typedef struct +typedef struct mbedtls_hmac_drbg_context { /* Working state: the key K is not stored explicitely, * but is implied by the HMAC context */ diff --git a/tools/sdk/include/mbedtls/mbedtls/md.h b/tools/sdk/include/mbedtls/mbedtls/md.h index 6b6f5c53..bf295249 100644 --- a/tools/sdk/include/mbedtls/mbedtls/md.h +++ b/tools/sdk/include/mbedtls/mbedtls/md.h @@ -80,7 +80,8 @@ typedef struct mbedtls_md_info_t mbedtls_md_info_t; /** * The generic message-digest context. */ -typedef struct { +typedef struct mbedtls_md_context_t +{ /** Information about the associated message digest. */ const mbedtls_md_info_t *md_info; diff --git a/tools/sdk/include/mbedtls/mbedtls/md2.h b/tools/sdk/include/mbedtls/mbedtls/md2.h index 08e75b24..a46bddb7 100644 --- a/tools/sdk/include/mbedtls/mbedtls/md2.h +++ b/tools/sdk/include/mbedtls/mbedtls/md2.h @@ -55,7 +55,7 @@ extern "C" { * stronger message digests instead. * */ -typedef struct +typedef struct mbedtls_md2_context { unsigned char cksum[16]; /*!< checksum of the data block */ unsigned char state[48]; /*!< intermediate digest state */ diff --git a/tools/sdk/include/mbedtls/mbedtls/md4.h b/tools/sdk/include/mbedtls/mbedtls/md4.h index 8ee4e5ca..1672e907 100644 --- a/tools/sdk/include/mbedtls/mbedtls/md4.h +++ b/tools/sdk/include/mbedtls/mbedtls/md4.h @@ -56,7 +56,7 @@ extern "C" { * stronger message digests instead. * */ -typedef struct +typedef struct mbedtls_md4_context { uint32_t total[2]; /*!< number of bytes processed */ uint32_t state[4]; /*!< intermediate digest state */ diff --git a/tools/sdk/include/mbedtls/mbedtls/md5.h b/tools/sdk/include/mbedtls/mbedtls/md5.h index 43ead4b7..4c950901 100644 --- a/tools/sdk/include/mbedtls/mbedtls/md5.h +++ b/tools/sdk/include/mbedtls/mbedtls/md5.h @@ -55,7 +55,7 @@ extern "C" { * stronger message digests instead. * */ -typedef struct +typedef struct mbedtls_md5_context { uint32_t total[2]; /*!< number of bytes processed */ uint32_t state[4]; /*!< intermediate digest state */ diff --git a/tools/sdk/include/mbedtls/mbedtls/net_sockets.h b/tools/sdk/include/mbedtls/mbedtls/net_sockets.h index 9f07eeb4..4c7ef00f 100644 --- a/tools/sdk/include/mbedtls/mbedtls/net_sockets.h +++ b/tools/sdk/include/mbedtls/mbedtls/net_sockets.h @@ -84,7 +84,7 @@ extern "C" { * (eg two file descriptors for combined IPv4 + IPv6 support, or additional * structures for hand-made UDP demultiplexing). */ -typedef struct +typedef struct mbedtls_net_context { int fd; /**< The underlying file descriptor */ } diff --git a/tools/sdk/include/mbedtls/mbedtls/oid.h b/tools/sdk/include/mbedtls/mbedtls/oid.h index f8255484..6fbd018a 100644 --- a/tools/sdk/include/mbedtls/mbedtls/oid.h +++ b/tools/sdk/include/mbedtls/mbedtls/oid.h @@ -403,7 +403,8 @@ extern "C" { /** * \brief Base OID descriptor structure */ -typedef struct { +typedef struct mbedtls_oid_descriptor_t +{ const char *asn1; /*!< OID ASN.1 representation */ size_t asn1_len; /*!< length of asn1 */ const char *name; /*!< official name (e.g. from RFC) */ diff --git a/tools/sdk/include/mbedtls/mbedtls/pem.h b/tools/sdk/include/mbedtls/mbedtls/pem.h index 2cf4c0a7..fa82f7bd 100644 --- a/tools/sdk/include/mbedtls/mbedtls/pem.h +++ b/tools/sdk/include/mbedtls/mbedtls/pem.h @@ -51,7 +51,7 @@ extern "C" { /** * \brief PEM context structure */ -typedef struct +typedef struct mbedtls_pem_context { unsigned char *buf; /*!< buffer for decoded data */ size_t buflen; /*!< length of the buffer */ diff --git a/tools/sdk/include/mbedtls/mbedtls/pk.h b/tools/sdk/include/mbedtls/mbedtls/pk.h index ee06b2fd..db54c6a6 100644 --- a/tools/sdk/include/mbedtls/mbedtls/pk.h +++ b/tools/sdk/include/mbedtls/mbedtls/pk.h @@ -87,7 +87,7 @@ typedef enum { * \brief Options for RSASSA-PSS signature verification. * See \c mbedtls_rsa_rsassa_pss_verify_ext() */ -typedef struct +typedef struct mbedtls_pk_rsassa_pss_options { mbedtls_md_type_t mgf1_hash_id; int expected_salt_len; @@ -107,7 +107,7 @@ typedef enum /** * \brief Item to send to the debug module */ -typedef struct +typedef struct mbedtls_pk_debug_item { mbedtls_pk_debug_type type; const char *name; @@ -125,7 +125,7 @@ typedef struct mbedtls_pk_info_t mbedtls_pk_info_t; /** * \brief Public key container */ -typedef struct +typedef struct mbedtls_pk_context { const mbedtls_pk_info_t * pk_info; /**< Public key informations */ void * pk_ctx; /**< Underlying public key context */ diff --git a/tools/sdk/include/mbedtls/mbedtls/pkcs11.h b/tools/sdk/include/mbedtls/mbedtls/pkcs11.h index bf65c55a..02427ddc 100644 --- a/tools/sdk/include/mbedtls/mbedtls/pkcs11.h +++ b/tools/sdk/include/mbedtls/mbedtls/pkcs11.h @@ -50,7 +50,8 @@ extern "C" { /** * Context for PKCS #11 private keys. */ -typedef struct { +typedef struct mbedtls_pkcs11_context +{ pkcs11h_certificate_t pkcs11h_cert; int len; } mbedtls_pkcs11_context; diff --git a/tools/sdk/include/mbedtls/mbedtls/platform.h b/tools/sdk/include/mbedtls/mbedtls/platform.h index 624cc642..a40a64f9 100644 --- a/tools/sdk/include/mbedtls/mbedtls/platform.h +++ b/tools/sdk/include/mbedtls/mbedtls/platform.h @@ -315,7 +315,8 @@ int mbedtls_platform_set_nv_seed( * \note This structure may be used to assist platform-specific * setup or teardown operations. */ -typedef struct { +typedef struct mbedtls_platform_context +{ char dummy; /**< A placeholder member, as empty structs are not portable. */ } mbedtls_platform_context; diff --git a/tools/sdk/include/mbedtls/mbedtls/platform_util.h b/tools/sdk/include/mbedtls/mbedtls/platform_util.h index 84f0732e..164a1a05 100644 --- a/tools/sdk/include/mbedtls/mbedtls/platform_util.h +++ b/tools/sdk/include/mbedtls/mbedtls/platform_util.h @@ -25,7 +25,17 @@ #ifndef MBEDTLS_PLATFORM_UTIL_H #define MBEDTLS_PLATFORM_UTIL_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include +#if defined(MBEDTLS_HAVE_TIME_DATE) +#include "mbedtls/platform_time.h" +#include +#endif /* MBEDTLS_HAVE_TIME_DATE */ #ifdef __cplusplus extern "C" { @@ -55,6 +65,37 @@ extern "C" { */ void mbedtls_platform_zeroize( void *buf, size_t len ); +#if defined(MBEDTLS_HAVE_TIME_DATE) +/** + * \brief Platform-specific implementation of gmtime_r() + * + * The function is a thread-safe abstraction that behaves + * similarly to the gmtime_r() function from Unix/POSIX. + * + * Mbed TLS will try to identify the underlying platform and + * make use of an appropriate underlying implementation (e.g. + * gmtime_r() for POSIX and gmtime_s() for Windows). If this is + * not possible, then gmtime() will be used. In this case, calls + * from the library to gmtime() will be guarded by the mutex + * mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is + * enabled. It is recommended that calls from outside the library + * are also guarded by this mutex. + * + * If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will + * unconditionally use the alternative implementation for + * mbedtls_platform_gmtime_r() supplied by the user at compile time. + * + * \param tt Pointer to an object containing time (in seconds) since the + * epoch to be converted + * \param tm_buf Pointer to an object where the results will be stored + * + * \return Pointer to an object of type struct tm on success, otherwise + * NULL + */ +struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, + struct tm *tm_buf ); +#endif /* MBEDTLS_HAVE_TIME_DATE */ + #ifdef __cplusplus } #endif diff --git a/tools/sdk/include/mbedtls/mbedtls/poly1305.h b/tools/sdk/include/mbedtls/mbedtls/poly1305.h index 54b50abc..c490cdf2 100644 --- a/tools/sdk/include/mbedtls/mbedtls/poly1305.h +++ b/tools/sdk/include/mbedtls/mbedtls/poly1305.h @@ -52,7 +52,7 @@ extern "C" { #if !defined(MBEDTLS_POLY1305_ALT) -typedef struct +typedef struct mbedtls_poly1305_context { uint32_t r[4]; /** The value for 'r' (low 128 bits of the key). */ uint32_t s[4]; /** The value for 's' (high 128 bits of the key). */ diff --git a/tools/sdk/include/mbedtls/mbedtls/ripemd160.h b/tools/sdk/include/mbedtls/mbedtls/ripemd160.h index a0dac0c3..0c8e568b 100644 --- a/tools/sdk/include/mbedtls/mbedtls/ripemd160.h +++ b/tools/sdk/include/mbedtls/mbedtls/ripemd160.h @@ -46,7 +46,7 @@ extern "C" { /** * \brief RIPEMD-160 context structure */ -typedef struct +typedef struct mbedtls_ripemd160_context { uint32_t total[2]; /*!< number of bytes processed */ uint32_t state[5]; /*!< intermediate digest state */ diff --git a/tools/sdk/include/mbedtls/mbedtls/rsa.h b/tools/sdk/include/mbedtls/mbedtls/rsa.h index 19eb2ee7..6eea5af2 100644 --- a/tools/sdk/include/mbedtls/mbedtls/rsa.h +++ b/tools/sdk/include/mbedtls/mbedtls/rsa.h @@ -92,7 +92,7 @@ extern "C" { * is deprecated. All manipulation should instead be done through * the public interface functions. */ -typedef struct +typedef struct mbedtls_rsa_context { int ver; /*!< Always 0.*/ size_t len; /*!< The size of \p N in Bytes. */ diff --git a/tools/sdk/include/mbedtls/mbedtls/sha1.h b/tools/sdk/include/mbedtls/mbedtls/sha1.h index 65a124c9..7a19da0a 100644 --- a/tools/sdk/include/mbedtls/mbedtls/sha1.h +++ b/tools/sdk/include/mbedtls/mbedtls/sha1.h @@ -58,7 +58,7 @@ extern "C" { * stronger message digests instead. * */ -typedef struct +typedef struct mbedtls_sha1_context { uint32_t total[2]; /*!< The number of Bytes processed. */ uint32_t state[5]; /*!< The intermediate digest state. */ diff --git a/tools/sdk/include/mbedtls/mbedtls/sha256.h b/tools/sdk/include/mbedtls/mbedtls/sha256.h index adf31a82..33aff283 100644 --- a/tools/sdk/include/mbedtls/mbedtls/sha256.h +++ b/tools/sdk/include/mbedtls/mbedtls/sha256.h @@ -53,7 +53,7 @@ extern "C" { * checksum calculations. The choice between these two is * made in the call to mbedtls_sha256_starts_ret(). */ -typedef struct +typedef struct mbedtls_sha256_context { uint32_t total[2]; /*!< The number of Bytes processed. */ uint32_t state[8]; /*!< The intermediate digest state. */ diff --git a/tools/sdk/include/mbedtls/mbedtls/sha512.h b/tools/sdk/include/mbedtls/mbedtls/sha512.h index 5bb83f43..01458904 100644 --- a/tools/sdk/include/mbedtls/mbedtls/sha512.h +++ b/tools/sdk/include/mbedtls/mbedtls/sha512.h @@ -52,7 +52,7 @@ extern "C" { * checksum calculations. The choice between these two is * made in the call to mbedtls_sha512_starts_ret(). */ -typedef struct +typedef struct mbedtls_sha512_context { uint64_t total[2]; /*!< The number of Bytes processed. */ uint64_t state[8]; /*!< The intermediate digest state. */ diff --git a/tools/sdk/include/mbedtls/mbedtls/ssl.h b/tools/sdk/include/mbedtls/mbedtls/ssl.h index 2d511a8e..83849a56 100644 --- a/tools/sdk/include/mbedtls/mbedtls/ssl.h +++ b/tools/sdk/include/mbedtls/mbedtls/ssl.h @@ -121,6 +121,7 @@ #define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH -0x6600 /**< Couldn't set the hash for verifying CertificateVerify */ #define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING -0x6580 /**< Internal-only message signaling that further message-processing should be done */ #define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 /**< The asynchronous operation is not completed yet. */ +#define MBEDTLS_ERR_SSL_EARLY_MESSAGE -0x6480 /**< Internal-only message signaling that a message arrived early. */ /* * Various constants @@ -242,6 +243,14 @@ #define MBEDTLS_SSL_OUT_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN #endif +/* + * Maximum number of heap-allocated bytes for the purpose of + * DTLS handshake message reassembly and future message buffering. + */ +#if !defined(MBEDTLS_SSL_DTLS_MAX_BUFFERING) +#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 +#endif + /* \} name SECTION: Module settings */ /* @@ -1022,14 +1031,14 @@ struct mbedtls_ssl_context int renego_records_seen; /*!< Records since renego request, or with DTLS, number of retransmissions of request if renego_max_records is < 0 */ -#endif +#endif /* MBEDTLS_SSL_RENEGOTIATION */ int major_ver; /*!< equal to MBEDTLS_SSL_MAJOR_VERSION_3 */ int minor_ver; /*!< either 0 (SSL3) or 1 (TLS1.0) */ #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) unsigned badmac_seen; /*!< records with a bad MAC received */ -#endif +#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ mbedtls_ssl_send_t *f_send; /*!< Callback for network send */ mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */ @@ -1085,11 +1094,11 @@ struct mbedtls_ssl_context uint16_t in_epoch; /*!< DTLS epoch for incoming records */ size_t next_record_offset; /*!< offset of the next record in datagram (equal to in_left if none) */ -#endif +#endif /* MBEDTLS_SSL_PROTO_DTLS */ #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) uint64_t in_window_top; /*!< last validated record seq_num */ uint64_t in_window; /*!< bitmask for replay detection */ -#endif +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ size_t in_hslen; /*!< current handshake message length, including the handshake header */ @@ -1098,6 +1107,11 @@ struct mbedtls_ssl_context int keep_current_message; /*!< drop or reuse current message on next call to record layer? */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + uint8_t disable_datagram_packing; /*!< Disable packing multiple records + * within a single datagram. */ +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + /* * Record layer (outgoing data) */ @@ -1112,12 +1126,18 @@ struct mbedtls_ssl_context size_t out_msglen; /*!< record header: message length */ size_t out_left; /*!< amount of data not yet written */ + unsigned char cur_out_ctr[8]; /*!< Outgoing record sequence number. */ + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + uint16_t mtu; /*!< path mtu, used to fragment outgoing messages */ +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + #if defined(MBEDTLS_ZLIB_SUPPORT) unsigned char *compress_buf; /*!< zlib data buffer */ -#endif +#endif /* MBEDTLS_ZLIB_SUPPORT */ #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) signed char split_done; /*!< current record already splitted? */ -#endif +#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ /* * PKI layer @@ -1130,11 +1150,11 @@ struct mbedtls_ssl_context #if defined(MBEDTLS_X509_CRT_PARSE_C) char *hostname; /*!< expected peer CN for verification (and SNI if available) */ -#endif +#endif /* MBEDTLS_X509_CRT_PARSE_C */ #if defined(MBEDTLS_SSL_ALPN) const char *alpn_chosen; /*!< negotiated protocol */ -#endif +#endif /* MBEDTLS_SSL_ALPN */ /* * Information for DTLS hello verify @@ -1142,7 +1162,7 @@ struct mbedtls_ssl_context #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) unsigned char *cli_id; /*!< transport-level ID of the client */ size_t cli_id_len; /*!< length of cli_id */ -#endif +#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ /* * Secure renegotiation @@ -1154,7 +1174,7 @@ struct mbedtls_ssl_context size_t verify_data_len; /*!< length of verify data stored */ char own_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ char peer_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ -#endif +#endif /* MBEDTLS_SSL_RENEGOTIATION */ }; #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) @@ -1374,6 +1394,52 @@ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, mbedtls_ssl_recv_t *f_recv, mbedtls_ssl_recv_timeout_t *f_recv_timeout ); +#if defined(MBEDTLS_SSL_PROTO_DTLS) +/** + * \brief Set the Maximum Tranport Unit (MTU). + * Special value: 0 means unset (no limit). + * This represents the maximum size of a datagram payload + * handled by the transport layer (usually UDP) as determined + * by the network link and stack. In practice, this controls + * the maximum size datagram the DTLS layer will pass to the + * \c f_send() callback set using \c mbedtls_ssl_set_bio(). + * + * \note The limit on datagram size is converted to a limit on + * record payload by subtracting the current overhead of + * encapsulation and encryption/authentication if any. + * + * \note This can be called at any point during the connection, for + * example when a Path Maximum Transfer Unit (PMTU) + * estimate becomes available from other sources, + * such as lower (or higher) protocol layers. + * + * \note This setting only controls the size of the packets we send, + * and does not restrict the size of the datagrams we're + * willing to receive. Client-side, you can request the + * server to use smaller records with \c + * mbedtls_ssl_conf_max_frag_len(). + * + * \note If both a MTU and a maximum fragment length have been + * configured (or negotiated with the peer), the resulting + * lower limit on record payload (see first note) is used. + * + * \note This can only be used to decrease the maximum size + * of datagrams (hence records, see first note) sent. It + * cannot be used to increase the maximum size of records over + * the limit set by #MBEDTLS_SSL_OUT_CONTENT_LEN. + * + * \note Values lower than the current record layer expansion will + * result in an error when trying to send data. + * + * \note Using record compression together with a non-zero MTU value + * will result in an error when trying to send data. + * + * \param ssl SSL context + * \param mtu Value of the path MTU in bytes + */ +void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ); +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + /** * \brief Set the timeout period for mbedtls_ssl_read() * (Default: no timeout.) @@ -1757,6 +1823,38 @@ void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limi #endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ #if defined(MBEDTLS_SSL_PROTO_DTLS) + +/** + * \brief Allow or disallow packing of multiple handshake records + * within a single datagram. + * + * \param ssl The SSL context to configure. + * \param allow_packing This determines whether datagram packing may + * be used or not. A value of \c 0 means that every + * record will be sent in a separate datagram; a + * value of \c 1 means that, if space permits, + * multiple handshake messages (including CCS) belonging to + * a single flight may be packed within a single datagram. + * + * \note This is enabled by default and should only be disabled + * for test purposes, or if datagram packing causes + * interoperability issues with peers that don't support it. + * + * \note Allowing datagram packing reduces the network load since + * there's less overhead if multiple messages share the same + * datagram. Also, it increases the handshake efficiency + * since messages belonging to a single datagram will not + * be reordered in transit, and so future message buffering + * or flight retransmission (if no buffering is used) as + * means to deal with reordering are needed less frequently. + * + * \note Application records are not affected by this option and + * are currently always sent in separate datagrams. + * + */ +void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl, + unsigned allow_packing ); + /** * \brief Set retransmit timeout values for the DTLS handshake. * (DTLS only, no effect on TLS.) @@ -2433,6 +2531,18 @@ void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, * (Client: set maximum fragment length to emit *and* * negotiate with the server during handshake) * + * \note With TLS, this currently only affects ApplicationData (sent + * with \c mbedtls_ssl_read()), not handshake messages. + * With DTLS, this affects both ApplicationData and handshake. + * + * \note This sets the maximum length for a record's payload, + * excluding record overhead that will be added to it, see + * \c mbedtls_ssl_get_record_expansion(). + * + * \note For DTLS, it is also possible to set a limit for the total + * size of daragrams passed to the transport layer, including + * record overhead, see \c mbedtls_ssl_set_mtu(). + * * \param conf SSL configuration * \param mfl_code Code for maximum fragment length (allowed values: * MBEDTLS_SSL_MAX_FRAG_LEN_512, MBEDTLS_SSL_MAX_FRAG_LEN_1024, @@ -2695,6 +2805,9 @@ const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl ); * \brief Return the (maximum) number of bytes added by the record * layer: header + encryption/MAC overhead (inc. padding) * + * \note This function is not available (always returns an error) + * when record compression is enabled. + * * \param ssl SSL context * * \return Current maximum record expansion in bytes, or @@ -2709,12 +2822,8 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ); * This is the value negotiated with peer if any, * or the locally configured value. * - * \note With DTLS, \c mbedtls_ssl_write() will return an error if - * called with a larger length value. - * With TLS, \c mbedtls_ssl_write() will fragment the input if - * necessary and return the number of bytes written; it is up - * to the caller to call \c mbedtls_ssl_write() again in - * order to send the remaining bytes if any. + * \sa mbedtls_ssl_conf_max_frag_len() + * \sa mbedtls_ssl_get_max_record_payload() * * \param ssl SSL context * @@ -2723,6 +2832,34 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ); size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl ); #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ +/** + * \brief Return the current maximum outgoing record payload in bytes. + * This takes into account the config.h setting \c + * MBEDTLS_SSL_OUT_CONTENT_LEN, the configured and negotiated + * max fragment length extension if used, and for DTLS the + * path MTU as configured and current record expansion. + * + * \note With DTLS, \c mbedtls_ssl_write() will return an error if + * called with a larger length value. + * With TLS, \c mbedtls_ssl_write() will fragment the input if + * necessary and return the number of bytes written; it is up + * to the caller to call \c mbedtls_ssl_write() again in + * order to send the remaining bytes if any. + * + * \note This function is not available (always returns an error) + * when record compression is enabled. + * + * \sa mbedtls_ssl_set_mtu() + * \sa mbedtls_ssl_get_max_frag_len() + * \sa mbedtls_ssl_get_record_expansion() + * + * \param ssl SSL context + * + * \return Current maximum payload for an outgoing record, + * or a negative error code. + */ +int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl ); + #if defined(MBEDTLS_X509_CRT_PARSE_C) /** * \brief Return the peer certificate from the current connection diff --git a/tools/sdk/include/mbedtls/mbedtls/ssl_cookie.h b/tools/sdk/include/mbedtls/mbedtls/ssl_cookie.h index 80b65bbb..6a0ad4fa 100644 --- a/tools/sdk/include/mbedtls/mbedtls/ssl_cookie.h +++ b/tools/sdk/include/mbedtls/mbedtls/ssl_cookie.h @@ -50,7 +50,7 @@ extern "C" { /** * \brief Context for the default cookie functions. */ -typedef struct +typedef struct mbedtls_ssl_cookie_ctx { mbedtls_md_context_t hmac_ctx; /*!< context for the HMAC portion */ #if !defined(MBEDTLS_HAVE_TIME) diff --git a/tools/sdk/include/mbedtls/mbedtls/ssl_internal.h b/tools/sdk/include/mbedtls/mbedtls/ssl_internal.h index d214703d..4b4417a5 100644 --- a/tools/sdk/include/mbedtls/mbedtls/ssl_internal.h +++ b/tools/sdk/include/mbedtls/mbedtls/ssl_internal.h @@ -155,6 +155,9 @@ #define MBEDTLS_SSL_OUT_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \ ( MBEDTLS_SSL_OUT_CONTENT_LEN ) ) +/* The maximum number of buffered handshake messages. */ +#define MBEDTLS_SSL_MAX_BUFFERED_HS 4 + /* Maximum length we can advertise as our max content length for RFC 6066 max_fragment_length extension negotiation purposes (the lesser of both sizes, if they are unequal.) @@ -294,18 +297,45 @@ struct mbedtls_ssl_handshake_params unsigned char verify_cookie_len; /*!< Cli: cookie length Srv: flag for sending a cookie */ - unsigned char *hs_msg; /*!< Reassembled handshake message */ - uint32_t retransmit_timeout; /*!< Current value of timeout */ unsigned char retransmit_state; /*!< Retransmission state */ - mbedtls_ssl_flight_item *flight; /*!< Current outgoing flight */ - mbedtls_ssl_flight_item *cur_msg; /*!< Current message in flight */ + mbedtls_ssl_flight_item *flight; /*!< Current outgoing flight */ + mbedtls_ssl_flight_item *cur_msg; /*!< Current message in flight */ + unsigned char *cur_msg_p; /*!< Position in current message */ unsigned int in_flight_start_seq; /*!< Minimum message sequence in the flight being received */ mbedtls_ssl_transform *alt_transform_out; /*!< Alternative transform for resending messages */ unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter for resending messages */ + + struct + { + size_t total_bytes_buffered; /*!< Cumulative size of heap allocated + * buffers used for message buffering. */ + + uint8_t seen_ccs; /*!< Indicates if a CCS message has + * been seen in the current flight. */ + + struct mbedtls_ssl_hs_buffer + { + unsigned is_valid : 1; + unsigned is_fragmented : 1; + unsigned is_complete : 1; + unsigned char *data; + size_t data_len; + } hs[MBEDTLS_SSL_MAX_BUFFERED_HS]; + + struct + { + unsigned char *data; + size_t len; + unsigned epoch; + } future_record; + + } buffering; + + uint16_t mtu; /*!< Handshake mtu, used to fragment outgoing messages */ #endif /* MBEDTLS_SSL_PROTO_DTLS */ /* @@ -364,6 +394,8 @@ struct mbedtls_ssl_handshake_params #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ }; +typedef struct mbedtls_ssl_hs_buffer mbedtls_ssl_hs_buffer; + /* * This structure contains a full set of runtime transform parameters * either in negotiation or active. @@ -478,7 +510,6 @@ int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ); void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ); int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_read_record_layer( mbedtls_ssl_context *ssl ); int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ); int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ); void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ); @@ -490,7 +521,10 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ); * of the logic of (D)TLS from the implementation * of the secure transport. * - * \param ssl SSL context to use + * \param ssl The SSL context to use. + * \param update_hs_digest This indicates if the handshake digest + * should be automatically updated in case + * a handshake message is found. * * \return 0 or non-zero error code. * @@ -556,10 +590,12 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ); * following the above definition. * */ -int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, + unsigned update_hs_digest ); int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ); -int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ); int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ); int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ); @@ -668,6 +704,7 @@ static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl ) void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ); void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl ); int mbedtls_ssl_resend( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ); #endif /* Visible for testing purposes only */ diff --git a/tools/sdk/include/mbedtls/mbedtls/ssl_ticket.h b/tools/sdk/include/mbedtls/mbedtls/ssl_ticket.h index 93ad46ac..b2686df0 100644 --- a/tools/sdk/include/mbedtls/mbedtls/ssl_ticket.h +++ b/tools/sdk/include/mbedtls/mbedtls/ssl_ticket.h @@ -44,7 +44,7 @@ extern "C" { /** * \brief Information for session ticket protection */ -typedef struct +typedef struct mbedtls_ssl_ticket_key { unsigned char name[4]; /*!< random key identifier */ uint32_t generation_time; /*!< key generation timestamp (seconds) */ @@ -55,7 +55,7 @@ mbedtls_ssl_ticket_key; /** * \brief Context for session ticket handling functions */ -typedef struct +typedef struct mbedtls_ssl_ticket_context { mbedtls_ssl_ticket_key keys[2]; /*!< ticket protection keys */ unsigned char active; /*!< index of the currently active key */ diff --git a/tools/sdk/include/mbedtls/mbedtls/threading.h b/tools/sdk/include/mbedtls/mbedtls/threading.h index c25daa5c..75298bf8 100644 --- a/tools/sdk/include/mbedtls/mbedtls/threading.h +++ b/tools/sdk/include/mbedtls/mbedtls/threading.h @@ -42,7 +42,7 @@ extern "C" { #if defined(MBEDTLS_THREADING_PTHREAD) #include -typedef struct +typedef struct mbedtls_threading_mutex_t { pthread_mutex_t mutex; char is_valid; @@ -99,6 +99,17 @@ extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex ); #if defined(MBEDTLS_FS_IO) extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex; #endif + +#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) +/* This mutex may or may not be used in the default definition of + * mbedtls_platform_gmtime_r(), but in order to determine that, + * we need to check POSIX features, hence modify _POSIX_C_SOURCE. + * With the current approach, this declaration is orphaned, lacking + * an accompanying definition, in case mbedtls_platform_gmtime_r() + * doesn't need it, but that's not a problem. */ +extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex; +#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ + #endif /* MBEDTLS_THREADING_C */ #ifdef __cplusplus diff --git a/tools/sdk/include/mbedtls/mbedtls/timing.h b/tools/sdk/include/mbedtls/mbedtls/timing.h index bbcb9068..a965fe0d 100644 --- a/tools/sdk/include/mbedtls/mbedtls/timing.h +++ b/tools/sdk/include/mbedtls/mbedtls/timing.h @@ -51,7 +51,7 @@ struct mbedtls_timing_hr_time /** * \brief Context for mbedtls_timing_set/get_delay() */ -typedef struct +typedef struct mbedtls_timing_delay_context { struct mbedtls_timing_hr_time timer; uint32_t int_ms; diff --git a/tools/sdk/include/mbedtls/mbedtls/version.h b/tools/sdk/include/mbedtls/mbedtls/version.h index eaf25d90..326b8bd4 100644 --- a/tools/sdk/include/mbedtls/mbedtls/version.h +++ b/tools/sdk/include/mbedtls/mbedtls/version.h @@ -39,17 +39,17 @@ * Major, Minor, Patchlevel */ #define MBEDTLS_VERSION_MAJOR 2 -#define MBEDTLS_VERSION_MINOR 12 -#define MBEDTLS_VERSION_PATCH 0 +#define MBEDTLS_VERSION_MINOR 13 +#define MBEDTLS_VERSION_PATCH 1 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x020C0000 -#define MBEDTLS_VERSION_STRING "2.12.0" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.12.0" +#define MBEDTLS_VERSION_NUMBER 0x020D0100 +#define MBEDTLS_VERSION_STRING "2.13.1" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.13.1" #if defined(MBEDTLS_VERSION_C) diff --git a/tools/sdk/include/mbedtls/mbedtls/x509_crt.h b/tools/sdk/include/mbedtls/mbedtls/x509_crt.h index ac23cffe..d41ec93a 100644 --- a/tools/sdk/include/mbedtls/mbedtls/x509_crt.h +++ b/tools/sdk/include/mbedtls/mbedtls/x509_crt.h @@ -105,7 +105,7 @@ mbedtls_x509_crt; * * All lists are bitfields, built by ORing flags from MBEDTLS_X509_ID_FLAG(). */ -typedef struct +typedef struct mbedtls_x509_crt_profile { uint32_t allowed_mds; /**< MDs for signatures */ uint32_t allowed_pks; /**< PK algs for signatures */ diff --git a/tools/sdk/include/mbedtls/mbedtls/xtea.h b/tools/sdk/include/mbedtls/mbedtls/xtea.h index 8df708a3..c70c3fe2 100644 --- a/tools/sdk/include/mbedtls/mbedtls/xtea.h +++ b/tools/sdk/include/mbedtls/mbedtls/xtea.h @@ -50,7 +50,7 @@ extern "C" { /** * \brief XTEA context structure */ -typedef struct +typedef struct mbedtls_xtea_context { uint32_t k[4]; /*!< key */ } diff --git a/tools/sdk/include/mbedtls_port/sha1_alt.h b/tools/sdk/include/mbedtls/sha1_alt.h similarity index 100% rename from tools/sdk/include/mbedtls_port/sha1_alt.h rename to tools/sdk/include/mbedtls/sha1_alt.h diff --git a/tools/sdk/include/mbedtls_port/sha256_alt.h b/tools/sdk/include/mbedtls/sha256_alt.h similarity index 100% rename from tools/sdk/include/mbedtls_port/sha256_alt.h rename to tools/sdk/include/mbedtls/sha256_alt.h diff --git a/tools/sdk/include/mbedtls_port/sha512_alt.h b/tools/sdk/include/mbedtls/sha512_alt.h similarity index 100% rename from tools/sdk/include/mbedtls_port/sha512_alt.h rename to tools/sdk/include/mbedtls/sha512_alt.h diff --git a/tools/sdk/include/mbedtls_port/mbedtls/bignum.h b/tools/sdk/include/mbedtls_port/mbedtls/bignum.h deleted file mode 100644 index 23cd5634..00000000 --- a/tools/sdk/include/mbedtls_port/mbedtls/bignum.h +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#ifndef __ESP_MBEDTLS_BIGNUM_H__ -#define __ESP_MBEDTLS_BIGNUM_H__ - -#include_next "mbedtls/bignum.h" - -/** - * This is a wrapper for the main mbedtls/bignum.h. This wrapper - * provides a few additional ESP32-only functions. - * - * This is because we don't set MBEDTLS_BIGNUM_ALT in the same way we - * do for AES, SHA, etc. Because we still use most of the bignum.h - * implementation and just replace a few hardware accelerated - * functions (see MBEDTLS_MPI_EXP_MOD_ALT & MBEDTLS_MPI_MUL_MPI_ALT in - * esp_config.h). - * - * @note Unlike the other hardware accelerator support functions in esp32/hwcrypto, there is no - * generic "hwcrypto/bignum.h" header for using these functions without mbedTLS. The reason for this - * is that all of the function implementations depend strongly upon the mbedTLS MPI implementation. - */ - -/** - * @brief Lock access to RSA Accelerator (MPI/bignum operations) - * - * RSA Accelerator hardware unit can only be used by one - * consumer at a time. - * - * @note This function is non-recursive (do not call it twice from the - * same task.) - * - * @note You do not need to call this if you are using the mbedTLS bignum.h - * API or esp_mpi_xxx functions. This function is only needed if you - * want to call ROM RSA functions or access the registers directly. - * - */ -void esp_mpi_acquire_hardware(void); - -/** - * @brief Unlock access to RSA Accelerator (MPI/bignum operations) - * - * Has to be called once for each call to esp_mpi_acquire_hardware(). - * - * @note You do not need to call this if you are using the mbedTLS bignum.h - * API or esp_mpi_xxx functions. This function is only needed if you - * want to call ROM RSA functions or access the registers directly. - */ -void esp_mpi_release_hardware(void); - -/* @brief MPI modular mupltiplication function - * - * Calculates Z = (X * Y) mod M using MPI hardware acceleration. - * - * This is not part of the standard mbedTLS bignum API. - * - * @note All of X, Y & Z should be less than 4096 bit long or an error is returned. - * - * @param Z Result bignum, should be pre-initialised with mbedtls_mpi_init(). - * @param X First multiplication argument. - * @param Y Second multiplication argument. - * @param M Modulus value for result. - * - * @return 0 on success, mbedTLS MPI error codes on failure. - */ -int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M); - -#endif diff --git a/tools/sdk/include/mbedtls_port/mbedtls/config.h b/tools/sdk/include/mbedtls_port/mbedtls/config.h deleted file mode 100644 index cf3d904d..00000000 --- a/tools/sdk/include/mbedtls_port/mbedtls/config.h +++ /dev/null @@ -1,9 +0,0 @@ -/* This shim header is added so that any application code - which includes "mbedtls/config.h" directly gets the correct - config. */ -#pragma once -#if !defined(MBEDTLS_CONFIG_FILE) -#include_next "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif diff --git a/tools/sdk/include/micro-ecc/types.h b/tools/sdk/include/micro-ecc/types.h new file mode 100644 index 00000000..9ee81438 --- /dev/null +++ b/tools/sdk/include/micro-ecc/types.h @@ -0,0 +1,108 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_TYPES_H_ +#define _UECC_TYPES_H_ + +#ifndef uECC_PLATFORM + #if __AVR__ + #define uECC_PLATFORM uECC_avr + #elif defined(__thumb2__) || defined(_M_ARMT) /* I think MSVC only supports Thumb-2 targets */ + #define uECC_PLATFORM uECC_arm_thumb2 + #elif defined(__thumb__) + #define uECC_PLATFORM uECC_arm_thumb + #elif defined(__arm__) || defined(_M_ARM) + #define uECC_PLATFORM uECC_arm + #elif defined(__aarch64__) + #define uECC_PLATFORM uECC_arm64 + #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__I86__) + #define uECC_PLATFORM uECC_x86 + #elif defined(__amd64__) || defined(_M_X64) + #define uECC_PLATFORM uECC_x86_64 + #else + #define uECC_PLATFORM uECC_arch_other + #endif +#endif + +#ifndef uECC_ARM_USE_UMAAL + #if (uECC_PLATFORM == uECC_arm) && (__ARM_ARCH >= 6) + #define uECC_ARM_USE_UMAAL 1 + #elif (uECC_PLATFORM == uECC_arm_thumb2) && (__ARM_ARCH >= 6) && !__ARM_ARCH_7M__ + #define uECC_ARM_USE_UMAAL 1 + #else + #define uECC_ARM_USE_UMAAL 0 + #endif +#endif + +#ifndef uECC_WORD_SIZE + #if uECC_PLATFORM == uECC_avr + #define uECC_WORD_SIZE 1 + #elif (uECC_PLATFORM == uECC_x86_64 || uECC_PLATFORM == uECC_arm64) + #define uECC_WORD_SIZE 8 + #else + #define uECC_WORD_SIZE 4 + #endif +#endif + +#if (uECC_WORD_SIZE != 1) && (uECC_WORD_SIZE != 4) && (uECC_WORD_SIZE != 8) + #error "Unsupported value for uECC_WORD_SIZE" +#endif + +#if ((uECC_PLATFORM == uECC_avr) && (uECC_WORD_SIZE != 1)) + #pragma message ("uECC_WORD_SIZE must be 1 for AVR") + #undef uECC_WORD_SIZE + #define uECC_WORD_SIZE 1 +#endif + +#if ((uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \ + uECC_PLATFORM == uECC_arm_thumb2) && \ + (uECC_WORD_SIZE != 4)) + #pragma message ("uECC_WORD_SIZE must be 4 for ARM") + #undef uECC_WORD_SIZE + #define uECC_WORD_SIZE 4 +#endif + +#if defined(__SIZEOF_INT128__) || ((__clang_major__ * 100 + __clang_minor__) >= 302) + #define SUPPORTS_INT128 1 +#else + #define SUPPORTS_INT128 0 +#endif + +typedef int8_t wordcount_t; +typedef int16_t bitcount_t; +typedef int8_t cmpresult_t; + +#if (uECC_WORD_SIZE == 1) + +typedef uint8_t uECC_word_t; +typedef uint16_t uECC_dword_t; + +#define HIGH_BIT_SET 0x80 +#define uECC_WORD_BITS 8 +#define uECC_WORD_BITS_SHIFT 3 +#define uECC_WORD_BITS_MASK 0x07 + +#elif (uECC_WORD_SIZE == 4) + +typedef uint32_t uECC_word_t; +typedef uint64_t uECC_dword_t; + +#define HIGH_BIT_SET 0x80000000 +#define uECC_WORD_BITS 32 +#define uECC_WORD_BITS_SHIFT 5 +#define uECC_WORD_BITS_MASK 0x01F + +#elif (uECC_WORD_SIZE == 8) + +typedef uint64_t uECC_word_t; +#if SUPPORTS_INT128 +typedef unsigned __int128 uECC_dword_t; +#endif + +#define HIGH_BIT_SET 0x8000000000000000ull +#define uECC_WORD_BITS 64 +#define uECC_WORD_BITS_SHIFT 6 +#define uECC_WORD_BITS_MASK 0x03F + +#endif /* uECC_WORD_SIZE */ + +#endif /* _UECC_TYPES_H_ */ diff --git a/tools/sdk/include/micro-ecc/uECC.h b/tools/sdk/include/micro-ecc/uECC.h new file mode 100644 index 00000000..43a19d63 --- /dev/null +++ b/tools/sdk/include/micro-ecc/uECC.h @@ -0,0 +1,365 @@ +/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_H_ +#define _UECC_H_ + +#include + +/* Platform selection options. +If uECC_PLATFORM is not defined, the code will try to guess it based on compiler macros. +Possible values for uECC_PLATFORM are defined below: */ +#define uECC_arch_other 0 +#define uECC_x86 1 +#define uECC_x86_64 2 +#define uECC_arm 3 +#define uECC_arm_thumb 4 +#define uECC_arm_thumb2 5 +#define uECC_arm64 6 +#define uECC_avr 7 + +/* If desired, you can define uECC_WORD_SIZE as appropriate for your platform (1, 4, or 8 bytes). +If uECC_WORD_SIZE is not explicitly defined then it will be automatically set based on your +platform. */ + +/* Optimization level; trade speed for code size. + Larger values produce code that is faster but larger. + Currently supported values are 0 - 4; 0 is unusably slow for most applications. + Optimization level 4 currently only has an effect ARM platforms where more than one + curve is enabled. */ +#ifndef uECC_OPTIMIZATION_LEVEL + #define uECC_OPTIMIZATION_LEVEL 2 +#endif + +/* uECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a specific function to be +used for (scalar) squaring instead of the generic multiplication function. This can make things +faster somewhat faster, but increases the code size. */ +#ifndef uECC_SQUARE_FUNC + #define uECC_SQUARE_FUNC 0 +#endif + +/* uECC_VLI_NATIVE_LITTLE_ENDIAN - If enabled (defined as nonzero), this will switch to native +little-endian format for *all* arrays passed in and out of the public API. This includes public +and private keys, shared secrets, signatures and message hashes. +Using this switch reduces the amount of call stack memory used by uECC, since less intermediate +translations are required. +Note that this will *only* work on native little-endian processors and it will treat the uint8_t +arrays passed into the public API as word arrays, therefore requiring the provided byte arrays +to be word aligned on architectures that do not support unaligned accesses. +IMPORTANT: Keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=1 are incompatible +with keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=0; all parties must use +the same endianness. */ +#ifndef uECC_VLI_NATIVE_LITTLE_ENDIAN + #define uECC_VLI_NATIVE_LITTLE_ENDIAN 0 +#endif + +/* Curve support selection. Set to 0 to remove that curve. */ +#ifndef uECC_SUPPORTS_secp160r1 + #define uECC_SUPPORTS_secp160r1 1 +#endif +#ifndef uECC_SUPPORTS_secp192r1 + #define uECC_SUPPORTS_secp192r1 1 +#endif +#ifndef uECC_SUPPORTS_secp224r1 + #define uECC_SUPPORTS_secp224r1 1 +#endif +#ifndef uECC_SUPPORTS_secp256r1 + #define uECC_SUPPORTS_secp256r1 1 +#endif +#ifndef uECC_SUPPORTS_secp256k1 + #define uECC_SUPPORTS_secp256k1 1 +#endif + +/* Specifies whether compressed point format is supported. + Set to 0 to disable point compression/decompression functions. */ +#ifndef uECC_SUPPORT_COMPRESSED_POINT + #define uECC_SUPPORT_COMPRESSED_POINT 1 +#endif + +struct uECC_Curve_t; +typedef const struct uECC_Curve_t * uECC_Curve; + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if uECC_SUPPORTS_secp160r1 +uECC_Curve uECC_secp160r1(void); +#endif +#if uECC_SUPPORTS_secp192r1 +uECC_Curve uECC_secp192r1(void); +#endif +#if uECC_SUPPORTS_secp224r1 +uECC_Curve uECC_secp224r1(void); +#endif +#if uECC_SUPPORTS_secp256r1 +uECC_Curve uECC_secp256r1(void); +#endif +#if uECC_SUPPORTS_secp256k1 +uECC_Curve uECC_secp256k1(void); +#endif + +/* uECC_RNG_Function type +The RNG function should fill 'size' random bytes into 'dest'. It should return 1 if +'dest' was filled with random data, or 0 if the random data could not be generated. +The filled-in values should be either truly random, or from a cryptographically-secure PRNG. + +A correctly functioning RNG function must be set (using uECC_set_rng()) before calling +uECC_make_key() or uECC_sign(). + +Setting a correctly functioning RNG function improves the resistance to side-channel attacks +for uECC_shared_secret() and uECC_sign_deterministic(). + +A correct RNG function is set by default when building for Windows, Linux, or OS X. +If you are building on another POSIX-compliant system that supports /dev/random or /dev/urandom, +you can define uECC_POSIX to use the predefined RNG. For embedded platforms there is no predefined +RNG function; you must provide your own. +*/ +typedef int (*uECC_RNG_Function)(uint8_t *dest, unsigned size); + +/* uECC_set_rng() function. +Set the function that will be used to generate random bytes. The RNG function should +return 1 if the random data was generated, or 0 if the random data could not be generated. + +On platforms where there is no predefined RNG function (eg embedded platforms), this must +be called before uECC_make_key() or uECC_sign() are used. + +Inputs: + rng_function - The function that will be used to generate random bytes. +*/ +void uECC_set_rng(uECC_RNG_Function rng_function); + +/* uECC_get_rng() function. + +Returns the function that will be used to generate random bytes. +*/ +uECC_RNG_Function uECC_get_rng(void); + +/* uECC_curve_private_key_size() function. + +Returns the size of a private key for the curve in bytes. +*/ +int uECC_curve_private_key_size(uECC_Curve curve); + +/* uECC_curve_public_key_size() function. + +Returns the size of a public key for the curve in bytes. +*/ +int uECC_curve_public_key_size(uECC_Curve curve); + +/* uECC_make_key() function. +Create a public/private key pair. + +Outputs: + public_key - Will be filled in with the public key. Must be at least 2 * the curve size + (in bytes) long. For example, if the curve is secp256r1, public_key must be 64 + bytes long. + private_key - Will be filled in with the private key. Must be as long as the curve order; this + is typically the same as the curve size, except for secp160r1. For example, if the + curve is secp256r1, private_key must be 32 bytes long. + + For secp160r1, private_key must be 21 bytes long! Note that the first byte will + almost always be 0 (there is about a 1 in 2^80 chance of it being non-zero). + +Returns 1 if the key pair was generated successfully, 0 if an error occurred. +*/ +int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve); + +/* uECC_shared_secret() function. +Compute a shared secret given your secret key and someone else's public key. +Note: It is recommended that you hash the result of uECC_shared_secret() before using it for +symmetric encryption or HMAC. + +Inputs: + public_key - The public key of the remote party. + private_key - Your private key. + +Outputs: + secret - Will be filled in with the shared secret value. Must be the same size as the + curve size; for example, if the curve is secp256r1, secret must be 32 bytes long. + +Returns 1 if the shared secret was generated successfully, 0 if an error occurred. +*/ +int uECC_shared_secret(const uint8_t *public_key, + const uint8_t *private_key, + uint8_t *secret, + uECC_Curve curve); + +#if uECC_SUPPORT_COMPRESSED_POINT +/* uECC_compress() function. +Compress a public key. + +Inputs: + public_key - The public key to compress. + +Outputs: + compressed - Will be filled in with the compressed public key. Must be at least + (curve size + 1) bytes long; for example, if the curve is secp256r1, + compressed must be 33 bytes long. +*/ +void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve); + +/* uECC_decompress() function. +Decompress a compressed public key. + +Inputs: + compressed - The compressed public key. + +Outputs: + public_key - Will be filled in with the decompressed public key. +*/ +void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve); +#endif /* uECC_SUPPORT_COMPRESSED_POINT */ + +/* uECC_valid_public_key() function. +Check to see if a public key is valid. + +Note that you are not required to check for a valid public key before using any other uECC +functions. However, you may wish to avoid spending CPU time computing a shared secret or +verifying a signature using an invalid public key. + +Inputs: + public_key - The public key to check. + +Returns 1 if the public key is valid, 0 if it is invalid. +*/ +int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve); + +/* uECC_compute_public_key() function. +Compute the corresponding public key for a private key. + +Inputs: + private_key - The private key to compute the public key for + +Outputs: + public_key - Will be filled in with the corresponding public key + +Returns 1 if the key was computed successfully, 0 if an error occurred. +*/ +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve); + +/* uECC_sign() function. +Generate an ECDSA signature for a given hash value. + +Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to +this function along with your private key. + +Inputs: + private_key - Your private key. + message_hash - The hash of the message to sign. + hash_size - The size of message_hash in bytes. + +Outputs: + signature - Will be filled in with the signature value. Must be at least 2 * curve size long. + For example, if the curve is secp256r1, signature must be 64 bytes long. + +Returns 1 if the signature generated successfully, 0 if an error occurred. +*/ +int uECC_sign(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + uint8_t *signature, + uECC_Curve curve); + +/* uECC_HashContext structure. +This is used to pass in an arbitrary hash function to uECC_sign_deterministic(). +The structure will be used for multiple hash computations; each time a new hash +is computed, init_hash() will be called, followed by one or more calls to +update_hash(), and finally a call to finish_hash() to produce the resulting hash. + +The intention is that you will create a structure that includes uECC_HashContext +followed by any hash-specific data. For example: + +typedef struct SHA256_HashContext { + uECC_HashContext uECC; + SHA256_CTX ctx; +} SHA256_HashContext; + +void init_SHA256(uECC_HashContext *base) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Init(&context->ctx); +} + +void update_SHA256(uECC_HashContext *base, + const uint8_t *message, + unsigned message_size) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Update(&context->ctx, message, message_size); +} + +void finish_SHA256(uECC_HashContext *base, uint8_t *hash_result) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Final(hash_result, &context->ctx); +} + +... when signing ... +{ + uint8_t tmp[32 + 32 + 64]; + SHA256_HashContext ctx = {{&init_SHA256, &update_SHA256, &finish_SHA256, 64, 32, tmp}}; + uECC_sign_deterministic(key, message_hash, &ctx.uECC, signature); +} +*/ +typedef struct uECC_HashContext { + void (*init_hash)(const struct uECC_HashContext *context); + void (*update_hash)(const struct uECC_HashContext *context, + const uint8_t *message, + unsigned message_size); + void (*finish_hash)(const struct uECC_HashContext *context, uint8_t *hash_result); + unsigned block_size; /* Hash function block size in bytes, eg 64 for SHA-256. */ + unsigned result_size; /* Hash function result size in bytes, eg 32 for SHA-256. */ + uint8_t *tmp; /* Must point to a buffer of at least (2 * result_size + block_size) bytes. */ +} uECC_HashContext; + +/* uECC_sign_deterministic() function. +Generate an ECDSA signature for a given hash value, using a deterministic algorithm +(see RFC 6979). You do not need to set the RNG using uECC_set_rng() before calling +this function; however, if the RNG is defined it will improve resistance to side-channel +attacks. + +Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it to +this function along with your private key and a hash context. Note that the message_hash +does not need to be computed with the same hash function used by hash_context. + +Inputs: + private_key - Your private key. + message_hash - The hash of the message to sign. + hash_size - The size of message_hash in bytes. + hash_context - A hash context to use. + +Outputs: + signature - Will be filled in with the signature value. + +Returns 1 if the signature generated successfully, 0 if an error occurred. +*/ +int uECC_sign_deterministic(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + const uECC_HashContext *hash_context, + uint8_t *signature, + uECC_Curve curve); + +/* uECC_verify() function. +Verify an ECDSA signature. + +Usage: Compute the hash of the signed data using the same hash as the signer and +pass it to this function along with the signer's public key and the signature values (r and s). + +Inputs: + public_key - The signer's public key. + message_hash - The hash of the signed data. + hash_size - The size of message_hash in bytes. + signature - The signature value. + +Returns 1 if the signature is valid, 0 if it is invalid. +*/ +int uECC_verify(const uint8_t *public_key, + const uint8_t *message_hash, + unsigned hash_size, + const uint8_t *signature, + uECC_Curve curve); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _UECC_H_ */ diff --git a/tools/sdk/include/micro-ecc/uECC_vli.h b/tools/sdk/include/micro-ecc/uECC_vli.h new file mode 100644 index 00000000..864cc333 --- /dev/null +++ b/tools/sdk/include/micro-ecc/uECC_vli.h @@ -0,0 +1,172 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_VLI_H_ +#define _UECC_VLI_H_ + +#include "uECC.h" +#include "types.h" + +/* Functions for raw large-integer manipulation. These are only available + if uECC.c is compiled with uECC_ENABLE_VLI_API defined to 1. */ +#ifndef uECC_ENABLE_VLI_API + #define uECC_ENABLE_VLI_API 0 +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if uECC_ENABLE_VLI_API + +void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words); + +/* Constant-time comparison to zero - secure way to compare long integers */ +/* Returns 1 if vli == 0, 0 otherwise. */ +uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words); + +/* Returns nonzero if bit 'bit' of vli is set. */ +uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit); + +/* Counts the number of bits required to represent vli. */ +bitcount_t uECC_vli_numBits(const uECC_word_t *vli, const wordcount_t max_words); + +/* Sets dest = src. */ +void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words); + +/* Constant-time comparison function - secure way to compare long integers */ +/* Returns one if left == right, zero otherwise */ +uECC_word_t uECC_vli_equal(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Constant-time comparison function - secure way to compare long integers */ +/* Returns sign of left - right, in constant time. */ +cmpresult_t uECC_vli_cmp(const uECC_word_t *left, const uECC_word_t *right, wordcount_t num_words); + +/* Computes vli = vli >> 1. */ +void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words); + +/* Computes result = left + right, returning carry. Can modify in place. */ +uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Computes result = left - right, returning borrow. Can modify in place. */ +uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Computes result = left * right. Result must be 2 * num_words long. */ +void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Computes result = left^2. Result must be 2 * num_words long. */ +void uECC_vli_square(uECC_word_t *result, const uECC_word_t *left, wordcount_t num_words); + +/* Computes result = (left + right) % mod. + Assumes that left < mod and right < mod, and that result does not overlap mod. */ +void uECC_vli_modAdd(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = (left - right) % mod. + Assumes that left < mod and right < mod, and that result does not overlap mod. */ +void uECC_vli_modSub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = product % mod, where product is 2N words long. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_mmod(uECC_word_t *result, + uECC_word_t *product, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Calculates result = product (mod curve->p), where product is up to + 2 * curve->num_words long. */ +void uECC_vli_mmod_fast(uECC_word_t *result, uECC_word_t *product, uECC_Curve curve); + +/* Computes result = (left * right) % mod. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_modMult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = (left * right) % curve->p. */ +void uECC_vli_modMult_fast(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + uECC_Curve curve); + +/* Computes result = left^2 % mod. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_modSquare(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = left^2 % curve->p. */ +void uECC_vli_modSquare_fast(uECC_word_t *result, const uECC_word_t *left, uECC_Curve curve); + +/* Computes result = (1 / input) % mod.*/ +void uECC_vli_modInv(uECC_word_t *result, + const uECC_word_t *input, + const uECC_word_t *mod, + wordcount_t num_words); + +#if uECC_SUPPORT_COMPRESSED_POINT +/* Calculates a = sqrt(a) (mod curve->p) */ +void uECC_vli_mod_sqrt(uECC_word_t *a, uECC_Curve curve); +#endif + +/* Converts an integer in uECC native format to big-endian bytes. */ +void uECC_vli_nativeToBytes(uint8_t *bytes, int num_bytes, const uECC_word_t *native); +/* Converts big-endian bytes to an integer in uECC native format. */ +void uECC_vli_bytesToNative(uECC_word_t *native, const uint8_t *bytes, int num_bytes); + +unsigned uECC_curve_num_words(uECC_Curve curve); +unsigned uECC_curve_num_bytes(uECC_Curve curve); +unsigned uECC_curve_num_bits(uECC_Curve curve); +unsigned uECC_curve_num_n_words(uECC_Curve curve); +unsigned uECC_curve_num_n_bytes(uECC_Curve curve); +unsigned uECC_curve_num_n_bits(uECC_Curve curve); + +const uECC_word_t *uECC_curve_p(uECC_Curve curve); +const uECC_word_t *uECC_curve_n(uECC_Curve curve); +const uECC_word_t *uECC_curve_G(uECC_Curve curve); +const uECC_word_t *uECC_curve_b(uECC_Curve curve); + +int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve); + +/* Multiplies a point by a scalar. Points are represented by the X coordinate followed by + the Y coordinate in the same array, both coordinates are curve->num_words long. Note + that scalar must be curve->num_n_words long (NOT curve->num_words). */ +void uECC_point_mult(uECC_word_t *result, + const uECC_word_t *point, + const uECC_word_t *scalar, + uECC_Curve curve); + +/* Generates a random integer in the range 0 < random < top. + Both random and top have num_words words. */ +int uECC_generate_random_int(uECC_word_t *random, + const uECC_word_t *top, + wordcount_t num_words); + +#endif /* uECC_ENABLE_VLI_API */ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _UECC_VLI_H_ */ diff --git a/tools/sdk/include/esp-mqtt/mqtt_client.h b/tools/sdk/include/mqtt/mqtt_client.h similarity index 68% rename from tools/sdk/include/esp-mqtt/mqtt_client.h rename to tools/sdk/include/mqtt/mqtt_client.h index 45fcbe7d..630ba172 100755 --- a/tools/sdk/include/esp-mqtt/mqtt_client.h +++ b/tools/sdk/include/mqtt/mqtt_client.h @@ -20,14 +20,31 @@ extern "C" { typedef struct esp_mqtt_client* esp_mqtt_client_handle_t; +/** + * @brief MQTT event types. + * + * User event handler receives context data in `esp_mqtt_event_t` structure with + * - `user_context` - user data from `esp_mqtt_client_config_t` + * - `client` - mqtt client handle + * - various other data depending on event type + * + */ typedef enum { MQTT_EVENT_ERROR = 0, - MQTT_EVENT_CONNECTED, - MQTT_EVENT_DISCONNECTED, - MQTT_EVENT_SUBSCRIBED, - MQTT_EVENT_UNSUBSCRIBED, - MQTT_EVENT_PUBLISHED, - MQTT_EVENT_DATA, + MQTT_EVENT_CONNECTED, /*!< connected event, additional context: session_present flag */ + MQTT_EVENT_DISCONNECTED, /*!< disconnected event */ + MQTT_EVENT_SUBSCRIBED, /*!< subscribed event, additional context: msg_id */ + MQTT_EVENT_UNSUBSCRIBED, /*!< unsubscribed event */ + MQTT_EVENT_PUBLISHED, /*!< published event, additional context: msg_id */ + MQTT_EVENT_DATA, /*!< data event, additional context: + - msg_id message id + - topic pointer to the received topic + - topic_len length of the topic + - data pointer to the received data + - data_len length of the data for this event + - current_data_offset offset of the current data for this event + - total_data_len total length of the data received + */ } esp_mqtt_event_id_t; typedef enum { @@ -52,6 +69,7 @@ typedef struct { char *topic; /*!< Topic asociated with this event */ int topic_len; /*!< Length of the topic for this event asociated with this event */ int msg_id; /*!< MQTT messaged id of message */ + int session_present; /*!< MQTT session_present flag for connection event */ } esp_mqtt_event_t; typedef esp_mqtt_event_t* esp_mqtt_event_handle_t; @@ -81,7 +99,9 @@ typedef struct { int task_prio; /*!< MQTT task priority, default is 5, can be changed in ``make menuconfig`` */ int task_stack; /*!< MQTT task stack size, default is 6144 bytes, can be changed in ``make menuconfig`` */ int buffer_size; /*!< size of MQTT send/receive buffer, default is 1024 */ - const char *cert_pem; /*!< pointer to CERT file for server verify (with SSL), default is NULL, not required to verify the server */ + const char *cert_pem; /*!< Pointer to certificate data in PEM format for server verify (with SSL), default is NULL, not required to verify the server */ + const char *client_cert_pem; /*!< Pointer to certificate data in PEM format for SSL mutual authentication, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_key_pem` has to be provided. */ + const char *client_key_pem; /*!< Pointer to private key data in PEM format for SSL mutual authentication, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_cert_pem` has to be provided. */ esp_mqtt_transport_t transport; /*!< overrides URI transport */ } esp_mqtt_client_config_t; diff --git a/tools/sdk/include/esp-mqtt/mqtt_config.h b/tools/sdk/include/mqtt/mqtt_config.h similarity index 100% rename from tools/sdk/include/esp-mqtt/mqtt_config.h rename to tools/sdk/include/mqtt/mqtt_config.h diff --git a/tools/sdk/include/newlib/assert.h b/tools/sdk/include/newlib/assert.h index afbea986..df46c030 100644 --- a/tools/sdk/include/newlib/assert.h +++ b/tools/sdk/include/newlib/assert.h @@ -1,28 +1,50 @@ -// Copyright 2017 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -/* This header file wraps newlib's own unmodified assert.h and adds - support for silent assertion failure. +/* + assert.h */ -#pragma once -#include -#include -#include_next - -#if defined(CONFIG_OPTIMIZATION_ASSERTIONS_SILENT) && !defined(NDEBUG) -#undef assert -#define assert(__e) ((__e) ? (void)0 : abort()) +#ifdef __cplusplus +extern "C" { +#endif + +#include "_ansi.h" + +#undef assert + +#ifdef NDEBUG /* required by ANSI standard */ +# define assert(__e) ((void) sizeof(__e)) +#else +# define assert(__e) ((__e) ? (void)0 : __assert_func (__FILE__, __LINE__, \ + __ASSERT_FUNC, #__e)) + +# ifndef __ASSERT_FUNC + /* Use g++'s demangled names in C++. */ +# if defined __cplusplus && defined __GNUC__ +# define __ASSERT_FUNC __PRETTY_FUNCTION__ + + /* C99 requires the use of __func__. */ +# elif __STDC_VERSION__ >= 199901L +# define __ASSERT_FUNC __func__ + + /* Older versions of gcc don't have __func__ but can use __FUNCTION__. */ +# elif __GNUC__ >= 2 +# define __ASSERT_FUNC __FUNCTION__ + + /* failed to detect __func__ support. */ +# else +# define __ASSERT_FUNC ((char *) 0) +# endif +# endif /* !__ASSERT_FUNC */ +#endif /* !NDEBUG */ + +void _EXFUN(__assert, (const char *, int, const char *) + _ATTRIBUTE ((__noreturn__))); +void _EXFUN(__assert_func, (const char *, int, const char *, const char *) + _ATTRIBUTE ((__noreturn__))); + +#if __STDC_VERSION__ >= 201112L && !defined __cplusplus +# define static_assert _Static_assert +#endif + +#ifdef __cplusplus +} #endif diff --git a/tools/sdk/include/newlib/errno.h b/tools/sdk/include/newlib/errno.h index 85fb2e15..7cc2ca86 100644 --- a/tools/sdk/include/newlib/errno.h +++ b/tools/sdk/include/newlib/errno.h @@ -1,39 +1,11 @@ +#ifndef __ERRNO_H__ +#define __ERRNO_H__ -// Copyright 2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#ifndef _ESP_PLATFORM_ERRNO_H_ -#define _ESP_PLATFORM_ERRNO_H_ - -#include_next "errno.h" - -// -// Possibly define some missing errors -// -#ifndef ESHUTDOWN -#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#ifndef __error_t_defined +typedef int error_t; +#define __error_t_defined 1 #endif -#ifndef EAI_SOCKTYPE -#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ -#endif +#include -#ifndef EAI_AGAIN -#define EAI_AGAIN 2 /* temporary failure in name resolution */ -#endif - -#ifndef EAI_BADFLAGS -#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ -#endif - -#endif // _ESP_PLATFORM_ERRNO_H_ +#endif /* !__ERRNO_H__ */ diff --git a/tools/sdk/include/newlib/pthread.h b/tools/sdk/include/newlib/pthread.h index 4515fb00..db1f9c1c 100644 --- a/tools/sdk/include/newlib/pthread.h +++ b/tools/sdk/include/newlib/pthread.h @@ -1,33 +1,431 @@ -// Copyright 2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#ifndef __ESP_PLATFORM_PTHREAD_H__ -#define __ESP_PLATFORM_PTHREAD_H__ +/* pthread.h + * + * Written by Joel Sherrill . + * + * COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION + * OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS + * SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + * $Id$ + */ -#include -#include -#include_next +#ifndef __PTHREAD_h +#define __PTHREAD_h #ifdef __cplusplus extern "C" { #endif -int pthread_condattr_getclock(const pthread_condattr_t * attr, clockid_t * clock_id); +#include + +#if defined(_POSIX_THREADS) + +#include +#include +#include +#include + +struct _pthread_cleanup_context { + void (*_routine)(void *); + void *_arg; + int _canceltype; + struct _pthread_cleanup_context *_previous; +}; + +/* Register Fork Handlers */ +int _EXFUN(pthread_atfork,(void (*prepare)(void), void (*parent)(void), + void (*child)(void))); + +/* Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81 */ + +int _EXFUN(pthread_mutexattr_init, (pthread_mutexattr_t *__attr)); +int _EXFUN(pthread_mutexattr_destroy, (pthread_mutexattr_t *__attr)); +int _EXFUN(pthread_mutexattr_getpshared, + (_CONST pthread_mutexattr_t *__attr, int *__pshared)); +int _EXFUN(pthread_mutexattr_setpshared, + (pthread_mutexattr_t *__attr, int __pshared)); + +#if defined(_UNIX98_THREAD_MUTEX_ATTRIBUTES) + +/* Single UNIX Specification 2 Mutex Attributes types */ + +int _EXFUN(pthread_mutexattr_gettype, + (_CONST pthread_mutexattr_t *__attr, int *__kind)); +int _EXFUN(pthread_mutexattr_settype, + (pthread_mutexattr_t *__attr, int __kind)); + +#endif + +/* Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87 */ + +int _EXFUN(pthread_mutex_init, + (pthread_mutex_t *__mutex, _CONST pthread_mutexattr_t *__attr)); +int _EXFUN(pthread_mutex_destroy, (pthread_mutex_t *__mutex)); + +/* This is used to statically initialize a pthread_mutex_t. Example: + + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + */ + +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) 0xFFFFFFFF) + +/* Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93 + NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29 */ + +int _EXFUN(pthread_mutex_lock, (pthread_mutex_t *__mutex)); +int _EXFUN(pthread_mutex_trylock, (pthread_mutex_t *__mutex)); +int _EXFUN(pthread_mutex_unlock, (pthread_mutex_t *__mutex)); + +#if defined(_POSIX_TIMEOUTS) + +int _EXFUN(pthread_mutex_timedlock, + (pthread_mutex_t *__mutex, _CONST struct timespec *__timeout)); + +#endif /* _POSIX_TIMEOUTS */ + +/* Condition Variable Initialization Attributes, P1003.1c/Draft 10, p. 96 */ + +int _EXFUN(pthread_condattr_init, (pthread_condattr_t *__attr)); +int _EXFUN(pthread_condattr_destroy, (pthread_condattr_t *__attr)); +int _EXFUN(pthread_condattr_getpshared, + (_CONST pthread_condattr_t *__attr, int *__pshared)); +int _EXFUN(pthread_condattr_setpshared, + (pthread_condattr_t *__attr, int __pshared)); + +/* Initializing and Destroying a Condition Variable, P1003.1c/Draft 10, p. 87 */ + +int _EXFUN(pthread_cond_init, + (pthread_cond_t *__cond, _CONST pthread_condattr_t *__attr)); +int _EXFUN(pthread_cond_destroy, (pthread_cond_t *__mutex)); + +/* This is used to statically initialize a pthread_cond_t. Example: + + pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + */ + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) 0xFFFFFFFF) + +/* Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101 */ + +int _EXFUN(pthread_cond_signal, (pthread_cond_t *__cond)); +int _EXFUN(pthread_cond_broadcast, (pthread_cond_t *__cond)); + +/* Waiting on a Condition, P1003.1c/Draft 10, p. 105 */ + +int _EXFUN(pthread_cond_wait, + (pthread_cond_t *__cond, pthread_mutex_t *__mutex)); + +int _EXFUN(pthread_cond_timedwait, + (pthread_cond_t *__cond, pthread_mutex_t *__mutex, + _CONST struct timespec *__abstime)); + +#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) + +/* Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120 */ + +int _EXFUN(pthread_attr_setscope, + (pthread_attr_t *__attr, int __contentionscope)); +int _EXFUN(pthread_attr_getscope, + (_CONST pthread_attr_t *__attr, int *__contentionscope)); +int _EXFUN(pthread_attr_setinheritsched, + (pthread_attr_t *__attr, int __inheritsched)); +int _EXFUN(pthread_attr_getinheritsched, + (_CONST pthread_attr_t *__attr, int *__inheritsched)); +int _EXFUN(pthread_attr_setschedpolicy, + (pthread_attr_t *__attr, int __policy)); +int _EXFUN(pthread_attr_getschedpolicy, + (_CONST pthread_attr_t *__attr, int *__policy)); + +#endif /* defined(_POSIX_THREAD_PRIORITY_SCHEDULING) */ + +int _EXFUN(pthread_attr_setschedparam, + (pthread_attr_t *__attr, _CONST struct sched_param *__param)); +int _EXFUN(pthread_attr_getschedparam, + (_CONST pthread_attr_t *__attr, struct sched_param *__param)); + +#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) + +/* Dynamic Thread Scheduling Parameters Access, P1003.1c/Draft 10, p. 124 */ + +int _EXFUN(pthread_getschedparam, + (pthread_t __pthread, int *__policy, struct sched_param *__param)); +int _EXFUN(pthread_setschedparam, + (pthread_t __pthread, int __policy, struct sched_param *__param)); + +#endif /* defined(_POSIX_THREAD_PRIORITY_SCHEDULING) */ + +#if defined(_POSIX_THREAD_PRIO_INHERIT) || defined(_POSIX_THREAD_PRIO_PROTECT) + +/* Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128 */ + +int _EXFUN(pthread_mutexattr_setprotocol, + (pthread_mutexattr_t *__attr, int __protocol)); +int _EXFUN(pthread_mutexattr_getprotocol, + (_CONST pthread_mutexattr_t *__attr, int *__protocol)); +int _EXFUN(pthread_mutexattr_setprioceiling, + (pthread_mutexattr_t *__attr, int __prioceiling)); +int _EXFUN(pthread_mutexattr_getprioceiling, + (_CONST pthread_mutexattr_t *__attr, int *__prioceiling)); + +#endif /* _POSIX_THREAD_PRIO_INHERIT || _POSIX_THREAD_PRIO_PROTECT */ + +#if defined(_POSIX_THREAD_PRIO_PROTECT) + +/* Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131 */ + +int _EXFUN(pthread_mutex_setprioceiling, + (pthread_mutex_t *__mutex, int __prioceiling, int *__old_ceiling)); +int _EXFUN(pthread_mutex_getprioceiling, + (pthread_mutex_t *__mutex, int *__prioceiling)); + +#endif /* _POSIX_THREAD_PRIO_PROTECT */ + +/* Thread Creation Attributes, P1003.1c/Draft 10, p, 140 */ + +int _EXFUN(pthread_attr_init, (pthread_attr_t *__attr)); +int _EXFUN(pthread_attr_destroy, (pthread_attr_t *__attr)); +int _EXFUN(pthread_attr_setstack, (pthread_attr_t *attr, + void *__stackaddr, size_t __stacksize)); +int _EXFUN(pthread_attr_getstack, (_CONST pthread_attr_t *attr, + void **__stackaddr, size_t *__stacksize)); +int _EXFUN(pthread_attr_getstacksize, + (_CONST pthread_attr_t *__attr, size_t *__stacksize)); +int _EXFUN(pthread_attr_setstacksize, + (pthread_attr_t *__attr, size_t __stacksize)); +int _EXFUN(pthread_attr_getstackaddr, + (_CONST pthread_attr_t *__attr, void **__stackaddr)); +int _EXFUN(pthread_attr_setstackaddr, + (pthread_attr_t *__attr, void *__stackaddr)); +int _EXFUN(pthread_attr_getdetachstate, + (_CONST pthread_attr_t *__attr, int *__detachstate)); +int _EXFUN(pthread_attr_setdetachstate, + (pthread_attr_t *__attr, int __detachstate)); +int _EXFUN(pthread_attr_getguardsize, + (_CONST pthread_attr_t *__attr, size_t *__guardsize)); +int _EXFUN(pthread_attr_setguardsize, + (pthread_attr_t *__attr, size_t __guardsize)); + +/* POSIX thread APIs beyond the POSIX standard but provided + * in GNU/Linux. They may be provided by other OSes for + * compatibility. + */ +#if defined(__GNU_VISIBLE) +#if defined(__rtems__) +int _EXFUN(pthread_attr_setaffinity_np, + (pthread_attr_t *__attr, size_t __cpusetsize, + const cpu_set_t *__cpuset)); +int _EXFUN(pthread_attr_getaffinity_np, + (const pthread_attr_t *__attr, size_t __cpusetsize, + cpu_set_t *__cpuset)); + +int _EXFUN(pthread_setaffinity_np, + (pthread_t __id, size_t __cpusetsize, const cpu_set_t *__cpuset)); +int _EXFUN(pthread_getaffinity_np, + (const pthread_t __id, size_t __cpusetsize, cpu_set_t *__cpuset)); + +int _EXFUN(pthread_getattr_np, + (pthread_t __id, pthread_attr_t *__attr)); +#endif /* defined(__rtems__) */ +#endif /* defined(__GNU_VISIBLE) */ + +/* Thread Creation, P1003.1c/Draft 10, p. 144 */ + +int _EXFUN(pthread_create, + (pthread_t *__pthread, _CONST pthread_attr_t *__attr, + void *(*__start_routine)( void * ), void *__arg)); + +/* Wait for Thread Termination, P1003.1c/Draft 10, p. 147 */ + +int _EXFUN(pthread_join, (pthread_t __pthread, void **__value_ptr)); + +/* Detaching a Thread, P1003.1c/Draft 10, p. 149 */ + +int _EXFUN(pthread_detach, (pthread_t __pthread)); + +/* Thread Termination, p1003.1c/Draft 10, p. 150 */ + +void _EXFUN(pthread_exit, (void *__value_ptr)); + +/* Get Calling Thread's ID, p1003.1c/Draft 10, p. XXX */ + +pthread_t _EXFUN(pthread_self, (void)); + +/* Compare Thread IDs, p1003.1c/Draft 10, p. 153 */ + +int _EXFUN(pthread_equal, (pthread_t __t1, pthread_t __t2)); + +/* Dynamic Package Initialization */ + +/* This is used to statically initialize a pthread_once_t. Example: + + pthread_once_t once = PTHREAD_ONCE_INIT; + + NOTE: This is named inconsistently -- it should be INITIALIZER. */ + +#define PTHREAD_ONCE_INIT { 1, 0 } /* is initialized and not run */ + +int _EXFUN(pthread_once, + (pthread_once_t *__once_control, void (*__init_routine)(void))); + +/* Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163 */ + +int _EXFUN(pthread_key_create, + (pthread_key_t *__key, void (*__destructor)( void * ))); + +/* Thread-Specific Data Management, P1003.1c/Draft 10, p. 165 */ + +int _EXFUN(pthread_setspecific, + (pthread_key_t __key, _CONST void *__value)); +void * _EXFUN(pthread_getspecific, (pthread_key_t __key)); + +/* Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167 */ + +int _EXFUN(pthread_key_delete, (pthread_key_t __key)); + +/* Execution of a Thread, P1003.1c/Draft 10, p. 181 */ + +#define PTHREAD_CANCEL_ENABLE 0 +#define PTHREAD_CANCEL_DISABLE 1 + +#define PTHREAD_CANCEL_DEFERRED 0 +#define PTHREAD_CANCEL_ASYNCHRONOUS 1 + +#define PTHREAD_CANCELED ((void *) -1) + +int _EXFUN(pthread_cancel, (pthread_t __pthread)); + +/* Setting Cancelability State, P1003.1c/Draft 10, p. 183 */ + +int _EXFUN(pthread_setcancelstate, (int __state, int *__oldstate)); +int _EXFUN(pthread_setcanceltype, (int __type, int *__oldtype)); +void _EXFUN(pthread_testcancel, (void)); + +/* Establishing Cancellation Handlers, P1003.1c/Draft 10, p. 184 */ + +void _EXFUN(_pthread_cleanup_push, + (struct _pthread_cleanup_context *_context, + void (*_routine)(void *), void *_arg)); + +void _EXFUN(_pthread_cleanup_pop, + (struct _pthread_cleanup_context *_context, + int _execute)); + +/* It is intentional to open and close the scope in two different macros */ +#define pthread_cleanup_push(_routine, _arg) \ + do { \ + struct _pthread_cleanup_context _pthread_clup_ctx; \ + _pthread_cleanup_push(&_pthread_clup_ctx, (_routine), (_arg)) + +#define pthread_cleanup_pop(_execute) \ + _pthread_cleanup_pop(&_pthread_clup_ctx, (_execute)); \ + } while (0) + +#if defined(_GNU_SOURCE) +void _EXFUN(_pthread_cleanup_push_defer, + (struct _pthread_cleanup_context *_context, + void (*_routine)(void *), void *_arg)); + +void _EXFUN(_pthread_cleanup_pop_restore, + (struct _pthread_cleanup_context *_context, + int _execute)); + +/* It is intentional to open and close the scope in two different macros */ +#define pthread_cleanup_push_defer_np(_routine, _arg) \ + do { \ + struct _pthread_cleanup_context _pthread_clup_ctx; \ + _pthread_cleanup_push_defer(&_pthread_clup_ctx, (_routine), (_arg)) + +#define pthread_cleanup_pop_restore_np(_execute) \ + _pthread_cleanup_pop_restore(&_pthread_clup_ctx, (_execute)); \ + } while (0) +#endif /* defined(_GNU_SOURCE) */ + +#if defined(_POSIX_THREAD_CPUTIME) + +/* Accessing a Thread CPU-time Clock, P1003.4b/D8, p. 58 */ + +int _EXFUN(pthread_getcpuclockid, + (pthread_t __pthread_id, clockid_t *__clock_id)); + +#endif /* defined(_POSIX_THREAD_CPUTIME) */ + + +#endif /* defined(_POSIX_THREADS) */ + +#if defined(_POSIX_BARRIERS) + +int _EXFUN(pthread_barrierattr_init, (pthread_barrierattr_t *__attr)); +int _EXFUN(pthread_barrierattr_destroy, (pthread_barrierattr_t *__attr)); +int _EXFUN(pthread_barrierattr_getpshared, + (_CONST pthread_barrierattr_t *__attr, int *__pshared)); +int _EXFUN(pthread_barrierattr_setpshared, + (pthread_barrierattr_t *__attr, int __pshared)); + +#define PTHREAD_BARRIER_SERIAL_THREAD -1 + +int _EXFUN(pthread_barrier_init, + (pthread_barrier_t *__barrier, + _CONST pthread_barrierattr_t *__attr, unsigned __count)); +int _EXFUN(pthread_barrier_destroy, (pthread_barrier_t *__barrier)); +int _EXFUN(pthread_barrier_wait,(pthread_barrier_t *__barrier)); + +#endif /* defined(_POSIX_BARRIERS) */ + +#if defined(_POSIX_SPIN_LOCKS) + +int _EXFUN(pthread_spin_init, + (pthread_spinlock_t *__spinlock, int __pshared)); +int _EXFUN(pthread_spin_destroy, (pthread_spinlock_t *__spinlock)); +int _EXFUN(pthread_spin_lock, (pthread_spinlock_t *__spinlock)); +int _EXFUN(pthread_spin_trylock, (pthread_spinlock_t *__spinlock)); +int _EXFUN(pthread_spin_unlock, (pthread_spinlock_t *__spinlock)); + +#endif /* defined(_POSIX_SPIN_LOCKS) */ + +#if defined(_POSIX_READER_WRITER_LOCKS) + +/* This is used to statically initialize a pthread_rwlock_t. Example: + + pthread_mutex_t mutex = PTHREAD_RWLOCK_INITIALIZER; + */ + +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) 0xFFFFFFFF) + +int _EXFUN(pthread_rwlockattr_init, (pthread_rwlockattr_t *__attr)); +int _EXFUN(pthread_rwlockattr_destroy, (pthread_rwlockattr_t *__attr)); +int _EXFUN(pthread_rwlockattr_getpshared, + (_CONST pthread_rwlockattr_t *__attr, int *__pshared)); +int _EXFUN(pthread_rwlockattr_setpshared, + (pthread_rwlockattr_t *__attr, int __pshared)); + +int _EXFUN(pthread_rwlock_init, + (pthread_rwlock_t *__rwlock, _CONST pthread_rwlockattr_t *__attr)); +int _EXFUN(pthread_rwlock_destroy, (pthread_rwlock_t *__rwlock)); +int _EXFUN(pthread_rwlock_rdlock,(pthread_rwlock_t *__rwlock)); +int _EXFUN(pthread_rwlock_tryrdlock,(pthread_rwlock_t *__rwlock)); +int _EXFUN(pthread_rwlock_timedrdlock, + (pthread_rwlock_t *__rwlock, _CONST struct timespec *__abstime)); +int _EXFUN(pthread_rwlock_unlock,(pthread_rwlock_t *__rwlock)); +int _EXFUN(pthread_rwlock_wrlock,(pthread_rwlock_t *__rwlock)); +int _EXFUN(pthread_rwlock_trywrlock,(pthread_rwlock_t *__rwlock)); +int _EXFUN(pthread_rwlock_timedwrlock, + (pthread_rwlock_t *__rwlock, _CONST struct timespec *__abstime)); + +#endif /* defined(_POSIX_READER_WRITER_LOCKS) */ -int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id); #ifdef __cplusplus } #endif -#endif // __ESP_PLATFORM_PTHREAD_H__ +#endif +/* end of include file */ diff --git a/tools/sdk/include/newlib/sys/unistd.h b/tools/sdk/include/newlib/sys/unistd.h index e09b68be..a741383d 100644 --- a/tools/sdk/include/newlib/sys/unistd.h +++ b/tools/sdk/include/newlib/sys/unistd.h @@ -1,29 +1,514 @@ -// Copyright 2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -#ifndef _ESP_SYS_UNISTD_H -#define _ESP_SYS_UNISTD_H +#ifndef _SYS_UNISTD_H +#define _SYS_UNISTD_H #ifdef __cplusplus extern "C" { #endif -#include_next +#include <_ansi.h> +#define __need_size_t +#define __need_ptrdiff_t +#include +#include +#include +#include +extern char **environ; + +void _EXFUN(_exit, (int __status ) _ATTRIBUTE ((__noreturn__))); + +int _EXFUN(access,(const char *__path, int __amode )); +unsigned _EXFUN(alarm, (unsigned __secs )); +int _EXFUN(chdir, (const char *__path )); +int _EXFUN(chmod, (const char *__path, mode_t __mode )); +#if !defined(__INSIDE_CYGWIN__) +int _EXFUN(chown, (const char *__path, uid_t __owner, gid_t __group )); +#endif +#if defined(__CYGWIN__) || defined(__rtems__) +int _EXFUN(chroot, (const char *__path )); +#endif +int _EXFUN(close, (int __fildes )); +#if defined(__CYGWIN__) +size_t _EXFUN(confstr, (int __name, char *__buf, size_t __len)); +#endif +char * _EXFUN(ctermid, (char *__s )); +char * _EXFUN(cuserid, (char *__s )); +#if defined(__CYGWIN__) +int _EXFUN(daemon, (int nochdir, int noclose)); +#endif +int _EXFUN(dup, (int __fildes )); +int _EXFUN(dup2, (int __fildes, int __fildes2 )); +#if defined(__CYGWIN__) +int _EXFUN(dup3, (int __fildes, int __fildes2, int flags)); +int _EXFUN(eaccess, (const char *__path, int __mode)); +void _EXFUN(endusershell, (void)); +int _EXFUN(euidaccess, (const char *__path, int __mode)); +#endif +int _EXFUN(execl, (const char *__path, const char *, ... )); +int _EXFUN(execle, (const char *__path, const char *, ... )); +int _EXFUN(execlp, (const char *__file, const char *, ... )); +#if defined(__CYGWIN__) +int _EXFUN(execlpe, (const char *__file, const char *, ... )); +#endif +int _EXFUN(execv, (const char *__path, char * const __argv[] )); +int _EXFUN(execve, (const char *__path, char * const __argv[], char * const __envp[] )); +int _EXFUN(execvp, (const char *__file, char * const __argv[] )); +#if defined(__CYGWIN__) +int _EXFUN(execvpe, (const char *__file, char * const __argv[], char * const __envp[] )); +#endif +#if __POSIX_VISIBLE >= 200809 || __BSD_VISIBLE || defined(__CYGWIN__) +int _EXFUN(faccessat, (int __dirfd, const char *__path, int __mode, int __flags)); +#endif +#if defined(__CYGWIN__) || defined(__rtems__) || defined(__SPU__) +int _EXFUN(fchdir, (int __fildes)); +#endif +int _EXFUN(fchmod, (int __fildes, mode_t __mode )); +#if !defined(__INSIDE_CYGWIN__) +int _EXFUN(fchown, (int __fildes, uid_t __owner, gid_t __group )); +#endif +#if __POSIX_VISIBLE >= 200809 || __BSD_VISIBLE || defined(__CYGWIN__) +int _EXFUN(fchownat, (int __dirfd, const char *__path, uid_t __owner, gid_t __group, int __flags)); +#endif +#if defined(__CYGWIN__) +int _EXFUN(fexecve, (int __fd, char * const __argv[], char * const __envp[] )); +#endif +pid_t _EXFUN(fork, (void )); +long _EXFUN(fpathconf, (int __fd, int __name )); +int _EXFUN(fsync, (int __fd)); +int _EXFUN(fdatasync, (int __fd)); +#if defined(__CYGWIN__) +char * _EXFUN(get_current_dir_name, (void)); +#endif +char * _EXFUN(getcwd, (char *__buf, size_t __size )); +#if defined(__CYGWIN__) +int _EXFUN(getdomainname ,(char *__name, size_t __len)); +#endif +#if !defined(__INSIDE_CYGWIN__) +gid_t _EXFUN(getegid, (void )); +uid_t _EXFUN(geteuid, (void )); +gid_t _EXFUN(getgid, (void )); +#endif +int _EXFUN(getgroups, (int __gidsetsize, gid_t __grouplist[] )); +#if defined(__CYGWIN__) +long _EXFUN(gethostid, (void)); +#endif +char * _EXFUN(getlogin, (void )); +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) +int _EXFUN(getlogin_r, (char *name, size_t namesize) ); +#endif +char * _EXFUN(getpass, (const char *__prompt)); +int _EXFUN(getpagesize, (void)); +#if defined(__CYGWIN__) +int _EXFUN(getpeereid, (int, uid_t *, gid_t *)); +#endif +pid_t _EXFUN(getpgid, (pid_t)); +pid_t _EXFUN(getpgrp, (void )); +pid_t _EXFUN(getpid, (void )); +pid_t _EXFUN(getppid, (void )); +#if defined(__CYGWIN__) || defined(__rtems__) +pid_t _EXFUN(getsid, (pid_t)); +#endif +#if !defined(__INSIDE_CYGWIN__) +uid_t _EXFUN(getuid, (void )); +#endif +#ifdef __CYGWIN__ +char * _EXFUN(getusershell, (void)); +char * _EXFUN(getwd, (char *__buf )); +int _EXFUN(iruserok, (unsigned long raddr, int superuser, const char *ruser, const char *luser)); +#endif +int _EXFUN(isatty, (int __fildes )); +#if !defined(__INSIDE_CYGWIN__) +int _EXFUN(lchown, (const char *__path, uid_t __owner, gid_t __group )); +#endif +int _EXFUN(link, (const char *__path1, const char *__path2 )); +#if __POSIX_VISIBLE >= 200809 || __BSD_VISIBLE || defined(__CYGWIN__) +int _EXFUN(linkat, (int __dirfd1, const char *__path1, int __dirfd2, const char *__path2, int __flags )); +#endif +int _EXFUN(nice, (int __nice_value )); +#if !defined(__INSIDE_CYGWIN__) +off_t _EXFUN(lseek, (int __fildes, off_t __offset, int __whence )); +#endif +#if defined(__SPU__) || defined(__CYGWIN__) +#define F_ULOCK 0 +#define F_LOCK 1 +#define F_TLOCK 2 +#define F_TEST 3 +int _EXFUN(lockf, (int __fd, int __cmd, off_t __len)); +#endif +long _EXFUN(pathconf, (const char *__path, int __name )); +int _EXFUN(pause, (void )); +#ifdef __CYGWIN__ +int _EXFUN(pthread_atfork, (void (*)(void), void (*)(void), void (*)(void))); +#endif +int _EXFUN(pipe, (int __fildes[2] )); +#ifdef __CYGWIN__ +int _EXFUN(pipe2, (int __fildes[2], int flags)); +#endif +ssize_t _EXFUN(pread, (int __fd, void *__buf, size_t __nbytes, off_t __offset)); +ssize_t _EXFUN(pwrite, (int __fd, const void *__buf, size_t __nbytes, off_t __offset)); +_READ_WRITE_RETURN_TYPE _EXFUN(read, (int __fd, void *__buf, size_t __nbyte )); +#if defined(__CYGWIN__) +int _EXFUN(rresvport, (int *__alport)); +int _EXFUN(revoke, (char *__path)); +#endif +int _EXFUN(rmdir, (const char *__path )); +#if defined(__CYGWIN__) +int _EXFUN(ruserok, (const char *rhost, int superuser, const char *ruser, const char *luser)); +#endif +void * _EXFUN(sbrk, (ptrdiff_t __incr)); +#if !defined(__INSIDE_CYGWIN__) +#if defined(__CYGWIN__) || defined(__rtems__) +int _EXFUN(setegid, (gid_t __gid )); +int _EXFUN(seteuid, (uid_t __uid )); +#endif +int _EXFUN(setgid, (gid_t __gid )); +#endif +#if defined(__CYGWIN__) +int _EXFUN(setgroups, (int ngroups, const gid_t *grouplist )); +#endif +#if __BSD_VISIBLE || (defined(_XOPEN_SOURCE) && __XSI_VISIBLE < 500) +int _EXFUN(sethostname, (const char *, size_t)); +#endif +int _EXFUN(setpgid, (pid_t __pid, pid_t __pgid )); +int _EXFUN(setpgrp, (void )); +#if defined(__CYGWIN__) && !defined(__INSIDE_CYGWIN__) +int _EXFUN(setregid, (gid_t __rgid, gid_t __egid)); +int _EXFUN(setreuid, (uid_t __ruid, uid_t __euid)); +#endif +pid_t _EXFUN(setsid, (void )); +#if !defined(__INSIDE_CYGWIN__) +int _EXFUN(setuid, (uid_t __uid )); +#endif +#if defined(__CYGWIN__) +void _EXFUN(setusershell, (void)); +#endif +unsigned _EXFUN(sleep, (unsigned int __seconds )); +void _EXFUN(swab, (const void *__restrict, void *__restrict, ssize_t)); +long _EXFUN(sysconf, (int __name )); +pid_t _EXFUN(tcgetpgrp, (int __fildes )); +int _EXFUN(tcsetpgrp, (int __fildes, pid_t __pgrp_id )); +char * _EXFUN(ttyname, (int __fildes )); +#if defined(__CYGWIN__) || defined(__rtems__) +int _EXFUN(ttyname_r, (int, char *, size_t)); +#endif +int _EXFUN(unlink, (const char *__path )); +int _EXFUN(usleep, (useconds_t __useconds)); +int _EXFUN(vhangup, (void )); +_READ_WRITE_RETURN_TYPE _EXFUN(write, (int __fd, const void *__buf, size_t __nbyte )); + +#ifdef __CYGWIN__ +# define __UNISTD_GETOPT__ +# include +# undef __UNISTD_GETOPT__ +#else +extern char *optarg; /* getopt(3) external variables */ +extern int optind, opterr, optopt; +int getopt(int, char * const [], const char *); +extern int optreset; /* getopt(3) external variable */ +#endif + +#ifndef _POSIX_SOURCE +pid_t _EXFUN(vfork, (void )); +#endif /* _POSIX_SOURCE */ + +#ifdef _COMPILING_NEWLIB +/* Provide prototypes for most of the _ names that are + provided in newlib for some compilers. */ +int _EXFUN(_close, (int __fildes )); +pid_t _EXFUN(_fork, (void )); +pid_t _EXFUN(_getpid, (void )); +int _EXFUN(_isatty, (int __fildes )); +int _EXFUN(_link, (const char *__path1, const char *__path2 )); +_off_t _EXFUN(_lseek, (int __fildes, _off_t __offset, int __whence )); +#ifdef __LARGE64_FILES +_off64_t _EXFUN(_lseek64, (int __filedes, _off64_t __offset, int __whence )); +#endif +_READ_WRITE_RETURN_TYPE _EXFUN(_read, (int __fd, void *__buf, size_t __nbyte )); +void * _EXFUN(_sbrk, (ptrdiff_t __incr)); +int _EXFUN(_unlink, (const char *__path )); +_READ_WRITE_RETURN_TYPE _EXFUN(_write, (int __fd, const void *__buf, size_t __nbyte )); +int _EXFUN(_execve, (const char *__path, char * const __argv[], char * const __envp[] )); +#endif + +#if defined(__CYGWIN__) || defined(__rtems__) || defined(__aarch64__) || defined (__arm__) || defined(__sh__) || defined(__SPU__) +#if !defined(__INSIDE_CYGWIN__) +int _EXFUN(ftruncate, (int __fd, off_t __length)); int _EXFUN(truncate, (const char *, off_t __length)); -int _EXFUN(gethostname, (char *__name, size_t __len)); +#endif +#endif + +#if defined(__CYGWIN__) || defined(__rtems__) +int _EXFUN(getdtablesize, (void)); +int _EXFUN(setdtablesize, (int)); +useconds_t _EXFUN(ualarm, (useconds_t __useconds, useconds_t __interval)); +#if !(defined (_WINSOCK_H) || defined (_WINSOCKAPI_) || defined (__USE_W32_SOCKETS)) +/* winsock[2].h defines as __stdcall, and with int as 2nd arg */ + int _EXFUN(gethostname, (char *__name, size_t __len)); +#endif +char * _EXFUN(mktemp, (char *)); +#endif + +#if defined(__CYGWIN__) || defined(__SPU__) || defined(__rtems__) +void _EXFUN(sync, (void)); +#endif + +ssize_t _EXFUN(readlink, (const char *__restrict __path, + char *__restrict __buf, size_t __buflen)); +#if __POSIX_VISIBLE >= 200809 || __BSD_VISIBLE || defined(__CYGWIN__) +ssize_t _EXFUN(readlinkat, (int __dirfd1, const char *__restrict __path, + char *__restrict __buf, size_t __buflen)); +#endif +int _EXFUN(symlink, (const char *__name1, const char *__name2)); +#if __POSIX_VISIBLE >= 200809 || __BSD_VISIBLE || defined(__CYGWIN__) +int _EXFUN(symlinkat, (const char *, int, const char *)); +int _EXFUN(unlinkat, (int, const char *, int)); +#endif + +#define F_OK 0 +#define R_OK 4 +#define W_OK 2 +#define X_OK 1 + +# define SEEK_SET 0 +# define SEEK_CUR 1 +# define SEEK_END 2 + +#include + +#define STDIN_FILENO 0 /* standard input file descriptor */ +#define STDOUT_FILENO 1 /* standard output file descriptor */ +#define STDERR_FILENO 2 /* standard error file descriptor */ + +/* + * sysconf values per IEEE Std 1003.1, 2008 Edition + */ + +#define _SC_ARG_MAX 0 +#define _SC_CHILD_MAX 1 +#define _SC_CLK_TCK 2 +#define _SC_NGROUPS_MAX 3 +#define _SC_OPEN_MAX 4 +#define _SC_JOB_CONTROL 5 +#define _SC_SAVED_IDS 6 +#define _SC_VERSION 7 +#define _SC_PAGESIZE 8 +#define _SC_PAGE_SIZE _SC_PAGESIZE +/* These are non-POSIX values we accidentally introduced in 2000 without + guarding them. Keeping them unguarded for backward compatibility. */ +#define _SC_NPROCESSORS_CONF 9 +#define _SC_NPROCESSORS_ONLN 10 +#define _SC_PHYS_PAGES 11 +#define _SC_AVPHYS_PAGES 12 +/* End of non-POSIX values. */ +#define _SC_MQ_OPEN_MAX 13 +#define _SC_MQ_PRIO_MAX 14 +#define _SC_RTSIG_MAX 15 +#define _SC_SEM_NSEMS_MAX 16 +#define _SC_SEM_VALUE_MAX 17 +#define _SC_SIGQUEUE_MAX 18 +#define _SC_TIMER_MAX 19 +#define _SC_TZNAME_MAX 20 +#define _SC_ASYNCHRONOUS_IO 21 +#define _SC_FSYNC 22 +#define _SC_MAPPED_FILES 23 +#define _SC_MEMLOCK 24 +#define _SC_MEMLOCK_RANGE 25 +#define _SC_MEMORY_PROTECTION 26 +#define _SC_MESSAGE_PASSING 27 +#define _SC_PRIORITIZED_IO 28 +#define _SC_REALTIME_SIGNALS 29 +#define _SC_SEMAPHORES 30 +#define _SC_SHARED_MEMORY_OBJECTS 31 +#define _SC_SYNCHRONIZED_IO 32 +#define _SC_TIMERS 33 +#define _SC_AIO_LISTIO_MAX 34 +#define _SC_AIO_MAX 35 +#define _SC_AIO_PRIO_DELTA_MAX 36 +#define _SC_DELAYTIMER_MAX 37 +#define _SC_THREAD_KEYS_MAX 38 +#define _SC_THREAD_STACK_MIN 39 +#define _SC_THREAD_THREADS_MAX 40 +#define _SC_TTY_NAME_MAX 41 +#define _SC_THREADS 42 +#define _SC_THREAD_ATTR_STACKADDR 43 +#define _SC_THREAD_ATTR_STACKSIZE 44 +#define _SC_THREAD_PRIORITY_SCHEDULING 45 +#define _SC_THREAD_PRIO_INHERIT 46 +/* _SC_THREAD_PRIO_PROTECT was _SC_THREAD_PRIO_CEILING in early drafts */ +#define _SC_THREAD_PRIO_PROTECT 47 +#define _SC_THREAD_PRIO_CEILING _SC_THREAD_PRIO_PROTECT +#define _SC_THREAD_PROCESS_SHARED 48 +#define _SC_THREAD_SAFE_FUNCTIONS 49 +#define _SC_GETGR_R_SIZE_MAX 50 +#define _SC_GETPW_R_SIZE_MAX 51 +#define _SC_LOGIN_NAME_MAX 52 +#define _SC_THREAD_DESTRUCTOR_ITERATIONS 53 +#define _SC_ADVISORY_INFO 54 +#define _SC_ATEXIT_MAX 55 +#define _SC_BARRIERS 56 +#define _SC_BC_BASE_MAX 57 +#define _SC_BC_DIM_MAX 58 +#define _SC_BC_SCALE_MAX 59 +#define _SC_BC_STRING_MAX 60 +#define _SC_CLOCK_SELECTION 61 +#define _SC_COLL_WEIGHTS_MAX 62 +#define _SC_CPUTIME 63 +#define _SC_EXPR_NEST_MAX 64 +#define _SC_HOST_NAME_MAX 65 +#define _SC_IOV_MAX 66 +#define _SC_IPV6 67 +#define _SC_LINE_MAX 68 +#define _SC_MONOTONIC_CLOCK 69 +#define _SC_RAW_SOCKETS 70 +#define _SC_READER_WRITER_LOCKS 71 +#define _SC_REGEXP 72 +#define _SC_RE_DUP_MAX 73 +#define _SC_SHELL 74 +#define _SC_SPAWN 75 +#define _SC_SPIN_LOCKS 76 +#define _SC_SPORADIC_SERVER 77 +#define _SC_SS_REPL_MAX 78 +#define _SC_SYMLOOP_MAX 79 +#define _SC_THREAD_CPUTIME 80 +#define _SC_THREAD_SPORADIC_SERVER 81 +#define _SC_TIMEOUTS 82 +#define _SC_TRACE 83 +#define _SC_TRACE_EVENT_FILTER 84 +#define _SC_TRACE_EVENT_NAME_MAX 85 +#define _SC_TRACE_INHERIT 86 +#define _SC_TRACE_LOG 87 +#define _SC_TRACE_NAME_MAX 88 +#define _SC_TRACE_SYS_MAX 89 +#define _SC_TRACE_USER_EVENT_MAX 90 +#define _SC_TYPED_MEMORY_OBJECTS 91 +#define _SC_V7_ILP32_OFF32 92 +#define _SC_V6_ILP32_OFF32 _SC_V7_ILP32_OFF32 +#define _SC_XBS5_ILP32_OFF32 _SC_V7_ILP32_OFF32 +#define _SC_V7_ILP32_OFFBIG 93 +#define _SC_V6_ILP32_OFFBIG _SC_V7_ILP32_OFFBIG +#define _SC_XBS5_ILP32_OFFBIG _SC_V7_ILP32_OFFBIG +#define _SC_V7_LP64_OFF64 94 +#define _SC_V6_LP64_OFF64 _SC_V7_LP64_OFF64 +#define _SC_XBS5_LP64_OFF64 _SC_V7_LP64_OFF64 +#define _SC_V7_LPBIG_OFFBIG 95 +#define _SC_V6_LPBIG_OFFBIG _SC_V7_LPBIG_OFFBIG +#define _SC_XBS5_LPBIG_OFFBIG _SC_V7_LPBIG_OFFBIG +#define _SC_XOPEN_CRYPT 96 +#define _SC_XOPEN_ENH_I18N 97 +#define _SC_XOPEN_LEGACY 98 +#define _SC_XOPEN_REALTIME 99 +#define _SC_STREAM_MAX 100 +#define _SC_PRIORITY_SCHEDULING 101 +#define _SC_XOPEN_REALTIME_THREADS 102 +#define _SC_XOPEN_SHM 103 +#define _SC_XOPEN_STREAMS 104 +#define _SC_XOPEN_UNIX 105 +#define _SC_XOPEN_VERSION 106 +#define _SC_2_CHAR_TERM 107 +#define _SC_2_C_BIND 108 +#define _SC_2_C_DEV 109 +#define _SC_2_FORT_DEV 110 +#define _SC_2_FORT_RUN 111 +#define _SC_2_LOCALEDEF 112 +#define _SC_2_PBS 113 +#define _SC_2_PBS_ACCOUNTING 114 +#define _SC_2_PBS_CHECKPOINT 115 +#define _SC_2_PBS_LOCATE 116 +#define _SC_2_PBS_MESSAGE 117 +#define _SC_2_PBS_TRACK 118 +#define _SC_2_SW_DEV 119 +#define _SC_2_UPE 120 +#define _SC_2_VERSION 121 +#define _SC_THREAD_ROBUST_PRIO_INHERIT 122 +#define _SC_THREAD_ROBUST_PRIO_PROTECT 123 +#define _SC_XOPEN_UUCP 124 + +/* + * pathconf values per IEEE Std 1003.1, 2008 Edition + */ + +#define _PC_LINK_MAX 0 +#define _PC_MAX_CANON 1 +#define _PC_MAX_INPUT 2 +#define _PC_NAME_MAX 3 +#define _PC_PATH_MAX 4 +#define _PC_PIPE_BUF 5 +#define _PC_CHOWN_RESTRICTED 6 +#define _PC_NO_TRUNC 7 +#define _PC_VDISABLE 8 +#define _PC_ASYNC_IO 9 +#define _PC_PRIO_IO 10 +#define _PC_SYNC_IO 11 +#define _PC_FILESIZEBITS 12 +#define _PC_2_SYMLINKS 13 +#define _PC_SYMLINK_MAX 14 +#define _PC_ALLOC_SIZE_MIN 15 +#define _PC_REC_INCR_XFER_SIZE 16 +#define _PC_REC_MAX_XFER_SIZE 17 +#define _PC_REC_MIN_XFER_SIZE 18 +#define _PC_REC_XFER_ALIGN 19 +#define _PC_TIMESTAMP_RESOLUTION 20 +#ifdef __CYGWIN__ +/* Ask for POSIX permission bits support. */ +#define _PC_POSIX_PERMISSIONS 90 +/* Ask for full POSIX permission support including uid/gid settings. */ +#define _PC_POSIX_SECURITY 91 +#endif + +/* + * confstr values per IEEE Std 1003.1, 2004 Edition + */ + +#ifdef __CYGWIN__ /* Only defined on Cygwin for now. */ +#define _CS_PATH 0 +#define _CS_POSIX_V7_ILP32_OFF32_CFLAGS 1 +#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS _CS_POSIX_V7_ILP32_OFF32_CFLAGS +#define _CS_XBS5_ILP32_OFF32_CFLAGS _CS_POSIX_V7_ILP32_OFF32_CFLAGS +#define _CS_POSIX_V7_ILP32_OFF32_LDFLAGS 2 +#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS _CS_POSIX_V7_ILP32_OFF32_LDFLAGS +#define _CS_XBS5_ILP32_OFF32_LDFLAGS _CS_POSIX_V7_ILP32_OFF32_LDFLAGS +#define _CS_POSIX_V7_ILP32_OFF32_LIBS 3 +#define _CS_POSIX_V6_ILP32_OFF32_LIBS _CS_POSIX_V7_ILP32_OFF32_LIBS +#define _CS_XBS5_ILP32_OFF32_LIBS _CS_POSIX_V7_ILP32_OFF32_LIBS +#define _CS_XBS5_ILP32_OFF32_LINTFLAGS 4 +#define _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS 5 +#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS +#define _CS_XBS5_ILP32_OFFBIG_CFLAGS _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS +#define _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS 6 +#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS +#define _CS_XBS5_ILP32_OFFBIG_LDFLAGS _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS +#define _CS_POSIX_V7_ILP32_OFFBIG_LIBS 7 +#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS _CS_POSIX_V7_ILP32_OFFBIG_LIBS +#define _CS_XBS5_ILP32_OFFBIG_LIBS _CS_POSIX_V7_ILP32_OFFBIG_LIBS +#define _CS_XBS5_ILP32_OFFBIG_LINTFLAGS 8 +#define _CS_POSIX_V7_LP64_OFF64_CFLAGS 9 +#define _CS_POSIX_V6_LP64_OFF64_CFLAGS _CS_POSIX_V7_LP64_OFF64_CFLAGS +#define _CS_XBS5_LP64_OFF64_CFLAGS _CS_POSIX_V7_LP64_OFF64_CFLAGS +#define _CS_POSIX_V7_LP64_OFF64_LDFLAGS 10 +#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS _CS_POSIX_V7_LP64_OFF64_LDFLAGS +#define _CS_XBS5_LP64_OFF64_LDFLAGS _CS_POSIX_V7_LP64_OFF64_LDFLAGS +#define _CS_POSIX_V7_LP64_OFF64_LIBS 11 +#define _CS_POSIX_V6_LP64_OFF64_LIBS _CS_POSIX_V7_LP64_OFF64_LIBS +#define _CS_XBS5_LP64_OFF64_LIBS _CS_POSIX_V7_LP64_OFF64_LIBS +#define _CS_XBS5_LP64_OFF64_LINTFLAGS 12 +#define _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS 13 +#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS +#define _CS_XBS5_LPBIG_OFFBIG_CFLAGS _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS +#define _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS 14 +#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS +#define _CS_XBS5_LPBIG_OFFBIG_LDFLAGS _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS +#define _CS_POSIX_V7_LPBIG_OFFBIG_LIBS 15 +#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS _CS_POSIX_V7_LPBIG_OFFBIG_LIBS +#define _CS_XBS5_LPBIG_OFFBIG_LIBS _CS_POSIX_V7_LPBIG_OFFBIG_LIBS +#define _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 16 +#define _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS 17 +#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS +#define _CS_XBS5_WIDTH_RESTRICTED_ENVS _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS +#define _CS_POSIX_V7_THREADS_CFLAGS 18 +#define _CS_POSIX_V7_THREADS_LDFLAGS 19 +#define _CS_V7_ENV 20 +#define _CS_V6_ENV _CS_V7_ENV +#endif #ifdef __cplusplus } diff --git a/tools/sdk/include/newlib/time.h b/tools/sdk/include/newlib/time.h index 954d824d..d7b6612d 100644 --- a/tools/sdk/include/newlib/time.h +++ b/tools/sdk/include/newlib/time.h @@ -1,35 +1,291 @@ -// Copyright 2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * time.h + * + * Struct and function declarations for dealing with time. + */ +#ifndef _TIME_H_ +#define _TIME_H_ -#ifndef _ESP_TIME_H -#define _ESP_TIME_H +#include "_ansi.h" +#include + +#define __need_size_t +#define __need_NULL +#include + +/* Get _CLOCKS_PER_SEC_ */ +#include + +#ifndef _CLOCKS_PER_SEC_ +#define _CLOCKS_PER_SEC_ 1000 +#endif + +#define CLOCKS_PER_SEC _CLOCKS_PER_SEC_ +#define CLK_TCK CLOCKS_PER_SEC + +#include + +_BEGIN_STD_C + +struct tm +{ + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +#ifdef __TM_GMTOFF + long __TM_GMTOFF; +#endif +#ifdef __TM_ZONE + const char *__TM_ZONE; +#endif +}; + +clock_t _EXFUN(clock, (void)); +double _EXFUN(difftime, (time_t _time2, time_t _time1)); +time_t _EXFUN(mktime, (struct tm *_timeptr)); +time_t _EXFUN(time, (time_t *_timer)); +#ifndef _REENT_ONLY +char *_EXFUN(asctime, (const struct tm *_tblock)); +char *_EXFUN(ctime, (const time_t *_time)); +struct tm *_EXFUN(gmtime, (const time_t *_timer)); +struct tm *_EXFUN(localtime,(const time_t *_timer)); +#endif +size_t _EXFUN(strftime, (char *__restrict _s, + size_t _maxsize, const char *__restrict _fmt, + const struct tm *__restrict _t)); + +char *_EXFUN(asctime_r, (const struct tm *__restrict, + char *__restrict)); +char *_EXFUN(ctime_r, (const time_t *, char *)); +struct tm *_EXFUN(gmtime_r, (const time_t *__restrict, + struct tm *__restrict)); +struct tm *_EXFUN(localtime_r, (const time_t *__restrict, + struct tm *__restrict)); + +_END_STD_C #ifdef __cplusplus extern "C" { #endif -#include_next -#define _POSIX_TIMERS 1 -#define CLOCK_MONOTONIC (clockid_t)4 -#define CLOCK_BOOTTIME (clockid_t)4 +#ifndef __STRICT_ANSI__ +char *_EXFUN(strptime, (const char *__restrict, + const char *__restrict, + struct tm *__restrict)); +_VOID _EXFUN(tzset, (_VOID)); +_VOID _EXFUN(_tzset_r, (struct _reent *)); + +typedef struct __tzrule_struct +{ + char ch; + int m; + int n; + int d; + int s; + time_t change; + long offset; /* Match type of _timezone. */ +} __tzrule_type; + +typedef struct __tzinfo_struct +{ + int __tznorth; + int __tzyear; + __tzrule_type __tzrule[2]; +} __tzinfo_type; + +__tzinfo_type *_EXFUN (__gettzinfo, (_VOID)); + +/* getdate functions */ + +#ifdef HAVE_GETDATE +#ifndef _REENT_ONLY +#define getdate_err (*__getdate_err()) +int *_EXFUN(__getdate_err,(_VOID)); + +struct tm * _EXFUN(getdate, (const char *)); +/* getdate_err is set to one of the following values to indicate the error. + 1 the DATEMSK environment variable is null or undefined, + 2 the template file cannot be opened for reading, + 3 failed to get file status information, + 4 the template file is not a regular file, + 5 an error is encountered while reading the template file, + 6 memory allication failed (not enough memory available), + 7 there is no line in the template that matches the input, + 8 invalid input specification */ +#endif /* !_REENT_ONLY */ + +/* getdate_r returns the error code as above */ +int _EXFUN(getdate_r, (const char *, struct tm *)); +#endif /* HAVE_GETDATE */ + +/* defines for the opengroup specifications Derived from Issue 1 of the SVID. */ +extern __IMPORT long _timezone; +extern __IMPORT int _daylight; +extern __IMPORT char *_tzname[2]; + +/* POSIX defines the external tzname being defined in time.h */ +#ifndef tzname +#define tzname _tzname +#endif +#endif /* !__STRICT_ANSI__ */ + +#ifdef __cplusplus +} +#endif + +#include + +#ifdef __CYGWIN__ +#include +#endif /*__CYGWIN__*/ + +#if defined(_POSIX_TIMERS) + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Clocks, P1003.1b-1993, p. 263 */ int _EXFUN(clock_settime, (clockid_t clock_id, const struct timespec *tp)); int _EXFUN(clock_gettime, (clockid_t clock_id, struct timespec *tp)); int _EXFUN(clock_getres, (clockid_t clock_id, struct timespec *res)); +/* Create a Per-Process Timer, P1003.1b-1993, p. 264 */ + +int _EXFUN(timer_create, + (clockid_t clock_id, + struct sigevent *__restrict evp, + timer_t *__restrict timerid)); + +/* Delete a Per_process Timer, P1003.1b-1993, p. 266 */ + +int _EXFUN(timer_delete, (timer_t timerid)); + +/* Per-Process Timers, P1003.1b-1993, p. 267 */ + +int _EXFUN(timer_settime, + (timer_t timerid, int flags, + const struct itimerspec *__restrict value, + struct itimerspec *__restrict ovalue)); +int _EXFUN(timer_gettime, (timer_t timerid, struct itimerspec *value)); +int _EXFUN(timer_getoverrun, (timer_t timerid)); + +/* High Resolution Sleep, P1003.1b-1993, p. 269 */ + +int _EXFUN(nanosleep, (const struct timespec *rqtp, struct timespec *rmtp)); + #ifdef __cplusplus } #endif -#endif /* _ESP_TIME_H */ +#endif /* _POSIX_TIMERS */ + +#if defined(_POSIX_CLOCK_SELECTION) + +#ifdef __cplusplus +extern "C" { +#endif + +int _EXFUN(clock_nanosleep, + (clockid_t clock_id, int flags, const struct timespec *rqtp, + struct timespec *rmtp)); + +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_CLOCK_SELECTION */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* CPU-time Clock Attributes, P1003.4b/D8, p. 54 */ + +/* values for the clock enable attribute */ + +#define CLOCK_ENABLED 1 /* clock is enabled, i.e. counting execution time */ +#define CLOCK_DISABLED 0 /* clock is disabled */ + +/* values for the pthread cputime_clock_allowed attribute */ + +#define CLOCK_ALLOWED 1 /* If a thread is created with this value a */ + /* CPU-time clock attached to that thread */ + /* shall be accessible. */ +#define CLOCK_DISALLOWED 0 /* If a thread is created with this value, the */ + /* thread shall not have a CPU-time clock */ + /* accessible. */ + +/* Manifest Constants, P1003.1b-1993, p. 262 */ + +#define CLOCK_REALTIME (clockid_t)1 + +/* Flag indicating time is "absolute" with respect to the clock + associated with a time. */ + +#define TIMER_ABSTIME 4 + +/* Manifest Constants, P1003.4b/D8, p. 55 */ + +#if defined(_POSIX_CPUTIME) + +/* When used in a clock or timer function call, this is interpreted as + the identifier of the CPU_time clock associated with the PROCESS + making the function call. */ + +#define CLOCK_PROCESS_CPUTIME_ID (clockid_t)2 + +#endif + +#if defined(_POSIX_THREAD_CPUTIME) + +/* When used in a clock or timer function call, this is interpreted as + the identifier of the CPU_time clock associated with the THREAD + making the function call. */ + +#define CLOCK_THREAD_CPUTIME_ID (clockid_t)3 + +#endif + +#if defined(_POSIX_MONOTONIC_CLOCK) + +/* The identifier for the system-wide monotonic clock, which is defined + * as a clock whose value cannot be set via clock_settime() and which + * cannot have backward clock jumps. */ + +#define CLOCK_MONOTONIC (clockid_t)4 + +#endif + +#if defined(_POSIX_CPUTIME) + +/* Accessing a Process CPU-time CLock, P1003.4b/D8, p. 55 */ + +int _EXFUN(clock_getcpuclockid, (pid_t pid, clockid_t *clock_id)); + +#endif /* _POSIX_CPUTIME */ + +#if defined(_POSIX_CPUTIME) || defined(_POSIX_THREAD_CPUTIME) + +/* CPU-time Clock Attribute Access, P1003.4b/D8, p. 56 */ + +int _EXFUN(clock_setenable_attr, (clockid_t clock_id, int attr)); +int _EXFUN(clock_getenable_attr, (clockid_t clock_id, int *attr)); + +#endif /* _POSIX_CPUTIME or _POSIX_THREAD_CPUTIME */ + +#ifdef __cplusplus +} +#endif + +#endif /* _TIME_H_ */ + diff --git a/tools/sdk/include/nghttp/http_parser/http_parser.h b/tools/sdk/include/nghttp/http_parser.h similarity index 100% rename from tools/sdk/include/nghttp/http_parser/http_parser.h rename to tools/sdk/include/nghttp/http_parser.h diff --git a/tools/sdk/include/nvs_flash/nvs.h b/tools/sdk/include/nvs_flash/nvs.h index bcc46563..0cc3ba09 100644 --- a/tools/sdk/include/nvs_flash/nvs.h +++ b/tools/sdk/include/nvs_flash/nvs.h @@ -28,23 +28,32 @@ extern "C" { */ typedef uint32_t nvs_handle; -#define ESP_ERR_NVS_BASE 0x1100 /*!< Starting number of error codes */ -#define ESP_ERR_NVS_NOT_INITIALIZED (ESP_ERR_NVS_BASE + 0x01) /*!< The storage driver is not initialized */ -#define ESP_ERR_NVS_NOT_FOUND (ESP_ERR_NVS_BASE + 0x02) /*!< Id namespace doesn’t exist yet and mode is NVS_READONLY */ -#define ESP_ERR_NVS_TYPE_MISMATCH (ESP_ERR_NVS_BASE + 0x03) /*!< The type of set or get operation doesn't match the type of value stored in NVS */ -#define ESP_ERR_NVS_READ_ONLY (ESP_ERR_NVS_BASE + 0x04) /*!< Storage handle was opened as read only */ -#define ESP_ERR_NVS_NOT_ENOUGH_SPACE (ESP_ERR_NVS_BASE + 0x05) /*!< There is not enough space in the underlying storage to save the value */ -#define ESP_ERR_NVS_INVALID_NAME (ESP_ERR_NVS_BASE + 0x06) /*!< Namespace name doesn’t satisfy constraints */ -#define ESP_ERR_NVS_INVALID_HANDLE (ESP_ERR_NVS_BASE + 0x07) /*!< Handle has been closed or is NULL */ -#define ESP_ERR_NVS_REMOVE_FAILED (ESP_ERR_NVS_BASE + 0x08) /*!< The value wasn’t updated because flash write operation has failed. The value was written however, and update will be finished after re-initialization of nvs, provided that flash operation doesn’t fail again. */ -#define ESP_ERR_NVS_KEY_TOO_LONG (ESP_ERR_NVS_BASE + 0x09) /*!< Key name is too long */ -#define ESP_ERR_NVS_PAGE_FULL (ESP_ERR_NVS_BASE + 0x0a) /*!< Internal error; never returned by nvs API functions */ -#define ESP_ERR_NVS_INVALID_STATE (ESP_ERR_NVS_BASE + 0x0b) /*!< NVS is in an inconsistent state due to a previous error. Call nvs_flash_init and nvs_open again, then retry. */ -#define ESP_ERR_NVS_INVALID_LENGTH (ESP_ERR_NVS_BASE + 0x0c) /*!< String or blob length is not sufficient to store data */ -#define ESP_ERR_NVS_NO_FREE_PAGES (ESP_ERR_NVS_BASE + 0x0d) /*!< NVS partition doesn't contain any empty pages. This may happen if NVS partition was truncated. Erase the whole partition and call nvs_flash_init again. */ -#define ESP_ERR_NVS_VALUE_TOO_LONG (ESP_ERR_NVS_BASE + 0x0e) /*!< String or blob length is longer than supported by the implementation */ -#define ESP_ERR_NVS_PART_NOT_FOUND (ESP_ERR_NVS_BASE + 0x0f) /*!< Partition with specified name is not found in the partition table */ -#define ESP_ERR_NVS_NEW_VERSION_FOUND (ESP_ERR_NVS_BASE + 0x10) /*!< NVS partition contains data in new format and cannot be recognized by this version of code */ +#define ESP_ERR_NVS_BASE 0x1100 /*!< Starting number of error codes */ +#define ESP_ERR_NVS_NOT_INITIALIZED (ESP_ERR_NVS_BASE + 0x01) /*!< The storage driver is not initialized */ +#define ESP_ERR_NVS_NOT_FOUND (ESP_ERR_NVS_BASE + 0x02) /*!< Id namespace doesn’t exist yet and mode is NVS_READONLY */ +#define ESP_ERR_NVS_TYPE_MISMATCH (ESP_ERR_NVS_BASE + 0x03) /*!< The type of set or get operation doesn't match the type of value stored in NVS */ +#define ESP_ERR_NVS_READ_ONLY (ESP_ERR_NVS_BASE + 0x04) /*!< Storage handle was opened as read only */ +#define ESP_ERR_NVS_NOT_ENOUGH_SPACE (ESP_ERR_NVS_BASE + 0x05) /*!< There is not enough space in the underlying storage to save the value */ +#define ESP_ERR_NVS_INVALID_NAME (ESP_ERR_NVS_BASE + 0x06) /*!< Namespace name doesn’t satisfy constraints */ +#define ESP_ERR_NVS_INVALID_HANDLE (ESP_ERR_NVS_BASE + 0x07) /*!< Handle has been closed or is NULL */ +#define ESP_ERR_NVS_REMOVE_FAILED (ESP_ERR_NVS_BASE + 0x08) /*!< The value wasn’t updated because flash write operation has failed. The value was written however, and update will be finished after re-initialization of nvs, provided that flash operation doesn’t fail again. */ +#define ESP_ERR_NVS_KEY_TOO_LONG (ESP_ERR_NVS_BASE + 0x09) /*!< Key name is too long */ +#define ESP_ERR_NVS_PAGE_FULL (ESP_ERR_NVS_BASE + 0x0a) /*!< Internal error; never returned by nvs API functions */ +#define ESP_ERR_NVS_INVALID_STATE (ESP_ERR_NVS_BASE + 0x0b) /*!< NVS is in an inconsistent state due to a previous error. Call nvs_flash_init and nvs_open again, then retry. */ +#define ESP_ERR_NVS_INVALID_LENGTH (ESP_ERR_NVS_BASE + 0x0c) /*!< String or blob length is not sufficient to store data */ +#define ESP_ERR_NVS_NO_FREE_PAGES (ESP_ERR_NVS_BASE + 0x0d) /*!< NVS partition doesn't contain any empty pages. This may happen if NVS partition was truncated. Erase the whole partition and call nvs_flash_init again. */ +#define ESP_ERR_NVS_VALUE_TOO_LONG (ESP_ERR_NVS_BASE + 0x0e) /*!< String or blob length is longer than supported by the implementation */ +#define ESP_ERR_NVS_PART_NOT_FOUND (ESP_ERR_NVS_BASE + 0x0f) /*!< Partition with specified name is not found in the partition table */ + +#define ESP_ERR_NVS_NEW_VERSION_FOUND (ESP_ERR_NVS_BASE + 0x10) /*!< NVS partition contains data in new format and cannot be recognized by this version of code */ +#define ESP_ERR_NVS_XTS_ENCR_FAILED (ESP_ERR_NVS_BASE + 0x11) /*!< XTS encryption failed while writing NVS entry */ +#define ESP_ERR_NVS_XTS_DECR_FAILED (ESP_ERR_NVS_BASE + 0x12) /*!< XTS decryption failed while reading NVS entry */ +#define ESP_ERR_NVS_XTS_CFG_FAILED (ESP_ERR_NVS_BASE + 0x13) /*!< XTS configuration setting failed */ +#define ESP_ERR_NVS_XTS_CFG_NOT_FOUND (ESP_ERR_NVS_BASE + 0x14) /*!< XTS configuration not found */ +#define ESP_ERR_NVS_ENCR_NOT_SUPPORTED (ESP_ERR_NVS_BASE + 0x15) /*!< NVS encryption is not supported in this version */ +#define ESP_ERR_NVS_KEYS_NOT_INITIALIZED (ESP_ERR_NVS_BASE + 0x16) /*!< NVS key partition is uninitialized */ +#define ESP_ERR_NVS_CORRUPT_KEY_PART (ESP_ERR_NVS_BASE + 0x17) /*!< NVS key partition is corrupt */ + #define NVS_DEFAULT_PART_NAME "nvs" /*!< Default partition name of the NVS partition in the partition table */ /** diff --git a/tools/sdk/include/nvs_flash/nvs_flash.h b/tools/sdk/include/nvs_flash/nvs_flash.h index a7ef7f45..55b218ec 100644 --- a/tools/sdk/include/nvs_flash/nvs_flash.h +++ b/tools/sdk/include/nvs_flash/nvs_flash.h @@ -19,6 +19,18 @@ extern "C" { #endif #include "nvs.h" +#include "esp_partition.h" + + +#define NVS_KEY_SIZE 32 // AES-256 + +/** + * @brief Key for encryption and decryption + */ +typedef struct { + uint8_t eky[NVS_KEY_SIZE]; /*!< XTS encryption and decryption key*/ + uint8_t tky[NVS_KEY_SIZE]; /*!< XTS tweak key */ +} nvs_sec_cfg_t; /** * @brief Initialize the default NVS partition. @@ -99,6 +111,81 @@ esp_err_t nvs_flash_erase(void); */ esp_err_t nvs_flash_erase_partition(const char *part_name); + +/** + * @brief Initialize the default NVS partition. + * + * This API initialises the default NVS partition. The default NVS partition + * is the one that is labeled "nvs" in the partition table. + * + * @param[in] cfg Security configuration (keys) to be used for NVS encryption/decryption. + * If cfg is NULL, no encryption is used. + * + * @return + * - ESP_OK if storage was successfully initialized. + * - ESP_ERR_NVS_NO_FREE_PAGES if the NVS storage contains no empty pages + * (which may happen if NVS partition was truncated) + * - ESP_ERR_NOT_FOUND if no partition with label "nvs" is found in the partition table + * - one of the error codes from the underlying flash storage driver + */ +esp_err_t nvs_flash_secure_init(nvs_sec_cfg_t* cfg); + +/** + * @brief Initialize NVS flash storage for the specified partition. + * + * @param[in] partition_label Label of the partition. Note that internally a reference to + * passed value is kept and it should be accessible for future operations + * + * @param[in] cfg Security configuration (keys) to be used for NVS encryption/decryption. + * If cfg is null, no encryption/decryption is used. + * @return + * - ESP_OK if storage was successfully initialized. + * - ESP_ERR_NVS_NO_FREE_PAGES if the NVS storage contains no empty pages + * (which may happen if NVS partition was truncated) + * - ESP_ERR_NOT_FOUND if specified partition is not found in the partition table + * - one of the error codes from the underlying flash storage driver + */ +esp_err_t nvs_flash_secure_init_partition(const char *partition_label, nvs_sec_cfg_t* cfg); + +/** + * @brief Generate and store NVS keys in the provided esp partition + * + * @param[in] partition Pointer to partition structure obtained using + * esp_partition_find_first or esp_partition_get. + * Must be non-NULL. + * @param[out] cfg Pointer to nvs security configuration structure. + * Pointer must be non-NULL. + * Generated keys will be populated in this structure. + * + * + * @return + * -ESP_OK, if cfg was read successfully; + * -or error codes from esp_partition_write/erase APIs. + */ + +esp_err_t nvs_flash_generate_keys(const esp_partition_t* partition, nvs_sec_cfg_t* cfg); + + +/** + * @brief Read NVS security configuration from a partition. + * + * @param[in] partition Pointer to partition structure obtained using + * esp_partition_find_first or esp_partition_get. + * Must be non-NULL. + * @param[out] cfg Pointer to nvs security configuration structure. + * Pointer must be non-NULL. + * + * @note Provided parition is assumed to be marked 'encrypted'. + * + * @return + * -ESP_OK, if cfg was read successfully; + * -ESP_ERR_NVS_KEYS_NOT_INITIALIZED, if the partition is not yet written with keys. + * -ESP_ERR_NVS_CORRUPT_KEY_PART, if the partition containing keys is found to be corrupt + * -or error codes from esp_partition_read API. + */ + +esp_err_t nvs_flash_read_security_cfg(const esp_partition_t* partition, nvs_sec_cfg_t* cfg); + #ifdef __cplusplus } #endif diff --git a/tools/sdk/include/protobuf-c/protobuf-c/protobuf-c.h b/tools/sdk/include/protobuf-c/protobuf-c/protobuf-c.h new file mode 100755 index 00000000..c8fa4fc2 --- /dev/null +++ b/tools/sdk/include/protobuf-c/protobuf-c/protobuf-c.h @@ -0,0 +1,1106 @@ +/* + * Copyright (c) 2008-2017, Dave Benson and the protobuf-c authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/*! \file + * \mainpage Introduction + * + * This is [protobuf-c], a C implementation of [Protocol Buffers]. + * + * This file defines the public API for the `libprotobuf-c` support library. + * This API includes interfaces that can be used directly by client code as well + * as the interfaces used by the code generated by the `protoc-c` compiler. + * + * The `libprotobuf-c` support library performs the actual serialization and + * deserialization of Protocol Buffers messages. It interacts with structures, + * definitions, and metadata generated by the `protoc-c` compiler from .proto + * files. + * + * \authors Dave Benson and the `protobuf-c` authors. + * + * \copyright 2008-2014. Licensed under the terms of the [BSD-2-Clause] license. + * + * [protobuf-c]: https://github.com/protobuf-c/protobuf-c + * [Protocol Buffers]: https://developers.google.com/protocol-buffers/ + * [BSD-2-Clause]: http://opensource.org/licenses/BSD-2-Clause + * + * \page gencode Generated Code + * + * For each enum, we generate a C enum. For each message, we generate a C + * structure which can be cast to a `ProtobufCMessage`. + * + * For each enum and message, we generate a descriptor object that allows us to + * implement a kind of reflection on the structures. + * + * First, some naming conventions: + * + * - The name of the type for enums and messages and services is camel case + * (meaning WordsAreCrammedTogether) except that double underscores are used + * to delimit scopes. For example, the following `.proto` file: + * +~~~{.proto} + package foo.bar; + message BazBah { + optional int32 val = 1; + } +~~~ + * + * would generate a C type `Foo__Bar__BazBah`. + * + * - Identifiers for functions and globals are all lowercase, with camel case + * words separated by single underscores. For example, one of the function + * prototypes generated by `protoc-c` for the above example: + * +~~~{.c} +Foo__Bar__BazBah * + foo__bar__baz_bah__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +~~~ + * + * - Identifiers for enum values contain an uppercase prefix which embeds the + * package name and the enum type name. + * + * - A double underscore is used to separate further components of identifier + * names. + * + * For example, in the name of the unpack function above, the package name + * `foo.bar` has become `foo__bar`, the message name BazBah has become + * `baz_bah`, and the method name is `unpack`. These are all joined with double + * underscores to form the C identifier `foo__bar__baz_bah__unpack`. + * + * We also generate descriptor objects for messages and enums. These are + * declared in the `.pb-c.h` files: + * +~~~{.c} +extern const ProtobufCMessageDescriptor foo__bar__baz_bah__descriptor; +~~~ + * + * The message structures all begin with `ProtobufCMessageDescriptor *` which is + * sufficient to allow them to be cast to `ProtobufCMessage`. + * + * For each message defined in a `.proto` file, we generate a number of + * functions and macros. Each function name contains a prefix based on the + * package name and message name in order to make it a unique C identifier. + * + * - `INIT`. Statically initializes a message object, initializing its + * descriptor and setting its fields to default values. Uninitialized + * messages cannot be processed by the protobuf-c library. + * +~~~{.c} +#define FOO__BAR__BAZ_BAH__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&foo__bar__baz_bah__descriptor), 0 } +~~~ + * - `init()`. Initializes a message object, initializing its descriptor and + * setting its fields to default values. Uninitialized messages cannot be + * processed by the protobuf-c library. + * +~~~{.c} +void foo__bar__baz_bah__init + (Foo__Bar__BazBah *message); +~~~ + * - `unpack()`. Unpacks data for a particular message format. Note that the + * `allocator` parameter is usually `NULL` to indicate that the system's + * `malloc()` and `free()` functions should be used for dynamically allocating + * memory. + * +~~~{.c} +Foo__Bar__BazBah * + foo__bar__baz_bah__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +~~~ + * + * - `free_unpacked()`. Frees a message object obtained with the `unpack()` + * method. Freeing `NULL` is allowed (the same as with `free()`). + * +~~~{.c} +void foo__bar__baz_bah__free_unpacked + (Foo__Bar__BazBah *message, + ProtobufCAllocator *allocator); +~~~ + * + * - `get_packed_size()`. Calculates the length in bytes of the serialized + * representation of the message object. + * +~~~{.c} +size_t foo__bar__baz_bah__get_packed_size + (const Foo__Bar__BazBah *message); +~~~ + * + * - `pack()`. Pack a message object into a preallocated buffer. Assumes that + * the buffer is large enough. (Use `get_packed_size()` first.) + * +~~~{.c} +size_t foo__bar__baz_bah__pack + (const Foo__Bar__BazBah *message, + uint8_t *out); +~~~ + * + * - `pack_to_buffer()`. Packs a message into a "virtual buffer". This is an + * object which defines an "append bytes" callback to consume data as it is + * serialized. + * +~~~{.c} +size_t foo__bar__baz_bah__pack_to_buffer + (const Foo__Bar__BazBah *message, + ProtobufCBuffer *buffer); +~~~ + * + * \page pack Packing and unpacking messages + * + * To pack a message, first compute the packed size of the message with + * protobuf_c_message_get_packed_size(), then allocate a buffer of at least + * that size, then call protobuf_c_message_pack(). + * + * Alternatively, a message can be serialized without calculating the final size + * first. Use the protobuf_c_message_pack_to_buffer() function and provide a + * ProtobufCBuffer object which implements an "append" method that consumes + * data. + * + * To unpack a message, call the protobuf_c_message_unpack() function. The + * result can be cast to an object of the type that matches the descriptor for + * the message. + * + * The result of unpacking a message should be freed with + * protobuf_c_message_free_unpacked(). + */ + +#ifndef PROTOBUF_C_H +#define PROTOBUF_C_H + +#include +#include +#include +#include + +#ifdef __cplusplus +# define PROTOBUF_C__BEGIN_DECLS extern "C" { +# define PROTOBUF_C__END_DECLS } +#else +# define PROTOBUF_C__BEGIN_DECLS +# define PROTOBUF_C__END_DECLS +#endif + +PROTOBUF_C__BEGIN_DECLS + +#if defined(_WIN32) && defined(PROTOBUF_C_USE_SHARED_LIB) +# ifdef PROTOBUF_C_EXPORT +# define PROTOBUF_C__API __declspec(dllexport) +# else +# define PROTOBUF_C__API __declspec(dllimport) +# endif +#else +# define PROTOBUF_C__API +#endif + +#if !defined(PROTOBUF_C__NO_DEPRECATED) && \ + ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +# define PROTOBUF_C__DEPRECATED __attribute__((__deprecated__)) +#else +# define PROTOBUF_C__DEPRECATED +#endif + +#ifndef PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE + #define PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(enum_name) \ + , _##enum_name##_IS_INT_SIZE = INT_MAX +#endif + +#define PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC 0x14159bc3 +#define PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC 0x28aaeef9 +#define PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC 0x114315af + +/* Empty string used for initializers */ +extern const char protobuf_c_empty_string[]; + +/** + * \defgroup api Public API + * + * This is the public API for `libprotobuf-c`. These interfaces are stable and + * subject to Semantic Versioning guarantees. + * + * @{ + */ + +/** + * Values for the `flags` word in `ProtobufCFieldDescriptor`. + */ +typedef enum { + /** Set if the field is repeated and marked with the `packed` option. */ + PROTOBUF_C_FIELD_FLAG_PACKED = (1 << 0), + + /** Set if the field is marked with the `deprecated` option. */ + PROTOBUF_C_FIELD_FLAG_DEPRECATED = (1 << 1), + + /** Set if the field is a member of a oneof (union). */ + PROTOBUF_C_FIELD_FLAG_ONEOF = (1 << 2), +} ProtobufCFieldFlag; + +/** + * Message field rules. + * + * \see [Defining A Message Type] in the Protocol Buffers documentation. + * + * [Defining A Message Type]: + * https://developers.google.com/protocol-buffers/docs/proto#simple + */ +typedef enum { + /** A well-formed message must have exactly one of this field. */ + PROTOBUF_C_LABEL_REQUIRED, + + /** + * A well-formed message can have zero or one of this field (but not + * more than one). + */ + PROTOBUF_C_LABEL_OPTIONAL, + + /** + * This field can be repeated any number of times (including zero) in a + * well-formed message. The order of the repeated values will be + * preserved. + */ + PROTOBUF_C_LABEL_REPEATED, + + /** + * This field has no label. This is valid only in proto3 and is + * equivalent to OPTIONAL but no "has" quantifier will be consulted. + */ + PROTOBUF_C_LABEL_NONE, +} ProtobufCLabel; + +/** + * Field value types. + * + * \see [Scalar Value Types] in the Protocol Buffers documentation. + * + * [Scalar Value Types]: + * https://developers.google.com/protocol-buffers/docs/proto#scalar + */ +typedef enum { + PROTOBUF_C_TYPE_INT32, /**< int32 */ + PROTOBUF_C_TYPE_SINT32, /**< signed int32 */ + PROTOBUF_C_TYPE_SFIXED32, /**< signed int32 (4 bytes) */ + PROTOBUF_C_TYPE_INT64, /**< int64 */ + PROTOBUF_C_TYPE_SINT64, /**< signed int64 */ + PROTOBUF_C_TYPE_SFIXED64, /**< signed int64 (8 bytes) */ + PROTOBUF_C_TYPE_UINT32, /**< unsigned int32 */ + PROTOBUF_C_TYPE_FIXED32, /**< unsigned int32 (4 bytes) */ + PROTOBUF_C_TYPE_UINT64, /**< unsigned int64 */ + PROTOBUF_C_TYPE_FIXED64, /**< unsigned int64 (8 bytes) */ + PROTOBUF_C_TYPE_FLOAT, /**< float */ + PROTOBUF_C_TYPE_DOUBLE, /**< double */ + PROTOBUF_C_TYPE_BOOL, /**< boolean */ + PROTOBUF_C_TYPE_ENUM, /**< enumerated type */ + PROTOBUF_C_TYPE_STRING, /**< UTF-8 or ASCII string */ + PROTOBUF_C_TYPE_BYTES, /**< arbitrary byte sequence */ + PROTOBUF_C_TYPE_MESSAGE, /**< nested message */ +} ProtobufCType; + +/** + * Field wire types. + * + * \see [Message Structure] in the Protocol Buffers documentation. + * + * [Message Structure]: + * https://developers.google.com/protocol-buffers/docs/encoding#structure + */ +typedef enum { + PROTOBUF_C_WIRE_TYPE_VARINT = 0, + PROTOBUF_C_WIRE_TYPE_64BIT = 1, + PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED = 2, + /* "Start group" and "end group" wire types are unsupported. */ + PROTOBUF_C_WIRE_TYPE_32BIT = 5, +} ProtobufCWireType; + +struct ProtobufCAllocator; +struct ProtobufCBinaryData; +struct ProtobufCBuffer; +struct ProtobufCBufferSimple; +struct ProtobufCEnumDescriptor; +struct ProtobufCEnumValue; +struct ProtobufCEnumValueIndex; +struct ProtobufCFieldDescriptor; +struct ProtobufCIntRange; +struct ProtobufCMessage; +struct ProtobufCMessageDescriptor; +struct ProtobufCMessageUnknownField; +struct ProtobufCMethodDescriptor; +struct ProtobufCService; +struct ProtobufCServiceDescriptor; + +typedef struct ProtobufCAllocator ProtobufCAllocator; +typedef struct ProtobufCBinaryData ProtobufCBinaryData; +typedef struct ProtobufCBuffer ProtobufCBuffer; +typedef struct ProtobufCBufferSimple ProtobufCBufferSimple; +typedef struct ProtobufCEnumDescriptor ProtobufCEnumDescriptor; +typedef struct ProtobufCEnumValue ProtobufCEnumValue; +typedef struct ProtobufCEnumValueIndex ProtobufCEnumValueIndex; +typedef struct ProtobufCFieldDescriptor ProtobufCFieldDescriptor; +typedef struct ProtobufCIntRange ProtobufCIntRange; +typedef struct ProtobufCMessage ProtobufCMessage; +typedef struct ProtobufCMessageDescriptor ProtobufCMessageDescriptor; +typedef struct ProtobufCMessageUnknownField ProtobufCMessageUnknownField; +typedef struct ProtobufCMethodDescriptor ProtobufCMethodDescriptor; +typedef struct ProtobufCService ProtobufCService; +typedef struct ProtobufCServiceDescriptor ProtobufCServiceDescriptor; + +/** Boolean type. */ +typedef int protobuf_c_boolean; + +typedef void (*ProtobufCClosure)(const ProtobufCMessage *, void *closure_data); +typedef void (*ProtobufCMessageInit)(ProtobufCMessage *); +typedef void (*ProtobufCServiceDestroy)(ProtobufCService *); + +/** + * Structure for defining a custom memory allocator. + */ +struct ProtobufCAllocator { + /** Function to allocate memory. */ + void *(*alloc)(void *allocator_data, size_t size); + + /** Function to free memory. */ + void (*free)(void *allocator_data, void *pointer); + + /** Opaque pointer passed to `alloc` and `free` functions. */ + void *allocator_data; +}; + +/** + * Structure for the protobuf `bytes` scalar type. + * + * The data contained in a `ProtobufCBinaryData` is an arbitrary sequence of + * bytes. It may contain embedded `NUL` characters and is not required to be + * `NUL`-terminated. + */ +struct ProtobufCBinaryData { + size_t len; /**< Number of bytes in the `data` field. */ + uint8_t *data; /**< Data bytes. */ +}; + +/** + * Structure for defining a virtual append-only buffer. Used by + * protobuf_c_message_pack_to_buffer() to abstract the consumption of serialized + * bytes. + * + * `ProtobufCBuffer` "subclasses" may be defined on the stack. For example, to + * write to a `FILE` object: + * +~~~{.c} +typedef struct { + ProtobufCBuffer base; + FILE *fp; +} BufferAppendToFile; + +static void +my_buffer_file_append(ProtobufCBuffer *buffer, + size_t len, + const uint8_t *data) +{ + BufferAppendToFile *file_buf = (BufferAppendToFile *) buffer; + fwrite(data, len, 1, file_buf->fp); // XXX: No error handling! +} +~~~ + * + * To use this new type of ProtobufCBuffer, it could be called as follows: + * +~~~{.c} +... +BufferAppendToFile tmp = {0}; +tmp.base.append = my_buffer_file_append; +tmp.fp = fp; +protobuf_c_message_pack_to_buffer(&message, &tmp); +... +~~~ + */ +struct ProtobufCBuffer { + /** Append function. Consumes the `len` bytes stored at `data`. */ + void (*append)(ProtobufCBuffer *buffer, + size_t len, + const uint8_t *data); +}; + +/** + * Simple buffer "subclass" of `ProtobufCBuffer`. + * + * A `ProtobufCBufferSimple` object is declared on the stack and uses a + * scratch buffer provided by the user for the initial allocation. It performs + * exponential resizing, using dynamically allocated memory. A + * `ProtobufCBufferSimple` object can be created and used as follows: + * +~~~{.c} +uint8_t pad[128]; +ProtobufCBufferSimple simple = PROTOBUF_C_BUFFER_SIMPLE_INIT(pad); +ProtobufCBuffer *buffer = (ProtobufCBuffer *) &simple; +~~~ + * + * `buffer` can now be used with `protobuf_c_message_pack_to_buffer()`. Once a + * message has been serialized to a `ProtobufCBufferSimple` object, the + * serialized data bytes can be accessed from the `.data` field. + * + * To free the memory allocated by a `ProtobufCBufferSimple` object, if any, + * call PROTOBUF_C_BUFFER_SIMPLE_CLEAR() on the object, for example: + * +~~~{.c} +PROTOBUF_C_BUFFER_SIMPLE_CLEAR(&simple); +~~~ + * + * \see PROTOBUF_C_BUFFER_SIMPLE_INIT + * \see PROTOBUF_C_BUFFER_SIMPLE_CLEAR + */ +struct ProtobufCBufferSimple { + /** "Base class". */ + ProtobufCBuffer base; + /** Number of bytes allocated in `data`. */ + size_t alloced; + /** Number of bytes currently stored in `data`. */ + size_t len; + /** Data bytes. */ + uint8_t *data; + /** Whether `data` must be freed. */ + protobuf_c_boolean must_free_data; + /** Allocator to use. May be NULL to indicate the system allocator. */ + ProtobufCAllocator *allocator; +}; + +/** + * Describes an enumeration as a whole, with all of its values. + */ +struct ProtobufCEnumDescriptor { + /** Magic value checked to ensure that the API is used correctly. */ + uint32_t magic; + + /** The qualified name (e.g., "namespace.Type"). */ + const char *name; + /** The unqualified name as given in the .proto file (e.g., "Type"). */ + const char *short_name; + /** Identifier used in generated C code. */ + const char *c_name; + /** The dot-separated namespace. */ + const char *package_name; + + /** Number elements in `values`. */ + unsigned n_values; + /** Array of distinct values, sorted by numeric value. */ + const ProtobufCEnumValue *values; + + /** Number of elements in `values_by_name`. */ + unsigned n_value_names; + /** Array of named values, including aliases, sorted by name. */ + const ProtobufCEnumValueIndex *values_by_name; + + /** Number of elements in `value_ranges`. */ + unsigned n_value_ranges; + /** Value ranges, for faster lookups by numeric value. */ + const ProtobufCIntRange *value_ranges; + + /** Reserved for future use. */ + void *reserved1; + /** Reserved for future use. */ + void *reserved2; + /** Reserved for future use. */ + void *reserved3; + /** Reserved for future use. */ + void *reserved4; +}; + +/** + * Represents a single value of an enumeration. + */ +struct ProtobufCEnumValue { + /** The string identifying this value in the .proto file. */ + const char *name; + + /** The string identifying this value in generated C code. */ + const char *c_name; + + /** The numeric value assigned in the .proto file. */ + int value; +}; + +/** + * Used by `ProtobufCEnumDescriptor` to look up enum values. + */ +struct ProtobufCEnumValueIndex { + /** Name of the enum value. */ + const char *name; + /** Index into values[] array. */ + unsigned index; +}; + +/** + * Describes a single field in a message. + */ +struct ProtobufCFieldDescriptor { + /** Name of the field as given in the .proto file. */ + const char *name; + + /** Tag value of the field as given in the .proto file. */ + uint32_t id; + + /** Whether the field is `REQUIRED`, `OPTIONAL`, or `REPEATED`. */ + ProtobufCLabel label; + + /** The type of the field. */ + ProtobufCType type; + + /** + * The offset in bytes of the message's C structure's quantifier field + * (the `has_MEMBER` field for optional members or the `n_MEMBER` field + * for repeated members or the case enum for oneofs). + */ + unsigned quantifier_offset; + + /** + * The offset in bytes into the message's C structure for the member + * itself. + */ + unsigned offset; + + /** + * A type-specific descriptor. + * + * If `type` is `PROTOBUF_C_TYPE_ENUM`, then `descriptor` points to the + * corresponding `ProtobufCEnumDescriptor`. + * + * If `type` is `PROTOBUF_C_TYPE_MESSAGE`, then `descriptor` points to + * the corresponding `ProtobufCMessageDescriptor`. + * + * Otherwise this field is NULL. + */ + const void *descriptor; /* for MESSAGE and ENUM types */ + + /** The default value for this field, if defined. May be NULL. */ + const void *default_value; + + /** + * A flag word. Zero or more of the bits defined in the + * `ProtobufCFieldFlag` enum may be set. + */ + uint32_t flags; + + /** Reserved for future use. */ + unsigned reserved_flags; + /** Reserved for future use. */ + void *reserved2; + /** Reserved for future use. */ + void *reserved3; +}; + +/** + * Helper structure for optimizing int => index lookups in the case + * where the keys are mostly consecutive values, as they presumably are for + * enums and fields. + * + * The data structures requires that the values in the original array are + * sorted. + */ +struct ProtobufCIntRange { + int start_value; + unsigned orig_index; + /* + * NOTE: the number of values in the range can be inferred by looking + * at the next element's orig_index. A dummy element is added to make + * this simple. + */ +}; + +/** + * An instance of a message. + * + * `ProtobufCMessage` is a light-weight "base class" for all messages. + * + * In particular, `ProtobufCMessage` doesn't have any allocation policy + * associated with it. That's because it's common to create `ProtobufCMessage` + * objects on the stack. In fact, that's what we recommend for sending messages. + * If the object is allocated from the stack, you can't really have a memory + * leak. + * + * This means that calls to functions like protobuf_c_message_unpack() which + * return a `ProtobufCMessage` must be paired with a call to a free function, + * like protobuf_c_message_free_unpacked(). + */ +struct ProtobufCMessage { + /** The descriptor for this message type. */ + const ProtobufCMessageDescriptor *descriptor; + /** The number of elements in `unknown_fields`. */ + unsigned n_unknown_fields; + /** The fields that weren't recognized by the parser. */ + ProtobufCMessageUnknownField *unknown_fields; +}; + +/** + * Describes a message. + */ +struct ProtobufCMessageDescriptor { + /** Magic value checked to ensure that the API is used correctly. */ + uint32_t magic; + + /** The qualified name (e.g., "namespace.Type"). */ + const char *name; + /** The unqualified name as given in the .proto file (e.g., "Type"). */ + const char *short_name; + /** Identifier used in generated C code. */ + const char *c_name; + /** The dot-separated namespace. */ + const char *package_name; + + /** + * Size in bytes of the C structure representing an instance of this + * type of message. + */ + size_t sizeof_message; + + /** Number of elements in `fields`. */ + unsigned n_fields; + /** Field descriptors, sorted by tag number. */ + const ProtobufCFieldDescriptor *fields; + /** Used for looking up fields by name. */ + const unsigned *fields_sorted_by_name; + + /** Number of elements in `field_ranges`. */ + unsigned n_field_ranges; + /** Used for looking up fields by id. */ + const ProtobufCIntRange *field_ranges; + + /** Message initialisation function. */ + ProtobufCMessageInit message_init; + + /** Reserved for future use. */ + void *reserved1; + /** Reserved for future use. */ + void *reserved2; + /** Reserved for future use. */ + void *reserved3; +}; + +/** + * An unknown message field. + */ +struct ProtobufCMessageUnknownField { + /** The tag number. */ + uint32_t tag; + /** The wire type of the field. */ + ProtobufCWireType wire_type; + /** Number of bytes in `data`. */ + size_t len; + /** Field data. */ + uint8_t *data; +}; + +/** + * Method descriptor. + */ +struct ProtobufCMethodDescriptor { + /** Method name. */ + const char *name; + /** Input message descriptor. */ + const ProtobufCMessageDescriptor *input; + /** Output message descriptor. */ + const ProtobufCMessageDescriptor *output; +}; + +/** + * Service. + */ +struct ProtobufCService { + /** Service descriptor. */ + const ProtobufCServiceDescriptor *descriptor; + /** Function to invoke the service. */ + void (*invoke)(ProtobufCService *service, + unsigned method_index, + const ProtobufCMessage *input, + ProtobufCClosure closure, + void *closure_data); + /** Function to destroy the service. */ + void (*destroy)(ProtobufCService *service); +}; + +/** + * Service descriptor. + */ +struct ProtobufCServiceDescriptor { + /** Magic value checked to ensure that the API is used correctly. */ + uint32_t magic; + + /** Service name. */ + const char *name; + /** Short version of service name. */ + const char *short_name; + /** C identifier for the service name. */ + const char *c_name; + /** Package name. */ + const char *package; + /** Number of elements in `methods`. */ + unsigned n_methods; + /** Method descriptors, in the order defined in the .proto file. */ + const ProtobufCMethodDescriptor *methods; + /** Sort index of methods. */ + const unsigned *method_indices_by_name; +}; + +/** + * Get the version of the protobuf-c library. Note that this is the version of + * the library linked against, not the version of the headers compiled against. + * + * \return A string containing the version number of protobuf-c. + */ +PROTOBUF_C__API +const char * +protobuf_c_version(void); + +/** + * Get the version of the protobuf-c library. Note that this is the version of + * the library linked against, not the version of the headers compiled against. + * + * \return A 32 bit unsigned integer containing the version number of + * protobuf-c, represented in base-10 as (MAJOR*1E6) + (MINOR*1E3) + PATCH. + */ +PROTOBUF_C__API +uint32_t +protobuf_c_version_number(void); + +/** + * The version of the protobuf-c headers, represented as a string using the same + * format as protobuf_c_version(). + */ +#define PROTOBUF_C_VERSION "1.3.0" + +/** + * The version of the protobuf-c headers, represented as an integer using the + * same format as protobuf_c_version_number(). + */ +#define PROTOBUF_C_VERSION_NUMBER 1003000 + +/** + * The minimum protoc-c version which works with the current version of the + * protobuf-c headers. + */ +#define PROTOBUF_C_MIN_COMPILER_VERSION 1000000 + +/** + * Look up a `ProtobufCEnumValue` from a `ProtobufCEnumDescriptor` by name. + * + * \param desc + * The `ProtobufCEnumDescriptor` object. + * \param name + * The `name` field from the corresponding `ProtobufCEnumValue` object to + * match. + * \return + * A `ProtobufCEnumValue` object. + * \retval NULL + * If not found or if the optimize_for = CODE_SIZE option was set. + */ +PROTOBUF_C__API +const ProtobufCEnumValue * +protobuf_c_enum_descriptor_get_value_by_name( + const ProtobufCEnumDescriptor *desc, + const char *name); + +/** + * Look up a `ProtobufCEnumValue` from a `ProtobufCEnumDescriptor` by numeric + * value. + * + * \param desc + * The `ProtobufCEnumDescriptor` object. + * \param value + * The `value` field from the corresponding `ProtobufCEnumValue` object to + * match. + * + * \return + * A `ProtobufCEnumValue` object. + * \retval NULL + * If not found. + */ +PROTOBUF_C__API +const ProtobufCEnumValue * +protobuf_c_enum_descriptor_get_value( + const ProtobufCEnumDescriptor *desc, + int value); + +/** + * Look up a `ProtobufCFieldDescriptor` from a `ProtobufCMessageDescriptor` by + * the name of the field. + * + * \param desc + * The `ProtobufCMessageDescriptor` object. + * \param name + * The name of the field. + * \return + * A `ProtobufCFieldDescriptor` object. + * \retval NULL + * If not found or if the optimize_for = CODE_SIZE option was set. + */ +PROTOBUF_C__API +const ProtobufCFieldDescriptor * +protobuf_c_message_descriptor_get_field_by_name( + const ProtobufCMessageDescriptor *desc, + const char *name); + +/** + * Look up a `ProtobufCFieldDescriptor` from a `ProtobufCMessageDescriptor` by + * the tag value of the field. + * + * \param desc + * The `ProtobufCMessageDescriptor` object. + * \param value + * The tag value of the field. + * \return + * A `ProtobufCFieldDescriptor` object. + * \retval NULL + * If not found. + */ +PROTOBUF_C__API +const ProtobufCFieldDescriptor * +protobuf_c_message_descriptor_get_field( + const ProtobufCMessageDescriptor *desc, + unsigned value); + +/** + * Determine the number of bytes required to store the serialised message. + * + * \param message + * The message object to serialise. + * \return + * Number of bytes. + */ +PROTOBUF_C__API +size_t +protobuf_c_message_get_packed_size(const ProtobufCMessage *message); + +/** + * Serialise a message from its in-memory representation. + * + * This function stores the serialised bytes of the message in a pre-allocated + * buffer. + * + * \param message + * The message object to serialise. + * \param[out] out + * Buffer to store the bytes of the serialised message. This buffer must + * have enough space to store the packed message. Use + * protobuf_c_message_get_packed_size() to determine the number of bytes + * required. + * \return + * Number of bytes stored in `out`. + */ +PROTOBUF_C__API +size_t +protobuf_c_message_pack(const ProtobufCMessage *message, uint8_t *out); + +/** + * Serialise a message from its in-memory representation to a virtual buffer. + * + * This function calls the `append` method of a `ProtobufCBuffer` object to + * consume the bytes generated by the serialiser. + * + * \param message + * The message object to serialise. + * \param buffer + * The virtual buffer object. + * \return + * Number of bytes passed to the virtual buffer. + */ +PROTOBUF_C__API +size_t +protobuf_c_message_pack_to_buffer( + const ProtobufCMessage *message, + ProtobufCBuffer *buffer); + +/** + * Unpack a serialised message into an in-memory representation. + * + * \param descriptor + * The message descriptor. + * \param allocator + * `ProtobufCAllocator` to use for memory allocation. May be NULL to + * specify the default allocator. + * \param len + * Length in bytes of the serialised message. + * \param data + * Pointer to the serialised message. + * \return + * An unpacked message object. + * \retval NULL + * If an error occurred during unpacking. + */ +PROTOBUF_C__API +ProtobufCMessage * +protobuf_c_message_unpack( + const ProtobufCMessageDescriptor *descriptor, + ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); + +/** + * Free an unpacked message object. + * + * This function should be used to deallocate the memory used by a call to + * protobuf_c_message_unpack(). + * + * \param message + * The message object to free. May be NULL. + * \param allocator + * `ProtobufCAllocator` to use for memory deallocation. May be NULL to + * specify the default allocator. + */ +PROTOBUF_C__API +void +protobuf_c_message_free_unpacked( + ProtobufCMessage *message, + ProtobufCAllocator *allocator); + +/** + * Check the validity of a message object. + * + * Makes sure all required fields (`PROTOBUF_C_LABEL_REQUIRED`) are present. + * Recursively checks nested messages. + * + * \retval TRUE + * Message is valid. + * \retval FALSE + * Message is invalid. + */ +PROTOBUF_C__API +protobuf_c_boolean +protobuf_c_message_check(const ProtobufCMessage *); + +/** Message initialiser. */ +#define PROTOBUF_C_MESSAGE_INIT(descriptor) { descriptor, 0, NULL } + +/** + * Initialise a message object from a message descriptor. + * + * \param descriptor + * Message descriptor. + * \param message + * Allocated block of memory of size `descriptor->sizeof_message`. + */ +PROTOBUF_C__API +void +protobuf_c_message_init( + const ProtobufCMessageDescriptor *descriptor, + void *message); + +/** + * Free a service. + * + * \param service + * The service object to free. + */ +PROTOBUF_C__API +void +protobuf_c_service_destroy(ProtobufCService *service); + +/** + * Look up a `ProtobufCMethodDescriptor` by name. + * + * \param desc + * Service descriptor. + * \param name + * Name of the method. + * + * \return + * A `ProtobufCMethodDescriptor` object. + * \retval NULL + * If not found or if the optimize_for = CODE_SIZE option was set. + */ +PROTOBUF_C__API +const ProtobufCMethodDescriptor * +protobuf_c_service_descriptor_get_method_by_name( + const ProtobufCServiceDescriptor *desc, + const char *name); + +/** + * Initialise a `ProtobufCBufferSimple` object. + */ +#define PROTOBUF_C_BUFFER_SIMPLE_INIT(array_of_bytes) \ +{ \ + { protobuf_c_buffer_simple_append }, \ + sizeof(array_of_bytes), \ + 0, \ + (array_of_bytes), \ + 0, \ + NULL \ +} + +/** + * Clear a `ProtobufCBufferSimple` object, freeing any allocated memory. + */ +#define PROTOBUF_C_BUFFER_SIMPLE_CLEAR(simp_buf) \ +do { \ + if ((simp_buf)->must_free_data) { \ + if ((simp_buf)->allocator != NULL) \ + (simp_buf)->allocator->free( \ + (simp_buf)->allocator, \ + (simp_buf)->data); \ + else \ + free((simp_buf)->data); \ + } \ +} while (0) + +/** + * The `append` method for `ProtobufCBufferSimple`. + * + * \param buffer + * The buffer object to append to. Must actually be a + * `ProtobufCBufferSimple` object. + * \param len + * Number of bytes in `data`. + * \param data + * Data to append. + */ +PROTOBUF_C__API +void +protobuf_c_buffer_simple_append( + ProtobufCBuffer *buffer, + size_t len, + const unsigned char *data); + +PROTOBUF_C__API +void +protobuf_c_service_generated_init( + ProtobufCService *service, + const ProtobufCServiceDescriptor *descriptor, + ProtobufCServiceDestroy destroy); + +PROTOBUF_C__API +void +protobuf_c_service_invoke_internal( + ProtobufCService *service, + unsigned method_index, + const ProtobufCMessage *input, + ProtobufCClosure closure, + void *closure_data); + +/**@}*/ + +PROTOBUF_C__END_DECLS + +#endif /* PROTOBUF_C_H */ diff --git a/tools/sdk/include/protobuf-c/protoc-c/c_bytes_field.h b/tools/sdk/include/protobuf-c/protoc-c/c_bytes_field.h new file mode 100644 index 00000000..c4a71e85 --- /dev/null +++ b/tools/sdk/include/protobuf-c/protoc-c/c_bytes_field.h @@ -0,0 +1,100 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// Copyright (c) 2008-2013, Dave Benson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Modified to implement C code by Dave Benson. + +#ifndef GOOGLE_PROTOBUF_COMPILER_C_BYTES_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_C_BYTES_FIELD_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace c { + +class BytesFieldGenerator : public FieldGenerator { + public: + explicit BytesFieldGenerator(const FieldDescriptor* descriptor); + ~BytesFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GenerateStructMembers(io::Printer* printer) const; + void GenerateDescriptorInitializer(io::Printer* printer) const; + void GenerateDefaultValueDeclarations(io::Printer* printer) const; + void GenerateDefaultValueImplementations(io::Printer* printer) const; + string GetDefaultValue(void) const; + void GenerateStaticInit(io::Printer* printer) const; + + private: + std::map variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(BytesFieldGenerator); +}; + + +} // namespace c +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_C_STRING_FIELD_H__ diff --git a/tools/sdk/include/protobuf-c/protoc-c/c_enum.h b/tools/sdk/include/protobuf-c/protoc-c/c_enum.h new file mode 100644 index 00000000..9eb9a667 --- /dev/null +++ b/tools/sdk/include/protobuf-c/protoc-c/c_enum.h @@ -0,0 +1,118 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// Copyright (c) 2008-2013, Dave Benson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Modified to implement C code by Dave Benson. + +#ifndef GOOGLE_PROTOBUF_COMPILER_C_ENUM_H__ +#define GOOGLE_PROTOBUF_COMPILER_C_ENUM_H__ + +#include +#include + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace c { + +class EnumGenerator { + public: + // See generator.cc for the meaning of dllexport_decl. + explicit EnumGenerator(const EnumDescriptor* descriptor, + const string& dllexport_decl); + ~EnumGenerator(); + + // Header stuff. + + // Generate header code defining the enum. This code should be placed + // within the enum's package namespace, but NOT within any class, even for + // nested enums. + void GenerateDefinition(io::Printer* printer); + + void GenerateDescriptorDeclarations(io::Printer* printer); + + + // Source file stuff. + + // Generate the ProtobufCEnumDescriptor for this enum + void GenerateEnumDescriptor(io::Printer* printer); + + // Generate static initializer for a ProtobufCEnumValue + // given the index of the value in the enum. + void GenerateValueInitializer(io::Printer *printer, int index); + + private: + const EnumDescriptor* descriptor_; + string dllexport_decl_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); +}; + +} // namespace c +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_C_ENUM_H__ diff --git a/tools/sdk/include/protobuf-c/protoc-c/c_enum_field.h b/tools/sdk/include/protobuf-c/protoc-c/c_enum_field.h new file mode 100644 index 00000000..11df6824 --- /dev/null +++ b/tools/sdk/include/protobuf-c/protoc-c/c_enum_field.h @@ -0,0 +1,98 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// Copyright (c) 2008-2013, Dave Benson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Modified to implement C code by Dave Benson. + +#ifndef GOOGLE_PROTOBUF_COMPILER_C_ENUM_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_C_ENUM_FIELD_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace c { + +class EnumFieldGenerator : public FieldGenerator { + public: + explicit EnumFieldGenerator(const FieldDescriptor* descriptor); + ~EnumFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GenerateStructMembers(io::Printer* printer) const; + void GenerateDescriptorInitializer(io::Printer* printer) const; + string GetDefaultValue(void) const; + void GenerateStaticInit(io::Printer* printer) const; + + private: + std::map variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); +}; + + +} // namespace c +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_C_ENUM_FIELD_H__ diff --git a/tools/sdk/include/protobuf-c/protoc-c/c_extension.h b/tools/sdk/include/protobuf-c/protoc-c/c_extension.h new file mode 100644 index 00000000..ddbf270e --- /dev/null +++ b/tools/sdk/include/protobuf-c/protoc-c/c_extension.h @@ -0,0 +1,110 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// Copyright (c) 2008-2013, Dave Benson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Modified to implement C code by Dave Benson. + +#ifndef GOOGLE_PROTOBUF_COMPILER_C_EXTENSION_H__ +#define GOOGLE_PROTOBUF_COMPILER_C_EXTENSION_H__ + +#include +#include + +namespace google { +namespace protobuf { + class FieldDescriptor; // descriptor.h + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace c { + +// Generates code for an extension, which may be within the scope of some +// message or may be at file scope. This is much simpler than FieldGenerator +// since extensions are just simple identifiers with interesting types. +class ExtensionGenerator { + public: + // See generator.cc for the meaning of dllexport_decl. + explicit ExtensionGenerator(const FieldDescriptor* descriptor, + const string& dllexport_decl); + ~ExtensionGenerator(); + + // Header stuff. + void GenerateDeclaration(io::Printer* printer); + + // Source file stuff. + void GenerateDefinition(io::Printer* printer); + + private: + const FieldDescriptor* descriptor_; + string type_traits_; + string dllexport_decl_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator); +}; + +} // namespace c +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_C_MESSAGE_H__ diff --git a/tools/sdk/include/protobuf-c/protoc-c/c_field.h b/tools/sdk/include/protobuf-c/protoc-c/c_field.h new file mode 100644 index 00000000..91f1a03d --- /dev/null +++ b/tools/sdk/include/protobuf-c/protoc-c/c_field.h @@ -0,0 +1,132 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// Copyright (c) 2008-2013, Dave Benson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Modified to implement C code by Dave Benson. + +#ifndef GOOGLE_PROTOBUF_COMPILER_C_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_C_FIELD_H__ + +#include +#include + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace c { + +class FieldGenerator { + public: + explicit FieldGenerator(const FieldDescriptor *descriptor) : descriptor_(descriptor) {} + virtual ~FieldGenerator(); + + // Generate definitions to be included in the structure. + virtual void GenerateStructMembers(io::Printer* printer) const = 0; + + // Generate a static initializer for this field. + virtual void GenerateDescriptorInitializer(io::Printer* printer) const = 0; + + virtual void GenerateDefaultValueDeclarations(io::Printer* printer) const { } + virtual void GenerateDefaultValueImplementations(io::Printer* printer) const { } + virtual string GetDefaultValue() const = 0; + + // Generate members to initialize this field from a static initializer + virtual void GenerateStaticInit(io::Printer* printer) const = 0; + + + protected: + void GenerateDescriptorInitializerGeneric(io::Printer* printer, + bool optional_uses_has, + const string &type_macro, + const string &descriptor_addr) const; + const FieldDescriptor *descriptor_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator); +}; + +// Convenience class which constructs FieldGenerators for a Descriptor. +class FieldGeneratorMap { + public: + explicit FieldGeneratorMap(const Descriptor* descriptor); + ~FieldGeneratorMap(); + + const FieldGenerator& get(const FieldDescriptor* field) const; + + private: + const Descriptor* descriptor_; + scoped_array > field_generators_; + + static FieldGenerator* MakeGenerator(const FieldDescriptor* field); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); +}; + +} // namespace c +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_C_FIELD_H__ diff --git a/tools/sdk/include/protobuf-c/protoc-c/c_file.h b/tools/sdk/include/protobuf-c/protoc-c/c_file.h new file mode 100644 index 00000000..ed38ce42 --- /dev/null +++ b/tools/sdk/include/protobuf-c/protoc-c/c_file.h @@ -0,0 +1,117 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// Copyright (c) 2008-2013, Dave Benson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Modified to implement C code by Dave Benson. + +#ifndef GOOGLE_PROTOBUF_COMPILER_C_FILE_H__ +#define GOOGLE_PROTOBUF_COMPILER_C_FILE_H__ + +#include +#include +#include +#include + +namespace google { +namespace protobuf { + class FileDescriptor; // descriptor.h + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace c { + +class EnumGenerator; // enum.h +class MessageGenerator; // message.h +class ServiceGenerator; // service.h +class ExtensionGenerator; // extension.h + +class FileGenerator { + public: + // See generator.cc for the meaning of dllexport_decl. + explicit FileGenerator(const FileDescriptor* file, + const string& dllexport_decl); + ~FileGenerator(); + + void GenerateHeader(io::Printer* printer); + void GenerateSource(io::Printer* printer); + + private: + const FileDescriptor* file_; + + scoped_array > message_generators_; + scoped_array > enum_generators_; + scoped_array > service_generators_; + scoped_array > extension_generators_; + + // E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}. + vector package_parts_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator); +}; + +} // namespace c +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_C_FILE_H__ diff --git a/tools/sdk/include/protobuf-c/protoc-c/c_generator.h b/tools/sdk/include/protobuf-c/protoc-c/c_generator.h new file mode 100644 index 00000000..f454710b --- /dev/null +++ b/tools/sdk/include/protobuf-c/protoc-c/c_generator.h @@ -0,0 +1,100 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// Copyright (c) 2008-2013, Dave Benson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Modified to implement C code by Dave Benson. + +// Generates C code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_C_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_C_GENERATOR_H__ + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace c { + +// CodeGenerator implementation which generates a C++ source file and +// header. If you create your own protocol compiler binary and you want +// it to support C++ output, you can do so by registering an instance of this +// CodeGenerator with the CommandLineInterface in your main() function. +class LIBPROTOC_EXPORT CGenerator : public CodeGenerator { + public: + CGenerator(); + ~CGenerator(); + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, + const string& parameter, + OutputDirectory* output_directory, + string* error) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CGenerator); +}; + +} // namespace c +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_C_GENERATOR_H__ diff --git a/tools/sdk/include/protobuf-c/protoc-c/c_helpers.h b/tools/sdk/include/protobuf-c/protoc-c/c_helpers.h new file mode 100644 index 00000000..9dc8c5e8 --- /dev/null +++ b/tools/sdk/include/protobuf-c/protoc-c/c_helpers.h @@ -0,0 +1,197 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// Copyright (c) 2008-2013, Dave Benson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Modified to implement C code by Dave Benson. + +#ifndef GOOGLE_PROTOBUF_COMPILER_C_HELPERS_H__ +#define GOOGLE_PROTOBUF_COMPILER_C_HELPERS_H__ + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace c { + +// Returns the non-nested type name for the given type. If "qualified" is +// true, prefix the type with the full namespace. For example, if you had: +// package foo.bar; +// message Baz { message Qux {} } +// Then the qualified ClassName for Qux would be: +// Foo__Bar__Baz_Qux +// While the non-qualified version would be: +// Baz_Qux +string ClassName(const Descriptor* descriptor, bool qualified); +string ClassName(const EnumDescriptor* enum_descriptor, bool qualified); + +// --- Borrowed from stubs. --- +template string SimpleItoa(T n) { + std::stringstream stream; + stream << n; + return stream.str(); +} + +string SimpleFtoa(float f); +string SimpleDtoa(double f); +void SplitStringUsing(const string &str, const char *delim, std::vector *out); +string CEscape(const string& src); +string StringReplace(const string& s, const string& oldsub, const string& newsub, bool replace_all); +inline bool HasSuffixString(const string& str, const string& suffix) { return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; } +inline string StripSuffixString(const string& str, const string& suffix) { if (HasSuffixString(str, suffix)) { return str.substr(0, str.size() - suffix.size()); } else { return str; } } +char* FastHexToBuffer(int i, char* buffer); + + +// Get the (unqualified) name that should be used for this field in C code. +// The name is coerced to lower-case to emulate proto1 behavior. People +// should be using lowercase-with-underscores style for proto field names +// anyway, so normally this just returns field->name(). +string FieldName(const FieldDescriptor* field); + +// Get macro string for deprecated field +string FieldDeprecated(const FieldDescriptor* field); + +// Returns the scope where the field was defined (for extensions, this is +// different from the message type to which the field applies). +inline const Descriptor* FieldScope(const FieldDescriptor* field) { + return field->is_extension() ? + field->extension_scope() : field->containing_type(); +} + +// convert a CamelCase class name into an all uppercase affair +// with underscores separating words, e.g. MyClass becomes MY_CLASS. +string CamelToUpper(const string &class_name); +string CamelToLower(const string &class_name); + +// lowercased, underscored name to camel case +string ToCamel(const string &name); + +// lowercase the string +string ToLower(const string &class_name); +string ToUpper(const string &class_name); + +// full_name() to lowercase with underscores +string FullNameToLower(const string &full_name); +string FullNameToUpper(const string &full_name); + +// full_name() to c-typename (with underscores for packages, otherwise camel case) +string FullNameToC(const string &class_name); + +// Splits, indents, formats, and prints comment lines +void PrintComment (io::Printer* printer, string comment); + +// make a string of spaces as long as input +string ConvertToSpaces(const string &input); + +// Strips ".proto" or ".protodevel" from the end of a filename. +string StripProto(const string& filename); + +// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.). +// Note: non-built-in type names will be qualified, meaning they will start +// with a ::. If you are using the type as a template parameter, you will +// need to insure there is a space between the < and the ::, because the +// ridiculous C++ standard defines "<:" to be a synonym for "[". +const char* PrimitiveTypeName(FieldDescriptor::CppType type); + +// Get the declared type name in CamelCase format, as is used e.g. for the +// methods of WireFormat. For example, TYPE_INT32 becomes "Int32". +const char* DeclaredTypeMethodName(FieldDescriptor::Type type); + +// Convert a file name into a valid identifier. +string FilenameIdentifier(const string& filename); + +// Return the name of the BuildDescriptors() function for a given file. +string GlobalBuildDescriptorsName(const string& filename); + +// return 'required', 'optional', or 'repeated' +string GetLabelName(FieldDescriptor::Label label); + + +// write IntRanges entries for a bunch of sorted values. +// returns the number of ranges there are to bsearch. +unsigned WriteIntRanges(io::Printer* printer, int n_values, const int *values, const string &name); + +struct NameIndex +{ + unsigned index; + const char *name; +}; +int compare_name_indices_by_name(const void*, const void*); + +// Return the syntax version of the file containing the field. +// This wrapper is needed to be able to compile against protobuf2. +inline int FieldSyntax(const FieldDescriptor* field) { +#ifdef HAVE_PROTO3 + return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ? 3 : 2; +#else + return 2; +#endif +} + +} // namespace c +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_C_HELPERS_H__ diff --git a/tools/sdk/include/protobuf-c/protoc-c/c_message.h b/tools/sdk/include/protobuf-c/protoc-c/c_message.h new file mode 100644 index 00000000..8b115d1c --- /dev/null +++ b/tools/sdk/include/protobuf-c/protoc-c/c_message.h @@ -0,0 +1,141 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// Copyright (c) 2008-2013, Dave Benson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Modified to implement C code by Dave Benson. + +#ifndef GOOGLE_PROTOBUF_COMPILER_C_MESSAGE_H__ +#define GOOGLE_PROTOBUF_COMPILER_C_MESSAGE_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace c { + +class EnumGenerator; // enum.h +class ExtensionGenerator; // extension.h + +class MessageGenerator { + public: + // See generator.cc for the meaning of dllexport_decl. + explicit MessageGenerator(const Descriptor* descriptor, + const string& dllexport_decl); + ~MessageGenerator(); + + // Header stuff. + + // Generate typedef. + void GenerateStructTypedef(io::Printer* printer); + + // Generate descriptor prototype + void GenerateDescriptorDeclarations(io::Printer* printer); + + // Generate descriptor prototype + void GenerateClosureTypedef(io::Printer* printer); + + // Generate definitions of all nested enums (must come before class + // definitions because those classes use the enums definitions). + void GenerateEnumDefinitions(io::Printer* printer); + + // Generate definitions for this class and all its nested types. + void GenerateStructDefinition(io::Printer* printer); + + // Generate __INIT macro for populating this structure + void GenerateStructStaticInitMacro(io::Printer* printer); + + // Generate standard helper functions declarations for this message. + void GenerateHelperFunctionDeclarations(io::Printer* printer, bool is_submessage); + + // Source file stuff. + + // Generate code that initializes the global variable storing the message's + // descriptor. + void GenerateMessageDescriptor(io::Printer* printer); + void GenerateHelperFunctionDefinitions(io::Printer* printer, bool is_submessage); + + private: + + string GetDefaultValueC(const FieldDescriptor *fd); + + const Descriptor* descriptor_; + string dllexport_decl_; + FieldGeneratorMap field_generators_; + scoped_array > nested_generators_; + scoped_array > enum_generators_; + scoped_array > extension_generators_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); +}; + +} // namespace c +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_C_MESSAGE_H__ diff --git a/tools/sdk/include/protobuf-c/protoc-c/c_message_field.h b/tools/sdk/include/protobuf-c/protoc-c/c_message_field.h new file mode 100644 index 00000000..b059fb03 --- /dev/null +++ b/tools/sdk/include/protobuf-c/protoc-c/c_message_field.h @@ -0,0 +1,97 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// Copyright (c) 2008-2013, Dave Benson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Modified to implement C code by Dave Benson. + +#ifndef GOOGLE_PROTOBUF_COMPILER_C_MESSAGE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_C_MESSAGE_FIELD_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace c { + +class MessageFieldGenerator : public FieldGenerator { + public: + explicit MessageFieldGenerator(const FieldDescriptor* descriptor); + ~MessageFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GenerateStructMembers(io::Printer* printer) const; + void GenerateDescriptorInitializer(io::Printer* printer) const; + string GetDefaultValue(void) const; + void GenerateStaticInit(io::Printer* printer) const; + + private: + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); +}; + + +} // namespace c +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_C_MESSAGE_FIELD_H__ diff --git a/tools/sdk/include/protobuf-c/protoc-c/c_primitive_field.h b/tools/sdk/include/protobuf-c/protoc-c/c_primitive_field.h new file mode 100644 index 00000000..5ff254c5 --- /dev/null +++ b/tools/sdk/include/protobuf-c/protoc-c/c_primitive_field.h @@ -0,0 +1,96 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// Copyright (c) 2008-2013, Dave Benson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Modified to implement C code by Dave Benson. + +#ifndef GOOGLE_PROTOBUF_COMPILER_C_PRIMITIVE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_C_PRIMITIVE_FIELD_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace c { + +class PrimitiveFieldGenerator : public FieldGenerator { + public: + explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor); + ~PrimitiveFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GenerateStructMembers(io::Printer* printer) const; + void GenerateDescriptorInitializer(io::Printer* printer) const; + string GetDefaultValue(void) const; + void GenerateStaticInit(io::Printer* printer) const; + + private: + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); +}; + +} // namespace c +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_C_PRIMITIVE_FIELD_H__ diff --git a/tools/sdk/include/protobuf-c/protoc-c/c_service.h b/tools/sdk/include/protobuf-c/protoc-c/c_service.h new file mode 100644 index 00000000..6f1798ca --- /dev/null +++ b/tools/sdk/include/protobuf-c/protoc-c/c_service.h @@ -0,0 +1,112 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// Copyright (c) 2008-2013, Dave Benson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Modified to implement C code by Dave Benson. + +#ifndef GOOGLE_PROTOBUF_COMPILER_C_SERVICE_H__ +#define GOOGLE_PROTOBUF_COMPILER_C_SERVICE_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace c { + +class ServiceGenerator { + public: + // See generator.cc for the meaning of dllexport_decl. + explicit ServiceGenerator(const ServiceDescriptor* descriptor, + const string& dllexport_decl); + ~ServiceGenerator(); + + // Header stuff. + void GenerateMainHFile(io::Printer* printer); + void GenerateVfuncs(io::Printer* printer); + void GenerateInitMacros(io::Printer* printer); + void GenerateDescriptorDeclarations(io::Printer* printer); + void GenerateCallersDeclarations(io::Printer* printer); + + // Source file stuff. + void GenerateCFile(io::Printer* printer); + void GenerateServiceDescriptor(io::Printer* printer); + void GenerateInit(io::Printer* printer); + void GenerateCallersImplementations(io::Printer* printer); + + const ServiceDescriptor* descriptor_; + std::map vars_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator); +}; + +} // namespace c +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_C_SERVICE_H__ diff --git a/tools/sdk/include/protobuf-c/protoc-c/c_string_field.h b/tools/sdk/include/protobuf-c/protoc-c/c_string_field.h new file mode 100644 index 00000000..68f0d25b --- /dev/null +++ b/tools/sdk/include/protobuf-c/protoc-c/c_string_field.h @@ -0,0 +1,100 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// Copyright (c) 2008-2013, Dave Benson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Modified to implement C code by Dave Benson. + +#ifndef GOOGLE_PROTOBUF_COMPILER_C_STRING_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_C_STRING_FIELD_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace c { + +class StringFieldGenerator : public FieldGenerator { + public: + explicit StringFieldGenerator(const FieldDescriptor* descriptor); + ~StringFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GenerateStructMembers(io::Printer* printer) const; + void GenerateDescriptorInitializer(io::Printer* printer) const; + void GenerateDefaultValueDeclarations(io::Printer* printer) const; + void GenerateDefaultValueImplementations(io::Printer* printer) const; + string GetDefaultValue(void) const; + void GenerateStaticInit(io::Printer* printer) const; + + private: + std::map variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator); +}; + + +} // namespace c +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_C_STRING_FIELD_H__ diff --git a/tools/sdk/include/protobuf-c/t/generated-code2/common-test-arrays.h b/tools/sdk/include/protobuf-c/t/generated-code2/common-test-arrays.h new file mode 100644 index 00000000..1535d38e --- /dev/null +++ b/tools/sdk/include/protobuf-c/t/generated-code2/common-test-arrays.h @@ -0,0 +1,62 @@ + +/* data included from the c++ packed-data generator, + and from the c test code. */ + +#define THOUSAND 1000 +#define MILLION 1000000 +#define BILLION 1000000000LL +#define TRILLION 1000000000000LL +#define QUADRILLION 1000000000000000LL +#define QUINTILLION 1000000000000000000LL + +int32_t int32_arr0[2] = { -1, 1 }; +int32_t int32_arr1[5] = { 42, 666, -1123123, 0, 47 }; +int32_t int32_arr_min_max[2] = { INT32_MIN, INT32_MAX }; + +uint32_t uint32_roundnumbers[4] = { BILLION, MILLION, 1, 0 }; +uint32_t uint32_0_max[2] = { 0, UINT32_MAX }; + +int64_t int64_roundnumbers[15] = { -QUINTILLION, -QUADRILLION, -TRILLION, + -BILLION, -MILLION, -THOUSAND, + 1, + THOUSAND, MILLION, BILLION, + TRILLION, QUADRILLION, QUINTILLION }; +int64_t int64_min_max[2] = { INT64_MIN, INT64_MAX }; + +uint64_t uint64_roundnumbers[9] = { 1, + THOUSAND, MILLION, BILLION, + TRILLION, QUADRILLION, QUINTILLION }; +uint64_t uint64_0_1_max[3] = { 0, 1, UINT64_MAX }; +uint64_t uint64_random[] = {0, + 666, + 4200000000ULL, + 16ULL * (uint64_t) QUINTILLION + 33 }; + +#define FLOATING_POINT_RANDOM \ +-1000.0, -100.0, -42.0, 0, 666, 131313 +float float_random[] = { FLOATING_POINT_RANDOM }; +double double_random[] = { FLOATING_POINT_RANDOM }; + +protobuf_c_boolean boolean_0[] = {0 }; +protobuf_c_boolean boolean_1[] = {1 }; +protobuf_c_boolean boolean_random[] = {0,1,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,1,1,0,1,1,0 }; + +TEST_ENUM_SMALL_TYPE_NAME enum_small_0[] = { TEST_ENUM_SMALL(VALUE) }; +TEST_ENUM_SMALL_TYPE_NAME enum_small_1[] = { TEST_ENUM_SMALL(OTHER_VALUE) }; +#define T(v) (TEST_ENUM_SMALL_TYPE_NAME)(v) +TEST_ENUM_SMALL_TYPE_NAME enum_small_random[] = {T(0),T(1),T(1),T(0),T(0),T(1),T(1),T(1),T(0),T(0),T(0),T(0),T(0),T(1),T(1),T(1),T(1),T(1),T(1),T(0),T(1),T(1),T(0),T(1),T(1),T(0) }; +#undef T + +#define T(v) (TEST_ENUM_TYPE_NAME)(v) +TEST_ENUM_TYPE_NAME enum_0[] = { T(0) }; +TEST_ENUM_TYPE_NAME enum_1[] = { T(1) }; +TEST_ENUM_TYPE_NAME enum_random[] = { + T(0), T(268435455), T(127), T(16384), T(16383), + T(2097152), T(2097151), T(128), T(268435456), + T(0), T(2097152), T(268435455), T(127), T(16383), T(16384) }; +#undef T + +char *repeated_strings_0[] = { (char*)"onestring" }; +char *repeated_strings_1[] = { (char*)"two", (char*)"string" }; +char *repeated_strings_2[] = { (char*)"many", (char*)"tiny", (char*)"little", (char*)"strings", (char*)"should", (char*)"be", (char*)"handled" }; +char *repeated_strings_3[] = { (char*)"one very long strings XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }; diff --git a/tools/sdk/include/protocomm/protocomm.h b/tools/sdk/include/protocomm/protocomm.h new file mode 100644 index 00000000..f5f67da6 --- /dev/null +++ b/tools/sdk/include/protocomm/protocomm.h @@ -0,0 +1,226 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include + +/** + * @brief Function prototype for protocomm endpoint handler + */ +typedef esp_err_t (*protocomm_req_handler_t)( + uint32_t session_id, /*!< Session ID for identifying protocomm client */ + const uint8_t *inbuf, /*!< Pointer to user provided input data buffer */ + ssize_t inlen, /*!< Length o the input buffer */ + uint8_t **outbuf, /*!< Pointer to output buffer allocated by handler */ + ssize_t *outlen, /*!< Length of the allocated output buffer */ + void *priv_data /*!< Private data passed to the handler (NULL if not used) */ +); + +/** + * @brief This structure corresponds to a unique instance of protocomm + * returned when the API `protocomm_new()` is called. The remaining + * Protocomm APIs require this object as the first parameter. + * + * @note Structure of the protocomm object is kept private + */ +typedef struct protocomm protocomm_t; + +/** + * @brief Create a new protocomm instance + * + * This API will return a new dynamically allocated protocomm instance + * with all elements of the protocomm_t structure initialised to NULL. + * + * @return + * - protocomm_t* : On success + * - NULL : No memory for allocating new instance + */ +protocomm_t *protocomm_new(); + +/** + * @brief Delete a protocomm instance + * + * This API will deallocate a protocomm instance that was created + * using `protocomm_new()`. + * + * @param[in] pc Pointer to the protocomm instance to be deleted + */ +void protocomm_delete(protocomm_t *pc); + +/** + * @brief Add endpoint request handler for a protocomm instance + * + * This API will bind an endpoint handler function to the specified + * endpoint name, along with any private data that needs to be pass to + * the handler at the time of call. + * + * @note + * - An endpoint must be bound to a valid protocomm instance, + * created using `protocomm_new()`. + * - This function internally calls the registered `add_endpoint()` + * function which is a member of the protocomm_t instance structure. + * + * @param[in] pc Pointer to the protocomm instance + * @param[in] ep_name Endpoint identifier(name) string + * @param[in] h Endpoint handler function + * @param[in] priv_data Pointer to private data to be passed as a + * parameter to the handler function on call. + * Pass NULL if not needed. + * + * @return + * - ESP_OK : Added new endpoint succesfully + * - ESP_FAIL : Error adding endpoint / Endpoint with this name already exists + * - ESP_ERR_NO_MEM : Error allocating endpoint resource + * - ESP_ERR_INVALID_ARG : Null instance/name/handler arguments + */ +esp_err_t protocomm_add_endpoint(protocomm_t *pc, const char *ep_name, + protocomm_req_handler_t h, void *priv_data); + +/** + * @brief Remove endpoint request handler for a protocomm instance + * + * This API will remove a registered endpoint handler identified by + * an endpoint name. + * + * @note + * - This function internally calls the registered `remove_endpoint()` + * function which is a member of the protocomm_t instance structure. + * + * @param[in] pc Pointer to the protocomm instance + * @param[in] ep_name Endpoint identifier(name) string + * + * @return + * - ESP_OK : Added new endpoint succesfully + * - ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist + * - ESP_ERR_INVALID_ARG : Null instance/name arguments + */ +esp_err_t protocomm_remove_endpoint(protocomm_t *pc, const char *ep_name); + +/** + * @brief Calls the registered handler of an endpoint session + * for processing incoming data and giving the output + * + * @note + * - An endpoint must be bound to a valid protocomm instance, + * created using `protocomm_new()`. + * - Resulting output buffer must be deallocated by the user. + * + * @param[in] pc Pointer to the protocomm instance + * @param[in] ep_name Endpoint identifier(name) string + * @param[in] session_id Unique ID for a communication session + * @param[in] inbuf Input buffer contains input request data which is to be + * processed by the registered handler + * @param[in] inlen Length of the input buffer + * @param[out] outbuf Pointer to internally allocated output buffer, + * where the resulting response data output from + * the registered handler is to be stored + * @param[out] outlen Buffer length of the allocated output buffer + * + * @return + * - ESP_OK : Request handled succesfully + * - ESP_FAIL : Internal error in execution of registered handler + * - ESP_ERR_NO_MEM : Error allocating internal resource + * - ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist + * - ESP_ERR_INVALID_ARG : Null instance/name arguments + */ +esp_err_t protocomm_req_handle(protocomm_t *pc, const char *ep_name, uint32_t session_id, + const uint8_t *inbuf, ssize_t inlen, + uint8_t **outbuf, ssize_t *outlen); + +/** + * @brief Add endpoint security for a protocomm instance + * + * This API will bind a security session establisher to the specified + * endpoint name, along with any proof of possession that may be required + * for authenticating a session client. + * + * @note + * - An endpoint must be bound to a valid protocomm instance, + * created using `protocomm_new()`. + * - The choice of security can be any `protocomm_security_t` instance. + * Choices `protocomm_security0` and `protocomm_security1` are readily available. + * + * @param[in] pc Pointer to the protocomm instance + * @param[in] ep_name Endpoint identifier(name) string + * @param[in] sec Pointer to endpoint security instance + * @param[in] pop Pointer to proof of possession for authenticating a client + * + * @return + * - ESP_OK : Added new security endpoint succesfully + * - ESP_FAIL : Error adding endpoint / Endpoint with this name already exists + * - ESP_ERR_INVALID_STATE : Security endpoint already set + * - ESP_ERR_NO_MEM : Error allocating endpoint resource + * - ESP_ERR_INVALID_ARG : Null instance/name/handler arguments + */ +esp_err_t protocomm_set_security(protocomm_t *pc, const char *ep_name, + const protocomm_security_t *sec, + const protocomm_security_pop_t *pop); + +/** + * @brief Remove endpoint security for a protocomm instance + * + * This API will remove a registered security endpoint identified by + * an endpoint name. + * + * @param[in] pc Pointer to the protocomm instance + * @param[in] ep_name Endpoint identifier(name) string + * + * @return + * - ESP_OK : Added new endpoint succesfully + * - ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist + * - ESP_ERR_INVALID_ARG : Null instance/name arguments + */ +esp_err_t protocomm_unset_security(protocomm_t *pc, const char *ep_name); + +/** + * @brief Set endpoint for version verification + * + * This API can be used for setting an application specific protocol + * version which can be verfied by clients through the endpoint. + * + * @note + * - An endpoint must be bound to a valid protocomm instance, + * created using `protocomm_new()`. + + * @param[in] pc Pointer to the protocomm instance + * @param[in] ep_name Endpoint identifier(name) string + * @param[in] version Version identifier(name) string + * + * @return + * - ESP_OK : Added new security endpoint succesfully + * - ESP_FAIL : Error adding endpoint / Endpoint with this name already exists + * - ESP_ERR_INVALID_STATE : Version endpoint already set + * - ESP_ERR_NO_MEM : Error allocating endpoint resource + * - ESP_ERR_INVALID_ARG : Null instance/name/handler arguments + */ +esp_err_t protocomm_set_version(protocomm_t *pc, const char *ep_name, + const char *version); + +/** + * @brief Remove version verification endpoint from a protocomm instance + * + * This API will remove a registered version endpoint identified by + * an endpoint name. + * + * @param[in] pc Pointer to the protocomm instance + * @param[in] ep_name Endpoint identifier(name) string + * + * @return + * - ESP_OK : Added new endpoint succesfully + * - ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist + * - ESP_ERR_INVALID_ARG : Null instance/name arguments + */ +esp_err_t protocomm_unset_version(protocomm_t *pc, const char *ep_name); diff --git a/tools/sdk/include/protocomm/protocomm_ble.h b/tools/sdk/include/protocomm/protocomm_ble.h new file mode 100644 index 00000000..b86059e5 --- /dev/null +++ b/tools/sdk/include/protocomm/protocomm_ble.h @@ -0,0 +1,92 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include + +/** + * BLE device name cannot be larger than this value + */ +#define MAX_BLE_DEVNAME_LEN 13 + +/** + * @brief This structure maps handler required by protocomm layer to + * UUIDs which are used to uniquely identify BLE characteristics + * from a smartphone or a similar client device. + */ +typedef struct name_uuid { + /** + * Name of the handler, which is passed to protocomm layer + */ + char *name; + + /** + * UUID to be assigned to the BLE characteristic which is + * mapped to the handler + */ + uint16_t uuid; +} protocomm_ble_name_uuid_t; + +/** + * @brief Config parameters for protocomm BLE service + */ +typedef struct { + /** + * BLE device name being broadcast at the time of provisioning + */ + char device_name[MAX_BLE_DEVNAME_LEN]; + uint8_t service_uuid[16]; /*!< SSID of the provisioning service */ + ssize_t nu_lookup_count; /*!< Number of entries in the Name-UUID lookup table */ + + /** + * Pointer to the Name-UUID lookup table + */ + protocomm_ble_name_uuid_t *nu_lookup; +} protocomm_ble_config_t; + +/** + * @brief Start Bluetooth Low Energy based transport layer for provisioning + * + * Initialize and start required BLE service for provisioning. This includes + * the initialization for characteristics/service for BLE. + * + * @param[in] pc Protocomm instance pointer obtained from protocomm_new() + * @param[in] config Pointer to config structure for initialising BLE + * + * @return + * - ESP_OK : if successful + * - ESP_FAIL : Simple BLE start error + * - ESP_ERR_NO_MEM : Error allocating memory for internal resources + * - ESP_ERR_INVALID_STATE : Error in ble config + * - ESP_ERR_INVALID_ARG : Null arguments + */ +esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *config); + +/** + * @brief Stop Bluetooth Low Energy based transport layer for provisioning + * + * Stops service/task responsible for BLE based interactions for provisioning + * + * @note You might want to optionally reclaim memory from Bluetooth. + * Refer to the documentation of `esp_bt_mem_release` in that case. + * + * @param[in] pc Same protocomm instance that was passed to protocomm_ble_start() + * + * @return + * - ESP_OK : For success or appropriate error code + * - ESP_FAIL : Simple BLE stop error + * - ESP_ERR_INVALID_ARG : Null / incorrect protocomm instance + */ +esp_err_t protocomm_ble_stop(protocomm_t *pc); diff --git a/tools/sdk/include/protocomm/protocomm_console.h b/tools/sdk/include/protocomm/protocomm_console.h new file mode 100644 index 00000000..b7004d02 --- /dev/null +++ b/tools/sdk/include/protocomm/protocomm_console.h @@ -0,0 +1,59 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include + +#define PROTOCOMM_CONSOLE_DEFAULT_CONFIG() { \ + .stack_size = 4096, \ + .task_priority = tskIDLE_PRIORITY + 3, \ +} + +/** + * @brief Config parameters for protocomm console + */ +typedef struct { + size_t stack_size; /*!< Stack size of console taks */ + unsigned task_priority; /*!< Priority of console task */ +} protocomm_console_config_t; + +/** + * @brief Start console based protocomm transport + * + * @note This is a singleton. ie. Protocomm can have multiple instances, but only + * one instance can be bound to a console based transport layer. + * + * @param[in] pc Protocomm instance pointer obtained from protocomm_new() + * @param[in] config Config param structure for protocomm console + * + * @return + * - ESP_OK : Server started succefully + * - ESP_ERR_INVALID_ARG : Null arguments + * - ESP_ERR_NOT_SUPPORTED : Transport layer bound to another protocomm instance + * - ESP_ERR_INVALID_STATE : Transport layer already bound to this protocomm instance + * - ESP_FAIL : Failed to start console thread + */ +esp_err_t protocomm_console_start(protocomm_t *pc, const protocomm_console_config_t *config); + +/** + * @brief Stop console protocomm transport + * + * @param[in] pc Same protocomm instance that was passed to protocomm_console_start() + * + * @return + * - ESP_OK : Server stopped succefully + * - ESP_ERR_INVALID_ARG : Null / incorrect protocomm instance pointer + */ +esp_err_t protocomm_console_stop(protocomm_t *pc); diff --git a/tools/sdk/include/protocomm/protocomm_httpd.h b/tools/sdk/include/protocomm/protocomm_httpd.h new file mode 100644 index 00000000..701fa968 --- /dev/null +++ b/tools/sdk/include/protocomm/protocomm_httpd.h @@ -0,0 +1,73 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include + +#define PROTOCOMM_HTTPD_DEFAULT_CONFIG() { \ + .port = 80, \ + .stack_size = 4096, \ + .task_priority = tskIDLE_PRIORITY + 5, \ +} + +/** + * @brief Config parameters for protocomm HTTP server + */ +typedef struct { + uint16_t port; /*!< Port on which the http server will listen */ + + /** + * Stack size of server task, adjusted depending + * upon stack usage of endpoint handler + */ + size_t stack_size; + unsigned task_priority; /*!< Priority of server task */ +} protocomm_httpd_config_t; + +/** + * @brief Start HTTPD protocomm transport + * + * This API internally creates a framework to allow endpoint registration and security + * configuration for the protocomm. + * + * @note This is a singleton. ie. Protocomm can have multiple instances, but only + * one instance can be bound to an HTTP transport layer. + * + * @param[in] pc Protocomm instance pointer obtained from protocomm_new() + * @param[in] config Pointer to config structure for initialising HTTP server + * + * @return + * - ESP_OK : Server started succefully + * - ESP_ERR_INVALID_ARG : Null arguments + * - ESP_ERR_NOT_SUPPORTED : Transport layer bound to another protocomm instance + * - ESP_ERR_INVALID_STATE : Transport layer already bound to this protocomm instance + * - ESP_ERR_NO_MEM : Memory allocation for server resource failed + * - ESP_ERR_HTTPD_* : HTTP server error on start + */ +esp_err_t protocomm_httpd_start(protocomm_t *pc, const protocomm_httpd_config_t *config); + +/** + * @brief Stop HTTPD protocomm transport + * + * This API cleans up the HTTPD transport protocomm and frees all the handlers registered + * with the protocomm. + * + * @param[in] pc Same protocomm instance that was passed to protocomm_httpd_start() + * + * @return + * - ESP_OK : Server stopped succefully + * - ESP_ERR_INVALID_ARG : Null / incorrect protocomm instance pointer + */ +esp_err_t protocomm_httpd_stop(protocomm_t *pc); diff --git a/tools/sdk/include/protocomm/protocomm_security.h b/tools/sdk/include/protocomm/protocomm_security.h new file mode 100644 index 00000000..7eeecc16 --- /dev/null +++ b/tools/sdk/include/protocomm/protocomm_security.h @@ -0,0 +1,93 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include + +/** + * @brief Proof Of Possession for authenticating a secure session + */ +typedef struct protocomm_security_pop { + /** + * Pointer to buffer containing the proof of possession data + */ + const uint8_t *data; + + /** + * Length (in bytes) of the proof of possession data + */ + uint16_t len; +} protocomm_security_pop_t; + +/** + * @brief Protocomm security object structure. + * + * The member functions are used for implementing secure + * protocomm sessions. + * + * @note This structure should not have any dynamic + * members to allow re-entrancy + */ +typedef struct protocomm_security { + /** + * Unique version number of security implmentation + */ + int ver; + + /** + * Function for initialising/allocating security + * infrastructure + */ + esp_err_t (*init)(); + + /** + * Function for deallocating security infrastructure + */ + esp_err_t (*cleanup)(); + + /** + * Starts new secure transport session with specified ID + */ + esp_err_t (*new_transport_session)(uint32_t session_id); + + /** + * Closes a secure transport session with specified ID + */ + esp_err_t (*close_transport_session)(uint32_t session_id); + + /** + * Handler function for authenticating connection + * request and establishing secure session + */ + esp_err_t (*security_req_handler)(const protocomm_security_pop_t *pop, + uint32_t session_id, + const uint8_t *inbuf, ssize_t inlen, + uint8_t **outbuf, ssize_t *outlen, + void *priv_data); + + /** + * Function which implements the encryption algorithm + */ + esp_err_t (*encrypt)(uint32_t session_id, + const uint8_t *inbuf, ssize_t inlen, + uint8_t *outbuf, ssize_t *outlen); + + /** + * Function which implements the decryption algorithm + */ + esp_err_t (*decrypt)(uint32_t session_id, + const uint8_t *inbuf, ssize_t inlen, + uint8_t *outbuf, ssize_t *outlen); +} protocomm_security_t; diff --git a/tools/sdk/include/bluedroid/btc/btc_manage.h b/tools/sdk/include/protocomm/protocomm_security0.h similarity index 58% rename from tools/sdk/include/bluedroid/btc/btc_manage.h rename to tools/sdk/include/protocomm/protocomm_security0.h index 46f746e8..7d0462d8 100644 --- a/tools/sdk/include/bluedroid/btc/btc_manage.h +++ b/tools/sdk/include/protocomm/protocomm_security0.h @@ -1,9 +1,9 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software @@ -12,17 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef __BTC_MANAGE_H__ -#define __BTC_MANAGE_H__ +#pragma once -#include "bta/bta_api.h" -#include "btc/btc_task.h" -#include "esp_bt_defs.h" +#include -/* reset gatt callback table */ -void esp_profile_cb_reset(void); - -int btc_profile_cb_set(btc_pid_t profile_id, void *cb); -void *btc_profile_cb_get(btc_pid_t profile_id); - -#endif /* __BTC_MANAGE_H__ */ +/** + * @brief Protocomm security version 0 implementation + * + * This is a simple implementation to be used when no + * security is required for the protocomm instance + */ +extern const protocomm_security_t protocomm_security0; diff --git a/tools/sdk/include/bluedroid/btc/btc_dev.h b/tools/sdk/include/protocomm/protocomm_security1.h similarity index 50% rename from tools/sdk/include/bluedroid/btc/btc_dev.h rename to tools/sdk/include/protocomm/protocomm_security1.h index 1d176633..098d61e6 100644 --- a/tools/sdk/include/bluedroid/btc/btc_dev.h +++ b/tools/sdk/include/protocomm/protocomm_security1.h @@ -1,9 +1,9 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software @@ -12,27 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef __BTC_DEV_H__ -#define __BTC_DEV_H__ +#pragma once -#include "esp_bt_defs.h" -#include "esp_bt_device.h" -#include "btc/btc_task.h" - -typedef enum { - BTC_DEV_ACT_SET_DEVICE_NAME -} btc_dev_act_t; - -/* btc_dev_args_t */ -typedef union { - // BTC_BT_GAP_ACT_SET_DEV_NAME - struct set_bt_dev_name_args { -#define ESP_DEV_DEVICE_NAME_MAX (32) - char device_name[ESP_DEV_DEVICE_NAME_MAX + 1]; - } set_dev_name; -} btc_dev_args_t; - -void btc_dev_call_handler(btc_msg_t *msg); - -#endif /* __BTC_DEV_H__ */ +#include +/** + * @brief Protocomm security version 1 implementation + * + * This is a full fledged security implmentation using + * Curve25519 key exchange and AES-256-CTR encryption + */ +extern const protocomm_security_t protocomm_security1; diff --git a/tools/sdk/include/pthread/esp_pthread.h b/tools/sdk/include/pthread/esp_pthread.h new file mode 100644 index 00000000..3ce3703d --- /dev/null +++ b/tools/sdk/include/pthread/esp_pthread.h @@ -0,0 +1,73 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PTHREAD_STACK_MIN +#define PTHREAD_STACK_MIN CONFIG_PTHREAD_STACK_MIN +#endif + +/** pthread configuration structure that influences pthread creation */ +typedef struct { + size_t stack_size; ///< the stack size of the pthread + size_t prio; ///< the thread's priority + bool inherit_cfg; ///< inherit this configuration further +} esp_pthread_cfg_t; + +/** + * @brief Configure parameters for creating pthread + * + * This API allows you to configure how the subsequent + * pthread_create() call will behave. This call can be used to setup + * configuration parameters like stack size, priority, configuration + * inheritance etc. + * + * If the 'inherit' flag in the configuration structure is enabled, + * then the same configuration is also inherited in the thread + * subtree. + * + * @note Passing non-NULL attributes to pthread_create() will override + * the stack_size parameter set using this API + * + * @param cfg The pthread config parameters + * + * @return + * - ESP_OK if configuration was successfully set + * - ESP_ERR_NO_MEM if out of memory + * - ESP_ERR_INVALID_ARG if stack_size is less than PTHREAD_STACK_MIN + */ +esp_err_t esp_pthread_set_cfg(const esp_pthread_cfg_t *cfg); + +/** + * @brief Get current pthread creation configuration + * + * This will retrieve the current configuration that will be used for + * creating threads. + * + * @param p Pointer to the pthread config structure that will be + * updated with the currently configured parameters + * + * @return + * - ESP_OK if the configuration was available + * - ESP_ERR_NOT_FOUND if a configuration wasn't previously set + */ +esp_err_t esp_pthread_get_cfg(esp_pthread_cfg_t *p); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/include/soc/soc/cpu.h b/tools/sdk/include/soc/soc/cpu.h index 05ec9177..f28feb59 100644 --- a/tools/sdk/include/soc/soc/cpu.h +++ b/tools/sdk/include/soc/soc/cpu.h @@ -19,6 +19,7 @@ #include #include #include "xtensa/corebits.h" +#include "xtensa/config/core.h" /* C macros for xtensa special register read/write/exchange */ @@ -51,6 +52,14 @@ static inline void cpu_write_itlb(unsigned vpn, unsigned attr) asm volatile ("witlb %1, %0; isync\n" :: "r" (vpn), "r" (attr)); } +static inline void cpu_init_memctl() +{ +#if XCHAL_ERRATUM_572 + uint32_t memctl = XCHAL_CACHE_MEMCTL_DEFAULT; + WSR(MEMCTL, memctl); +#endif // XCHAL_ERRATUM_572 +} + /** * @brief Configure memory region protection * diff --git a/tools/sdk/include/soc/soc/efuse_reg.h b/tools/sdk/include/soc/soc/efuse_reg.h index 0be58c46..6c3f45c5 100644 --- a/tools/sdk/include/soc/soc/efuse_reg.h +++ b/tools/sdk/include/soc/soc/efuse_reg.h @@ -298,6 +298,9 @@ #define EFUSE_RD_CODING_SCHEME_V 0x3 #define EFUSE_RD_CODING_SCHEME_S 0 +#define EFUSE_CODING_SCHEME_VAL_NONE 0x0 +#define EFUSE_CODING_SCHEME_VAL_34 0x1 + #define EFUSE_BLK0_WDATA0_REG (DR_REG_EFUSE_BASE + 0x01c) /* EFUSE_FLASH_CRYPT_CNT : R/W ;bitpos:[27:20] ;default: 8'b0 ; */ /*description: program for flash_crypt_cnt*/ diff --git a/tools/sdk/include/soc/soc/periph_defs.h b/tools/sdk/include/soc/soc/periph_defs.h index 7aa21fc9..c4ad589c 100644 --- a/tools/sdk/include/soc/soc/periph_defs.h +++ b/tools/sdk/include/soc/soc/periph_defs.h @@ -52,6 +52,9 @@ typedef enum { PERIPH_WIFI_BT_COMMON_MODULE, PERIPH_BT_BASEBAND_MODULE, PERIPH_BT_LC_MODULE, + PERIPH_AES_MODULE, + PERIPH_SHA_MODULE, + PERIPH_RSA_MODULE, } periph_module_t; #ifdef __cplusplus diff --git a/tools/sdk/include/soc/soc/soc.h b/tools/sdk/include/soc/soc/soc.h index 59d171f3..c3cb55db 100644 --- a/tools/sdk/include/soc/soc/soc.h +++ b/tools/sdk/include/soc/soc/soc.h @@ -59,16 +59,18 @@ #define APP_CPU_NUM (1) /* Overall memory map */ -#define SOC_IROM_LOW 0x400D0000 -#define SOC_IROM_HIGH 0x40400000 -#define SOC_DROM_LOW 0x3F400000 -#define SOC_DROM_HIGH 0x3F800000 -#define SOC_RTC_IRAM_LOW 0x400C0000 -#define SOC_RTC_IRAM_HIGH 0x400C2000 -#define SOC_RTC_DATA_LOW 0x50000000 -#define SOC_RTC_DATA_HIGH 0x50002000 -#define SOC_EXTRAM_DATA_LOW 0x3F800000 -#define SOC_EXTRAM_DATA_HIGH 0x3FC00000 +#define SOC_IROM_LOW 0x400D0000 +#define SOC_IROM_HIGH 0x40400000 +#define SOC_DROM_LOW 0x3F400000 +#define SOC_DROM_HIGH 0x3F800000 +#define SOC_DRAM_LOW 0x3FAE0000 +#define SOC_DRAM_HIGH 0x40000000 +#define SOC_RTC_IRAM_LOW 0x400C0000 +#define SOC_RTC_IRAM_HIGH 0x400C2000 +#define SOC_RTC_DATA_LOW 0x50000000 +#define SOC_RTC_DATA_HIGH 0x50002000 +#define SOC_EXTRAM_DATA_LOW 0x3F800000 +#define SOC_EXTRAM_DATA_HIGH 0x3FC00000 #define DR_REG_DPORT_BASE 0x3ff00000 @@ -130,7 +132,7 @@ //Registers Operation {{ #define ETS_UNCACHED_ADDR(addr) (addr) -#define ETS_CACHED_ADDR(addr) (addr) +#define ETS_CACHED_ADDR(addr) (addr) #ifndef __ASSEMBLER__ #define BIT(nr) (1UL << (nr)) @@ -284,10 +286,16 @@ #define SOC_DROM_HIGH 0x3F800000 #define SOC_IROM_LOW 0x400D0000 #define SOC_IROM_HIGH 0x40400000 +#define SOC_CACHE_PRO_LOW 0x40070000 +#define SOC_CACHE_PRO_HIGH 0x40078000 +#define SOC_CACHE_APP_LOW 0x40078000 +#define SOC_CACHE_APP_HIGH 0x40080000 #define SOC_IRAM_LOW 0x40080000 #define SOC_IRAM_HIGH 0x400A0000 #define SOC_RTC_IRAM_LOW 0x400C0000 #define SOC_RTC_IRAM_HIGH 0x400C2000 +#define SOC_RTC_DRAM_LOW 0x3FF80000 +#define SOC_RTC_DRAM_HIGH 0x3FF82000 #define SOC_RTC_DATA_LOW 0x50000000 #define SOC_RTC_DATA_HIGH 0x50002000 diff --git a/tools/sdk/include/soc/soc/soc_memory_layout.h b/tools/sdk/include/soc/soc/soc_memory_layout.h index b1e8d6eb..68c87623 100644 --- a/tools/sdk/include/soc/soc/soc_memory_layout.h +++ b/tools/sdk/include/soc/soc/soc_memory_layout.h @@ -173,3 +173,19 @@ inline static bool IRAM_ATTR esp_ptr_internal(const void *p) { inline static bool IRAM_ATTR esp_ptr_external_ram(const void *p) { return ((intptr_t)p >= SOC_EXTRAM_DATA_LOW && (intptr_t)p < SOC_EXTRAM_DATA_HIGH); } + +inline static bool IRAM_ATTR esp_ptr_in_iram(const void *p) { +#ifndef CONFIG_FREERTOS_UNICORE + return ((intptr_t)p >= SOC_IRAM_LOW && (intptr_t)p < SOC_IRAM_HIGH); +#else + return ((intptr_t)p >= SOC_CACHE_APP_LOW && (intptr_t)p < SOC_IRAM_HIGH); +#endif +} + +inline static bool IRAM_ATTR esp_ptr_in_drom(const void *p) { + return ((intptr_t)p >= SOC_DROM_LOW && (intptr_t)p < SOC_DROM_HIGH); +} + +inline static bool IRAM_ATTR esp_ptr_in_dram(const void *p) { + return ((intptr_t)p >= SOC_DRAM_LOW && (intptr_t)p < SOC_DRAM_HIGH); +} diff --git a/tools/sdk/include/spi_flash/esp_partition.h b/tools/sdk/include/spi_flash/esp_partition.h index 5345fa97..b1203696 100644 --- a/tools/sdk/include/spi_flash/esp_partition.h +++ b/tools/sdk/include/spi_flash/esp_partition.h @@ -70,6 +70,7 @@ typedef enum { ESP_PARTITION_SUBTYPE_DATA_PHY = 0x01, //!< PHY init data partition ESP_PARTITION_SUBTYPE_DATA_NVS = 0x02, //!< NVS partition ESP_PARTITION_SUBTYPE_DATA_COREDUMP = 0x03, //!< COREDUMP partition + ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS = 0x04, //!< Partition for NVS keys ESP_PARTITION_SUBTYPE_DATA_ESPHTTPD = 0x80, //!< ESPHTTPD partition ESP_PARTITION_SUBTYPE_DATA_FAT = 0x81, //!< FAT partition diff --git a/tools/sdk/include/spi_flash/esp_spi_flash.h b/tools/sdk/include/spi_flash/esp_spi_flash.h index 7977e116..254e4089 100644 --- a/tools/sdk/include/spi_flash/esp_spi_flash.h +++ b/tools/sdk/include/spi_flash/esp_spi_flash.h @@ -244,15 +244,13 @@ void spi_flash_mmap_dump(); /** * @brief get free pages number which can be mmap * - * This function will return free page number of the mmu table which can mmap, - * when you want to call spi_flash_mmap to mmap an ranger of flash data to Dcache or Icache - * memmory region, maybe the size of MMU table will exceed,so if you are not sure the - * size need mmap is ok, can call the interface and watch how many MMU table page can be - * mmaped. + * This function will return number of free pages available in mmu table. This could be useful + * before calling actual spi_flash_mmap (maps flash range to DCache or ICache memory) to check + * if there is sufficient space available for mapping. * - * @param memory memmory type of MMU table free page + * @param memory memory type of MMU table free page * - * @return number of free pages which can be mmaped + * @return number of free pages which can be mmaped */ uint32_t spi_flash_mmap_get_free_pages(spi_flash_mmap_memory_t memory); @@ -315,6 +313,10 @@ typedef void (*spi_flash_op_lock_func_t)(void); * @brief SPI flash operation unlock function. */ typedef void (*spi_flash_op_unlock_func_t)(void); +/** + * @brief Function to protect SPI flash critical regions corruption. + */ +typedef bool (*spi_flash_is_safe_write_address_t)(size_t addr, size_t size); /** * Structure holding SPI flash access critical sections management functions. @@ -334,6 +336,9 @@ typedef void (*spi_flash_op_unlock_func_t)(void); * - 'op_unlock' unlocks access to flash API internal data. * These two functions are recursive and can be used around the outside of multiple calls to * 'start' & 'end', in order to create atomic multi-part flash operations. + * 3) When CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is disabled, flash writing/erasing + * API checks for addresses provided by user to avoid corruption of critical flash regions + * (bootloader, partition table, running application etc.). * * Different versions of the guarding functions should be used depending on the context of * execution (with or without functional OS). In normal conditions when flash API is called @@ -345,10 +350,13 @@ typedef void (*spi_flash_op_unlock_func_t)(void); * For example structure can be placed in DRAM and functions in IRAM sections. */ typedef struct { - spi_flash_guard_start_func_t start; /**< critical section start function. */ - spi_flash_guard_end_func_t end; /**< critical section end function. */ - spi_flash_op_lock_func_t op_lock; /**< flash access API lock function.*/ - spi_flash_op_unlock_func_t op_unlock; /**< flash access API unlock function.*/ + spi_flash_guard_start_func_t start; /**< critical section start function. */ + spi_flash_guard_end_func_t end; /**< critical section end function. */ + spi_flash_op_lock_func_t op_lock; /**< flash access API lock function.*/ + spi_flash_op_unlock_func_t op_unlock; /**< flash access API unlock function.*/ +#if !CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED + spi_flash_is_safe_write_address_t is_safe_write_address; /**< checks flash write addresses.*/ +#endif } spi_flash_guard_funcs_t; /** @@ -361,7 +369,6 @@ typedef struct { */ void spi_flash_guard_set(const spi_flash_guard_funcs_t* funcs); - /** * @brief Get the guard functions used for flash access * diff --git a/tools/sdk/include/tcp_transport/transport.h b/tools/sdk/include/tcp_transport/esp_transport.h similarity index 59% rename from tools/sdk/include/tcp_transport/transport.h rename to tools/sdk/include/tcp_transport/esp_transport.h index a54cb83c..e163a010 100644 --- a/tools/sdk/include/tcp_transport/transport.h +++ b/tools/sdk/include/tcp_transport/esp_transport.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef _TRANSPORT_H_ -#define _TRANSPORT_H_ +#ifndef _ESP_TRANSPORT_H_ +#define _ESP_TRANSPORT_H_ #include @@ -22,26 +22,27 @@ extern "C" { #endif -typedef struct transport_list_t* transport_list_handle_t; -typedef struct transport_item_t* transport_handle_t; +typedef struct esp_transport_list_t* esp_transport_list_handle_t; +typedef struct esp_transport_item_t* esp_transport_handle_t; -typedef int (*connect_func)(transport_handle_t t, const char *host, int port, int timeout_ms); -typedef int (*io_func)(transport_handle_t t, const char *buffer, int len, int timeout_ms); -typedef int (*io_read_func)(transport_handle_t t, char *buffer, int len, int timeout_ms); -typedef int (*trans_func)(transport_handle_t t); -typedef int (*poll_func)(transport_handle_t t, int timeout_ms); -typedef transport_handle_t (*payload_transfer_func)(transport_handle_t); +typedef int (*connect_func)(esp_transport_handle_t t, const char *host, int port, int timeout_ms); +typedef int (*io_func)(esp_transport_handle_t t, const char *buffer, int len, int timeout_ms); +typedef int (*io_read_func)(esp_transport_handle_t t, char *buffer, int len, int timeout_ms); +typedef int (*trans_func)(esp_transport_handle_t t); +typedef int (*poll_func)(esp_transport_handle_t t, int timeout_ms); +typedef int (*connect_async_func)(esp_transport_handle_t t, const char *host, int port, int timeout_ms); +typedef esp_transport_handle_t (*payload_transfer_func)(esp_transport_handle_t); /** * @brief Create transport list * * @return A handle can hold all transports */ -transport_list_handle_t transport_list_init(); +esp_transport_list_handle_t esp_transport_list_init(); /** * @brief Cleanup and free all transports, include itself, - * this function will invoke transport_destroy of every transport have added this the list + * this function will invoke esp_transport_destroy of every transport have added this the list * * @param[in] list The list * @@ -49,7 +50,7 @@ transport_list_handle_t transport_list_init(); * - ESP_OK * - ESP_FAIL */ -esp_err_t transport_list_destroy(transport_list_handle_t list); +esp_err_t esp_transport_list_destroy(esp_transport_list_handle_t list); /** * @brief Add a transport to the list, and define a scheme to indentify this transport in the list @@ -61,11 +62,11 @@ esp_err_t transport_list_destroy(transport_list_handle_t list); * @return * - ESP_OK */ -esp_err_t transport_list_add(transport_list_handle_t list, transport_handle_t t, const char *scheme); +esp_err_t esp_transport_list_add(esp_transport_list_handle_t list, esp_transport_handle_t t, const char *scheme); /** * @brief This function will remove all transport from the list, - * invoke transport_destroy of every transport have added this the list + * invoke esp_transport_destroy of every transport have added this the list * * @param[in] list The list * @@ -73,24 +74,24 @@ esp_err_t transport_list_add(transport_list_handle_t list, transport_handle_t t, * - ESP_OK * - ESP_ERR_INVALID_ARG */ -esp_err_t transport_list_clean(transport_list_handle_t list); +esp_err_t esp_transport_list_clean(esp_transport_list_handle_t list); /** - * @brief Get the transport by scheme, which has been defined when calling function `transport_list_add` + * @brief Get the transport by scheme, which has been defined when calling function `esp_transport_list_add` * * @param[in] list The list * @param[in] tag The tag * * @return The transport handle */ -transport_handle_t transport_list_get_transport(transport_list_handle_t list, const char *scheme); +esp_transport_handle_t esp_transport_list_get_transport(esp_transport_list_handle_t list, const char *scheme); /** * @brief Initialize a transport handle object * * @return The transport handle */ -transport_handle_t transport_init(); +esp_transport_handle_t esp_transport_init(); /** * @brief Cleanup and free memory the transport @@ -101,7 +102,7 @@ transport_handle_t transport_init(); * - ESP_OK * - ESP_FAIL */ -esp_err_t transport_destroy(transport_handle_t t); +esp_err_t esp_transport_destroy(esp_transport_handle_t t); /** * @brief Get default port number used by this transport @@ -110,7 +111,7 @@ esp_err_t transport_destroy(transport_handle_t t); * * @return the port number */ -int transport_get_default_port(transport_handle_t t); +int esp_transport_get_default_port(esp_transport_handle_t t); /** * @brief Set default port number that can be used by this transport @@ -122,7 +123,7 @@ int transport_get_default_port(transport_handle_t t); * - ESP_OK * - ESP_FAIL */ -esp_err_t transport_set_default_port(transport_handle_t t, int port); +esp_err_t esp_transport_set_default_port(esp_transport_handle_t t, int port); /** * @brief Transport connection function, to make a connection to server @@ -136,7 +137,21 @@ esp_err_t transport_set_default_port(transport_handle_t t, int port); * - socket for will use by this transport * - (-1) if there are any errors, should check errno */ -int transport_connect(transport_handle_t t, const char *host, int port, int timeout_ms); +int esp_transport_connect(esp_transport_handle_t t, const char *host, int port, int timeout_ms); + +/** + * @brief Non-blocking transport connection function, to make a connection to server + * + * @param t The transport handle + * @param[in] host Hostname + * @param[in] port Port + * @param[in] timeout_ms The timeout milliseconds + * + * @return + * - socket for will use by this transport + * - (-1) if there are any errors, should check errno + */ +int esp_transport_connect_async(esp_transport_handle_t t, const char *host, int port, int timeout_ms); /** * @brief Transport read function @@ -150,7 +165,7 @@ int transport_connect(transport_handle_t t, const char *host, int port, int time * - Number of bytes was read * - (-1) if there are any errors, should check errno */ -int transport_read(transport_handle_t t, char *buffer, int len, int timeout_ms); +int esp_transport_read(esp_transport_handle_t t, char *buffer, int len, int timeout_ms); /** * @brief Poll the transport until readable or timeout @@ -163,7 +178,7 @@ int transport_read(transport_handle_t t, char *buffer, int len, int timeout_ms); * - (-1) If there are any errors, should check errno * - other The transport can read */ -int transport_poll_read(transport_handle_t t, int timeout_ms); +int esp_transport_poll_read(esp_transport_handle_t t, int timeout_ms); /** * @brief Transport write function @@ -177,7 +192,7 @@ int transport_poll_read(transport_handle_t t, int timeout_ms); * - Number of bytes was written * - (-1) if there are any errors, should check errno */ -int transport_write(transport_handle_t t, const char *buffer, int len, int timeout_ms); +int esp_transport_write(esp_transport_handle_t t, const char *buffer, int len, int timeout_ms); /** * @brief Poll the transport until writeable or timeout @@ -190,7 +205,7 @@ int transport_write(transport_handle_t t, const char *buffer, int len, int timeo * - (-1) If there are any errors, should check errno * - other The transport can write */ -int transport_poll_write(transport_handle_t t, int timeout_ms); +int esp_transport_poll_write(esp_transport_handle_t t, int timeout_ms); /** * @brief Transport close @@ -201,7 +216,7 @@ int transport_poll_write(transport_handle_t t, int timeout_ms); * - 0 if ok * - (-1) if there are any errors, should check errno */ -int transport_close(transport_handle_t t); +int esp_transport_close(esp_transport_handle_t t); /** * @brief Get user data context of this transport @@ -210,7 +225,7 @@ int transport_close(transport_handle_t t); * * @return The user data context */ -void *transport_get_context_data(transport_handle_t t); +void *esp_transport_get_context_data(esp_transport_handle_t t); /** * @brief Get transport handle of underlying protocol @@ -221,7 +236,7 @@ void *transport_get_context_data(transport_handle_t t); * * @return Payload transport handle */ -transport_handle_t transport_get_payload_transport_handle(transport_handle_t t); +esp_transport_handle_t esp_transport_get_payload_transport_handle(esp_transport_handle_t t); /** * @brief Set the user context data for this transport @@ -232,7 +247,7 @@ transport_handle_t transport_get_payload_transport_handle(transport_handle_t t); * @return * - ESP_OK */ -esp_err_t transport_set_context_data(transport_handle_t t, void *data); +esp_err_t esp_transport_set_context_data(esp_transport_handle_t t, void *data); /** * @brief Set transport functions for the transport handle @@ -245,21 +260,45 @@ esp_err_t transport_set_context_data(transport_handle_t t, void *data); * @param[in] _poll_read The poll read function pointer * @param[in] _poll_write The poll write function pointer * @param[in] _destroy The destroy function pointer - * @param[in] _parrent_transport The parrent transfer getter pointer * * @return * - ESP_OK */ -esp_err_t transport_set_func(transport_handle_t t, +esp_err_t esp_transport_set_func(esp_transport_handle_t t, connect_func _connect, io_read_func _read, io_func _write, trans_func _close, poll_func _poll_read, poll_func _poll_write, - trans_func _destroy, - payload_transfer_func _parrent_transport); + trans_func _destroy); + + +/** + * @brief Set transport functions for the transport handle + * + * @param[in] t The transport handle + * @param[in] _connect_async_func The connect_async function pointer + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t esp_transport_set_async_connect_func(esp_transport_handle_t t, connect_async_func _connect_async_func); + +/** + * @brief Set parent transport function to the handle + * + * @param[in] t The transport handle + * @param[in] _parent_transport The underlying transport getter pointer + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t esp_transport_set_parent_transport_func(esp_transport_handle_t t, payload_transfer_func _parent_transport); + #ifdef __cplusplus } #endif -#endif +#endif /* _ESP_TRANSPORT_ */ diff --git a/tools/sdk/include/tcp_transport/esp_transport_ssl.h b/tools/sdk/include/tcp_transport/esp_transport_ssl.h new file mode 100644 index 00000000..34045ae7 --- /dev/null +++ b/tools/sdk/include/tcp_transport/esp_transport_ssl.h @@ -0,0 +1,69 @@ +// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _ESP_TRANSPORT_SSL_H_ +#define _ESP_TRANSPORT_SSL_H_ + +#include "esp_transport.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Create new SSL transport, the transport handle must be release esp_transport_destroy callback + * + * @return the allocated esp_transport_handle_t, or NULL if the handle can not be allocated + */ +esp_transport_handle_t esp_transport_ssl_init(); + +/** + * @brief Set SSL certificate data (as PEM format). + * Note that, this function stores the pointer to data, rather than making a copy. + * So this data must remain valid until after the connection is cleaned up + * + * @param t ssl transport + * @param[in] data The pem data + * @param[in] len The length + */ +void esp_transport_ssl_set_cert_data(esp_transport_handle_t t, const char *data, int len); + +/** + * @brief Set SSL client certificate data for mutual authentication (as PEM format). + * Note that, this function stores the pointer to data, rather than making a copy. + * So this data must remain valid until after the connection is cleaned up + * + * @param t ssl transport + * @param[in] data The pem data + * @param[in] len The length + */ +void esp_transport_ssl_set_client_cert_data(esp_transport_handle_t t, const char *data, int len); + +/** + * @brief Set SSL client key data for mutual authentication (as PEM format). + * Note that, this function stores the pointer to data, rather than making a copy. + * So this data must remain valid until after the connection is cleaned up + * + * @param t ssl transport + * @param[in] data The pem data + * @param[in] len The length + */ +void esp_transport_ssl_set_client_key_data(esp_transport_handle_t t, const char *data, int len); + +#ifdef __cplusplus +} +#endif +#endif /* _ESP_TRANSPORT_SSL_H_ */ + diff --git a/tools/sdk/include/tcp_transport/transport_tcp.h b/tools/sdk/include/tcp_transport/esp_transport_tcp.h similarity index 71% rename from tools/sdk/include/tcp_transport/transport_tcp.h rename to tools/sdk/include/tcp_transport/esp_transport_tcp.h index e1cc1d34..57ad4533 100644 --- a/tools/sdk/include/tcp_transport/transport_tcp.h +++ b/tools/sdk/include/tcp_transport/esp_transport_tcp.h @@ -12,25 +12,25 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef _TRANSPORT_TCP_H_ -#define _TRANSPORT_TCP_H_ +#ifndef _ESP_TRANSPORT_TCP_H_ +#define _ESP_TRANSPORT_TCP_H_ -#include "transport.h" +#include "esp_transport.h" #ifdef __cplusplus extern "C" { #endif /** - * @brief Create TCP transport, the transport handle must be release transport_destroy callback + * @brief Create TCP transport, the transport handle must be release esp_transport_destroy callback * - * @return the allocated transport_handle_t, or NULL if the handle can not be allocated + * @return the allocated esp_transport_handle_t, or NULL if the handle can not be allocated */ -transport_handle_t transport_tcp_init(); +esp_transport_handle_t esp_transport_tcp_init(); #ifdef __cplusplus } #endif -#endif +#endif /* _ESP_TRANSPORT_TCP_H_ */ diff --git a/tools/sdk/include/tcp_transport/transport_utils.h b/tools/sdk/include/tcp_transport/esp_transport_utils.h similarity index 78% rename from tools/sdk/include/tcp_transport/transport_utils.h rename to tools/sdk/include/tcp_transport/esp_transport_utils.h index 0e72812e..405b4f6b 100644 --- a/tools/sdk/include/tcp_transport/transport_utils.h +++ b/tools/sdk/include/tcp_transport/esp_transport_utils.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef _TRANSPORT_UTILS_H_ -#define _TRANSPORT_UTILS_H_ +#ifndef _ESP_TRANSPORT_UTILS_H_ +#define _ESP_TRANSPORT_UTILS_H_ #include #ifdef __cplusplus @@ -26,10 +26,10 @@ extern "C" { * @param[in] timeout_ms The timeout milliseconds * @param[out] tv Timeval struct */ -void transport_utils_ms_to_timeval(int timeout_ms, struct timeval *tv); +void esp_transport_utils_ms_to_timeval(int timeout_ms, struct timeval *tv); -#define TRANSPORT_MEM_CHECK(TAG, a, action) if (!(a)) { \ +#define ESP_TRANSPORT_MEM_CHECK(TAG, a, action) if (!(a)) { \ ESP_LOGE(TAG,"%s:%d (%s): %s", __FILE__, __LINE__, __FUNCTION__, "Memory exhausted"); \ action; \ } @@ -37,4 +37,4 @@ void transport_utils_ms_to_timeval(int timeout_ms, struct timeval *tv); #ifdef __cplusplus } #endif -#endif /* _TRANSPORT_UTILS_H_ */ \ No newline at end of file +#endif /* _ESP_TRANSPORT_UTILS_H_ */ \ No newline at end of file diff --git a/tools/sdk/include/tcp_transport/esp_transport_ws.h b/tools/sdk/include/tcp_transport/esp_transport_ws.h new file mode 100644 index 00000000..582c5c7d --- /dev/null +++ b/tools/sdk/include/tcp_transport/esp_transport_ws.h @@ -0,0 +1,34 @@ +/* + * This file is subject to the terms and conditions defined in + * file 'LICENSE', which is part of this source code package. + * Tuan PM + */ + +#ifndef _ESP_TRANSPORT_WS_H_ +#define _ESP_TRANSPORT_WS_H_ + +#include "esp_transport.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Create web socket transport + * + * @return + * - transport + * - NULL + */ +esp_transport_handle_t esp_transport_ws_init(esp_transport_handle_t parent_handle); + +void esp_transport_ws_set_path(esp_transport_handle_t t, const char *path); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _ESP_TRANSPORT_WS_H_ */ diff --git a/tools/sdk/include/tcp_transport/transport_ssl.h b/tools/sdk/include/tcp_transport/transport_ssl.h deleted file mode 100644 index a00b36ba..00000000 --- a/tools/sdk/include/tcp_transport/transport_ssl.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef _TRANSPORT_SSL_H_ -#define _TRANSPORT_SSL_H_ - -#include "transport.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * @brief Create new SSL transport, the transport handle must be release transport_destroy callback - * - * @return the allocated transport_handle_t, or NULL if the handle can not be allocated - */ -transport_handle_t transport_ssl_init(); - -/** - * @brief Set SSL certificate data (as PEM format). - * Note that, this function stores the pointer to data, rather than making a copy. - * So we need to make sure to keep the data lifetime before cleanup the connection - * - * @param t ssl transport - * @param[in] data The pem data - * @param[in] len The length - */ -void transport_ssl_set_cert_data(transport_handle_t t, const char *data, int len); - - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/tools/sdk/include/tcpip_adapter/tcpip_adapter.h b/tools/sdk/include/tcpip_adapter/tcpip_adapter.h index 205c05fa..7d9e4ad8 100644 --- a/tools/sdk/include/tcpip_adapter/tcpip_adapter.h +++ b/tools/sdk/include/tcpip_adapter/tcpip_adapter.h @@ -618,6 +618,16 @@ esp_err_t tcpip_adapter_get_hostname(tcpip_adapter_if_t tcpip_if, const char **h */ esp_err_t tcpip_adapter_get_netif(tcpip_adapter_if_t tcpip_if, void ** netif); +/** + * @brief Test if supplied interface is up or down + * + * @param[in] tcpip_if: the interface which we will get the hostname + * + * @return true: tcpip_if is UP + * false: tcpip_if id DOWN + */ +bool tcpip_adapter_is_netif_up(tcpip_adapter_if_t tcpip_if); + #ifdef __cplusplus } #endif diff --git a/tools/sdk/include/unity/unity.h b/tools/sdk/include/unity/unity.h new file mode 100644 index 00000000..a0c301d2 --- /dev/null +++ b/tools/sdk/include/unity/unity.h @@ -0,0 +1,503 @@ +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_FRAMEWORK_H +#define UNITY_FRAMEWORK_H +#define UNITY + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "unity_internals.h" + +/*------------------------------------------------------- + * Test Setup / Teardown + *-------------------------------------------------------*/ + +/* These functions are intended to be called before and after each test. */ +void setUp(void); +void tearDown(void); + +/* These functions are intended to be called at the beginning and end of an + * entire test suite. suiteTearDown() is passed the number of tests that + * failed, and its return value becomes the exit code of main(). */ +void suiteSetUp(void); +int suiteTearDown(int num_failures); + +/* If the compiler supports it, the following block provides stub + * implementations of the above functions as weak symbols. Note that on + * some platforms (MinGW for example), weak function implementations need + * to be in the same translation unit they are called from. This can be + * achieved by defining UNITY_INCLUDE_SETUP_STUBS before including unity.h. */ +#ifdef UNITY_INCLUDE_SETUP_STUBS + #ifdef UNITY_WEAK_ATTRIBUTE + UNITY_WEAK_ATTRIBUTE void setUp(void) { } + UNITY_WEAK_ATTRIBUTE void tearDown(void) { } + UNITY_WEAK_ATTRIBUTE void suiteSetUp(void) { } + UNITY_WEAK_ATTRIBUTE int suiteTearDown(int num_failures) { return num_failures; } + #elif defined(UNITY_WEAK_PRAGMA) + #pragma weak setUp + void setUp(void) { } + #pragma weak tearDown + void tearDown(void) { } + #pragma weak suiteSetUp + void suiteSetUp(void) { } + #pragma weak suiteTearDown + int suiteTearDown(int num_failures) { return num_failures; } + #endif +#endif + +/*------------------------------------------------------- + * Configuration Options + *------------------------------------------------------- + * All options described below should be passed as a compiler flag to all files using Unity. If you must add #defines, place them BEFORE the #include above. + + * Integers/longs/pointers + * - Unity attempts to automatically discover your integer sizes + * - define UNITY_EXCLUDE_STDINT_H to stop attempting to look in + * - define UNITY_EXCLUDE_LIMITS_H to stop attempting to look in + * - If you cannot use the automatic methods above, you can force Unity by using these options: + * - define UNITY_SUPPORT_64 + * - set UNITY_INT_WIDTH + * - set UNITY_LONG_WIDTH + * - set UNITY_POINTER_WIDTH + + * Floats + * - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons + * - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT + * - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats + * - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons + * - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default) + * - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE + * - define UNITY_DOUBLE_TYPE to specify something other than double + * - define UNITY_EXCLUDE_FLOAT_PRINT to trim binary size, won't print floating point values in errors + + * Output + * - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired + * - define UNITY_DIFFERENTIATE_FINAL_FAIL to print FAILED (vs. FAIL) at test end summary - for automated search for failure + + * Optimization + * - by default, line numbers are stored in unsigned shorts. Define UNITY_LINE_TYPE with a different type if your files are huge + * - by default, test and failure counters are unsigned shorts. Define UNITY_COUNTER_TYPE with a different type if you want to save space or have more than 65535 Tests. + + * Test Cases + * - define UNITY_SUPPORT_TEST_CASES to include the TEST_CASE macro, though really it's mostly about the runner generator script + + * Parameterized Tests + * - you'll want to create a define of TEST_CASE(...) which basically evaluates to nothing + + * Tests with Arguments + * - you'll want to define UNITY_USE_COMMAND_LINE_ARGS if you have the test runner passing arguments to Unity + + *------------------------------------------------------- + * Basic Fail and Ignore + *-------------------------------------------------------*/ + +#define TEST_FAIL_MESSAGE(message) UNITY_TEST_FAIL(__LINE__, (message)) +#define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL) +#define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, (message)) +#define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL) +#define TEST_ONLY() + +/* It is not necessary for you to call PASS. A PASS condition is assumed if nothing fails. + * This method allows you to abort a test immediately with a PASS state, ignoring the remainder of the test. */ +#define TEST_PASS() TEST_ABORT() + +/* This macro does nothing, but it is useful for build tools (like Ceedling) to make use of this to figure out + * which files should be linked to in order to perform a test. Use it like TEST_FILE("sandwiches.c") */ +#define TEST_FILE(a) + +/*------------------------------------------------------- + * Test Asserts (simple) + *-------------------------------------------------------*/ + +/* Boolean */ +#define TEST_ASSERT(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expression Evaluated To FALSE") +#define TEST_ASSERT_TRUE(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expected TRUE Was FALSE") +#define TEST_ASSERT_UNLESS(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expression Evaluated To TRUE") +#define TEST_ASSERT_FALSE(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expected FALSE Was TRUE") +#define TEST_ASSERT_NULL(pointer) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, " Expected NULL") +#define TEST_ASSERT_NOT_NULL(pointer) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, " Expected Non-NULL") + +/* Integers (of all sizes) */ +#define TEST_ASSERT_EQUAL_INT(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal") +#define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(-1), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(0), (actual), __LINE__, NULL) +#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, NULL) +#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, NULL) + +/* Integer Greater Than/ Less Than (of all sizes) */ +#define TEST_ASSERT_GREATER_THAN(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, NULL) + +#define TEST_ASSERT_LESS_THAN(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, NULL) + +#define TEST_ASSERT_GREATER_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL) + +#define TEST_ASSERT_LESS_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL) + +/* Integer Ranges (of all sizes) */ +#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, NULL) + +/* Structs and Strings */ +#define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING(expected, actual) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, NULL) + +/* Arrays */ +#define TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, NULL) + +/* Arrays Compared To Single Value */ +#define TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, NULL) + +/* Floating Point (If Enabled) */ +#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, NULL) + +/* Double (If Enabled) */ +#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, NULL) + +/*------------------------------------------------------- + * Test Asserts (with additional messages) + *-------------------------------------------------------*/ + +/* Boolean */ +#define TEST_ASSERT_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message)) +#define TEST_ASSERT_TRUE_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message)) +#define TEST_ASSERT_UNLESS_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message)) +#define TEST_ASSERT_FALSE_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message)) +#define TEST_ASSERT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, (message)) +#define TEST_ASSERT_NOT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, (message)) + +/* Integers (of all sizes) */ +#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(-1), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(0), (actual), __LINE__, (message)) +#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, (message)) +#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, (message)) + +/* Integer Greater Than/ Less Than (of all sizes) */ +#define TEST_ASSERT_GREATER_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, (message)) + +#define TEST_ASSERT_LESS_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, (message)) + +#define TEST_ASSERT_GREATER_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message)) + +#define TEST_ASSERT_LESS_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message)) + +/* Integer Ranges (of all sizes) */ +#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, (message)) + +/* Structs and Strings */ +#define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_LEN_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, (message)) + +/* Arrays */ +#define TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, (message)) + +/* Arrays Compared To Single Value*/ +#define TEST_ASSERT_EACH_EQUAL_INT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_PTR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_STRING_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_MEMORY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, (message)) + +/* Floating Point (If Enabled) */ +#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_FLOAT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, (message)) + +/* Double (If Enabled) */ +#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_DOUBLE_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, (message)) + +/* end of UNITY_FRAMEWORK_H */ +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/sdk/include/unity/unity_config.h b/tools/sdk/include/unity/unity_config.h new file mode 100644 index 00000000..b23a5fe1 --- /dev/null +++ b/tools/sdk/include/unity/unity_config.h @@ -0,0 +1,53 @@ +#ifndef UNITY_CONFIG_H +#define UNITY_CONFIG_H + +// This file gets included from unity.h via unity_internals.h +// It is inside #ifdef __cplusplus / extern "C" block, so we can +// only use C features here + +#include +#include +#include "sdkconfig.h" + +#ifdef CONFIG_UNITY_ENABLE_FLOAT +#define UNITY_INCLUDE_FLOAT +#else +#define UNITY_EXCLUDE_FLOAT +#endif //CONFIG_UNITY_ENABLE_FLOAT + +#ifdef CONFIG_UNITY_ENABLE_DOUBLE +#define UNITY_INCLUDE_DOUBLE +#else +#define UNITY_EXCLUDE_DOUBLE +#endif //CONFIG_UNITY_ENABLE_DOUBLE + +#ifdef CONFIG_UNITY_ENABLE_COLOR +#define UNITY_OUTPUT_COLOR +#endif + +#define UNITY_EXCLUDE_TIME_H + +void unity_flush(void); +void unity_putc(int c); +void unity_gets(char* dst, size_t len); +void unity_exec_time_start(void); +void unity_exec_time_stop(void); +uint32_t unity_exec_time_get_ms(void); + +#define UNITY_OUTPUT_CHAR(a) unity_putc(a) +#define UNITY_OUTPUT_FLUSH() unity_flush() +#define UNITY_EXEC_TIME_START() unity_exec_time_start() +#define UNITY_EXEC_TIME_STOP() unity_exec_time_stop() +#define UNITY_EXEC_TIME_MS() unity_exec_time_get_ms() + +#ifdef CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER + +#include "unity_test_runner.h" + +#endif //CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER + +// shorthand to check esp_err_t return code +#define TEST_ESP_OK(rc) TEST_ASSERT_EQUAL_HEX32(ESP_OK, rc) +#define TEST_ESP_ERR(err, rc) TEST_ASSERT_EQUAL_HEX32(err, rc) + +#endif //UNITY_CONFIG_H diff --git a/tools/sdk/include/unity/unity_internals.h b/tools/sdk/include/unity/unity_internals.h new file mode 100644 index 00000000..7249fc79 --- /dev/null +++ b/tools/sdk/include/unity/unity_internals.h @@ -0,0 +1,928 @@ +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_INTERNALS_H +#define UNITY_INTERNALS_H + +#ifdef UNITY_INCLUDE_CONFIG_H +#include "unity_config.h" +#endif + +#ifndef UNITY_EXCLUDE_SETJMP_H +#include +#endif + +#ifndef UNITY_EXCLUDE_MATH_H +#include +#endif + +#ifndef UNITY_EXCLUDE_STDDEF_H +#include +#endif + +/* Unity Attempts to Auto-Detect Integer Types + * Attempt 1: UINT_MAX, ULONG_MAX in , or default to 32 bits + * Attempt 2: UINTPTR_MAX in , or default to same size as long + * The user may override any of these derived constants: + * UNITY_INT_WIDTH, UNITY_LONG_WIDTH, UNITY_POINTER_WIDTH */ +#ifndef UNITY_EXCLUDE_STDINT_H +#include +#endif + +#ifndef UNITY_EXCLUDE_LIMITS_H +#include +#endif + +#ifndef UNITY_EXCLUDE_TIME_H +#include +#endif + +/*------------------------------------------------------- + * Guess Widths If Not Specified + *-------------------------------------------------------*/ + +/* Determine the size of an int, if not already specified. + * We cannot use sizeof(int), because it is not yet defined + * at this stage in the translation of the C program. + * Therefore, infer it from UINT_MAX if possible. */ +#ifndef UNITY_INT_WIDTH + #ifdef UINT_MAX + #if (UINT_MAX == 0xFFFF) + #define UNITY_INT_WIDTH (16) + #elif (UINT_MAX == 0xFFFFFFFF) + #define UNITY_INT_WIDTH (32) + #elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF) + #define UNITY_INT_WIDTH (64) + #endif + #else /* Set to default */ + #define UNITY_INT_WIDTH (32) + #endif /* UINT_MAX */ +#endif + +/* Determine the size of a long, if not already specified. */ +#ifndef UNITY_LONG_WIDTH + #ifdef ULONG_MAX + #if (ULONG_MAX == 0xFFFF) + #define UNITY_LONG_WIDTH (16) + #elif (ULONG_MAX == 0xFFFFFFFF) + #define UNITY_LONG_WIDTH (32) + #elif (ULONG_MAX == 0xFFFFFFFFFFFFFFFF) + #define UNITY_LONG_WIDTH (64) + #endif + #else /* Set to default */ + #define UNITY_LONG_WIDTH (32) + #endif /* ULONG_MAX */ +#endif + +/* Determine the size of a pointer, if not already specified. */ +#ifndef UNITY_POINTER_WIDTH + #ifdef UINTPTR_MAX + #if (UINTPTR_MAX <= 0xFFFF) + #define UNITY_POINTER_WIDTH (16) + #elif (UINTPTR_MAX <= 0xFFFFFFFF) + #define UNITY_POINTER_WIDTH (32) + #elif (UINTPTR_MAX <= 0xFFFFFFFFFFFFFFFF) + #define UNITY_POINTER_WIDTH (64) + #endif + #else /* Set to default */ + #define UNITY_POINTER_WIDTH UNITY_LONG_WIDTH + #endif /* UINTPTR_MAX */ +#endif + +/*------------------------------------------------------- + * Int Support (Define types based on detected sizes) + *-------------------------------------------------------*/ + +#if (UNITY_INT_WIDTH == 32) + typedef unsigned char UNITY_UINT8; + typedef unsigned short UNITY_UINT16; + typedef unsigned int UNITY_UINT32; + typedef signed char UNITY_INT8; + typedef signed short UNITY_INT16; + typedef signed int UNITY_INT32; +#elif (UNITY_INT_WIDTH == 16) + typedef unsigned char UNITY_UINT8; + typedef unsigned int UNITY_UINT16; + typedef unsigned long UNITY_UINT32; + typedef signed char UNITY_INT8; + typedef signed int UNITY_INT16; + typedef signed long UNITY_INT32; +#else + #error Invalid UNITY_INT_WIDTH specified! (16 or 32 are supported) +#endif + +/*------------------------------------------------------- + * 64-bit Support + *-------------------------------------------------------*/ + +#ifndef UNITY_SUPPORT_64 + #if UNITY_LONG_WIDTH == 64 || UNITY_POINTER_WIDTH == 64 + #define UNITY_SUPPORT_64 + #endif +#endif + +#ifndef UNITY_SUPPORT_64 + /* No 64-bit Support */ + typedef UNITY_UINT32 UNITY_UINT; + typedef UNITY_INT32 UNITY_INT; +#else + + /* 64-bit Support */ + #if (UNITY_LONG_WIDTH == 32) + typedef unsigned long long UNITY_UINT64; + typedef signed long long UNITY_INT64; + #elif (UNITY_LONG_WIDTH == 64) + typedef unsigned long UNITY_UINT64; + typedef signed long UNITY_INT64; + #else + #error Invalid UNITY_LONG_WIDTH specified! (32 or 64 are supported) + #endif + typedef UNITY_UINT64 UNITY_UINT; + typedef UNITY_INT64 UNITY_INT; + +#endif + +/*------------------------------------------------------- + * Pointer Support + *-------------------------------------------------------*/ + +#if (UNITY_POINTER_WIDTH == 32) +#define UNITY_PTR_TO_INT UNITY_INT32 +#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX32 +#elif (UNITY_POINTER_WIDTH == 64) +#define UNITY_PTR_TO_INT UNITY_INT64 +#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX64 +#elif (UNITY_POINTER_WIDTH == 16) +#define UNITY_PTR_TO_INT UNITY_INT16 +#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX16 +#else + #error Invalid UNITY_POINTER_WIDTH specified! (16, 32 or 64 are supported) +#endif + +#ifndef UNITY_PTR_ATTRIBUTE +#define UNITY_PTR_ATTRIBUTE +#endif + +#ifndef UNITY_INTERNAL_PTR +#define UNITY_INTERNAL_PTR UNITY_PTR_ATTRIBUTE const void* +#endif + +/*------------------------------------------------------- + * Float Support + *-------------------------------------------------------*/ + +#ifdef UNITY_EXCLUDE_FLOAT + +/* No Floating Point Support */ +#ifndef UNITY_EXCLUDE_DOUBLE +#define UNITY_EXCLUDE_DOUBLE /* Remove double when excluding float support */ +#endif +#ifndef UNITY_EXCLUDE_FLOAT_PRINT +#define UNITY_EXCLUDE_FLOAT_PRINT +#endif + +#else + +/* Floating Point Support */ +#ifndef UNITY_FLOAT_PRECISION +#define UNITY_FLOAT_PRECISION (0.00001f) +#endif +#ifndef UNITY_FLOAT_TYPE +#define UNITY_FLOAT_TYPE float +#endif +typedef UNITY_FLOAT_TYPE UNITY_FLOAT; + +/* isinf & isnan macros should be provided by math.h */ +#ifndef isinf +/* The value of Inf - Inf is NaN */ +#define isinf(n) (isnan((n) - (n)) && !isnan(n)) +#endif + +#ifndef isnan +/* NaN is the only floating point value that does NOT equal itself. + * Therefore if n != n, then it is NaN. */ +#define isnan(n) ((n != n) ? 1 : 0) +#endif + +#endif + +/*------------------------------------------------------- + * Double Float Support + *-------------------------------------------------------*/ + +/* unlike float, we DON'T include by default */ +#if defined(UNITY_EXCLUDE_DOUBLE) || !defined(UNITY_INCLUDE_DOUBLE) + + /* No Floating Point Support */ + #ifndef UNITY_EXCLUDE_DOUBLE + #define UNITY_EXCLUDE_DOUBLE + #else + #undef UNITY_INCLUDE_DOUBLE + #endif + + #ifndef UNITY_EXCLUDE_FLOAT + #ifndef UNITY_DOUBLE_TYPE + #define UNITY_DOUBLE_TYPE double + #endif + typedef UNITY_FLOAT UNITY_DOUBLE; + /* For parameter in UnityPrintFloat(UNITY_DOUBLE), which aliases to double or float */ + #endif + +#else + + /* Double Floating Point Support */ + #ifndef UNITY_DOUBLE_PRECISION + #define UNITY_DOUBLE_PRECISION (1e-12) + #endif + + #ifndef UNITY_DOUBLE_TYPE + #define UNITY_DOUBLE_TYPE double + #endif + typedef UNITY_DOUBLE_TYPE UNITY_DOUBLE; + +#endif + +/*------------------------------------------------------- + * Output Method: stdout (DEFAULT) + *-------------------------------------------------------*/ +#ifndef UNITY_OUTPUT_CHAR + /* Default to using putchar, which is defined in stdio.h */ + #include + #define UNITY_OUTPUT_CHAR(a) (void)putchar(a) +#else + /* If defined as something else, make sure we declare it here so it's ready for use */ + #ifdef UNITY_OUTPUT_CHAR_HEADER_DECLARATION + extern void UNITY_OUTPUT_CHAR_HEADER_DECLARATION; + #endif +#endif + +#ifndef UNITY_OUTPUT_FLUSH + #ifdef UNITY_USE_FLUSH_STDOUT + /* We want to use the stdout flush utility */ + #include + #define UNITY_OUTPUT_FLUSH() (void)fflush(stdout) + #else + /* We've specified nothing, therefore flush should just be ignored */ + #define UNITY_OUTPUT_FLUSH() + #endif +#else + /* If defined as something else, make sure we declare it here so it's ready for use */ + #ifdef UNITY_OUTPUT_FLUSH_HEADER_DECLARATION + extern void UNITY_OUTPUT_FLUSH_HEADER_DECLARATION; + #endif +#endif + +#ifndef UNITY_OUTPUT_FLUSH +#define UNITY_FLUSH_CALL() +#else +#define UNITY_FLUSH_CALL() UNITY_OUTPUT_FLUSH() +#endif + +#ifndef UNITY_PRINT_EOL +#define UNITY_PRINT_EOL() UNITY_OUTPUT_CHAR('\n') +#endif + +#ifndef UNITY_OUTPUT_START +#define UNITY_OUTPUT_START() +#endif + +#ifndef UNITY_OUTPUT_COMPLETE +#define UNITY_OUTPUT_COMPLETE() +#endif + +#ifndef UNITY_EXEC_TIME_RESET +#ifdef UNITY_INCLUDE_EXEC_TIME +#define UNITY_EXEC_TIME_RESET()\ + Unity.CurrentTestStartTime = 0;\ + Unity.CurrentTestStopTime = 0; +#else +#define UNITY_EXEC_TIME_RESET() +#endif +#endif + +#ifndef UNITY_EXEC_TIME_START +#ifdef UNITY_INCLUDE_EXEC_TIME +#define UNITY_EXEC_TIME_START() Unity.CurrentTestStartTime = UNITY_CLOCK_MS(); +#else +#define UNITY_EXEC_TIME_START() +#endif +#endif + +#ifndef UNITY_EXEC_TIME_STOP +#ifdef UNITY_INCLUDE_EXEC_TIME +#define UNITY_EXEC_TIME_STOP() Unity.CurrentTestStopTime = UNITY_CLOCK_MS(); +#else +#define UNITY_EXEC_TIME_STOP() +#endif +#endif + +#ifndef UNITY_PRINT_EXEC_TIME +#ifdef UNITY_INCLUDE_EXEC_TIME +#define UNITY_PRINT_EXEC_TIME() \ + UnityPrint(" (");\ + UNITY_COUNTER_TYPE execTimeMs = (Unity.CurrentTestStopTime - Unity.CurrentTestStartTime);\ + UnityPrintNumberUnsigned(execTimeMs);\ + UnityPrint(" ms)"); +#else +#define UNITY_PRINT_EXEC_TIME() +#endif +#endif + +/*------------------------------------------------------- + * Footprint + *-------------------------------------------------------*/ + +#ifndef UNITY_LINE_TYPE +#define UNITY_LINE_TYPE UNITY_UINT +#endif + +#ifndef UNITY_COUNTER_TYPE +#define UNITY_COUNTER_TYPE UNITY_UINT +#endif + +/*------------------------------------------------------- + * Language Features Available + *-------------------------------------------------------*/ +#if !defined(UNITY_WEAK_ATTRIBUTE) && !defined(UNITY_WEAK_PRAGMA) +# if defined(__GNUC__) || defined(__ghs__) /* __GNUC__ includes clang */ +# if !(defined(__WIN32__) && defined(__clang__)) && !defined(__TMS470__) +# define UNITY_WEAK_ATTRIBUTE __attribute__((weak)) +# endif +# endif +#endif + +#ifdef UNITY_NO_WEAK +# undef UNITY_WEAK_ATTRIBUTE +# undef UNITY_WEAK_PRAGMA +#endif + + +/*------------------------------------------------------- + * Internal Structs Needed + *-------------------------------------------------------*/ + +typedef void (*UnityTestFunction)(void); + +#define UNITY_DISPLAY_RANGE_INT (0x10) +#define UNITY_DISPLAY_RANGE_UINT (0x20) +#define UNITY_DISPLAY_RANGE_HEX (0x40) + +typedef enum +{ +UNITY_DISPLAY_STYLE_INT = sizeof(int)+ UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT8 = 1 + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT16 = 2 + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT32 = 4 + UNITY_DISPLAY_RANGE_INT, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_INT64 = 8 + UNITY_DISPLAY_RANGE_INT, +#endif + +UNITY_DISPLAY_STYLE_UINT = sizeof(unsigned) + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT8 = 1 + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT16 = 2 + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT32 = 4 + UNITY_DISPLAY_RANGE_UINT, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_UINT64 = 8 + UNITY_DISPLAY_RANGE_UINT, +#endif + + UNITY_DISPLAY_STYLE_HEX8 = 1 + UNITY_DISPLAY_RANGE_HEX, + UNITY_DISPLAY_STYLE_HEX16 = 2 + UNITY_DISPLAY_RANGE_HEX, + UNITY_DISPLAY_STYLE_HEX32 = 4 + UNITY_DISPLAY_RANGE_HEX, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_HEX64 = 8 + UNITY_DISPLAY_RANGE_HEX, +#endif + + UNITY_DISPLAY_STYLE_UNKNOWN +} UNITY_DISPLAY_STYLE_T; + +typedef enum +{ + UNITY_EQUAL_TO = 1, + UNITY_GREATER_THAN = 2, + UNITY_GREATER_OR_EQUAL = 2 + UNITY_EQUAL_TO, + UNITY_SMALLER_THAN = 4, + UNITY_SMALLER_OR_EQUAL = 4 + UNITY_EQUAL_TO +} UNITY_COMPARISON_T; + +#ifndef UNITY_EXCLUDE_FLOAT +typedef enum UNITY_FLOAT_TRAIT +{ + UNITY_FLOAT_IS_NOT_INF = 0, + UNITY_FLOAT_IS_INF, + UNITY_FLOAT_IS_NOT_NEG_INF, + UNITY_FLOAT_IS_NEG_INF, + UNITY_FLOAT_IS_NOT_NAN, + UNITY_FLOAT_IS_NAN, + UNITY_FLOAT_IS_NOT_DET, + UNITY_FLOAT_IS_DET, + UNITY_FLOAT_INVALID_TRAIT +} UNITY_FLOAT_TRAIT_T; +#endif + +typedef enum +{ + UNITY_ARRAY_TO_VAL = 0, + UNITY_ARRAY_TO_ARRAY +} UNITY_FLAGS_T; + +struct UNITY_STORAGE_T +{ + const char* TestFile; + const char* CurrentTestName; +#ifndef UNITY_EXCLUDE_DETAILS + const char* CurrentDetail1; + const char* CurrentDetail2; +#endif + UNITY_LINE_TYPE CurrentTestLineNumber; + UNITY_COUNTER_TYPE NumberOfTests; + UNITY_COUNTER_TYPE TestFailures; + UNITY_COUNTER_TYPE TestIgnores; + UNITY_COUNTER_TYPE CurrentTestFailed; + UNITY_COUNTER_TYPE CurrentTestIgnored; +#ifdef UNITY_INCLUDE_EXEC_TIME + UNITY_COUNTER_TYPE CurrentTestStartTime; + UNITY_COUNTER_TYPE CurrentTestStopTime; +#endif +#ifndef UNITY_EXCLUDE_SETJMP_H + jmp_buf AbortFrame; +#endif +}; + +extern struct UNITY_STORAGE_T Unity; + +/*------------------------------------------------------- + * Test Suite Management + *-------------------------------------------------------*/ + +void UnityBegin(const char* filename); +int UnityEnd(void); +void UnityConcludeTest(void); +void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum); + +/*------------------------------------------------------- + * Details Support + *-------------------------------------------------------*/ + +#ifdef UNITY_EXCLUDE_DETAILS +#define UNITY_CLR_DETAILS() +#define UNITY_SET_DETAIL(d1) +#define UNITY_SET_DETAILS(d1,d2) +#else +#define UNITY_CLR_DETAILS() { Unity.CurrentDetail1 = 0; Unity.CurrentDetail2 = 0; } +#define UNITY_SET_DETAIL(d1) { Unity.CurrentDetail1 = (d1); Unity.CurrentDetail2 = 0; } +#define UNITY_SET_DETAILS(d1,d2) { Unity.CurrentDetail1 = (d1); Unity.CurrentDetail2 = (d2); } + +#ifndef UNITY_DETAIL1_NAME +#define UNITY_DETAIL1_NAME "Function" +#endif + +#ifndef UNITY_DETAIL2_NAME +#define UNITY_DETAIL2_NAME "Argument" +#endif +#endif + +/*------------------------------------------------------- + * Test Output + *-------------------------------------------------------*/ + +void UnityPrint(const char* string); +void UnityPrintLen(const char* string, const UNITY_UINT32 length); +void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number); +void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style); +void UnityPrintNumber(const UNITY_INT number_to_print); +void UnityPrintNumberUnsigned(const UNITY_UINT number); +void UnityPrintNumberHex(const UNITY_UINT number, const char nibbles_to_print); + +#ifndef UNITY_EXCLUDE_FLOAT_PRINT +void UnityPrintFloat(const UNITY_DOUBLE input_number); +#endif + +/*------------------------------------------------------- + * Test Assertion Functions + *------------------------------------------------------- + * Use the macros below this section instead of calling + * these directly. The macros have a consistent naming + * convention and will pull in file and line information + * for you. */ + +void UnityAssertEqualNumber(const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold, + const UNITY_INT actual, + const UNITY_COMPARISON_T compare, + const char *msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style, + const UNITY_FLAGS_T flags); + +void UnityAssertBits(const UNITY_INT mask, + const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualString(const char* expected, + const char* actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualStringLen(const char* expected, + const char* actual, + const UNITY_UINT32 length, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualStringArray( UNITY_INTERNAL_PTR expected, + const char** actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertEqualMemory( UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 length, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertNumbersWithin(const UNITY_UINT delta, + const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityFail(const char* msg, const UNITY_LINE_TYPE line); + +void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line); + +#ifndef UNITY_EXCLUDE_FLOAT +void UnityAssertFloatsWithin(const UNITY_FLOAT delta, + const UNITY_FLOAT expected, + const UNITY_FLOAT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected, + UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertFloatSpecial(const UNITY_FLOAT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style); +#endif + +#ifndef UNITY_EXCLUDE_DOUBLE +void UnityAssertDoublesWithin(const UNITY_DOUBLE delta, + const UNITY_DOUBLE expected, + const UNITY_DOUBLE actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expected, + UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style); +#endif + +/*------------------------------------------------------- + * Helpers + *-------------------------------------------------------*/ + +UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size); +#ifndef UNITY_EXCLUDE_FLOAT +UNITY_INTERNAL_PTR UnityFloatToPtr(const float num); +#endif +#ifndef UNITY_EXCLUDE_DOUBLE +UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num); +#endif + +/*------------------------------------------------------- + * Error Strings We Might Need + *-------------------------------------------------------*/ + +extern const char UnityStrErrFloat[]; +extern const char UnityStrErrDouble[]; +extern const char UnityStrErr64[]; + +/*------------------------------------------------------- + * Test Running Macros + *-------------------------------------------------------*/ + +#ifndef UNITY_EXCLUDE_SETJMP_H +#define TEST_PROTECT() (setjmp(Unity.AbortFrame) == 0) +#define TEST_ABORT() longjmp(Unity.AbortFrame, 1) +#else +#define TEST_PROTECT() 1 +#define TEST_ABORT() return +#endif + +#ifndef UNITY_EXCLUDE_TIME_H +#define UNITY_CLOCK_MS() (UNITY_COUNTER_TYPE)((clock() * 1000) / CLOCKS_PER_SEC) +#else +#define UNITY_CLOCK_MS() +#endif + +/* This tricky series of macros gives us an optional line argument to treat it as RUN_TEST(func, num=__LINE__) */ +#ifndef RUN_TEST +#ifdef __STDC_VERSION__ +#if __STDC_VERSION__ >= 199901L +#define RUN_TEST(...) UnityDefaultTestRun(RUN_TEST_FIRST(__VA_ARGS__), RUN_TEST_SECOND(__VA_ARGS__)) +#define RUN_TEST_FIRST(...) RUN_TEST_FIRST_HELPER(__VA_ARGS__, throwaway) +#define RUN_TEST_FIRST_HELPER(first, ...) (first), #first +#define RUN_TEST_SECOND(...) RUN_TEST_SECOND_HELPER(__VA_ARGS__, __LINE__, throwaway) +#define RUN_TEST_SECOND_HELPER(first, second, ...) (second) +#endif +#endif +#endif + +/* If we can't do the tricky version, we'll just have to require them to always include the line number */ +#ifndef RUN_TEST +#ifdef CMOCK +#define RUN_TEST(func, num) UnityDefaultTestRun(func, #func, num) +#else +#define RUN_TEST(func) UnityDefaultTestRun(func, #func, __LINE__) +#endif +#endif + +#define TEST_LINE_NUM (Unity.CurrentTestLineNumber) +#define TEST_IS_IGNORED (Unity.CurrentTestIgnored) +#define UNITY_NEW_TEST(a) \ + Unity.CurrentTestName = (a); \ + Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)(__LINE__); \ + Unity.NumberOfTests++; + +#ifndef UNITY_BEGIN +#define UNITY_BEGIN() UnityBegin(__FILE__) +#endif + +#ifndef UNITY_END +#define UNITY_END() UnityEnd() +#endif + +/*----------------------------------------------- + * Command Line Argument Support + *-----------------------------------------------*/ + +#ifdef UNITY_USE_COMMAND_LINE_ARGS +int UnityParseOptions(int argc, char** argv); +int UnityTestMatches(void); +#endif + +/*------------------------------------------------------- + * Basic Fail and Ignore + *-------------------------------------------------------*/ + +#define UNITY_TEST_FAIL(line, message) UnityFail( (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_IGNORE(line, message) UnityIgnore( (message), (UNITY_LINE_TYPE)(line)) + +/*------------------------------------------------------- + * Test Asserts + *-------------------------------------------------------*/ + +#define UNITY_TEST_ASSERT(condition, line, message) if (condition) {} else {UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), (message));} +#define UNITY_TEST_ASSERT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) == NULL), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_NOT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) != NULL), (UNITY_LINE_TYPE)(line), (message)) + +#define UNITY_TEST_ASSERT_EQUAL_INT(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_EQUAL_INT8(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_EQUAL_INT16(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT16)(expected), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_EQUAL_INT32(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT32)(expected), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_EQUAL_UINT(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_EQUAL_UINT8(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_UINT8 )(expected), (UNITY_INT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_EQUAL_UINT16(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_UINT16)(expected), (UNITY_INT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_EQUAL_UINT32(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_UINT32)(expected), (UNITY_INT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_EQUAL_HEX8(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_EQUAL_HEX16(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT16)(expected), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_EQUAL_HEX32(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT32)(expected), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_BITS(mask, expected, actual, line, message) UnityAssertBits((UNITY_INT)(mask), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line)) + +#define UNITY_TEST_ASSERT_GREATER_THAN_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) + +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) + +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) + +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) + +#define UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_INT16)(expected), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_INT32)(expected), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_UINT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_UINT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_UINT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) + +#define UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, line, message) UnityAssertEqualNumber((UNITY_PTR_TO_INT)(expected), (UNITY_PTR_TO_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER) +#define UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, line, message) UnityAssertEqualString((const char*)(expected), (const char*)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len, line, message) UnityAssertEqualStringLen((const char*)(expected), (const char*)(actual), (UNITY_UINT32)(len), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), 1, (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) + +#define UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((UNITY_INTERNAL_PTR)(expected), (const char**)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) + +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT) (expected), sizeof(int)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT16 )(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT32 )(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT) (expected), sizeof(unsigned int)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT16)(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT32)(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT16 )(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT32 )(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_PTR_TO_INT) (expected), sizeof(int*)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((UNITY_INTERNAL_PTR)(expected), (const char**)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) + +#ifdef UNITY_SUPPORT_64 +#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#else +#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#endif + +#ifdef UNITY_EXCLUDE_FLOAT +#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#else +#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UnityAssertFloatsWithin((UNITY_FLOAT)(delta), (UNITY_FLOAT)(expected), (UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((UNITY_FLOAT)(expected) * (UNITY_FLOAT)UNITY_FLOAT_PRECISION, (UNITY_FLOAT)(expected), (UNITY_FLOAT)(actual), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray((UNITY_FLOAT*)(expected), (UNITY_FLOAT*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray(UnityFloatToPtr(expected), (UNITY_FLOAT*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) +#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_DET) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NEG_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NAN) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET) +#endif + +#ifdef UNITY_EXCLUDE_DOUBLE +#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#else +#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((UNITY_DOUBLE)(delta), (UNITY_DOUBLE)(expected), (UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)line) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((UNITY_DOUBLE)(expected) * (UNITY_DOUBLE)UNITY_DOUBLE_PRECISION, (UNITY_DOUBLE)expected, (UNITY_DOUBLE)actual, (UNITY_LINE_TYPE)(line), message) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray((UNITY_DOUBLE*)(expected), (UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray(UnityDoubleToPtr(expected), (UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) +#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_DET) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NEG_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NAN) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET) +#endif + +/* End of UNITY_INTERNALS_H */ +#endif diff --git a/tools/sdk/include/unity/unity_test_runner.h b/tools/sdk/include/unity/unity_test_runner.h new file mode 100644 index 00000000..8f41eb83 --- /dev/null +++ b/tools/sdk/include/unity/unity_test_runner.h @@ -0,0 +1,174 @@ +// Copyright 2016-2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#include +#include + +// This file gets included from unity.h via unity_internals.h via unity_config.h +// It is inside #ifdef __cplusplus / extern "C" block, so we can +// only use C features here + +// Define helpers to register test cases from multiple files +#define UNITY_EXPAND2(a, b) a ## b +#define UNITY_EXPAND(a, b) UNITY_EXPAND2(a, b) +#define UNITY_TEST_UID(what) UNITY_EXPAND(what, __LINE__) + +#define UNITY_TEST_REG_HELPER reg_helper ## UNITY_TEST_UID +#define UNITY_TEST_DESC_UID desc ## UNITY_TEST_UID + + +// get count of __VA_ARGS__ +#define PP_NARG(...) \ + PP_NARG_(__VA_ARGS__,PP_RSEQ_N()) +#define PP_NARG_(...) \ + PP_ARG_N(__VA_ARGS__) +#define PP_ARG_N( \ + _1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N +#define PP_RSEQ_N() 9,8,7,6,5,4,3,2,1,0 + +// support max 5 test func now +#define FN_NAME_SET_1(a) {#a} +#define FN_NAME_SET_2(a, b) {#a, #b} +#define FN_NAME_SET_3(a, b, c) {#a, #b, #c} +#define FN_NAME_SET_4(a, b, c, d) {#a, #b, #c, #d} +#define FN_NAME_SET_5(a, b, c, d, e) {#a, #b, #c, #d, #e} + +#define FN_NAME_SET2(n) FN_NAME_SET_##n +#define FN_NAME_SET(n, ...) FN_NAME_SET2(n)(__VA_ARGS__) + +#define UNITY_TEST_FN_SET(...) \ + static test_func UNITY_TEST_UID(test_functions)[] = {__VA_ARGS__}; \ + static const char* UNITY_TEST_UID(test_fn_name)[] = FN_NAME_SET(PP_NARG(__VA_ARGS__), __VA_ARGS__) + + +typedef void (* test_func)(void); + +typedef struct test_desc_t +{ + const char* name; + const char* desc; + test_func* fn; + const char* file; + int line; + uint8_t test_fn_count; + const char ** test_fn_name; + struct test_desc_t* next; +} test_desc_t; + +void unity_testcase_register(test_desc_t* desc); + + +/* Test case macro, a-la CATCH framework. + First argument is a free-form description, + second argument is (by convention) a list of identifiers, each one in square brackets. + Identifiers are used to group related tests, or tests with specific properties. + Use like: + + TEST_CASE("Frobnicator forbnicates", "[frobnicator][rom]") + { + // test goes here + } +*/ + +#define TEST_CASE(name_, desc_) \ + static void UNITY_TEST_UID(test_func_) (void); \ + static void __attribute__((constructor)) UNITY_TEST_UID(test_reg_helper_) () \ + { \ + static test_func test_fn_[] = {&UNITY_TEST_UID(test_func_)}; \ + static test_desc_t UNITY_TEST_UID(test_desc_) = { \ + .name = name_, \ + .desc = desc_, \ + .fn = test_fn_, \ + .file = __FILE__, \ + .line = __LINE__, \ + .test_fn_count = 1, \ + .test_fn_name = NULL, \ + .next = NULL \ + }; \ + unity_testcase_register( & UNITY_TEST_UID(test_desc_) ); \ + }\ + static void UNITY_TEST_UID(test_func_) (void) + + +/* + * Multiple stages test cases will handle the case that test steps are separated by DUT reset. + * e.g: we want to verify some function after SW reset, WDT reset or deep sleep reset. + * + * First argument is a free-form description, + * second argument is (by convention) a list of identifiers, each one in square brackets. + * subsequent arguments are names test functions separated by reset. + * e.g: + * TEST_CASE_MULTIPLE_STAGES("run light sleep after deep sleep","[sleep]", goto_deepsleep, light_sleep_after_deep_sleep_wakeup); + * */ + +#define TEST_CASE_MULTIPLE_STAGES(name_, desc_, ...) \ + UNITY_TEST_FN_SET(__VA_ARGS__); \ + static void __attribute__((constructor)) UNITY_TEST_UID(test_reg_helper_) () \ + { \ + static test_desc_t UNITY_TEST_UID(test_desc_) = { \ + .name = name_, \ + .desc = desc_"[multi_stage]", \ + .fn = UNITY_TEST_UID(test_functions), \ + .file = __FILE__, \ + .line = __LINE__, \ + .test_fn_count = PP_NARG(__VA_ARGS__), \ + .test_fn_name = UNITY_TEST_UID(test_fn_name), \ + .next = NULL \ + }; \ + unity_testcase_register( & UNITY_TEST_UID(test_desc_) ); \ + } + +/* + * First argument is a free-form description, + * second argument is (by convention) a list of identifiers, each one in square brackets. + * subsequent arguments are names of test functions for different DUTs + * e.g: + * TEST_CASE_MULTIPLE_DEVICES("master and slave spi","[spi][test_env=UT_T2_1]", master_test, slave_test); + * */ + +#define TEST_CASE_MULTIPLE_DEVICES(name_, desc_, ...) \ + UNITY_TEST_FN_SET(__VA_ARGS__); \ + static void __attribute__((constructor)) UNITY_TEST_UID(test_reg_helper_) () \ + { \ + static test_desc_t UNITY_TEST_UID(test_desc_) = { \ + .name = name_, \ + .desc = desc_"[multi_device]", \ + .fn = UNITY_TEST_UID(test_functions), \ + .file = __FILE__, \ + .line = __LINE__, \ + .test_fn_count = PP_NARG(__VA_ARGS__), \ + .test_fn_name = UNITY_TEST_UID(test_fn_name), \ + .next = NULL \ + }; \ + unity_testcase_register( & UNITY_TEST_UID(test_desc_) ); \ + } + +/** + * Note: initialization of test_desc_t fields above has to be done exactly + * in the same order as the fields are declared in the structure. + * Otherwise the initializer will not be valid in C++ (which doesn't + * support designated initializers). G++ can parse the syntax, but + * field names are treated as annotations and don't affect initialization + * order. Also make sure all the fields are initialized. + */ + +void unity_run_test_by_name(const char *name); + +void unity_run_tests_by_tag(const char *tag, bool invert); + +void unity_run_all_tests(); + +void unity_run_menu(); + diff --git a/tools/sdk/include/vfs/esp_vfs.h b/tools/sdk/include/vfs/esp_vfs.h index d7467d22..e54a3e98 100644 --- a/tools/sdk/include/vfs/esp_vfs.h +++ b/tools/sdk/include/vfs/esp_vfs.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "esp_err.h" @@ -180,6 +181,10 @@ typedef struct int (*truncate_p)(void* ctx, const char *path, off_t length); int (*truncate)(const char *path, off_t length); }; + union { + int (*utime_p)(void* ctx, const char *path, const struct utimbuf *times); + int (*utime)(const char *path, const struct utimbuf *times); + }; #ifdef CONFIG_SUPPORT_TERMIOS union { int (*tcsetattr_p)(void *ctx, int fd, int optional_actions, const struct termios *p); @@ -330,6 +335,7 @@ int esp_vfs_stat(struct _reent *r, const char * path, struct stat * st); int esp_vfs_link(struct _reent *r, const char* n1, const char* n2); int esp_vfs_unlink(struct _reent *r, const char *path); int esp_vfs_rename(struct _reent *r, const char *src, const char *dst); +int esp_vfs_utime(const char *path, const struct utimbuf *times); /**@}*/ /** diff --git a/tools/sdk/include/wifi_provisioning/wifi_provisioning/wifi_config.h b/tools/sdk/include/wifi_provisioning/wifi_provisioning/wifi_config.h new file mode 100644 index 00000000..2794ae47 --- /dev/null +++ b/tools/sdk/include/wifi_provisioning/wifi_provisioning/wifi_config.h @@ -0,0 +1,120 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _WIFI_PROV_CONFIG_H_ +#define _WIFI_PROV_CONFIG_H_ + +#include + +/** + * @brief WiFi STA status for conveying back to the provisioning master + */ +typedef enum { + WIFI_PROV_STA_CONNECTING, + WIFI_PROV_STA_CONNECTED, + WIFI_PROV_STA_DISCONNECTED +} wifi_prov_sta_state_t; + +/** + * @brief WiFi STA connection fail reason + */ +typedef enum { + WIFI_PROV_STA_AUTH_ERROR, + WIFI_PROV_STA_AP_NOT_FOUND +} wifi_prov_sta_fail_reason_t; + +/** + * @brief WiFi STA connected status information + */ +typedef struct { + /** + * IP Address received by station + */ + char ip_addr[IP4ADDR_STRLEN_MAX]; + + char bssid[6]; /*!< BSSID of the AP to which connection was estalished */ + char ssid[33]; /*!< SSID of the to which connection was estalished */ + uint8_t channel; /*!< Channel of the AP */ + uint8_t auth_mode; /*!< Authorization mode of the AP */ +} wifi_prov_sta_conn_info_t; + +/** + * @brief WiFi status data to be sent in response to `get_status` request from master + */ +typedef struct { + wifi_prov_sta_state_t wifi_state; /*!< WiFi state of the station */ + union { + /** + * Reason for disconnection (valid only when `wifi_state` is `WIFI_STATION_DISCONNECTED`) + */ + wifi_prov_sta_fail_reason_t fail_reason; + + /** + * Connection information (valid only when `wifi_state` is `WIFI_STATION_CONNECTED`) + */ + wifi_prov_sta_conn_info_t conn_info; + }; +} wifi_prov_config_get_data_t; + +/** + * @brief WiFi config data received by slave during `set_config` request from master + */ +typedef struct { + char ssid[33]; /*!< SSID of the AP to which the slave is to be connected */ + char password[65]; /*!< Password of the AP */ + char bssid[6]; /*!< BSSID of the AP */ + uint8_t channel; /*!< Channel of the AP */ +} wifi_prov_config_set_data_t; + +/** + * @brief Internal handlers for receiving and responding to protocomm + * requests from master + * + * This is to be passed as priv_data for protocomm request handler + * (refer to `wifi_prov_config_data_handler()`) when calling `protocomm_add_endpoint()`. + */ +typedef struct wifi_prov_config_handlers { + /** + * Handler function called when connection status + * of the slave (in WiFi station mode) is requested + */ + esp_err_t (*get_status_handler)(wifi_prov_config_get_data_t *resp_data); + + /** + * Handler function called when WiFi connection configuration + * (eg. AP SSID, password, etc.) of the slave (in WiFi station mode) + * is to be set to user provided values + */ + esp_err_t (*set_config_handler)(const wifi_prov_config_set_data_t *req_data); + + /** + * Handler function for applying the configuration that was set in + * `set_config_handler`. After applying the station may get connected to + * the AP or may fail to connect. The slave must be ready to convey the + * updated connection status information when `get_status_handler` is + * invoked again by the master. + */ + esp_err_t (*apply_config_handler)(void); +} wifi_prov_config_handlers_t; + +/** + * @brief Handler for receiving and responding to requests from master + * + * This is to be registered as the `wifi_config` endpoint handler + * (protocomm `protocomm_req_handler_t`) using `protocomm_add_endpoint()` + */ +esp_err_t wifi_prov_config_data_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, + uint8_t **outbuf, ssize_t *outlen, void *priv_data); + +#endif diff --git a/tools/sdk/include/wpa_supplicant/crypto/crypto.h b/tools/sdk/include/wpa_supplicant/crypto/crypto.h index bccb6fed..f6b7b2f2 100644 --- a/tools/sdk/include/wpa_supplicant/crypto/crypto.h +++ b/tools/sdk/include/wpa_supplicant/crypto/crypto.h @@ -606,4 +606,363 @@ int __must_check fast_crypto_mod_exp(const uint8_t *base, size_t base_len, int rc4_skip(const u8 *key, size_t keylen, size_t skip, u8 *data, size_t data_len); + +/** + * crypto_get_random - Generate cryptographically strong pseudy-random bytes + * @buf: Buffer for data + * @len: Number of bytes to generate + * Returns: 0 on success, -1 on failure + * + * If the PRNG does not have enough entropy to ensure unpredictable byte + * sequence, this functions must return -1. + */ +int crypto_get_random(void *buf, size_t len); + + +/** + * struct crypto_bignum - bignum + * + * Internal data structure for bignum implementation. The contents is specific + * to the used crypto library. + */ +struct crypto_bignum; + +/** + * crypto_bignum_init - Allocate memory for bignum + * Returns: Pointer to allocated bignum or %NULL on failure + */ +struct crypto_bignum * crypto_bignum_init(void); + +/** + * crypto_bignum_init_set - Allocate memory for bignum and set the value + * @buf: Buffer with unsigned binary value + * @len: Length of buf in octets + * Returns: Pointer to allocated bignum or %NULL on failure + */ +struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len); + +/** + * crypto_bignum_deinit - Free bignum + * @n: Bignum from crypto_bignum_init() or crypto_bignum_init_set() + * @clear: Whether to clear the value from memory + */ +void crypto_bignum_deinit(struct crypto_bignum *n, int clear); + +/** + * crypto_bignum_to_bin - Set binary buffer to unsigned bignum + * @a: Bignum + * @buf: Buffer for the binary number + * @len: Length of @buf in octets + * @padlen: Length in octets to pad the result to or 0 to indicate no padding + * Returns: Number of octets written on success, -1 on failure + */ +int crypto_bignum_to_bin(const struct crypto_bignum *a, + u8 *buf, size_t buflen, size_t padlen); + +/** + * crypto_bignum_add - c = a + b + * @a: Bignum + * @b: Bignum + * @c: Bignum; used to store the result of a + b + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_add(const struct crypto_bignum *a, + const struct crypto_bignum *b, + struct crypto_bignum *c); + +/** + * crypto_bignum_mod - c = a % b + * @a: Bignum + * @b: Bignum + * @c: Bignum; used to store the result of a % b + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_mod(const struct crypto_bignum *a, + const struct crypto_bignum *b, + struct crypto_bignum *c); + +/** + * crypto_bignum_exptmod - Modular exponentiation: d = a^b (mod c) + * @a: Bignum; base + * @b: Bignum; exponent + * @c: Bignum; modulus + * @d: Bignum; used to store the result of a^b (mod c) + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_exptmod(const struct crypto_bignum *a, + const struct crypto_bignum *b, + const struct crypto_bignum *c, + struct crypto_bignum *d); + +/** + * crypto_bignum_inverse - Inverse a bignum so that a * c = 1 (mod b) + * @a: Bignum + * @b: Bignum + * @c: Bignum; used to store the result + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_inverse(const struct crypto_bignum *a, + const struct crypto_bignum *b, + struct crypto_bignum *c); + +/** + * crypto_bignum_sub - c = a - b + * @a: Bignum + * @b: Bignum + * @c: Bignum; used to store the result of a - b + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_sub(const struct crypto_bignum *a, + const struct crypto_bignum *b, + struct crypto_bignum *c); + +/** + * crypto_bignum_div - c = a / b + * @a: Bignum + * @b: Bignum + * @c: Bignum; used to store the result of a / b + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_div(const struct crypto_bignum *a, + const struct crypto_bignum *b, + struct crypto_bignum *c); + +/** + * crypto_bignum_mulmod - d = a * b (mod c) + * @a: Bignum + * @b: Bignum + * @c: Bignum + * @d: Bignum; used to store the result of (a * b) % c + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_mulmod(const struct crypto_bignum *a, + const struct crypto_bignum *b, + const struct crypto_bignum *c, + struct crypto_bignum *d); + +/** + * crypto_bignum_cmp - Compare two bignums + * @a: Bignum + * @b: Bignum + * Returns: -1 if a < b, 0 if a == b, or 1 if a > b + */ +int crypto_bignum_cmp(const struct crypto_bignum *a, + const struct crypto_bignum *b); + +/** + * crypto_bignum_bits - Get size of a bignum in bits + * @a: Bignum + * Returns: Number of bits in the bignum + */ +int crypto_bignum_bits(const struct crypto_bignum *a); + +/** + * crypto_bignum_is_zero - Is the given bignum zero + * @a: Bignum + * Returns: 1 if @a is zero or 0 if not + */ +int crypto_bignum_is_zero(const struct crypto_bignum *a); + +/** + * crypto_bignum_is_one - Is the given bignum one + * @a: Bignum + * Returns: 1 if @a is one or 0 if not + */ +int crypto_bignum_is_one(const struct crypto_bignum *a); + +/** + * crypto_bignum_legendre - Compute the Legendre symbol (a/p) + * @a: Bignum + * @p: Bignum + * Returns: Legendre symbol -1,0,1 on success; -2 on calculation failure + */ +int crypto_bignum_legendre(const struct crypto_bignum *a, + const struct crypto_bignum *p); + + +/** + * struct crypto_ec - Elliptic curve context + * + * Internal data structure for EC implementation. The contents is specific + * to the used crypto library. + */ +struct crypto_ec; + +/** + * crypto_ec_init - Initialize elliptic curve context + * @group: Identifying number for the ECC group (IANA "Group Description" + * attribute registrty for RFC 2409) + * Returns: Pointer to EC context or %NULL on failure + */ +struct crypto_ec * crypto_ec_init(int group); + +/** + * crypto_ec_deinit - Deinitialize elliptic curve context + * @e: EC context from crypto_ec_init() + */ +void crypto_ec_deinit(struct crypto_ec *e); + +/** + * crypto_ec_prime_len - Get length of the prime in octets + * @e: EC context from crypto_ec_init() + * Returns: Length of the prime defining the group + */ +size_t crypto_ec_prime_len(struct crypto_ec *e); + +/** + * crypto_ec_prime_len_bits - Get length of the prime in bits + * @e: EC context from crypto_ec_init() + * Returns: Length of the prime defining the group in bits + */ +size_t crypto_ec_prime_len_bits(struct crypto_ec *e); + +/** + * crypto_ec_get_prime - Get prime defining an EC group + * @e: EC context from crypto_ec_init() + * Returns: Prime (bignum) defining the group + */ +const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e); + +/** + * crypto_ec_get_order - Get order of an EC group + * @e: EC context from crypto_ec_init() + * Returns: Order (bignum) of the group + */ +const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e); + +/** + * struct crypto_ec_point - Elliptic curve point + * + * Internal data structure for EC implementation to represent a point. The + * contents is specific to the used crypto library. + */ +struct crypto_ec_point; + +/** + * crypto_ec_point_init - Initialize data for an EC point + * @e: EC context from crypto_ec_init() + * Returns: Pointer to EC point data or %NULL on failure + */ +struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e); + +/** + * crypto_ec_point_deinit - Deinitialize EC point data + * @p: EC point data from crypto_ec_point_init() + * @clear: Whether to clear the EC point value from memory + */ +void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear); + +/** + * crypto_ec_point_to_bin - Write EC point value as binary data + * @e: EC context from crypto_ec_init() + * @p: EC point data from crypto_ec_point_init() + * @x: Buffer for writing the binary data for x coordinate or %NULL if not used + * @y: Buffer for writing the binary data for y coordinate or %NULL if not used + * Returns: 0 on success, -1 on failure + * + * This function can be used to write an EC point as binary data in a format + * that has the x and y coordinates in big endian byte order fields padded to + * the length of the prime defining the group. + */ +int crypto_ec_point_to_bin(struct crypto_ec *e, + const struct crypto_ec_point *point, u8 *x, u8 *y); + +/** + * crypto_ec_point_from_bin - Create EC point from binary data + * @e: EC context from crypto_ec_init() + * @val: Binary data to read the EC point from + * Returns: Pointer to EC point data or %NULL on failure + * + * This function readers x and y coordinates of the EC point from the provided + * buffer assuming the values are in big endian byte order with fields padded to + * the length of the prime defining the group. + */ +struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e, + const u8 *val); + +/** + * crypto_bignum_add - c = a + b + * @e: EC context from crypto_ec_init() + * @a: Bignum + * @b: Bignum + * @c: Bignum; used to store the result of a + b + * Returns: 0 on success, -1 on failure + */ +int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a, + const struct crypto_ec_point *b, + struct crypto_ec_point *c); + +/** + * crypto_bignum_mul - res = b * p + * @e: EC context from crypto_ec_init() + * @p: EC point + * @b: Bignum + * @res: EC point; used to store the result of b * p + * Returns: 0 on success, -1 on failure + */ +int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p, + const struct crypto_bignum *b, + struct crypto_ec_point *res); + +/** + * crypto_ec_point_invert - Compute inverse of an EC point + * @e: EC context from crypto_ec_init() + * @p: EC point to invert (and result of the operation) + * Returns: 0 on success, -1 on failure + */ +int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p); + +/** + * crypto_ec_point_solve_y_coord - Solve y coordinate for an x coordinate + * @e: EC context from crypto_ec_init() + * @p: EC point to use for the returning the result + * @x: x coordinate + * @y_bit: y-bit (0 or 1) for selecting the y value to use + * Returns: 0 on success, -1 on failure + */ +int crypto_ec_point_solve_y_coord(struct crypto_ec *e, + struct crypto_ec_point *p, + const struct crypto_bignum *x, int y_bit); + +/** + * crypto_ec_point_compute_y_sqr - Compute y^2 = x^3 + ax + b + * @e: EC context from crypto_ec_init() + * @x: x coordinate + * Returns: y^2 on success, %NULL failure + */ +struct crypto_bignum * +crypto_ec_point_compute_y_sqr(struct crypto_ec *e, + const struct crypto_bignum *x); + +/** + * crypto_ec_point_is_at_infinity - Check whether EC point is neutral element + * @e: EC context from crypto_ec_init() + * @p: EC point + * Returns: 1 if the specified EC point is the neutral element of the group or + * 0 if not + */ +int crypto_ec_point_is_at_infinity(struct crypto_ec *e, + const struct crypto_ec_point *p); + +/** + * crypto_ec_point_is_on_curve - Check whether EC point is on curve + * @e: EC context from crypto_ec_init() + * @p: EC point + * Returns: 1 if the specified EC point is on the curve or 0 if not + */ +int crypto_ec_point_is_on_curve(struct crypto_ec *e, + const struct crypto_ec_point *p); + +/** + * crypto_ec_point_cmp - Compare two EC points + * @e: EC context from crypto_ec_init() + * @a: EC point + * @b: EC point + * Returns: 0 on equal, non-zero otherwise + */ +int crypto_ec_point_cmp(const struct crypto_ec *e, + const struct crypto_ec_point *a, + const struct crypto_ec_point *b); + + #endif /* CRYPTO_H */ diff --git a/tools/sdk/include/wpa_supplicant/endian.h b/tools/sdk/include/wpa_supplicant/endian.h index 5e6a876f..1e2453f1 100644 --- a/tools/sdk/include/wpa_supplicant/endian.h +++ b/tools/sdk/include/wpa_supplicant/endian.h @@ -29,6 +29,7 @@ #ifndef _ENDIAN_H_ #define _ENDIAN_H_ +#include #include "byteswap.h" #ifndef BIG_ENDIAN diff --git a/tools/sdk/include/wpa_supplicant/os.h b/tools/sdk/include/wpa_supplicant/os.h index 48f7ab85..0028c21e 100644 --- a/tools/sdk/include/wpa_supplicant/os.h +++ b/tools/sdk/include/wpa_supplicant/os.h @@ -270,7 +270,7 @@ char * ets_strdup(const char *s); #ifdef _MSC_VER #define os_snprintf _snprintf #else -#define os_snprintf vsnprintf +#define os_snprintf snprintf #endif #endif diff --git a/tools/sdk/ld/esp32.common.ld b/tools/sdk/ld/esp32.common.ld index cf1a3a7a..888508e2 100644 --- a/tools/sdk/ld/esp32.common.ld +++ b/tools/sdk/ld/esp32.common.ld @@ -1,3 +1,7 @@ +/* Automatically generated file; DO NOT EDIT */ +/* Espressif IoT Development Framework Linker Script */ +/* Generated from: /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/esp32/ld/esp32.common.ld.in */ + /* Default entry point: */ ENTRY(call_start_cpu0); @@ -9,22 +13,54 @@ SECTIONS .rtc.text : { . = ALIGN(4); - *(.rtc.literal .rtc.text) - *rtc_wake_stub*.*(.literal .text .literal.* .text.*) - } > rtc_iram_seg - /* RTC slow memory holds RTC wake stub + *( .rtc.literal .rtc.text) + + *rtc_wake_stub*.*(.literal .text .literal.* .text.*) + _rtc_text_end = ABSOLUTE(.); + } > rtc_iram_seg + + /* + This section is required to skip rtc.text area because rtc_iram_seg and + rtc_data_seg are reflect the same address space on different buses. + */ + .rtc.dummy : + { + _rtc_dummy_start = ABSOLUTE(.); + _rtc_fast_start = ABSOLUTE(.); + . = SIZEOF(.rtc.text); + _rtc_dummy_end = ABSOLUTE(.); + } > rtc_data_seg + + /* This section located in RTC FAST Memory area. + It holds data marked with RTC_FAST_ATTR attribute. + See the file "esp_attr.h" for more information. + */ + .rtc.force_fast : + { + . = ALIGN(4); + _rtc_force_fast_start = ABSOLUTE(.); + *(.rtc.force_fast .rtc.force_fast.*) + . = ALIGN(4) ; + _rtc_force_fast_end = ABSOLUTE(.); + } > rtc_data_seg + + /* RTC data section holds RTC wake stub data/rodata, including from any source file - named rtc_wake_stub*.c + named rtc_wake_stub*.c and the data marked with + RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. + The memory location of the data is dependent on + CONFIG_ESP32_RTCDATA_IN_FAST_MEM option. */ .rtc.data : { _rtc_data_start = ABSOLUTE(.); - *(.rtc.data) - *(.rtc.rodata) + + *( .rtc.data .rtc.rodata) + *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*) _rtc_data_end = ABSOLUTE(.); - } > rtc_slow_seg + } > rtc_data_location /* RTC bss, from any source file named rtc_wake_stub*.c */ .rtc.bss (NOLOAD) : @@ -32,14 +68,18 @@ SECTIONS _rtc_bss_start = ABSOLUTE(.); *rtc_wake_stub*.*(.bss .bss.*) *rtc_wake_stub*.*(COMMON) - *(.rtc.bss) + + *( .rtc.bss) + _rtc_bss_end = ABSOLUTE(.); - } > rtc_slow_seg + } > rtc_data_location /* This section holds data that should not be initialized at power up - and will be retained during deep sleep. The section located in - RTC SLOW Memory area. User data marked with RTC_NOINIT_ATTR will be placed - into this section. See the file "esp_attr.h" for more information. + and will be retained during deep sleep. + User data marked with RTC_NOINIT_ATTR will be placed + into this section. See the file "esp_attr.h" for more information. + The memory location of the data is dependent on + CONFIG_ESP32_RTCDATA_IN_FAST_MEM option. */ .rtc_noinit (NOLOAD): { @@ -48,8 +88,36 @@ SECTIONS *(.rtc_noinit .rtc_noinit.*) . = ALIGN(4) ; _rtc_noinit_end = ABSOLUTE(.); + } > rtc_data_location + + /* This section located in RTC SLOW Memory area. + It holds data marked with RTC_SLOW_ATTR attribute. + See the file "esp_attr.h" for more information. + */ + .rtc.force_slow : + { + . = ALIGN(4); + _rtc_force_slow_start = ABSOLUTE(.); + *(.rtc.force_slow .rtc.force_slow.*) + . = ALIGN(4) ; + _rtc_force_slow_end = ABSOLUTE(.); } > rtc_slow_seg + /* Get size of rtc slow data based on rtc_data_location alias */ + _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) + ? (_rtc_force_slow_end - _rtc_data_start) + : (_rtc_force_slow_end - _rtc_force_slow_start); + + _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) + ? (_rtc_force_fast_end - _rtc_fast_start) + : (_rtc_noinit_end - _rtc_fast_start); + + ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), + "RTC_SLOW segment data does not fit.") + + ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), + "RTC_FAST segment data does not fit.") + /* Send .iram0 code to iram */ .iram0.vectors : { @@ -87,32 +155,45 @@ SECTIONS *(.init.literal) *(.init) _init_end = ABSOLUTE(.); -} > iram0_0_seg + } > iram0_0_seg .iram0.text : { /* Code marked as runnning out of IRAM */ _iram_text_start = ABSOLUTE(.); - *(.iram1 .iram1.*) - *libfreertos.a:(.literal .text .literal.* .text.*) - *libheap.a:multi_heap.*(.literal .text .literal.* .text.*) - *libheap.a:multi_heap_poisoning.*(.literal .text .literal.* .text.*) - *libesp32.a:panic.*(.literal .text .literal.* .text.*) - *libesp32.a:core_dump.*(.literal .text .literal.* .text.*) - *libapp_trace.a:(.literal .text .literal.* .text.*) - *libxtensa-debug-module.a:eri.*(.literal .text .literal.* .text.*) - *librtc.a:(.literal .text .literal.* .text.*) - *libsoc.a:rtc_*.*(.literal .text .literal.* .text.*) - *libsoc.a:cpu_util.*(.literal .text .literal.* .text.*) - *libhal.a:(.literal .text .literal.* .text.*) - *libgcc.a:lib2funcs.*(.literal .text .literal.* .text.*) - *libspi_flash.a:spi_flash_rom_patch.*(.literal .text .literal.* .text.*) - *libgcov.a:(.literal .text .literal.* .text.*) + + *( .iram1 .iram1.*) + *libspi_flash.a:spi_flash_rom_patch.*( .literal .literal.* .text .text.*) + *libesp_ringbuf.a:( .literal .literal.* .text .text.*) + *libhal.a:( .literal .literal.* .text .text.*) + *libapp_trace.a:( .literal .literal.* .text .text.*) + *libesp32.a:panic.*( .literal .literal.* .text .text.*) + *libesp32.a:core_dump.*( .literal .literal.* .text .text.*) + *librtc.a:( .literal .literal.* .text .text.*) + *libgcc.a:lib2funcs.*( .literal .literal.* .text .text.*) + *libsoc.a:cpu_util.*( .literal .literal.* .text .text.*) + *libsoc.a:rtc_clk.*( .literal .literal.* .text .text.*) + *libsoc.a:rtc_init.*( .literal .literal.* .text .text.*) + *libsoc.a:rtc_periph.*( .literal .literal.* .text .text.*) + *libsoc.a:rtc_clk_init.*( .literal .literal.* .text .text.*) + *libsoc.a:rtc_wdt.*( .literal .literal.* .text .text.*) + *libsoc.a:rtc_sleep.*( .literal .literal.* .text .text.*) + *libsoc.a:rtc_pm.*( .literal .literal.* .text .text.*) + *libsoc.a:rtc_time.*( .literal .literal.* .text .text.*) + *libfreertos.a:( .literal .literal.* .text .text.*) + *libgcov.a:( .literal .literal.* .text .text.*) + *libxtensa-debug-module.a:eri.*( .literal .literal.* .text .text.*) + *libheap.a:multi_heap_poisoning.*( .literal .literal.* .text .text.*) + *libheap.a:multi_heap.*( .literal .literal.* .text .text.*) + INCLUDE esp32.spiram.rom-functions-iram.ld _iram_text_end = ABSOLUTE(.); _iram_end = ABSOLUTE(.); } > iram0_0_seg + ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), + "IRAM0 segment data does not fit.") + .dram0.data : { _data_start = ABSOLUTE(.); @@ -124,8 +205,6 @@ SECTIONS *libbtdm_app.a:(.data .data.*) . = ALIGN (4); _btdm_data_end = ABSOLUTE(.); - *(.data) - *(.data.*) *(.gnu.linkonce.d.*) *(.data1) *(.sdata) @@ -135,14 +214,16 @@ SECTIONS *(.sdata2.*) *(.gnu.linkonce.s2.*) *(.jcr) - *(.dram1 .dram1.*) - *libesp32.a:panic.*(.rodata .rodata.*) - *libphy.a:(.rodata .rodata.*) - *libsoc.a:rtc_clk.*(.rodata .rodata.*) - *libapp_trace.a:(.rodata .rodata.*) - *libgcov.a:(.rodata .rodata.*) - *libheap.a:multi_heap.*(.rodata .rodata.*) - *libheap.a:multi_heap_poisoning.*(.rodata .rodata.*) + + *( .data .data.* .dram1 .dram1.*) + *libapp_trace.a:( .rodata .rodata.*) + *libesp32.a:panic.*( .rodata .rodata.*) + *libphy.a:( .rodata .rodata.*) + *libsoc.a:rtc_clk.*( .rodata .rodata.*) + *libgcov.a:( .rodata .rodata.*) + *libheap.a:multi_heap_poisoning.*( .rodata .rodata.*) + *libheap.a:multi_heap.*( .rodata .rodata.*) + INCLUDE esp32.spiram.rom-functions-dram.ld _data_end = ABSOLUTE(.); . = ALIGN(4); @@ -167,6 +248,7 @@ SECTIONS { . = ALIGN (8); _bss_start = ABSOLUTE(.); + *(.ext_ram.bss*) _bt_bss_start = ABSOLUTE(.); *libbt.a:(.bss .bss.* COMMON) . = ALIGN (4); @@ -175,6 +257,9 @@ SECTIONS *libbtdm_app.a:(.bss .bss.* COMMON) . = ALIGN (4); _btdm_bss_end = ABSOLUTE(.); + + *( .bss .bss.* COMMON) + *(.dynsbss) *(.sbss) *(.sbss.*) @@ -184,22 +269,24 @@ SECTIONS *(.sbss2.*) *(.gnu.linkonce.sb2.*) *(.dynbss) - *(.bss) - *(.bss.*) *(.share.mem) *(.gnu.linkonce.b.*) - *(COMMON) + . = ALIGN (8); _bss_end = ABSOLUTE(.); /* The heap starts right after end of this section */ _heap_start = ABSOLUTE(.); } > dram0_0_seg + ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), + "DRAM segment data does not fit.") + .flash.rodata : { _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) + + *(EXCLUDE_FILE(*libapp_trace.a *libesp32.a:panic.* *libphy.a *libsoc.a:rtc_clk.* *libgcov.a *libheap.a:multi_heap.* *libheap.a:multi_heap_poisoning.*) .rodata EXCLUDE_FILE(*libapp_trace.a *libesp32.a:panic.* *libphy.a *libsoc.a:rtc_clk.* *libgcov.a *libheap.a:multi_heap.* *libheap.a:multi_heap_poisoning.*) .rodata.*) + *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ *(.gnu.linkonce.r.*) *(.rodata1) @@ -257,7 +344,10 @@ SECTIONS { _stext = .; _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + + *(EXCLUDE_FILE(*libspi_flash.a:spi_flash_rom_patch.* *libesp_ringbuf.a *libhal.a *libapp_trace.a *libesp32.a:core_dump.* *libesp32.a:panic.* *librtc.a *libgcc.a:lib2funcs.* *libsoc.a:rtc_time.* *libsoc.a:rtc_pm.* *libsoc.a:rtc_sleep.* *libsoc.a:rtc_wdt.* *libsoc.a:rtc_clk_init.* *libsoc.a:rtc_periph.* *libsoc.a:rtc_init.* *libsoc.a:rtc_clk.* *libsoc.a:cpu_util.* *libfreertos.a *libgcov.a *libxtensa-debug-module.a:eri.* *libheap.a:multi_heap.* *libheap.a:multi_heap_poisoning.*) .literal EXCLUDE_FILE(*libspi_flash.a:spi_flash_rom_patch.* *libesp_ringbuf.a *libhal.a *libapp_trace.a *libesp32.a:core_dump.* *libesp32.a:panic.* *librtc.a *libgcc.a:lib2funcs.* *libsoc.a:rtc_time.* *libsoc.a:rtc_pm.* *libsoc.a:rtc_sleep.* *libsoc.a:rtc_wdt.* *libsoc.a:rtc_clk_init.* *libsoc.a:rtc_periph.* *libsoc.a:rtc_init.* *libsoc.a:rtc_clk.* *libsoc.a:cpu_util.* *libfreertos.a *libgcov.a *libxtensa-debug-module.a:eri.* *libheap.a:multi_heap.* *libheap.a:multi_heap_poisoning.*) .literal.* EXCLUDE_FILE(*libspi_flash.a:spi_flash_rom_patch.* *libesp_ringbuf.a *libhal.a *libapp_trace.a *libesp32.a:core_dump.* *libesp32.a:panic.* *librtc.a *libgcc.a:lib2funcs.* *libsoc.a:rtc_time.* *libsoc.a:rtc_pm.* *libsoc.a:rtc_sleep.* *libsoc.a:rtc_wdt.* *libsoc.a:rtc_clk_init.* *libsoc.a:rtc_periph.* *libsoc.a:rtc_init.* *libsoc.a:rtc_clk.* *libsoc.a:cpu_util.* *libfreertos.a *libgcov.a *libxtensa-debug-module.a:eri.* *libheap.a:multi_heap.* *libheap.a:multi_heap_poisoning.*) .text EXCLUDE_FILE(*libspi_flash.a:spi_flash_rom_patch.* *libesp_ringbuf.a *libhal.a *libapp_trace.a *libesp32.a:core_dump.* *libesp32.a:panic.* *librtc.a *libgcc.a:lib2funcs.* *libsoc.a:rtc_time.* *libsoc.a:rtc_pm.* *libsoc.a:rtc_sleep.* *libsoc.a:rtc_wdt.* *libsoc.a:rtc_clk_init.* *libsoc.a:rtc_periph.* *libsoc.a:rtc_init.* *libsoc.a:rtc_clk.* *libsoc.a:cpu_util.* *libfreertos.a *libgcov.a *libxtensa-debug-module.a:eri.* *libheap.a:multi_heap.* *libheap.a:multi_heap_poisoning.*) .text.*) + + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ *(.fini.literal) *(.fini) diff --git a/tools/sdk/ld/esp32.extram.bss.ld b/tools/sdk/ld/esp32.extram.bss.ld new file mode 100644 index 00000000..6e0ab496 --- /dev/null +++ b/tools/sdk/ld/esp32.extram.bss.ld @@ -0,0 +1,17 @@ +/* This section is only included if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + is set, to link some sections to BSS in PSRAM */ + +SECTIONS +{ + /* external memory bss, from any global variable with EXT_RAM_ATTR attribute*/ + .ext_ram.bss (NOLOAD) : + { + _ext_ram_bss_start = ABSOLUTE(.); + *(.ext_ram.bss*) + *libnet80211.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON) + *libpp.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON) + *liblwip.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON) + *libbt.a:(EXCLUDE_FILE (libbtdm_app.a) .dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON) + _ext_ram_bss_end = ABSOLUTE(.); + } > extern_ram_seg +} diff --git a/tools/sdk/ld/esp32.ld b/tools/sdk/ld/esp32.ld index ee41f747..fd02e0d2 100644 --- a/tools/sdk/ld/esp32.ld +++ b/tools/sdk/ld/esp32.ld @@ -61,6 +61,9 @@ MEMORY /* RTC fast memory (executable). Persists over deep sleep. */ rtc_iram_seg(RWX) : org = 0x400C0000, len = 0x2000 + + /* RTC fast memory (same block as above), viewed from data bus */ + rtc_data_seg(RW) : org = 0x3ff80000, len = 0x2000 /* RTC slow memory (data accessible). Persists over deep sleep. @@ -68,7 +71,22 @@ MEMORY */ rtc_slow_seg(RW) : org = 0x50000000 + CONFIG_ULP_COPROC_RESERVE_MEM, len = 0x1000 - CONFIG_ULP_COPROC_RESERVE_MEM + + /* external memory ,including data and text */ + extern_ram_seg(RWX) : org = 0x3F800000, + len = 0x400000 } /* Heap ends at top of dram0_0_seg */ _heap_end = 0x40000000 - CONFIG_TRACEMEM_RESERVE_DRAM; + +_data_seg_org = ORIGIN(rtc_data_seg); + +/* The lines below define location alias for .rtc.data section based on Kconfig option. + When the option is not defined then use slow memory segment + else the data will be placed in fast memory segment */ +#ifndef CONFIG_ESP32_RTCDATA_IN_FAST_MEM +REGION_ALIAS("rtc_data_location", rtc_slow_seg ); +#else +REGION_ALIAS("rtc_data_location", rtc_data_seg ); +#endif diff --git a/tools/sdk/ld/esp32.rom.ld b/tools/sdk/ld/esp32.rom.ld index fe5a4e7c..14e17763 100644 --- a/tools/sdk/ld/esp32.rom.ld +++ b/tools/sdk/ld/esp32.rom.ld @@ -3,19 +3,13 @@ ESP32 ROM address table Generated for ROM with MD5sum: ab8282ae908fe9e7a63fb2a4ac2df013 ../../rom_image/prorom.elf */ -PROVIDE ( abort = 0x4000bba4 ); PROVIDE ( Add2SelfBigHex256 = 0x40015b7c ); PROVIDE ( AddBigHex256 = 0x40015b28 ); PROVIDE ( AddBigHexModP256 = 0x40015c98 ); PROVIDE ( AddP256 = 0x40015c74 ); PROVIDE ( AddPdiv2_256 = 0x40015ce0 ); -PROVIDE ( aes_128_cbc_decrypt = 0x4005cc7c ); -PROVIDE ( aes_128_cbc_encrypt = 0x4005cc18 ); -PROVIDE ( aes_unwrap = 0x4005ccf0 ); PROVIDE ( app_gpio_arg = 0x3ffe003c ); PROVIDE ( app_gpio_handler = 0x3ffe0040 ); -PROVIDE ( base64_decode = 0x4005ced8 ); -PROVIDE ( base64_encode = 0x4005cdbc ); PROVIDE ( BasePoint_x_256 = 0x3ff97488 ); PROVIDE ( BasePoint_y_256 = 0x3ff97468 ); PROVIDE ( bigHexInversion256 = 0x400168f0 ); @@ -63,6 +57,7 @@ PROVIDE ( _bss_start_btdm = 0x3ffb8000); PROVIDE ( _bss_end_btdm = 0x3ffbff70); PROVIDE ( _daylight = 0x3ffae0a4 ); PROVIDE ( dbg_default_handler = 0x3ff97218 ); +PROVIDE ( dbg_default_state = 0x3ff97220 ); PROVIDE ( dbg_state = 0x3ffb8d5d ); PROVIDE ( DebugE256PublicKey_x = 0x3ff97428 ); PROVIDE ( DebugE256PublicKey_y = 0x3ff97408 ); @@ -97,12 +92,8 @@ PROVIDE ( ets_startup_callback = 0x3ffe0404 ); PROVIDE ( exc_cause_table = 0x3ff991d0 ); PROVIDE ( _exit_r = 0x4000bd28 ); PROVIDE ( free = 0x4000beb8 ); -PROVIDE ( _free_r = 0x4000bbcc ); PROVIDE ( _fstat_r = 0x4000bccc ); PROVIDE ( __gcc_bcmp = 0x40064a70 ); -PROVIDE ( _getpid_r = 0x4000bcfc ); -PROVIDE ( __getreent = 0x4000be8c ); -PROVIDE ( _gettimeofday_r = 0x4000bc58 ); PROVIDE ( GF_Jacobian_Point_Addition256 = 0x400163a4 ); PROVIDE ( GF_Jacobian_Point_Double256 = 0x40016260 ); PROVIDE ( GF_Point_Jacobian_To_Affine256 = 0x40016b0c ); @@ -126,16 +117,9 @@ PROVIDE ( hci_evt_dbg_desc_tab = 0x3ff9750c ); PROVIDE ( hci_evt_desc_tab = 0x3ff9751c ); PROVIDE ( hci_evt_le_desc_tab = 0x3ff974b4 ); PROVIDE ( hci_fc_env = 0x3ffb9340 ); -PROVIDE ( hmac_md5 = 0x4005d264 ); -PROVIDE ( hmac_md5_vector = 0x4005d17c ); -PROVIDE ( hmac_sha1 = 0x40060acc ); -PROVIDE ( hmac_sha1_vector = 0x400609e4 ); -PROVIDE ( hmac_sha256 = 0x40060d58 ); -PROVIDE ( hmac_sha256_vector = 0x40060c84 ); PROVIDE ( jd_decomp = 0x400613e8 ); PROVIDE ( jd_prepare = 0x40060fa8 ); PROVIDE ( ke_env = 0x3ffb93cc ); -PROVIDE ( _kill_r = 0x4000bd10 ); PROVIDE ( lb_default_handler = 0x3ff982b8 ); PROVIDE ( lb_default_state_tab_p_get = 0x4001c198 ); PROVIDE ( lb_env = 0x3ffb9424 ); @@ -198,23 +182,10 @@ PROVIDE ( lm_n_page_tab = 0x3ff990e8 ); PROVIDE ( lmp_desc_tab = 0x3ff96e6c ); PROVIDE ( lmp_ext_desc_tab = 0x3ff96d9c ); PROVIDE ( lm_state = 0x3ffb9a1c ); -PROVIDE ( _lock_acquire_recursive = 0x4000be28 ); -PROVIDE ( _lock_close = 0x4000bdec ); -PROVIDE ( _lock_close_recursive = 0x4000be00 ); -PROVIDE ( _lock_init = 0x4000bdc4 ); -PROVIDE ( _lock_init_recursive = 0x4000bdd8 ); -PROVIDE ( _lock_release_recursive = 0x4000be78 ); -PROVIDE ( _lock_try_acquire = 0x4000be3c ); -PROVIDE ( _lock_try_acquire_recursive = 0x4000be50 ); PROVIDE ( _lseek_r = 0x4000bd8c ); PROVIDE ( malloc = 0x4000bea0 ); -PROVIDE ( _malloc_r = 0x4000bbb4 ); PROVIDE ( maxSecretKey_256 = 0x3ff97448 ); PROVIDE ( __mb_cur_max = 0x3ff96530 ); -PROVIDE ( MD5Final = 0x4005db1c ); -PROVIDE ( MD5Init = 0x4005da7c ); -PROVIDE ( MD5Update = 0x4005da9c ); -PROVIDE ( md5_vector = 0x4005db80 ); PROVIDE ( mmu_init = 0x400095a4 ); PROVIDE ( __month_lengths = 0x3ff9609c ); PROVIDE ( MultiplyBigHexByUint32_256 = 0x40016214 ); @@ -227,7 +198,6 @@ PROVIDE ( mz_free = 0x4005eed4 ); PROVIDE ( notEqual256 = 0x40015b04 ); PROVIDE ( one_bits = 0x3ff971f8 ); PROVIDE ( _open_r = 0x4000bd54 ); -PROVIDE ( pbkdf2_sha1 = 0x40060ba4 ); PROVIDE ( phy_get_romfuncs = 0x40004100 ); PROVIDE ( _Pri_4_HandlerAddress = 0x3ffe0648 ); PROVIDE ( _Pri_5_HandlerAddress = 0x3ffe064c ); @@ -245,7 +215,6 @@ PROVIDE ( r_bt_util_buf_sync_rx_alloc = 0x40010468 ); PROVIDE ( r_bt_util_buf_sync_rx_free = 0x4001049c ); PROVIDE ( r_bt_util_buf_sync_tx_alloc = 0x400103ec ); PROVIDE ( r_bt_util_buf_sync_tx_free = 0x40010428 ); -PROVIDE ( rc4_skip = 0x40060928 ); PROVIDE ( r_co_bdaddr_compare = 0x40014324 ); PROVIDE ( r_co_bytes_to_string = 0x400142e4 ); PROVIDE ( r_co_list_check_size_available = 0x400142c4 ); @@ -292,7 +261,6 @@ PROVIDE ( r_ea_interval_remove = 0x40015590 ); PROVIDE ( ea_conflict_check = 0x40014e9c ); PROVIDE ( ea_prog_timer = 0x40014f88 ); PROVIDE ( realloc = 0x4000becc ); -PROVIDE ( _realloc_r = 0x4000bbe0 ); PROVIDE ( r_ea_offset_req = 0x40015748 ); PROVIDE ( r_ea_sleep_check = 0x40015928 ); PROVIDE ( r_ea_sw_isr = 0x40015724 ); @@ -703,9 +671,11 @@ PROVIDE ( ld_acl_tx = 0x4002ffdc ); PROVIDE ( ld_acl_rx_sync = 0x4002fbec ); PROVIDE ( ld_acl_rx_sync2 = 0x4002fd8c ); PROVIDE ( ld_acl_rx_no_sync = 0x4002fe78 ); +PROVIDE ( ld_acl_clk_isr = 0x40030cf8 ); PROVIDE ( ld_sco_modify = 0x40031778 ); PROVIDE ( lm_cmd_cmp_send = 0x40051838 ); PROVIDE ( ld_sco_frm_cbk = 0x400349dc ); +PROVIDE ( ld_acl_sniff_frm_cbk = 0x4003482c ); PROVIDE ( r_ld_acl_active_hop_types_get = 0x40036e10 ); PROVIDE ( r_ld_acl_afh_confirm = 0x40036d40 ); PROVIDE ( r_ld_acl_afh_prepare = 0x40036c84 ); @@ -1315,14 +1285,9 @@ PROVIDE ( rwip_priority = 0x3ff99159 ); PROVIDE ( rwip_rf = 0x3ffbdb28 ); PROVIDE ( rwip_rf_p_get = 0x400558f4 ); PROVIDE ( r_XorKey = 0x400112c0 ); -PROVIDE ( _sbrk_r = 0x4000bce4 ); PROVIDE ( __sf_fake_stderr = 0x3ff96458 ); PROVIDE ( __sf_fake_stdin = 0x3ff96498 ); PROVIDE ( __sf_fake_stdout = 0x3ff96478 ); -PROVIDE ( sha1_prf = 0x40060ae8 ); -PROVIDE ( sha1_vector = 0x40060b64 ); -PROVIDE ( sha256_prf = 0x40060d70 ); -PROVIDE ( sha256_vector = 0x40060e08 ); PROVIDE ( sha_blk_bits = 0x3ff99290 ); PROVIDE ( sha_blk_bits_bytes = 0x3ff99288 ); PROVIDE ( sha_blk_hash_bytes = 0x3ff9928c ); @@ -1378,7 +1343,6 @@ PROVIDE ( tdefl_get_prev_return_status = 0x400608d0 ); PROVIDE ( tdefl_init = 0x40060810 ); PROVIDE ( tdefl_write_image_to_png_file_in_memory = 0x4006091c ); PROVIDE ( tdefl_write_image_to_png_file_in_memory_ex = 0x40060910 ); -PROVIDE ( _times_r = 0x4000bc40 ); PROVIDE ( _timezone = 0x3ffae0a0 ); PROVIDE ( tinfl_decompress = 0x4005ef30 ); PROVIDE ( tinfl_decompress_mem_to_callback = 0x40060090 ); @@ -1413,8 +1377,8 @@ PROVIDE ( esp_rom_spiflash_attach = 0x40062a6c ); PROVIDE ( esp_rom_spiflash_config_clk = 0x40062bc8 ); PROVIDE ( g_rom_spiflash_chip = 0x3ffae270 ); -/* -These functions are xtos-related (or call xtos-related functions) and do not play well +/* +These functions are xtos-related (or call xtos-related functions) and do not play well with multicore FreeRTOS. Where needed, we provide alternatives that are multicore compatible. These functions also use a chunk of static RAM, by not using them we can allocate that RAM for general use. @@ -1511,7 +1475,6 @@ PROVIDE ( uart_tx_flush = 0x40009258 ); PROVIDE ( uart_tx_one_char = 0x40009200 ); PROVIDE ( uart_tx_one_char2 = 0x4000922c ); PROVIDE ( uart_tx_switch = 0x40009028 ); -PROVIDE ( uart_tx_wait_idle = 0x40009278 ); /* @@ -1578,8 +1541,6 @@ PROVIDE ( ets_efuse_read_op = 0x40008600 ); PROVIDE ( ets_intr_lock = 0x400067b0 ); PROVIDE ( ets_intr_unlock = 0x400067c4 ); PROVIDE ( ets_isr_attach = 0x400067ec ); -PROVIDE ( ets_isr_mask = 0x400067fc ); -PROVIDE ( ets_isr_unmask = 0x40006808 ); PROVIDE ( ets_waiti0 = 0x400067d8 ); PROVIDE ( intr_matrix_set = 0x4000681c ); PROVIDE ( check_pos = 0x400068b8 ); @@ -1619,13 +1580,6 @@ PROVIDE ( ets_delay_us = 0x40008534 ); PROVIDE ( ets_get_cpu_frequency = 0x4000855c ); PROVIDE ( ets_get_detected_xtal_freq = 0x40008588 ); PROVIDE ( ets_get_xtal_scale = 0x4000856c ); -PROVIDE ( ets_timer_arm = 0x40008368 ); -PROVIDE ( ets_timer_arm_us = 0x400083ac ); -PROVIDE ( ets_timer_disarm = 0x400083ec ); -PROVIDE ( ets_timer_done = 0x40008428 ); -PROVIDE ( ets_timer_handler_isr = 0x40008454 ); -PROVIDE ( ets_timer_init = 0x400084e8 ); -PROVIDE ( ets_timer_setfn = 0x40008350 ); PROVIDE ( ets_update_cpu_frequency_rom = 0x40008550 ); /* Updates g_ticks_per_us on the current CPU only; not on the other core */ /* Following are static data, but can be used, not generated by script <<<<< btdm data */ diff --git a/tools/sdk/ld/esp32.rom.redefined.ld b/tools/sdk/ld/esp32.rom.redefined.ld new file mode 100644 index 00000000..c229640a --- /dev/null +++ b/tools/sdk/ld/esp32.rom.redefined.ld @@ -0,0 +1,60 @@ +/* + ROM Functions defined in this file are not used in ESP-IDF as is, + and different definitions for functions with the same names are provided. + This file is not used when linking ESP-IDF and is intended for reference only +*/ + +PROVIDE ( abort = 0x4000bba4 ); +PROVIDE ( aes_128_cbc_decrypt = 0x4005cc7c ); +PROVIDE ( aes_128_cbc_encrypt = 0x4005cc18 ); +PROVIDE ( aes_unwrap = 0x4005ccf0 ); +PROVIDE ( base64_decode = 0x4005ced8 ); +PROVIDE ( base64_encode = 0x4005cdbc ); +PROVIDE ( ets_isr_mask = 0x400067fc ); +PROVIDE ( ets_isr_unmask = 0x40006808 ); +PROVIDE ( ets_timer_arm = 0x40008368 ); +PROVIDE ( ets_timer_arm_us = 0x400083ac ); +PROVIDE ( ets_timer_disarm = 0x400083ec ); +PROVIDE ( ets_timer_done = 0x40008428 ); +PROVIDE ( ets_timer_init = 0x400084e8 ); +PROVIDE ( ets_timer_handler_isr = 0x40008454 ); +PROVIDE ( ets_timer_setfn = 0x40008350 ); +PROVIDE ( _free_r = 0x4000bbcc ); +PROVIDE ( _getpid_r = 0x4000bcfc ); +PROVIDE ( __getreent = 0x4000be8c ); +PROVIDE ( _gettimeofday_r = 0x4000bc58 ); +PROVIDE ( hmac_md5 = 0x4005d264 ); +PROVIDE ( hmac_md5_vector = 0x4005d17c ); +PROVIDE ( hmac_sha1 = 0x40060acc ); +PROVIDE ( hmac_sha1_vector = 0x400609e4 ); +PROVIDE ( hmac_sha256 = 0x40060d58 ); +PROVIDE ( hmac_sha256_vector = 0x40060c84 ); +PROVIDE ( _kill_r = 0x4000bd10 ); +PROVIDE ( _lock_acquire = 0x4000be14 ); +PROVIDE ( _lock_acquire_recursive = 0x4000be28 ); +PROVIDE ( _lock_close = 0x4000bdec ); +PROVIDE ( _lock_close_recursive = 0x4000be00 ); +PROVIDE ( _lock_init = 0x4000bdc4 ); +PROVIDE ( _lock_init_recursive = 0x4000bdd8 ); +PROVIDE ( _lock_release = 0x4000be64 ); +PROVIDE ( _lock_release_recursive = 0x4000be78 ); +PROVIDE ( _lock_try_acquire = 0x4000be3c ); +PROVIDE ( _lock_try_acquire_recursive = 0x4000be50 ); +PROVIDE ( _malloc_r = 0x4000bbb4 ); +PROVIDE ( MD5Final = 0x4005db1c ); +PROVIDE ( MD5Init = 0x4005da7c ); +PROVIDE ( MD5Update = 0x4005da9c ); +PROVIDE ( md5_vector = 0x4005db80 ); +PROVIDE ( pbkdf2_sha1 = 0x40060ba4 ); +PROVIDE ( rc4_skip = 0x40060928 ); +PROVIDE ( _raise_r = 0x4000bc70 ); +PROVIDE ( _realloc_r = 0x4000bbe0 ); +PROVIDE ( _sbrk_r = 0x4000bce4 ); +PROVIDE ( sha1_prf = 0x40060ae8 ); +PROVIDE ( sha1_vector = 0x40060b64 ); +PROVIDE ( sha256_prf = 0x40060d70 ); +PROVIDE ( sha256_vector = 0x40060e08 ); +PROVIDE ( _system_r = 0x4000bc10 ); +PROVIDE ( _times_r = 0x4000bc40 ); +PROVIDE ( uart_tx_wait_idle = 0x40009278 ); + diff --git a/tools/sdk/ld/esp32.rom.spiram_incompatible_fns.ld b/tools/sdk/ld/esp32.rom.spiram_incompatible_fns.ld index e4899b66..17a38d35 100644 --- a/tools/sdk/ld/esp32.rom.spiram_incompatible_fns.ld +++ b/tools/sdk/ld/esp32.rom.spiram_incompatible_fns.ld @@ -64,8 +64,6 @@ PROVIDE ( __locale_mb_cur_max = 0x40059548 ); PROVIDE ( __locale_msgcharset = 0x40059550 ); PROVIDE ( localtime = 0x400595dc ); PROVIDE ( localtime_r = 0x400595fc ); -PROVIDE ( _lock_acquire = 0x4000be14 ); -PROVIDE ( _lock_release = 0x4000be64 ); PROVIDE ( longjmp = 0x400562cc ); PROVIDE ( memccpy = 0x4000c220 ); PROVIDE ( memchr = 0x4000c244 ); @@ -77,7 +75,6 @@ PROVIDE ( memset = 0x4000c44c ); PROVIDE ( mktime = 0x4005a5e8 ); PROVIDE ( open = 0x4000178c ); PROVIDE ( qsort = 0x40056424 ); -PROVIDE ( _raise_r = 0x4000bc70 ); PROVIDE ( rand = 0x40001058 ); PROVIDE ( rand_r = 0x400010d4 ); PROVIDE ( read = 0x400017dc ); @@ -145,7 +142,6 @@ PROVIDE ( __swbuf = 0x40058cb4 ); PROVIDE ( __swbuf_r = 0x40058bec ); PROVIDE ( __swrite = 0x40001150 ); PROVIDE ( __swsetup_r = 0x40058cc8 ); -PROVIDE ( _system_r = 0x4000bc10 ); PROVIDE ( time = 0x40001844 ); PROVIDE ( __time_load_locale = 0x4000183c ); PROVIDE ( times = 0x40001808 ); diff --git a/tools/sdk/ld/esp32_out.ld b/tools/sdk/ld/esp32_out.ld index fef78d56..c644ae71 100644 --- a/tools/sdk/ld/esp32_out.ld +++ b/tools/sdk/ld/esp32_out.ld @@ -53,12 +53,22 @@ MEMORY /* RTC fast memory (executable). Persists over deep sleep. */ rtc_iram_seg(RWX) : org = 0x400C0000, len = 0x2000 + /* RTC fast memory (same block as above), viewed from data bus */ + rtc_data_seg(RW) : org = 0x3ff80000, len = 0x2000 /* RTC slow memory (data accessible). Persists over deep sleep. Start of RTC slow memory is reserved for ULP co-processor code + data, if enabled. */ rtc_slow_seg(RW) : org = 0x50000000 + 512, len = 0x1000 - 512 + /* external memory ,including data and text */ + extern_ram_seg(RWX) : org = 0x3F800000, + len = 0x400000 } /* Heap ends at top of dram0_0_seg */ _heap_end = 0x40000000 - 0x0; +_data_seg_org = ORIGIN(rtc_data_seg); +/* The lines below define location alias for .rtc.data section based on Kconfig option. + When the option is not defined then use slow memory segment + else the data will be placed in fast memory segment */ +REGION_ALIAS("rtc_data_location", rtc_slow_seg ); diff --git a/tools/sdk/lib/libapp_trace.a b/tools/sdk/lib/libapp_trace.a index 53aa0850f250f4e7177060b2925d6021b0fb80e3..a74a2fa1a58492d728b1133d4de3f88f3c9f2099 100644 GIT binary patch delta 96 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≫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 PqV2s_jdwXp;OzY$C0HqD literal 52882 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�{Mf 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� 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 z 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ⅈYx9oZIkrO2sEwj+Nx11 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 diff --git a/tools/sdk/lib/libbt.a b/tools/sdk/lib/libbt.a index 9155a3dd1dc75dea139a58a59321b6250c61bffa..48e627f3dbc86b3b0e4896274a506133ed7708ac 100644 GIT binary patch delta 2557666 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

qT|4??U$SNcLk=_T6=| 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%0Di=@;9G(LUU7s4&H>1v-Li=#| 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

bM43LypA9Hwrep91FgDV%X^wP#pzGo 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

jv4+xQgJ&8#OAPt-2Cp%6?l9yJ7`)@OPSSdk z9x?9=WUh(f4uf-q-!ODOB8#a%H{>=h7y0s3vZPtV;3Bf5S)tkMf7TFsq@BhYN(&76 zm43W$LFoF=fhUKj6L41;N-M}x($$9iUPHdkknb`02wBqn+TawN@A;O_%0d3V zQX?av1z95ZGUR6&^1%j=B1_FCk$G+nHw~O4Jm1i{hO8@w`Y$&E)*JlrDJ9F=Wyqf+ zOQN3|{1;jJPzY14uaj+XEwU7}kerO`f?AE>$q{a0D0L!B6Ld4={S5g)Lq5vjsRl1J zc!j~q4Tk4GJZDJW9C~f=|l(nH3rO?F{Z~ z@MyAFZi*ql+Ta_KhUa#J?>G1ngZGl9K+lpJ>GE3#z&XON8S?iG{>l@d{B4&Jk{9=yWDaAqE)w7Z^Or;5lST|B9MC zhb;9nxEcXD!W*b0iEcI`JZSJivgjXG?=D)Impo|%hj0wEn|Mj{DS{l~80C_GAz89% zY{=UfJdiALhZ=mj!Am@S&zLLeX(}xT&Jn)fkUwJZ9)n*XOW}@^n|bNH0nQQr$k6$Q zEEV{%7V`HapELpjwNJ~d8(i1mW(Kz>ck(jsOqPr1@97<|~^<77$a2ZLi+N%->m;G|#srVJ?aGAIY<2zR7h%-e(9$p??lH(4@!<#Yt=ZG*ox_&2f?G^H-Mg;&sY zaE@>e<)TxE+$rfP6&e9&k|jbW!bJbTF! z`2~ZI8~mf8f0EqF%h-t{W8nzcuVsuZ8P_)C?a9zjT5#ROLmp=EII@^)8o4zT;AX{< zneZa8uX7z)GFxfL?<0%;PJ>^Jb3rZvZyFIkCbzM)`y8Aj{3GR3AiLgao$6$f*CMy| z;>N)_!li~z8?r7a>VJk2(EU^ZF0dQ&p$1<of z3^C-h3|?#SZiC-6_@u$Lv9R+Cbf&>QJ=Xot8fFBHGkA)@a}8ccmfGJ=Zs%FzPH>L! zLx#>1WU@OA3!*%f)o$0!nm>@oORgAW+|vcazz{EopN82p*RUmE;_ z$6hP`Vg&qUFju;M;nEEb8yqz_W-wof<;N{FxWwRQd|`sG)Y=GWZ*Uib69)G(xSzp; z3?6LoaDzwt%=%yAd%%+oo@MZ51}`>viNPxjUS;q)gEttw89dOh{T)WYeFkqcxXR$i z4Bl_>vkj^a%&r(>tIu=xgw=+h?k=)_R9!!6f~OrD?~JMWuNQ>Xu&D@or_1?aHFfb* z;RxRq?*9PMMIC-+Y2hUPrs<0=FnEN)V+@{c@H~ST8@$Be8w|cteYk97o|?Fxvyz*S-|$FSg(o~6Rvo`?5?1Zr7!y{T za`$vp9j`#>OZ)Dw?ib=Ab?cs9d66e{qF%Z7D|`RldG>2+MfaL{_Sb6PtU7tB<0M%7 z(C`Psk<HyC`A+IP`47P&mz0Wq}MlxYMzhKqW$jm)?y&4#zrUsWA+|FP= zMe8R~VQ`PC70HUYtJ-gA9aBFauAHmhZ8bcmYP{3`F7;^Z{7e--@+h9-ezCH)DzCUd zrVbCAlBpKGSUEnMud(#c+4zY9yQ%tgl2fS89W~`kmA(qk7Vc+0@>_3!w+i5wO}ZB3 zu*VOQU61)m5x*;6rtYukm6sff=zjC;Ajdpaeq_SG7CoJeb2mEuGcryD=-MDVI}U(5 zNG|kvW+u3S$G?*0Iz|DCr1nKi?XBbB})l zIEyUjVYiXxH0e3Aob`N1mJ^PA*up;t=;k7#zreqg0kTwHLzX4+cCsw^ma4U@D@v0v zqqPv-h_B+U2EIzTI`~@QD0q!9?RA?lZLw9DMY>0rId2p00)9le0{pmefAD^O7>F64 z4bSruFbvGWLiup;QQ=F#ZwXHVe;_;;{HgFf@K?f1z#J<~XDRrE@EY(*;hWfKDd>4r z+Jt}%;k&?5;RnEVgm;09gr5PI2tNld6Mg~QM)(kzqlxJs19uaC6Wo)WM8JFS^p}7S zz=MQ80S^)W7Cb`u5AZl)-YYUyn2%)56XqaWB+Q$-t`;r?FBj%hSjpAm;iFsYg!usC zZNhE9TZOxT?-A||-X_dL_anl5l4`dwpO`vK#$cp-RT$H^^`^)8Fd002%AQK>X#B(x zIS&3(xG9*gkfWUAgI}{CC%}IQcL%$$W;RAI9UtK$GqVC=<`oy_B+!r#tx>5Mo)QUY z2JS@0D5a|qWet}s{fLxsD5M+&p&Uo6}mJV{vJDLF$teGzb(@L6E? z4Q4h7yhQkX@O8o$f>#NT04w3i;9G@ff^QdI1m-*RnC2DW-C(uy(3WWOSxQ}ejtA01 z!g25`!i8Yo%SD}r;P-@SwvUCIfWHuC8+|9-8T^Yd+v`u^{$LBU57JEP`ww&Ip<&_j zg=zD;!VKce!>L1?mkM*XDHrYtZYz8ym^Y45pBeMMF>((uU(7stw_4gOiU1k6uZ zF-8Y4kJ4n?I!(AYI3he4%$vQaGY*_DJQG}3nBA{|@JeuLI*$a1a2q`35^x{5t?+Je zC*kM86~dfUdkKFGK1=uu@HxWYgU69`0dNzA*&fq{tMf=OS3LC*uu!-Ne3dYdan}lW z1+NsQeQy#T4(7dh%#4SrEyDA`cL}rh_X#fp^B%qIWDErN3_W0$?w~N6=4D|R$$DKl z4t`gdbL2 zJ7Lzov+z!ELii}Sw{ViviEfnu3}x$fVfN(vg=x|%VGheDggb(t5@v^eLAVR} zMd1qYYr;I5pV5ys9MA&fc18Y9dD*c@^R0FHO6l3CCz zg;|JY!a3mN3h{7hvWZ*@fcuXyBitvb&>A`wLxCs0Lxd{O7MPU~DHDTa*YQ4Zhi&&fw|^Gvh|WtYuT-IJl)S zC%X20jSnMtf#*yKU}vcm=1}Y-+y{KNFo)v#!smc_UoF$Q06bcF7PH z1DvFXrhZQXXzGuJX}Zsa*+2du>*);ZLDyquoF>eSBf`wMx-c^?BDVyG{2W;(OUTqDEH7iNX8&)eUzkryEfVeozLDGxIl=KJXfm5%qi`Dd4q^0R>t5k}j=!DaDMY{?VNQa)Q<@1e z-Gjm%z%L84nO+w@6a1lYSMX=ToHM=_9t8egcnFxzu3CFX#Tx;2xZ;YK`eboYPt|_% zEoJKNshz^=!b={CsrHZW9;6PZU0SAY9k;)yIzD&64t4Xz`$wo-6O)S6q>|E(s^7WK zK(BuJRjS|dYl~Fmyl3!+wLMp_RPDd5GeSMu9eQ0Ks3=R1d07rnUte05r)J*w_*nJx z0~K>s(+SnXYUG+ZbJYvEH9D%M+whjiN$)*Uq(1qpu%~)q8(xOCc;fIP_1iYQ#cadzql;7No`FSQ{3jd^89eDr7=J_&Vm0`H~S48#W9Odegyyj;_ zWLmk3!7bH8dCi;W%YffYk?URXI;vE$oRj>Pti`23m6|p#*7>={D|FbM7VxQNk zTX$6Sz?)*vUhm|nm;TJi3Z<;Wg)sEI+ttY4k-F-GN#~`g*bBEu)wVmbvqC#=_D1pT zYVndLb=8K}rFf6*#2Q(_?--!&--(CtzEWpj&@NAP$vi77*knCUH`QMdt2fRW58Z8@ zvx3_o9Hja^Qqf4Y8rm+3SKD^Zilp4)JsN&Hikqp<{-OomsajGaMeQi5A5~?|XJkdD zLW74bYDCobHS3|#bajf_`ua0b6%G_+MRq}>3Cj+RYDnV|XoT>p;Hye%;0>^SCuK!G z-r&8ZWRifHM>)a8rJO5s2cF|op{M_NRW`(^tSHE35wk<;onH4hSdjM}`bqLH)aHg$mB`RaRm-?>c{JPPl9s_Uch zPTZ(2q4y27ir()ws@?Qj>gC;dA>nt;>t{LRH>r%>$l;|K=fza4X^kvr`6e}llK4zC z!_nP%@8-%u;2n?-JPPA@2vI_*PHt8|=KdRhMY z)Kgi(pYFlBM6F;DAAr2p3kqM~C#&fj_oAfIpLtyL3o;t1n+1vDNIyvJTemE#mW8)h zi}0fuhoH|2oU8I*F0L6I50wnh2z_5J&Wd~vm8Ts~<$RTYL!X+#nV8XVOT~HlQPuB; zKGh=kZNnj5a=$>0Jkg@&P2(|yKfitmZ2Azce5%?{q0mz?olW%$J@_efx%m&POP)fL zeV|r7g(e%cL+z$_yej`?aGqLOEi=nmw^L<24cT5*{xnnuKca@vd!JfN@1ZJn54~Th zm+4J;RQ(Qba4?QAd0svppPrKCl(sty5Pk1%^#!~t z>kLdL(Pz=c(jQYDo`u32YUHy}81R_77GCw!>OL{`{IjURy2sR8kOYgcz$x%jjy(tY z2alBv&m+OalWI5RJt1%C$xl$e{7IGZ0_0Oq>-T&C@}p0x zA&_GpU;F~HtF=enL+>{AGQDH=sNWfDFJhhVb%AyV5NrM()%yU{Vrtsx6?tkYWnb-6 z>mduy%;Ef~j|y)<9$X547iHrpannJl{j^_YAFODY%3I|RHc*`pR@6^DaR4jK`f40F zcq5h&v(@&q@%Hyk&<}>XVDu>aj_Nt8Z^aE+&Q)Klw-7)01cp~*wRtOsX6#T!R$v&u z-&K03qCxPJzPNnp1&l{P>bih!eHTy*4Uswv?PA!{G}|hxp^h-@oQrVI zrM_QZo}*=MH8{)QC&Z=bJSq^cfp_K<*^8UXICw?`Y;Oh{3IOd z@m}hD91$Up45(vUTXE3jXxgOgm6ea{_J$&?($>Szm+-yqocsyR-x>d^-ZCbTxt;&ne%B$LRq+-J$yB*%a z&>|<$rmU^1*SWn1`w9~^oHp&%zGN!zX}0}G5!RzMjj|UR3SO158 zuw9GRZOYV#H$L6iZeCSqU*gvEU4?E6zB=|F0h;dvIn1)mP;9x{SbQw`6vc&+~BhZDv233bQe#Hif&VcitF z#}`iO+cYi997ugj)jE=xQ?Kmd_?CS&J!y+TjTT+op?Ie<$w}Rz?m3cZ+90*a`sJMT zhB>tw7M}a;R%_f-&eavxxL2LjHde!jo$i~gXB**q-=9Yk?E`RH?NB)jOx4B(wdwyQA{1BTN)&_^=bpc$E!uBS%AF)Lce-$>qK%Tm{ zA^sm`ysCPyBwE_`jcW1F*|-zz)x>wn4p{f3Ag<+ZvbW*l2BN{G*w++eIkPDnSF5Am zDYlm5pR*H}B?HyVfB`%8Ni0U3R}m?Y-Azl<`NKoN3BFt(0pH=MAIKfb04MELm>?x3 zIAQWk%Xt!s1`1~K0!Sbw?T0-0(u2n-Oi%k8={rpjCxy2>TFwDvkx~Pvz?QQaS2R-U z4IrM|5ZH7AaY;S=tG9+Y5QllE{zl@q8u(X;Ws~K66vn?|S}@I;!o~qR zy&h^Bssd-E1X6-)VN~StI+g(GDU@cW2G95g`|y8MpJRzy_E~EDu|&hApmHuB6$-k`3bB@S??nD-ZoRrl(B<9kA@^GtAj2(T;%+@~*yT+D z5w{M^<+{(*!pV)>2X)PI-^4|e>XuW9q=Q5A(Qm3n(O~JRc`EXHqMO}A4R}3~n|u-Z zSngV+XS)YrX9wMBCPb+v%g{aCH?gd>+|_79+nt7bIqnCrb-?`894dk!YIt3aXqocq2-f{Q-=YcELTwC)9gyBz7dyL)4<b=mtvPYbOxfjltrUdz)^d2VqRd?FY*R-2JF`ip$5hf-Zl=Np*{un9C;; z)7`f*PD5@6x>ttV4VKGvUqJ^7yLpae3$LW?zd9+sg z^wfu8$r=-9UTUQ$XQcMRV6bv?*pp|bR);4m_hZyAeOBsT1jKT)k$?JZ9l0QPEUc40 zM|)~oLH=T%J~wqdl8eUDFHhwuWNs8@NuQs35Rt9il}ImrfzBhvOKG833@g|Ybxcnt zQ~8FWXf*wb)DEb+SE?($Le&^EVYZciRq9@(l;vf;M90qdlDb-Za;#t>>wQfs?>|8~ zu1)1F8eTcB^UC3+v|OhoIvO+4uvbS13d(`<@cQx7v@3e%I}@MY?S@VFPC_gU@( z=s>pHlk=H-3}wJ@K#xmtpG2n#y49OtI9Sek=men_>;n#OD+^5|CY?DLCZXHdS`HtQ z550CXsucXa5%4NK`$z52H4g7-$X$kk9$M-!W2g+IZ<(_ezI=QTYPoZQI(+OVbiG4^ zSh;ghtI!P&Zz4<0{S(2VmCiJHLIpolZIyEj{hu#I3eIJItDRlY3Gy-8&?{cvWuc=E zPbbg>D4L`Ds&0GEkU5sya zF;cBy@*CFqJEt!rghM|#{PEw5@S{Z7f!QSVlQRsRD>b)AV|adcc(Y5o6>NpB5c!A9TIgznj_p;boWG7n5D+Pv;ma{dY}%G(432%i)i(xQSI~b5hqj%Px2u zve4gJv$|byDOxsU1=wKOb^$wJ$PTar=GX;YX-Ow=2YgYx-~!A~p@7z`0kbZ^7z?EY zc;^D!C_QlVsRD)qY@?**wM#~T?UI_CkM0)A42(zp{w~nX7YVTWEF^YuF~X_^_~U;x zEtDO2;Z#~VIxQ==2m4ix0B^8?ZA)3(yucmQ&j=L+;wYPEoSLG)tUB61R7)2(HFq}i zuB|<3xwm3;gz5xns&p^ixK1}@1y|#c5~?3~%_~QPz<^WfHk5Qf#TW=R@{+ZJXRsWN z1N

V!%Ii>MC`E7T;Aq)n~dJRCbi&2$7*bVD4z<^ldP9_&sFwhQps6KsyTA=EuE z0Gyv?heiZSFjBo5jgp+T$wq6FNsk|+EgLH6iDOADH>7mUID z9lAKc!(hlR*jkF+cQc_Zy#1X$JFcSf2-q9@V z;=m&K^3(0mRe|qLMY!6``WiFqrDBZ(XuQy}z(M5C?+^r!)8y9%wlOi(V?}^(J@QO@ zgPGV$GqF{EJqFMUs{?-`HfF1}0sexU`y=gkQ$S{`yJ=w+=zx$~F*~$A&;=bVc4o2$ z#J2=Ey~W>Biy(CxZaV)@8Bv{joa_89tK=#D_MBxJE0*vI~(OC4*^2zP4Z$Npfi zyi51**n`aY?f~br*j+5pJpoQtv5{<(djp&!V|Q^Xzb~LC$zUhuc7K3BTBoP5vbAG& zM$L->b!LnmZDrJ^%xdcJ{XiLY2EvnhRYv@8?89Tx6Ef<5h+r$sqgO^D7Yt6gm-^%&9(PpyR{86G=l0R5xcFX9ro#{Nze9mM(R@T_*Rz?>tbM5e8ObZ!Z zDXt!V5r>?NZj+&%Z8@WvV#Q_fcl{0XG5*rr;zEX@om5z07d9djiVgOE9a1doZ4rHF4}@E8KGw zFePjD$ca|C*Hfr|y5-D9lZ1QcLCGsqc++@hR0OkFZi4l(oL^D2@a<_|Q|7O+#-AA7(ZP z;0+tm@T<5G+US!+(;8Up;BK_^l+8%An!`R5ez#Oj_#{y~{Wv0Ig+CdluKy%aD>t8s ze7=lXTXlb6U$n#DT(9;bELofJzP}zxg{{;zP`M45_Br5$Rjpne9RBqwW~3`{!m9um z4&mR}YN=MWV>n`j!+(DPr5akvvb9z&C)==X-vhODE501-<#0I7=3Tpo0Ed>MGbN2 zPjxRqKTLD4!RjL2eH6hVcPOfu;SNGNneGmx6LzmFLi+AvL~z~dY;N~s9ObjzTo|>w zy9F6!yDvaL$8Chum8g3+x^oS8J(@b#jiMRy+)U&Wb2}n#zWX!gg#vd53RyGhX2Da- zJ&tI#t!PT*TKhqyliLjii7dA_vKqOSFlJ3p#q_dYjdZ){5L{r$&(%&toEM z?FLBSJB^9lWS7C?oyJ6zj_jSrMAq3fmv*&xB9G`=cqc)TDxI}=5)|2`Jva$^9i2Dw zsJ)yi#UfAIJP-3KvDd4Fm(o6+5-O3b2mSpzws#T~c}nMqlc0l`B_dDT$Cy+&@`9aU zQk;S#2W5b9+(Zt^xC!2jCX5`m<4}vHMqaTmKBa$D#!qk_x=Z9WdjLZ6YDM0%ALToc z^tn;w9o>%l+$i#{w!J<#ioB;ysZWg}?`y;8Q=`ZSx@uPNOIG+pdj@kI6#3K+pcJ`$ zfGP61T^+Wza&KhQ9M{P^xjgrZe4*2i=i<1Pv?5>X9NJmIk1(G{zOwoLrRcE8_jXGr zr7QfSRQQS_X#Aw}z{0;bEBv!v4ZCPj|l4mk@StRJ(2jB@#B-PQq*y}xM+T)$zMAEeMDiWJajnP-@RBw3^@u9sSo2D&0vuq%6BL#F~Mc_+G&V&^bCF0cMtZbQt3wtLv- ztacev3bgBdE| zj>3$bVg+x&WESbm}nNBGqj)zGx{h^a!soIh)(9NlifZ#be0z}Stc+oQ+!+{|s zGQznC0s2%qGSVqPxe(MR&Y*G5Wv7BJb_(=IrL6eP=$0vwiO!l+VUzr5&*4ZgJ~G`Y zhf#8uAfd<%Z4B=q7MZCVJjH9FS-OS7x!19m&(>|1mHPqPZjP>eG`Au9#aw3;(uw7^ zjexBA08=h}fcG5?RsbRsjwSPMZ>h55?SN$tyEr$ zYyF^WbY>fz=T8OQ>IYrzFxD35qfoz2o|N35*a<$=WeHmGelSUT&ZrJBMBKd#5d0C*8^$9~tHx z#>kGfXH7;q6%fY`Gn4Upc*crgk7Q)B9+0sZ);5uadH}{oaZPoV!+ssZxqub9R`=%^ zAEAn@)EziBimiT=?yxc5=O0<;&3s2V8Qi9OYb=BrA+l9>&)A1F!#%n`#;VXDkt*E* zld+Fj=qGiLi|s>YBTqZ*6R{Dj=0V-=u?C!zUe*mA>&zOzsT(u)D>M7A(-_fW?_jYN zIj&nHHlFeyw2`ggA1vLE+K}FC>YlKFgI(Nx7+Fcn?S+W8`wX)1e+Q|S-w{VuHwVMs za{Hk$w#yfaIqvI7D&U@hs-(ETpyveLYcQx&-Di*lmXO-+^?t?9dDjVyM;i4<5;I|k z`lCpc6;806_w~$zo>X%(B%z(isOU3v4ZAnUT8Pcw@T9u<`$Ws8eKDf!a~jRZShxFW z&!EN`XvHJUAGza-INHgYU5<3>sOP><6gOH7EydM(rR7OnJQJsEB6bH!c^k8n4O;FVpix$aFg;P6zD31 z;K3wp_J&z?aVDJ#n?g#q2R7SO9lL96o-zbh9bHg3ee6ujUTUvK@taSYaj|7Dvp)p~ zRvlVUoIoPXv;t8}Y!&@6k(+uG{Fl~MWj`kBkJ}7}!FXY!$x!C9Q|CQe=UqFFyr*Nv zfRya#z3X3jKWgN?`*hx&kO=esvaZTPz8U@CXWlt+=3QsPNcbgxUf*f55!0l7K<9rR zg6s{?#F0N%1C)~e{15*t|072JFP_f742dxR8`bci5;cR&`Z1OKDN&e|TzNsO{A`S4 z`?yX4`uc8Ndqc;1cqE1w#u35`mhf6lH=$qHU)aaM_BqAqkJdd%G7n*1m#~UaRBI<> zrKe@3EX7{PM8|4*N$n&OxEEsmfRw%AZD=>*1=M6Iut6+jc}@j;n^CquOOwaVrEIL%;z9B+Zc0jtKcs z3b<+rzwn2N#GU~ue)j=w=w2UY;StTA!7E<&Kwh=7zCx5Ngdi=ug{95$D@27_G}JD) zia}b7?|<^NN}E9RYq_fXOQImT5aMFAfYzBTIxVeI90j1mC``p_@*h~*ZlJ4o5<&Kc zPYTgEmpWQX<{jV7wEY^}G+z!?nIwtpHv+?Pv3vR7OPb#G9%)ybC*g3xK9jS!ge=>k+N zFny6~`)eXnGXn8+=)*n?vWlO9?qXDXHSUhZpa~rn|HEqGuZdc^6ThuC{(8C-^EzS^ z{q>3Ux)@g=g1zA`bj21+IiT0uM+2D4=1~kD|!vuGnGC^@Ml8K>k=OHq?%XDdv z;tQle&g>#@SWkd}W9zmeJ*<<9;NJ{CrWIbqZkfeWRKaiEh(g#KQgBT4y89E--8<3V zzV+-qsW?b$bElwA9O@NbFQ zWp9aplBpRCR6>ji+-^}~UugHRic?WMMq8sU_$^T<#HZHieM~K)_d@Z0r0)DJQ8)E! z?Nx_e zO+#STu{deie=UWjv>~zsVhFBw&tRZ7#4PymOkk4cW$6DjZIsjz!T@BzgS#~|9Gfh^@Ry?YA zgV(~c6xQemYc$Y@q;9+iA_uv4895zCs02e=!CQv8#u|W(&|7!`xhMtQ*&YwSOg>dm zY_}ZA+2fb#$*0|V)Wja|9l*OXaW&zOglpfV=KhhWU*``N;VQ#k*J+I23W1Jdi#$=P0eME)t^3}-B{KBGf{ICbzl;^6-H|?zyh+XbU_KnvV=E7 zU`@qlZ)lI9(ykL`YWrrQJ+J|;1lu=rdC~(l?EDJ#*Pn@?@$l-2k^}rDwf@gU?I7_- z_4uEOI;q6`V)enFiMX@4TseQ?2A8Q^M!j#(K-KAx6mqOMQH0&c$N+0)ElJ!?NdP^I zKNeHxVdU5JOwQy1{ZpSku<0mt6Zl?bk2|LnSI(@1aaL<+aJrTLH|$pV7pK~Ehh3Gf z2^MllDp2Ad4AUJR440uA?dM|AW@k7I+Y5gw%xq0Up0rsx(sWi0W1CXHvNpQ3UE@@; z&7f*;xZqT(HFT<9pGq}Pr^*+mlqR8cD%mnW*@ROcDb&}c)r-jY>G(dPG$6GsnwXprD0P1fy)|WAE zL4+Q9p;fHw@eBMNd5jEU<83hQdt)rv9h~j3ZbmAKJ|6*7yiODh+yxIFtLTY;Q>nZP z(d@1co3%caJFZ3mdXRM?0((rr7}6`*)~N_D{SV{^Rg=FHvDTF^aM=#{c}TW8{(*lD zvAuy<-T`m|Zn5G4@Y99G836XE`_+ekCvZpj--(pu6ZE4p%Ls{zu3}gnWpQIj2LcQm&5|m#-aBSu@B{y<_d7%9_ccw9UmR^)(QcO#-YY zECFzVRlE=IDwfz^ohp}Ad;~HsL$JzZT~Jo5_#Jq^EW`=BAv+Ek-@Dq_ka5y4jKf-< zEXl}ayusmCWLuo=c-9~5g|dJB!%A@pU*d=Vp~HDz!C9ub9N|1r-fZMJOyWH1$1&4P z!t{5D!mAQVr{>H;akfjy*Z(7guZCkciC|R11nH}+Syuh@O|?)C9rM2uUgCwHI%?t+ z$SVF$0xO$gr0CA@C#o?_hea_AneZq-BJ9rE>A-ptxWEextU4VpAwlc?co!M*&X&NP z|07;T@k|MOMQz5dddbD&{rZ2X7T+&Hk>=8cO+&(tMc-5RLO3-LI@=-;a+;7!hi_bzn0EG!Jz zi|63~P_Ak`TQ8E}<`O(x2V;)*f|pBhe+izYgK^mNg8BA3<~79&{zpgFMLlq_XxtzP z80W^i2l3J|i}!#TZnt9w?3&+6^dtXE2AogwG1GE+`Lo)cQduWi4_+>^LJ+aC(=qD! z7P`&wTfHI}q|PCyAv~#nYZu}q*^3_saSl73DTg0U%Nx}SV;*k8Y1ljIZ*&i42)h}7 zBNo9Km@e(+{IORHl2-3cU~XB(eHJ%>aj^A$IgaN#u~kp8d-Kgt+*14Yc_E4i+p+at zfO2uO+xNZ@=QrH!4!u(`WpT4R_5M2xcg0}K?$!IjLOhm@ExTXu2Vom-*=O|T7u>KV zt;|NfzeK6I6t z$3(>~yR!G!xX{5ZyGQRCFf6wkL;5sFZMgNGfHeWP?25k044m}fA8s`W_I(IO=jJv` z>HPrA!7WgHEqFh1vj=%Lg*4Ut0+^73ywdlMW7glZS6AIgE z%DdgRsjQbWFSsdVYJb3aBh`0!Mc^b@YFx!gz$e>C>{U9s&2fp!VXrAj#sAH zX*D5oLRo5By~+vcS1i;9{k!VF^(tqksi_~WuA`=&(ITSe6;~e39y?>|aNN-`eB`W| zcQv%te=TL0f{71Kf5r9`bz(f0{sFm6L~|-Fmz0aOgVzB^9(uJ*T343 zlQBW-^lt()9@F8hRlo;WDd58-bPOP4F4c1V6Qjt6lF9aYG^v8SBRsL)YP#?eK~IWy8xu4hT?>tp*Ha^EHvraaDilyml^qdu992YG?T z11}S$5|6Nsa0j)$^46MomOHbj${Nw5x+)u5nWehCk_f7e&H83nU3o#}ovDF#E!$N! z9Z~tBW8YZy*Qm;55VP)r@s;y+z@OtQpRbYJf&`-pFX!#TEc||hj|k(aWxZ?2zcKiC zVYUu`9ATPFr@-Kb!mM3ukK1Ua?uODpVI1wO;f8#w!An(nvND<64VAmFF|W9A=EVTG z=dtnj6ppH+WatzL`#L{~4o4fCg*uIaWM3yvInv=MY$7@wnP7bGUNY+|N*tc&ixRsp z+1HsZI;*f>Bs#62v#4s;qRIyYNgg!Uz#m2GtkfgIls{$gO9sDZ@RtUkFqp3mWtvQf z*UNmq#o(3>)--;=Wb`pI`{9+s9H$)g{K$J4iSH3P6Xm1TzWfJ6e!`GvB0hE4I||8C zpvEE(BY*1*@kF6?j-fR8loGBd3A1-xY3OkE;uqpZL;j$_#|-|?;EWW+O-hN1=s`)* z?-DuV^2O5BL6G%^q4TT3e;OQdU`jusMyl!6m2K_c ztHxekd6tvpo!|`OrCUC5LFUv!Kl4})FFA7_0FJLOr+lSw=6PCd6^NYOjO@!xMb1M5 zITPz|y7N4F(%K*%Kf-VZpb%rRA0^Bwo_@-C+!!y+Zo_M_l(VZajLe6sW(sp!r=Ri# z*v}K@VPJuSuE7BI#YGapzPXW%T5dw&$bRAO75P@k$-cZw0_S5-7EOV>5dCI|Qq_mI!ODEt)7NTaaD~BV8$8b783r#lc!j|?8~mWbk9&-hbGR4Of{m3u zlKK)rd(Uuu)t+Cjt_JgsdcJ(9!4nLgW$?8ID}(Pa_%V-%=$xN70$wxtzXpGAa2n6p zq|i}=`2ss%-dx?fsWQ(VsFuW<_e~e&ZR+NBW6n@TA3f5wiHKV9%uKke!Q&0ST&)#&ihYZd6gm3UqhCZUNq!y8~mB-clHiEn^^61ra1=JHMpI@Qw+YsV7{%( zFZ>+_KVIBoUUjDWWd=9{?uMD-_&rB1&aa;_(Qom7J(2FKN{9meG44>Lrg z44$C&Ay}3DRwov@*N|7KuFLD>CEqbb`m?}Nik}R5TJ_VVsB3T&gA)c1F!(})XB&Kl z$KHW>qY+SL@YCvvGsfiEU#hdWR^|=K!R0mI7;O#iW^g})2OB)v;K>GGrdb_0V?{~i zZbQCP*&SEpC0{p0?;8A(!N(2$*5IEF=7TVP(QW+Z?{k{L5rg?KD|FiE4wP>M)HS$) z!KDV5tCu^D$xC)JL=^_>4+BdppJm9;HF&7OBMrXTVEw^hNoR&3zs%zjUG}6Au*BfC z25(W3PGj;qy<&*oH~1@qe=|5OdfJY))JPE#>T(BM`E_cHiAgGYPp8DW|caKFL(4Svz!;|Bj?aDczbOX0E% zu5ECM!R`1!x*wsR5paRQd_2t8nP%_;gReFCc7yLW_(6kr`m7e;UD+uAi0?%=_{?B@ z3F+?2!X)2K;g=vacAD!NtiSdvRo9PW3AZzJ5(euJ0*lUYLq5^qc^-QQCf@Vt7h)&X7EP_>n{aMA^uX^??GMlH-AOcE&p_uXBm8uK z4Ax)zmAJPW@_SXku{Y=CKVyhqHTVNHtsAC0eHV(vPREZgeq+`!n4j+TT!ZzL)f4yQALo4(p%7UqK}xgDeqB4L;l8QHH+$I$TpRxW@uVj3b5u|4N>%8f@(AN8q^UW1>Ul=+k3@)mRxT2FV zSbtzw@jY4k&@YBOC0XxuO6Sf$c^3g$|l?t4S$WIg2XD^;(5Izo}bZ4K^0mJIZ_ZEJXmo(*}9@G$BK zPcb-Y#J!q~rH8KnweaLA?Yk?on`#@Y9}>mLD^8-Xe>&j+3Q8 zKN$S0p<^{Tt&>KU^y3ZC|9wwe29)W%tR9BaMTT5|2Ua34G309vef^nMN#}7x{;Hw> zu`lQN3pPZ?V%|(Lrc=6V;2hxsL#K!=H7+*fEe&})L*Cus!DLBu7&z&h@lpmzqB9M? zj4YM}^!XUCFG=z-tOLq}CM|gsvGuz-*hW>W)ATRDN zL+42{Mi<@wBs@9dIcx;HM{e#ZeQU^rjZe$7$P%}qAul)NJq-CkLq102y8ct?ks8k? zqj%EH1Lp`YF?4Priy1c=@_P*VgJg;OELke^vLXMxG3S2?_{j)xaqELGFCa@oO$~W> zvK0DkGWrGGx!@e(VTR6VGV-9~3y^X&qyCc(rCDTbbiAc2NBAnrC9~BAZz7A%4nw|& z?41`_Pl0oUj~F^{lKuJrJtN>aSHYE&@%$k9j*=l6gg>tEJrJ-|? z!514m&EQ#Jrt=5VSxC8Le7&#J7Xc6W9`JJpziIHhU?$Yq#&U{sN$3|tCs%cP3}}6iip@yK@riQB1I8>eC+L~ z&!aq`Ja!Nj8zTO{-#K$&{Jrmcz1Q_WaI&Ad=bn4|oH=zg`7;{7;^;8{?`a;VHBQ1< z=Om)F#sf8;sqt+Z@6q^OjepdbpSg`Y5fsDW@F0z6YrIb5Cp3Ob<6ksRXnVn`Tm0kA zH3jj|pKcn$;8Xwm9WsP6g_-&2;*Sd90GSGt5bwtim7iY_Ji>V2nrlZ3?SFy z1oPrZHI-D0lIw4R8JN$8P|iY=%Wr~NHgfq*aC7htN~aWji{b&`+Y}E1-=TOk;y3P8 zjL{aTrGwvz7A+6o%!X@V4SIuw050@=EZ(lzbfc6gjT? z#}9OX8JP#Mq{t~bp1e^^c>{7Y0JcVoDVIxVHkV?12~99+)Ludp%o6HFeK5@qC%3Tm z<5wvM1B_Rk3$9j7yL{!+St48KB{;T_;tlMg5Onq6Zj*=tH8$;-wr;Ri27&FHp6jR zdE5>DUGYO;BWUaF0QwYjm5TU%;x~$w<4rKX zT1t<%!CWbf{64ss;!nVq;$vXBEiCgk6O$0_+~@MOgtE2o3wjNmso z<|vOpzzY;7U|d_GI1PM@;w&whzvD`e?%-0zgTUpA`5I<_#eBlFQt<}xNW~9=xi$gqJPDqpm~UHNqnHme z^Yw1(#QAvYJmq)`yht%$zg(`EZ(H81m`^+Nlk5!4$6q%p#v4WkKafZ{-@x3aI1l`g zVm<}EQ!$^e-op=eF+f{5_9+j(hIv3S-?}`acqsTa#e7EgZN=lkA1daXnEY@MZ7u_U zrkGDnf2Eku-JVvw-i`V{s~j8PaZWMct>9NDX=oeRrlDR%z?q7l12q<|Q1%s~sPl$o1$_BdLenM>Jud!R4=5O(C(fu@j$L$uk@^{5CzyK#>g%io=Q#N+%e zd`ev4@4BbNz#s9uA+w|PeYQ5F->wN_3vd(yz3yJX3M8jp8Jwm0=ao! z^n8g6EgpzRT-is&o0Q>Av{UmlMDQH+J~<*9oJ^C+{+u#B*^Do4( z@HVDo*{No!VkhMz3&jD-d*6leTl^4@6}UQWzay!A(d1!zrZ59ll=)GIH=x|8?g zCxM^HkD&h>SJj=WSDs)tuFD<*5%u z?Wv(GL}X^c0=676n3vscaA*}FXAtwB2T>>4R*-8dpn z_AW2-ZiH~KEiCL)-pP9s?o!)*s8zm4eD`j8P^{=vUSt-EU46<2nI+=SKIKi_+jCS4 z=vr1DF+UXp%F3IX^+odD?ipg+wg=Fx%aDWtIQ@KI95%Xde zn#V*qVvWG?Fgao!GuMf-WGg>>ld&i2n)av)utLmBwpx}{G_>78cOIJi9N%1{sCRyf z(Qey?rtSUtFaDgHdv+x{@V2vU@powGP_9uvUA&TPHB2j?WaOv%dg9TG6uWISq0pg$b*h7AVa+u!xVLYMLSdK7wu+_c z-8M;r*>lwNlx&q_1n2CO1G*gPhmpAQx^z~Cwcm;SgGV=#6(3$XDSC08$8 zMR29`f)17<?F{;tvjE#YFzn(2YzEdTdlYeE{k69IlqVKo zdlOfgT#p99_5y52FpY8B3$QJRm)l-|?PrV>Zn*#(7Cb}6($H26EM6>tR__S_l5!PF z!*vg=duB5#SBqTu=WQgKNPsv0UgF!Z4s}Nl)dufKUk`56dJuREhI7vt%oTnbh57zLZkS7^=7ss_Wq$Z5qA3V}h-eDKyjIva z%!_hO!sXC!8ZJfBi^5G1Z?o{-sW=g79=-!b&?3wafVK>Cy{cB>2l8+{GLr1|+`jci z5Nr4X%E$<>PGd$&HKbOCoc{@ClZ%6+8-DPzd$tz*U-$OcF$!-p1rP6_~J6F#%{5_?^m%JQ_ z@%J)Y(Rgx}Sk=U87$1$s=kH^7hAef0%Rj<=7nC>&W$Pbl-cOdsN7*s?UP0>pqfMSw z`D#$;{>d_BL7)F>vj}cGDc9KAc2cHEhb#FeRH1*m`4=+cN#4h#%rO5#ff`=Jw;E@3 z{+Z@CFdG@?@?UG-cG1=x-Byil%g$D0cz%pEw)+-M>V}Z|8iOjHUjJ+PQ{*x#YxLGl+of*DUc9I-aw>x|T%Gwj|feQ5+u2pC`fwgg2 z-SyB{0%zIvd=Ek=@PRB;Up;h>z=vi!3pv zGuJUhoqU`|n!A_`BY8ej8))H5MjU4Hb|fm$(sdRdezu{w5oqON#6ekef!5NIlspc$ z18tDQ>XS-BJQqPX0r;G%LANH9*FIOv=MjU-ypQt#H|1v$2autbOGpVnN zL?+&nc74hBvr=M?-7zTlK!s~P?fL`#TpTFuocGtw4$#dG)Xc^MgKWEo?-n$qz+l%` zH029ay12f$ZEC1)YM3%56E$20Mj1YeBUE67s~y4wlLA+|p1T-$lnN}H!BwgmaP$a_ zh9&erfAR^m(ZCp2V^lyw@^qHySeM1xFnr@!H&w1#wCf3scYQ;HWjx;r;AMwe z;96-1xZd@zivbqu5iD}_7qR3QyPknsLUthT+KhuoqFm2zsq6=dzo8@p%VeugY{9}> zE~_?CW-^X1)x$sWJr=_X*(?*Mu;bh$n^Gdb4vB^DxbR8hGV0tSt2VKWJ$#j{j>KOu z`Uh6aqD~w@`5IY@i65}2*2)|wzQVA#%FHBwfdd}a#$(AD4SZL!bFX)O0aw7o#HaIh zJ%2*RPhw_Et7rT`E;5$$C_FOd@hzb+2WblP^&2D1`)X$R9yD2(ppyq@F>cS8@V7v?*3{%~8w6$pQd8b}DA0w;z8aU3;* z;U5rND0~bBlN6pp`{Dg)Fp+S1Bh(+#{S%VsdKMmuS8qdXc1nXeEWPj;G)W`;G&IdH zulTycpTe{|+!cKQ>muePxxKr z%p2YfLs;LC9{>rKehL%yHX>9T9uf8fa+S$Y1K!RE^Z9!t{6DaQ!vd6D;cl?v4*!H{ zh$mc?M~fa>4EI5G*9*@?;rip@WDc(3jX5 zlf$Q=pAzQeJvDp*WtA4LL>bi&uSNvvVcrYP2)99kGQ-;uDl7aYjww;Y#jDbxPRxN_ z8lm{*E{xXU=VWy+L#nad(*?vI>i+d5rJhZw(+~A#gt-_nbpFK}>l1=Q8R}a>o$rw# zv<@T%Ivp8V1=j^qI{i0O=f6m<5&jm|%<%d+>|pAI=HU)=H3LuhF&x6Y;U{nu@P&CL zzg~DHa)6bp#-n&bBZk97R&nU6>CDiTXlS7^+mKr$Dwow7%ey7MC|~OgRdJr?k1mF# z(6|Xu2}Zd9S76Ev^S}i-6 zj2ZVcSNWmYo0+S@EVpZUbJ2)4K*@yW+ycxqTzq>YR5Ksm>94YNhZgOpzMJC3tRr|l z3W+Cl!v_~VROH9wY?b{?OjLsnr23DfG0hRo?}EMk$@orPBUG7frpOOwrN- zrF0OH`$I4DlCy2;sAlOErSu(2A?^viae-RnnejL2gA&>0Vp)BV0h7^>Y4<}88t~|d zdNf0y7SrQl7UD4$4?K9&!yh_1oE{sP^Z(ir4o7i^zEBY^LkseUzPp}Ey#E_I6^YAY zNM-Xlt+ZakQ05Pvz4xNl&$cP4^ovq@5y|z3&L6p`^rxnD!B%RJjyU}IeA{=>O1_*K z^qNvFIgMT1XHH=KdyEFZp#}LviDnw=&sGfTiXkXUz299dmsGP2^<=Y4Gufwcpy@A5 zJZfG+FW!d;HBcrvy$ofWk4h8S!O(&V^zfWK_JSq%^VVC=OpFMj8`+j~9>;Miw1%xW z=MbCR9c-^TxhSR37B){Bbt69NDq!*t~LNS3bx#lp}lZt86JbvSYr* z_K;J7o)`KbR(j5=bmTwuAJ%iuL#%@@S+fl%j>lpktje6r*#CcJh2?ZcfY4v8mBa+r zT|JY9pZF!kNwSC&v)B>q%Ti1%#~2vOktJpLDp94OhO%sYe{mRTY);@z-7}SIwKd{; zg}FS2iY6o^cAKD!ze7_Z{EF7F90~)j9?kC^I%nvq4Fe%9~R@e}82^=_qWA#>=hvD!iccsrzlW7Ph|D28ZL&MD9;EEW& zMI14Qn~cXkVkD(M1`anw(v0w7425Qx3-G$a7vuq>0X#k7+Y!oZq(6yvn3j}#7P6>? z7?biiz8O*8|4Pc|QO*-xfP5ttFzf#4?XSO!LP9J)?YONu>E<$#?&7g@&wc-^VWUXj$!?iA@0;qWJQoJbG$iKI?; zFJ+fV>dYR26Qu04q(+;ek&_E|QWNGlCyb;gwK_*!mIrLlZwlnFO(k_3-NAZLU88#Yy z08KjFgjvpxHb4r)O=Y{ym^h)v2sdMz3**u8sFQGWMo<(TN<%F+f}2I#BUrd4xp}k+ z$}!xE+#+f*g4Q(JGJ1@OXv2Cbj`F%lxR~4y^};6UI_-j}?fodD^q*ka6D|oMvgk?F zX81B%Gcv@T9j%Nw>m%HW61S|UaAzud?D-y-M9SY!?SeYAC9|))0+PZ-Xk%ty_S(W- zh|KKEzS}qz=`v%o6EtZGtLAu=7KTUc=9YgTT+`Xpu}q7#ZRLo$1q`G|yD3_BJbz`)h)!vL_S$ueyXX^UR? z)2cnn$Q)&V%C;pxWDg;>*8fK9G6xY`VmG%~u+XA8uycFyWhW~q{wi{1R$h$fGO4u$ zT5T{U8D+5B2CdQ^xdwCL*k;+@V`YLtq@ z5VF|~te)p(S#E;6-Ar+zvz70wMe3Gih_>Zcdi#>8@K_4LeJDy4j%%(DCF8F#YK{DP zxH4U`0{#r}s`8)b6XVOQw1koeRKOp^+AdaM+(e`Z>6+^@F5_3de%4~0x@J!_vL}S?^*If8=#?PiT`jV{0SfwYEiWCGqFQbZ^^x(B-vj(1M z!`RI&Zz53Bn(AvQ-AGAg2U&J=rORk1i*BBDxYk#-Kr{xc2X@V3rh9!=OMH90Eo|53 zA~YZJ!RUa$=9Wy`Lixr~y{O6z{5)z)aU6QUaAx#Yh9 zR@fWj+OAf1oOOG`3FyHoQ#0EzMX;NdQnUjl)=jqU8a8eB`tPp4 zT(OeaQvr?u9`vx5oI}VfhD?gq@jqS6-7{3{#yk z!Lz%&Uv_uq+V1ZG+22_xC8bc7wPUB)H7CRxU=ro$!AoW+|8y8*j^?Z}|EAF5LB@>4 zNY51uTZ)<axXcls^kw_Xcpru)hJYU;SxT;#sJx9aO{z&-7!=s zQVMPOkQ&=;$x^@}z?D){jqVIm${?LYpwtQmo>odLM8i@mKfuonzK$@DidZSe`Ibod zM{pWV-h&6${s0*@r2Wgj+{#=cW=5mpHlAGa2Nf;1EJr=Ih8rQ zV{NK*O+e`N@NFi?qXcQ~Nx0i>>cXa;=#svO*^SHWR-!lCBk)o? zw?jKTktVWwSvg+jYKyqMmzC#bY|o4Fy{u^5i42J|nsml_hPhEjRv{zXl#9rCTLe;B zc$G!-cs$tXdX)Y{o5{iYF6nm@qPCNAuT08aaF_7#%!tci$Swofk>x;wZwH!UcgqUj zrrws<%Mz^?3B9cbGI=+O=D>@|tA(B7modVbLuB$~^jp5pL(|}t8B!h*o!U*X%04AD!0E6O4Z`|&^ReaprYSZil zQaBnhG9Po0H?|)Z-)tpAeYIEx*;3KAkChW*wx4#?Wh)Z1`yit%{Ex)-eQ?jrDSXy+ zaT}bFntY%W55JkfEop@~(8|I5K^L!uVp_5hnS#zs(809iA8165YgpS!HJI)_?Be9m z9NM;K&P2o9VY`Nv;AktWVRAl`kC9YXfaq3kC8n0akA+_{QYo#==L{wzb-LrRM0q@? zJZ^V99#9@9Z4a@n%w+#@6KoLfW`l$&X8U>J~@-xRNIn%6!Ey9*m0lP^rnI3?>uU%`K0k$UDg* zzaWeJJvIb+cs1NC*t2lADS|3%u1z}!x;jwqz+eY>WS7d59Ei_!Xn_OE9ay8lD3;6o zG{cC5AruKTw|v>!X${TXc5AQ`)3@9q$-hNuL&HoilSS~V8O`&!x35JwvvCJeK^d#ht;t7GU%8gewGotJ5chow~07ssa!3D4D&O??B?F**y-=ssiGZ6L)xjKofXQ?gW`&q zO3p@zWUflxnN3x4Ryt+y3m@2E)gNjOt2;TyDWzZoXkIle5?{!#7__9Sv#b0h)PV znRyQZR7*Gx5wYjrTf#}l`Zex8EtT~;$9nuVns-#B`C~Nyoig7RA(VNZ>l1tZ-TZmS z{0#SYD9gn26TY&6@P(FAM?+fAgrvlSBMO`GZ7oHwL8>g%Ad_{1`E@I0rv;Ryo$j>b zXh=JJ8>J*$**PWd9i&=FONe9(sd0~W%v3vO7SN2NA*o_oJz z=3d7PUL-L}9Sv#bD9sE|W*!k&4OR_pjAQ0HcNE7@SvVg%X1=2tM?;!1l3=D)gohvDxB32p}pbb7w!)o zGrZ9*&5WZNM?;#ar5R4gX$Ir;5GyavNg-MRC!j|0zi={Z-XbRn-$BjXa=zG^zuY1x z2{*w)M>%P{#mz}0U&-hwr;WDzeYo4piQ{TF!zSSbpuLF%srSLLu6W z>r9#J+&uHDg>Oku`2LFYZ4zxNt)`7Q6MLc!(}>G1_&eI{U|&_??C$M0_RMk*!pJGx zX#hRWDGxsyv-IG5WArF2mLbIPO3M?LKAV)!K-))N3#5n9bvDw-c~>3M*-V}Vyzk~& z0H5Y7xd)y!xK(r+Y89GGMb%I%M_z(8Pq=w%a~HMVS6V;V#^d}ZzBJAY@Gw>UIkZf^ zkz*L+u$x;xz|`8FG5#b=d>0hj%M~GimL>Ql++8tqG&*AE%H7T6sq62u03#91B6Hy( zXNVY3Z76Xd-d#}(XJYA8eOC)U=;g+fG$}Kin^_Ft`=dla?m*X^7FgiH(bw9F7*v5?=}F@m|ZtQ#lAk>?N3J2 zO%vSdg`oQ-LA+a2G=8(kB}q440yax831Ul;FSE;YNU3eLVl^&ha1RXiRy>JwQ|^K1 zJry+=Zny`Ic`8bC(busDdU-2$C*mat?184Gr9{7i+->bQ}XNo^YLjMXk62?8^ zG5ePwLhk*-C_C=SqxwxnPPm76_dk!u#=XLg>~arG_Es!FL2wUT=B?mFj(foLR(yq` zp6yW0BM^!7kXW1{yoYk}EX?4M>mVgF3?w?Zwt zjDFs_YelR-uC??Fghk@#SCn$axo7H%XIY!-4Z|`RrVs1IajiCktD!;QvDc3y`P33= za-}x4G@QLmoJ+2V<_e@Bpi3?p=Lw`qcGsPoXFcW-ix*i-#H@wZN8*n~R)@3%c$zXE zldI6VpZ5j)b!CgKfvyl2tFyh_0k7B=x27h~zk2f3RTF2;oQVb1X3v^aYl!Y+nl}(< z7hD+=gZoBXiu>-cQWK3Cg&b&JqI&Hj~%h(NNulSJ*)cm95$?~vaILO zK?65EIjDa7Uc-7<4UYAZ@}b5>m7!QdZD6@kGi!3~_}TUfZd{(tm^gL(9MOK6HAM8> zWMw9epE$7| z-NAIx_TJ2NaoG)4j@bTZhZIr!$Nd>%T>AJ(mX_+FWtAghz00b4TRjK%EfbBl#~O*) z_CYD4-U=(vH+y_d&HPEC=?bf|sHS$jU66pp9SvJG18MDKo1l z|3lU zVp3=%LZ1#NiZ%O-!=lkDD}6)`zk9}%zo-%QbH}8 z(a@^Op@YT8tE@(1`}fgQ5&2PImRC~)LG^;_iBH)ET0Ka5VLp2g85U&&zyuM18e5Yo2d5+bY4K9yqZ z(+9Jg*oz#pt*UyH%?T06l+PSLqq+(&35cq-R=Rlca8{<6yVe>lHta!r96z{CH zx_f8MoKjsQg11_OGbf_wP8g4*>#=eb!`p7PDn!a*D@`4K8sM;RO z6iaTilEkoIhh~VS!<&S}p4Vzq#G&d3(!}x6js4p4il<+)qMIJf$`|SDtklqSM4T)C zu%UNdXSEL3&KW2+3?cwyhcd&TUI3o|!u#Y&Jr zuD31^)Xu8q8j8s2!NAgNvGI0mf>^mLikdmtF;l#K;r^(2A$NRp5nrAj2&=N?SW-2+ zUA0)f!739ku0jioY_v)eY;U8cc8(ad(P}G}K95#=A+5Z=$W2cQh^IGNjW4z)#`wt^ zG@tAj(cq6if6y=f+K6KPaf8)Rfj7;eac2~^qM)ddb+{Rz{DCetE(qf@y6k- z*;TSVVU{n~r4*lTk2Mf0_a7V_lAU|Npgv_)1A30!a8P85&?d_tvU98~3GWLB3&n*U z3!8}US7i9b>np8n@z@O&8FDd6v2>GV+0NNt1QW%po2=|$%{<10)`B5ae7ngi5DWHJ zqC3uRo+vgvvaq`wqo6qR9>&DGh1EMr_BeZtsVo~Jei2rFJq*(Q2MsL~LvBE;*m>Zf zA43Vt>mjpfMKwu4yKG&@_&S=nH?Xmc03SMGf=f63(56H&qAtLzb3)7W3!)~`{p3dx$T~j?rE;q``pTZ-UJup;Fo;!1*IF|5YM$kT#R#nfLGi#1`b_<$r zw|lHkqTT+3*<#r}R=SVF5;F3@J=S$1`gm5lxToS^J@M3|2kVOk51})T-fGoPn~lL@ zBF3tV31-{ew$P$qsrSyJOQz^`2df2 zmLAJ)LJhUrW{vdXiaRp>X`wz4rJ)1h>W0y$?&(ujMlkda&Uei& zRK{0D#K*r|1tC7r?1=J3-u){uTRvwMhj@DJ$XALn=d8;^Z)u`W#e?UpHX%Nt>S#3; zC(gm(2u(CeB>!Pu-gcKJdS2tVHU3oNZ^hz2&^tru1&;9s;y#FC-84}@jmK%s*KeI* z3pHM+@jYVKk%1ZULz?IfjsLCj8I8|t?8oIACz>>kb2V z!*UfzRdUlc`5cY;Sr|uuiNnl4KMCV_@FRB)^CNc-^CNc-^CNc-^CNc-^PZZ+k88YF zV}9e#(cw4l;*NtKxpSBwxpSBwxpSBwxpVkG8uOl;BR{XPJ9tSR)tK)fEBz5h(@PGc zyT*Mq?x*ntji+iXpVCxSP%GL#H!>r>RP$b`@fwZg)nFCuPEEd3<9!+*(fDnRKhgLr zo9(uJR`cLzD4l`|YRo%ij=WIgVvW0MY-v19<8d0#2#FEbjmj6Fn6aSP_>YG&+rFUr z{zGGa+suib-!pUgd$E28Mu>X6WUWewH=rEO)wrd`e3!)0;luL|S86;~<7+gYuQA^^ zN7!ESNO+s(!H<7AMtOJ1VZM{;@L`SL5JMhWQIPecCgRt(9Mwee>1P`X;%zadcSPMZ zj%hqX;|Uti)OexByba{o+@SF`jd$8?Hx$IBYOtMPv{KBe(Fjq71X;Y3_t<9v;a zHSQMC2Eq!>W1Pm*G?tI#sYbC(ldsWOXuMtHT^jFm7{3PJ(s5G#rZ{z3vyAvjP4vCS z9^7tlRKpraHEyDDJB_<*+)v{xH0G;Iu-`~Fz85u*QyTxCELwMJmLBSYvpXj-eZ{g) z%`(jK;!kfZBXpDIvsUE!Vj1S0q7{DHKB)QZ)Oer9M>Kw0bbfF{L5Qz~IZ@RUp}lDt z@g}(9?ugoH+(YAj8egIDbdBe0yj)}6mvQXhsqs#mRm0Uhj%fV0#-C{XmBwc^HqtId z7SuRX<3f##)7o4L&{gxWG#;n%bn(tE3~DPh(K?N{XuLz?=QTd6G2f+j3g>5yP2S*C z{Ub-?W;Tl&e=I$&{QGJCm1LX&a2o;Un%LZCX*zO^P8F74^1sD{ir}oKZ{qC7Y;A{4AYNvbz+?No`i2taGT)b7RR8ut0*Z4AxV;YaqxR$I6a3LAP4!1a%pIG3=4+}uY z?*9*J0rqME-qPf9`A+l^ZvTQjRq=l{9l4aJDkwhG;}lv%V}3TqNnCE$v`b2jHIHH~ zK&i%MWEJs9ji+h6MC0`uKOpjgDDXEm(PtX}qOn}cQ$^#CUWzh{tO~Xf8I6Zq0hsSV zbL00X9Gy;NRUX}Jx$Ww!d0a(SfvdnYG!cg6VxV25O=G3_v-_Tm_%7vr0n%p}OnDz7 zt9axBpvv4S$`vOyxWxSUm?Q75v88c;Fq6XTmcuD`8cU6)B$xG65j>*FxsoRX^J3Uh zJFv{ihnmhW8fV~=os*z08g~cN4lkZvk*ysprf5nxX}m+@e~NBNsPL~f(Rq!%d`3j2 zJx61{(do$foeGCb$!+cW7^TUlk&A8ljhg&!avRmd9@9LYCaap;Pews-I|NQu{7+3s zu9Dfo){(1Zs<2;BN6Ej{^ncOhf8?--sQ`h7mpF~A0`n^ij!vN_Z>GsRYCKTW8A?`( zzFvHKd>UG*COWL~2O58^aRBo)$3&E@lAA|HUbr;|rz$Sibh>LCBX>{*K2Y-*t??XN zNgAC`Rz~m9c)!MPkX3@-Cu8UK5q?t@e@?m5`Jqw#lH)JUBOw=ZRp4Q=3J}%gjmXMq zxyF+I z_#3iQXXJc4;-A5(ij(l`=wxeLPF6ZoG@dP)<&SN>=5d$C&ue@{@xqkfK=?nPTqT( z&M~se*q0aek^gU1032>dq zx!s6gNB>q$XG0UzzoYb!7T^Vq539f%Vdxz#@V_+vkEZ{*rvII$^Mj`2X{zF7|I2Y4 z;5;x>x)a=%a+R|#8u!rjdu#grHJu@v&LoW&YrG5`U}Q%S*?MszeMCn5Ud{i0u;aax za+Maj04RcSJEG}-s__XG_7mv*poKlB@n4$0yGX_rHy9uYhZ9*cSw&W;aW{>7f|<~> z2s?ywmC#WdS84haHT~(D&b38ab6BATxJTprRN$bAhkv!e&uM&6(|<|Re_hjgN7Fg! zFq^|4jsyG`m^mv%WZ`C)a+axa4q25@9@x=uuIaSVbb4ugrN(2xaR%;+$Y#((72`aO z7it0GU`PLEO=qp9BNq}?iL2A(&#SP*5Z6C1g^e5UUvd~9YXLsh0(_zAe5>hP(71l{ zOQj+g5=A2TSZ_1RRmR$B+)?VY{IOjQ2Xn>%av@O_ASRV;ozWWCXgptq<#QZ2QLe(S z)A$Ze|4vPRdt6g`SW|jV<99Uv0L+B);gJ7Qt|B|F@lTrmubRHm;*!3X3_CLanaaU@ zw$Zpfn33^;=iZd7$ogwMMAILx>5tWPCTcqKG+x_+(*Z=lZM_QoIwHGI3;d|YPiTRk z()9OhI)^o#_ci`j=BLsq3Orp&;op@ zDg9ehI<2v{)umDifSEJ-3K-=ovV4u3YWgiS{SsTp?th&%rT!XE)OZS*k?}>b`IM{3 zmTG*Xrhkj3f4in5G@VCVA%3Th4{IJTtH6An>;o%nm+vb(6HBEDA( zaK9E{r>66yrgKE&|Izp>vYN4fPsYKG+fQJ7)oS$r0IwUVh~=`fDnOPdZ>U{cYNp9M zYaG*9E<>v#tAw19;X^jfkip?RAAy&CV+ct4nS4#Cc0%9Wkh$;!?vhWITChdYy%emA9`jIiaDt3(VTtFR;5a{N~Ts_3D3 zs>au9e7(l2HRc+*Oq_+tHdC%5yPvEg+o9?2xyZ;rSITAJVF>&@JyhVMWEJ?I7X#pF zJ5A?PG7hoaPJmMtdvVjn37bGx@>Gqp$vpmZYpi*+*0`g_r5elCX;nf;QjQ^-+h}mA z;wh9Xop~BBBV%CV7Qc}Jlw*yi^nk|uHGY+ho!c9l{9`gofZH)m{tX%Ji`(~_{138o z{ncm>he~OXi~)jMvL??V54Gj_n!Jg|tu=0^aTkrdYh2zQ_3uPnp?OqlJVN8K8c)#p z8jWXaJXhoEG+yQ~$DA7-2Y8jnw`zQc__T2>BWs%`dO+hx#EE-zGvZHcqGvTetntel zzoGFv8h@J89ths9cqn*>;;X=qE1m(~tN1!FA84e_RdF~DDF^Q;@rg!yJO$xZ+B%T=5r%c(fX?k4G zdd2&|Lh*j^J&F&3?^paP_z}e)fuB(P9r$U*XTZ-Z=Czx{iqC^zaZ<$VEN>`}T=08} zc}e7B#m&I~QQR8*U&S53-ztuQe^AV;4!JV|sFh*_H`*)4A;{>gn7yfoVhdcRm>G!o zQ;z9y3{gB2e1+nr;4zAC2TxSYUURkLhrqKGv)9a3{2X|p;@82;6dwcMWOLj&4#!&M z@gsPHVvmW#nqnWAUru4}Grm#*d{C8PE5R=*o&^3!h~qyz z`2DrFl*a-vKdDanD)7G*^Xk(H#aqE#B!W7-!QU$01HM33$7m0Z(PUOrf?|%O5yiQP z-$+*uw(4xfY}NUS+kuM|vxT=-+!b7+xI36%Y++>O;8Mk`?{dY1!Tl9;RILQZ8GsF8 zr1BUI=EJmUfYbl=zo~@X}?L5T`z>5@L4_>Z#Ie4Yw72rF`_RJ-2+^ZZc zqK6c-h;}N@2JcbKF#8m9hI2qMOXY}Smc(m{dxGCq+#md*;t}9aB%}PVgyS>i!5n|3 zcqaI?;%mWY6)yyzQ@j#vgzeni0`w_n?+7a13QkdcA2?I-PH;oM_s61m2983-&w`sP zJ_6=f_NntGxP#(%z+Dx80`8^w3$Ug5Yw$qDXTif1UjUC%95>No$0-L7LX#DzgQqLz z;^}h~^MJHKF%LpZ6t@MhP|Qo~s}%F=!Rr+B;Iv6G4^CUc9RHCsepz_C^5D^FhvMnr z#}%`S?p1sp_&LSA0)0sFt>B}I*MnbI%&yBPo*CCe;ExnP!b_pYl!F(1PbxkD{zma( z@EOIggMU%{A((4@(dfruSH$L%V87zi;3UOAfVpG@^?6w|N{++fa~W7%!1lmLC5$GD zc{#JC;)dXMiu1so6!R)%cg6hHZ6C#*!F=qRk@4c;V8w&LBNSJH>7yTwEo&uh# z_-gP>#k^Kmt2hq6Uhy*UQpLQ+wo>sX@LI)u$#K2nZD1~bl2XLuFSbW*ha4t%E9PY3 z8O2fXe#H&JFDlLjzp5A+HQrR*8~ncF82Dd`+3$}l9tZw{PpKmn#xyv-Qy$lWe^k5@ z{F~ytz!wzn0P~4)hTQ{BP|TxWL@~Q-y5fI>vlX8K=PSOz{1+()KOEIsaT2&haXz?< z;x^z?#eKl#ig{$~uXr@LQZc_XI#Mxv&{)OnHIu+`=3p}%*C-EmkJ*ZOWSgh>8So;- zuYs2<{vYtoivI(?Rq>DDjfxG__g#uZ;BAWQ^JUkEl%oh9TvM6}VoTnmxDR-r;{MN#QB-xo4{O=Fom~5?}g*E^4JbOtM~=*ImL&-m@Uf0 zy$JRx=80)g@rU4u;*Y>wm?MQpDQwLY^B~toF%NQ=#gzl`7?&%?dAiY4F{jUc6|)x% zP@D@Msu)LPgA2VdGR_;S6t@OfE9Mb$n&M92YZc3{bIn(da(FCOY=Li3TmimCF%P4+ zDINyCLovJ7or*_-`3gb`Q-f`fV&l~|>(lv;H9N@572D%0x5HtC^^nf_P-!%tB(yZ7(^EWYO7Suck#p7_g zZaye3P<&ntm<{ph!(!`fhB_=x^LO`Q(fwK(YVEb~4!$Ig!Rgxal4w0giWkp;c-zb3 zO*+qtoEkWX9ThWcVnLnrQa<^I@0geen?GeEF!y z;unfJ^L*46?vy7t~2bA0f?qzZ8=p^G?sg5mx-r zwN0AHx$e#|8pP8Jk&p!t`&B|lKjIhX7smYFr4Xjs!t6z{h9_n8eXJ;GWP3wn1* z;j$Jlq=^}eVqx$8OG-<(?e&PwRC@c8a6c@eEx)k{`SX7zepwW2;`2|72WK6YKBpmnz==a+pVKTM`TU`gb$2NRZgG zB$n^(e4SxDD?VO=Hu$6Xa|!CHl~^xEWr%H|Cq1Gxj+|8AjbpA@c4|nPsE)_Np{ZAx z@(UOUY1E4G7s?uVy<0GHie(qd3Vb6+nm7j%WB*LbH&2OE@mSN)1A8#*z~IG`x}oCQ zdH6z1x23UW`ugt~bt{&}-uIb-x+`yr)eo6_>Sk?>T~&5bh0EM~+m)1b>>$SauWXv~ zGMWNLRvwplf$&}9t-5QU*j8bRw0mU@5Lcp4u1RL>}8k+`i)@d#cfmf98TMQIA{ytd3#O@~KrmsYX#}sw0X%rUmGaCmGkE>fInR{iXXJ!nZE0EV~ zYE7py*x;8!b5t-930k!==nrPETeG3gj{s{%?f>bx+sHXH=WrIvY|o3q?T4dwvU~Mq zQFl9I|J$B|1H1XI%m1Rw(>eJ%bKIHQ!N*x0DB7Ge;>3ojX-}co4q8;ZvloWn!zhRr+tXCNK2qbP`Ng#0K9$6xjp?^1iMPIs z73HR%Of2%G-=4T5ExjVq32obZ#GM{Z5N~H#X}ReS_@PzlhgO3B|Dp9SpVaD5RG8k& zoA35G3c1^Jm8F9H&%NQY6SA++mgSr&D%@F_@AiqokMwIA$ADvuG5_y&baCS?Exh~x z!%jQMQJ^_I3%OXZohPhEsm7dQP1!MLO@*Dp9k*Yk%Kfj|GNd|Xhim6Ie{&^hu6%L& zR4kM4%*jhdGygAsJ0T2O^TqI-YW~03nE?64?2I=$rLd(uf|hc0XIyV8%iYH7zdea- zDfg@D@I8o-5bSc>3HROizufn*5kX;xQaHNVfQqer^p3xWz5SAx?>0Y=fsRdLEr^H*v@K(djDE z{}tyHErXL7WM8V2AKy6J-SDDdG@ks$t&o@YrCyB3cZC@BeXP-lLB@`Po83WnL0^9k zP^C9-v;5mUyz#Y6_V{wt)yw{MqQTz@9k5CQKz z6Dx@S69L}G{yFyVu}4fCe6Y92-W$7teJb{wuovSTZX|YI_1KS{pKN*z`!M+Nyl*Rh zAH!aU{Uz*gVgChtBK$J37h*@#yw7Pg=yIaz53vDa_gys!V#JTJ?jrj~d<+nO7KknT z{Rv{p53wY%|A&|*ULV*fQ|$aPwobJCutkFClH|ts0)K+XnR^koA_2}tW141);$dnc{dsH9p91$W97QsU=nh1=!r(HUxsP7 zzaF23bbGvYe*V;Rp(MQ?Ksr@TKbLUxOl8=#$zAxv+b5p-{fT@o(34k9T+kVRTFoZb z72}#*9%e3vrx`|8SN;pcC3(PtSEWJ+V3UW56*#|hHA_I8Zqvmpg}z*$nEp$w*!6UR z*!oK>>YAP|p8F+M5PcAZ;o4~)L#V{yW#C2P-2l0m{Iv6%Me?=$aI{%`6KV5 zi+STCc=8>22)<@yEsVM%@4(v~S&Cqu$or^0Z)5=y=Zg$N1=NfD(3pw1BFIFPH)SGT zhJnP$W>^SDiZM+JMV>*ENs2s-`UppS$WkQoEG#5Pu7=H&$U2l#YNP`)pBCxOC9vy9 z{(%7Lkp|hg7aduE2r?sCX}DJ%S&3^TQNuH@2=NbM)hBy=s~*EVGljj;x0=;vq}-2u z`qq$LhUX<@-M4lXbdnQ%xBWrgF}gfqFwqnkbNnS z;!x+?NcN+J^?>7!XJAMboM?oe6uFj{Zz6nF$}~K)P(QxAe2@n`jMDQ(C$akXSfhB6 z4<65thDYiY{7GZmLHk87@*SkKzFilGOs-57S%T6tB4f~a&B(LRaYZ(x%H5F+NIa42 zQQF?fPi)PR*V?l#Ud(4*bVr~-WF2~MLZm)Yl^BVku>~Vl`M4YtihL?tM6+a8#yR9A z66u=9%6JtOpAuP(@=uM7L4o~nB9 zx#ymH@44rmyHs^GdT)Wg4}}<_KM9*E)W;+7P(1@G7^WwqKt=j>u)E><4s?NHoj=?> z1&s!SagB0NgRXm`h5CJULTDiyEh>s{T`0b}ifEqgW;ZS+BKBN?h(aLl_ zo{*C^>3Rg3iJ2n(hQ~>(@w#KSs~16}Z!|h(%ns=$6kjw77_(FT862vQKcbG=CAs)l zx*t){V`$-+o7D!S^v1>9ranp$GS%%emEs!%dyBb4<@ly5u0f?}tC&00>%iywGy&LS z>gNu$c1*J<`Jp-^G$9|jEsECWyaCDGqo^V0WEj7DJF|7>!0g;_{1q}?^-!C8wpz*( zINfvAI&@5YsCK2|o+o`I{_DM6anG07p}6)TPxo2saBz9u?q>B009j}EBD>BZRNCDV zQE7LpS_AP;{8u^}-`%FpGgB{7pOBfgbt>+5E46}7;66t!M$y3kV;(~IGgXs+sroH* zdlAZacbfdM{HmdGdt=xPtO!o>I!6u=2 z*I!9nsYZj@o8exib}-d$YUzBHPmiD-=DAvm@SAyFAhS$ST%VwgL+%UJ(~!uuz7UB* zvQ1r$Fbnru^)jk?xO=@?j<9bpx}Wz-AU{7`u@l^k7pJksCp_K zpgTck80T9_aegO9|9Bri5aUjCW@CIxFjbf&+5A2}rF19DK%%dlffN}?Qe4BS-E^lD z#rCT1LC&{We!d{;&XO!B^Z|^W?ri6?1CT%ZTCOvheqGiv&#Gg8Az1Qd0+-Llb}ewS zIbsyo296X%oF77NQikdt=A;KVQx{pOzoDXsJA>3v^50HFpx8M8?WU;7%PDJwRD@Ga z4jrV%N~FtjtI4v$BV~oXYVvd>caM^Bx|;ku3}5ciGNE5hmPHyPib%?0guhQc$NdC%4tLtEsiA(gL)R zQ-I5*Hnn(iSIBy6LovR)12R8tF6q;xHWgRZ=?GLhzlKPU6z6&igN1vBb1p}+L2kHW9)b-s+7Kh3n z3>R-e&d<#M^C8TC8)~BJ{CSE)Uyd#mrSoeBPJJqJh}Kgf)TQ%H`WXE~l)|m=gIRm@ zm2kBK^xwlXYx<=j6w<3NK+duH?s(=u2cie+&q1@gz8)Hn(?=9=F7i1j33@$5__6Gm z2pQx0P!#7)NHt*6BxuTcIm8T@k_{Ia^8m_MLSMKMAVzUcXM!?vnR*-$oQqifOFj}) z^{e1I9Qr~uMU>*a4~;aSa3^qU4_Zim@4tWCRnKdNih=IuvVnSYO9WqvCwb2}Q|q4Uq-qjY}o)2TT3 zWFyu4SAr9%LSWTC{5z9PK@C*>3|t-hY+RjsBGietLbzI4!sESqI5nNcIrPtdC__v9Dz&!dK4Sv51_mCb~LX?KaBDY zP+Z&K3bYip7UI0wTDr<}5__xXzuC{(Gx6yJFCTy3aI;yu-C(^)JkR zE38sGMdjL8@$s`OA#H>VsXp$4XeBb>@I^EGkt#X_%5n(x)W*wzTTTMBQW^02e!_63 zmC5q!zIw7vRXL{neG`zaRxV>w!2Tp zzInWC^ybM(5maNrl;{k>a1?Ek%E#z>BQA>WfcdEUv)M?3$vjoRSe=3xuU~6dp9Sz0 zKylhRvM`F-Qs>I{aQdD=U(`Be0o=Y8vMrT0_4;<9qiH=d;Pc%GyV6!NQ%n~W*Fxl_ zov-qdz1OE*sHUMIkq0ADJ)jkaC} zyo&4SV1$09zDlu9?Q)g-9zHIOwJRix;=6^f#AsK_5GuO`-Bi0uK2*Wuee@eF1M=pnT5JbO^40Jw)db=_gIDc z3H?*MSGIueL!&9$eNt^mTt-#xRzGH9zxJTo#>BElzcCYsVq4o+DB8oa7P?vReKPBK zvmB4eK!W1pPlB~a)gh38T0EulznINh^sBNGrlkE+l2wUkWMY?Dy=P^Pm~LIoj`Ezk zjFLiL?M3xnisEEVJ7~4{2QXOeWhvLKxW=;~f2Z;*f?k*Qd({C)ZSucv@++=Zcx~+s z^%JlR$k5(Wo4}$?XPX?B&8R(1Lw;N8UTcOY)ZUSr3~6s-;MU%in$ae}RJ0?qYOqRH z_^9fGByW@Up}L*9c2l8$S9eNlkn%s0@*O^z!N)R#Y@f{G6Pd$!#dY%#B>GfcNJ;ax zFVt5kN!ItvkX7Mij4Rq#G7nVPg=%PDtNiq!H&6Rs)iCy$34XNryV!$%Qtv@IT)s4n z1lrHC&PdER;WWkZ7893f(T++ahQTPB%OQ=}G@ck4(9!-&U`lQo%2r$lz^r*3{Pv)? zP#fs@eK_Yh2mLQJz^)kYpbK@yp4+xc(Gnb-X~g(snf#6iz?JN~iw%+}+2EPsWwaz2 zlj@V^n(Ux!&+vu#drB?E!P!W*?@BmaE!FWb0(pw7-;Ge3qY*_IP@-iy^4QhigDGn{ z4w{VSWj7n_pgCx(8JX*#rnJ*AcxidE;@W-mJNdF6imMAgQ!8-1118I*hK4$pAf-NA zddqL+cvprRI`kA6U6fvg?&Q?>AvRin3qIDRxTc|W+DJzUl37B=Id)RU_4K8B7cQ6- zqU;X+eb{uAJ`V}7KJE|3Z&8c-bMuel5+EKSd#*&cM z<9L~IQ_-GUuT+NRd;4UAJAJZ+mdh6M%B7vQLN=Z*mv-7pS$V%)9BSt|IAo^yy4gId zq~r{9SUX?F%$MsnZM6(6#G;S>_X24ct#Z|;T_^)><_z{QN+xHpla=&(h;(Y}9sds3 zXmNl!&^;gnUUQ&(PzHQHZq8~C$$)N-dcTo@cqQEhYjbOlJBEdGdcrJ( z?=w2ICmkFHol5!^X*8i{9Dy+7vvz4$WTX3QFF2Nlqh7RRNU!yhSy(0gCA79vd)2Wa z%y-BZ5sm4WS9`o;XHW1jaQXAFOmY;LTy=o-^EdYJZY$2Z}$?^tQM zajCuQxC82O`o3W&I4a8$t)xdmC2s9QM>eRYhW}$*JWbH4UJS>sj zQ~QQ~rc?Gut(ZJ(WCzqXV}7h%?4Vg|P71g@B<)$7jhbp3r2%W@9E7$=i`6pe%eR`I zZ#SL6c4@6z{utm}rFm*^vkG@hd(^I?x7#NTP)p_*`joUdZA&5WbJ8ZXUkw93D4SiI z!mTOoHQCVGi>&dVWn*gZGqd*`&$3)&=~F+Ft)W$s{!gi7#Wk2E{ZeYu)d2UTedkz< zT6vt8;F_=n7e7~bej-q*GIK@ZP3AI3@8j1&6#ZpnqUt|D#SZ;8Xedg5cpREaFC0&= z`!oj{{T+1i7<~iexb=~zah1V8TOXj`!UF32zOPsR3aMiCezvQ=dm{4EYtSaTJ`=HV z`ccS<*Q-Z!*|!K@!LPgE8$*dYf5w=k{~7k0tkLA-ufrO;!;xU zU}7$BBOfNk-voi)Cds6vj)XQ<@9Zo_a8t&6rd;_bsr(46!#i*MAm~5d58>YVl!XkB zq9!rk-~uLD4CQ(k$|UiRz-qkBl&dPKi-tn4-qx$g#7^UFdw_}Koh@leWp;4droHv<(F2sATS&jAlNgy6-BZVuTPoKO?iQV#nled$2fPCQO?IQLnsS8lP z9B?9dskI@5 z+};ZeaxH=VdoMJ(#L5tlDZ8Y!0WwaCz;Zy zhfBGTR?@fw?%hEBIOF-jdGBS+0SQKypwuDn6?`IWioMbl`!tQ|DmlSYQd{9$yxvX! z3Nu|3!L(U2#dEgoy_SWA*k1Iq7_Ugrwxw>3NN~L+m4CJC^=_-l4%u8cNiMUr+gVyy z{LO5e9ad>Ob7*5Xw^6J##9L$nCG};PlFNJhns9!1SP@NV7nk>L!3er)?>%Nj#&GZ0 zJ0UIeYvdC0PNXZyNIy+hBF7y)bRCcROek;pc$&QqniWJ@&cAd=8sG)ZT`%30c z^j+^v_KwVAn$;Zkfy`l0ymtYuK648$-bLdH=bQq#god5jgBI|1(|kjj1(Sf6(=s#v z$YwjAMwI#ZWWW%OC-cX6z>8@inTy$oU{bF1l z`VL&9^v7^@>Tlp0tsleHrSq$hF?s>6*cXeUgS-$rAE2KKN2uv@arG*L_F(nmc-s** z5wf%J0RC-9i2L_hiwH@~ZdV-d%E=l0btwore?S2S|AY#tqoR62$X$Re)KT>7xhs)_ zI*Q&s??o7tdTJk_l79?pRF63T6?kp@@$*ASSHO+~D)Unt3IrM%p~MhMq&61(2`z{q z_v6(jWk?r_tKJ7r^F1ha+X~dNfRkQOB~wEI{SHDjRkg8@qcuY813U`oeGsPcsxybm zg5Ixk0E*i5)tc;{wmwDOqdxCYMk>SbUv`SRSLGgW)TU3@6jdPoBjxxd5%R>}UPo>E zVU1EW6U6->cI4vCVSvbJs<6~cq9CeLNviyO8hn~ah0j~2D6;2<=p1Do-S}ePnMc4bcD-p=kmFkOVG?E5j{lZw!NLp`EcrH zxfjccm1^a((kA||;pCVfGeHM5otMQZiJZ$uR2r;$v zlgj7yYNJ_PC0tz7X4MESIl@IRvfJX%5Gzgg(>23Yu{7OC8f_Nfadyd5WdTeh=O{&6E6f+#g7qFNt>rRJOmO@?WIX9J6JI zM6=^x?Vw^G#;I<5ywEP^)$(B`T!(ZdSDTKcv5+%fq!{LeLqthTwQV{{ZP!GoZS!%p z4M!GlpuNs1RK`+o(LIX$=QO2gBj{|>%aOTM=QmL2JV!4A^YP7}qMe9mJMS%&8VNmw zu&L+s{3y+%vi!3^RJS$5>zR6f)Gj}lBjDkCGIldReo}d#h$!!qzbtPFghmv1K&e%p z*+XS{#KIiIX?2yE@WAQ~vWd(BeH$*&4W{q3`r|e!^g^&WNK>Bs`cgxS8#>`9~?jsJHBkx*^mcLbCpXhaNj0@qQOVfCO^04axX zs@n#_I!;{%&!JWjstsf4RWQj@CSl|m+YSm`o05+jjpMr!XiGPKYRu=a{0g4J>J0`b z%IoNLD#g<*+W0yPFrp_L@9!jy&H2n~Oqb zjy-uw(Rzz`hn>Q!6w|a>vZCuP@SGi~E5*0jk-IH$)Qj#4N(W z6N>P=lZx<4L=j#+UIZEsi}1()T!bG@@(DfD@)4)f@^6hxgc3}YU2_e)CVy)_@ySVy{S>kBsL43_S@E?mK*A^ncjBV%We4R? zyvJ})frfKACh=zHeSWAr+x&IxxW&xp0N?*%>lFP1y#In;7mg4|ZYoI+74hfn93566 zF^7ddT<5FfmGMrn)1$Csvo5El;KEP!jcdt+$k+K|*E`@DHvz+>`UYQt%R==^$TqGd zAGAN>qAUb$5-Y)UfRZ+GBeaitabxdYH7c`~F0540JR3b~L6dlW0k%5AD)C|>f(EGYk61r15tH+b)YK$k2O0tK>I9|eHAFL?!jV?dzOV?@BW2P2#X~J^ z7F7U{^*o!Eb7~TwzUSy3ihI^YNyILxOHh--D)p!s1m+{&)JZ4@is+Ucb`;fBW~IISgcu|mKOHf}NON2i_)%)UHkN-e3Z}-P5%EnV zoa(lW(I_=Hoj@gig{7V{REA%JU8&y2qC?=E0Ew>AqN>2iKZ}!OYRmmI@=!7V@;JF+ zm4D7a@cSVEqY0d<>R{WjH2PEI23`Kh&g*H9oRIy`- zkr;Xl;TclhXGJgPtZ%p)j9wvuW0~Sui7(zRbJD_59lp5Waq`W){I5!o%P?6fXblbV zD$Dg`w4@TN4X3XKyE;6IJ1q*gk(328pSfy@*|roG;+s(Uw^PS_yMiw)0B)O%Rx#(d zBcsfPav>iGfagiXk8mQE55KV#XIO12;L~qAG_!z@zwOYhVh#xH$Xdz2pN3H?^C@Jy zZI^|Z5w~$bwld<5B0>~Aof)m>lA$!}GH|L*#jqV^IfZ$gPq66n-`(n^NONGnWGvEf z^HHt0Bo_Rg4OAb+7`1T>%t1K^=L!Ueh7!p+N4|9I*wi#Me@H}dZV?hH>yVoUUYhKt zCaR8xE9c);h`s{R!%m2n9gx%WSyptl9X&VPsTkdg=#W72#a28M&Wo0HQO0*7mXiTw zs~Tv)^G*!Ijj;MJ!KBr5WfBbx>b83!s~9oLEfB2ayIG%Z8E@Lj*N88Wzh>{IWngXC zP;do>bVo5tZIqUBKN7RPvP72kz0Ukbj{pz9!-s8Doa(j`jM)X;xCK?(LIb}?raT@N zfJFRLa&@)rMCj*8bR`pUFH|jBZElS;6mUBfOtPOhnvU-R)A2QpM<-N%TOp40{K{Vq zdH13NtLq}~rF{~iv>}giDDXujI>h+5UIIAZr zN_lTji=ti;MIi=!T6t?P_Q|f4;ROiGX)cH4Pf$Db8C8s%R;BwnY)R)@GzWn3i4(2S zoxO=}x9DOkW{MdzwfK4~Mj3M>5KKYY6)wRpnPYdj1UJj@MJ&O?mK9&OB?3UrXDCc8K&gZ6_ImIf}$C4^zqJW@Qr4w2(HS(xT_e5CEV>0|I!V{!n zJT6DD_b4|5iK&4FNGyA@*frcpoIk$A63;n84}?$RPg9El%p6{j68{y>;YAttz}(Cn zUXnRvAY4>!2mL>vEBn{;7 z2?k3WIVDD7DP7;yaAa~AvSo_buq%e zfS6Qbq=vW$a~IOxHN{rYMY8sORAdZ)=SjEI4xtltG`hOM$>~|P8>+bjk!b;h#_*@0 z9B(#~?cF@ET_xH0K)m=NMCMC2{#ul5`^a`(3fQi7hA55?Qi}T#TO#@Ri&FBvL%ulr zv>T+ji^#^c&uNnFRUj5FnkDBucIr;ab}QNbgve=RI}LL*Wg1!dTui-PPW+z-%V|}J z7#l)NId*UEkV)SMT^a92yUjpa4*D?JG5kd<%d?bHdWS*EgOWQHuCq7?kqcyb@+`J% z!)%XAwuxjbM&uH*jZXx!rI!q!48MsIj^QtE3lXiA+RgWz-F)ReZM_)UoS#At*P(KS zN2B;^ifqowO-S2omKQd|*-alLjo}Y?GXZ9YMIN+87PTUdBBqr}5#yF2914p-V!ma} z#J7YKzZOos&PsfZmG}yTe;t|l8W1>=d=*aoW;pS7EAcyK;_N#S7U9GkMn<8E!;$)* z(0yE)I5Nseb`hUaCVm8-dj}ZKC^P#2H(~8QP_zJv_(PC$Wu!%h1GM@`Q9I%{B7VJ@ z*e0I`GFKxz%0%aABRRAI!_UJfvTOs(8z8?F&Q>Y94>Zou{}!el&#L$}L|y@>R&)e_ zv%#3DEU;bF;!i>Tp7B2d+=A*CoAHibHSxHZqF5D+OT^Yq75b@0N+=KE#}RIk+}4^K zwBLfZGJ;kL8s~&pNm^I|^&oTBciV~NR**S)d&VR?dfmg-1-5n`ao~%*5dTL+hUj*B zQR?SFY=)=)Sf-G)@h^kM!90eZ?O(i57q)O;A6oMOETd0?}B*N`LV=;{}e zGZ`t>ZHvKK#4g7Th6V&o?hq*GKo&hhLSSMs7J4r`R)N*^vpjM#QLDh;GC=>GV-x92 zj0ZEMPrh>yvKh=xNwW}>`AZcw_c&qNAt;1rI`@zkAaWnnt{HqN+=X?*{jXXO{@Ts&hxt6G8^Pxp3rl^;sw z>HeL&YCP~T~z@G!qZ*jsZtTo z)7|2!v@?xQt*nC)^NdfbT8%pKbho&xK0pKUbho;z?m`84x|c&D)W_4k-d*(s|H~5> z#eKiK>T%S8r~4gu)fMOjJl&tWtBycpJl$t{svtuiuEAPmEVR!vA+72kXlI`8@$O13 zA07{<|AopMkPT1&fyyr&&<#%iOO*%F?|J%PuFU5b6LC@euTX^!UWXIEg zsB$7aFHip;tBTOdJl)ALRTsh#dAcXWRQ(mvJl(Tns%}ldw-|A{x4Wv&%)#%Qak_7h zu3CKxG=tN9cXZWA z;Upto9BDp(fS7!mk-Tr>B%{}{sCRcYYuRh(u7(d#%7!5b&jW&}|*PDDhD zclP&ZID)Fs&+G7q%p9A*Ef0<(CaKY)$RGtng})?)xyZp>BDju|!d&Fw`<4y9y=ohOrVnjKDRN-{~|l;oNq)}=g=AfEc;R88Dk_gJb}^iWo+NciHiRI#h7 zGF4nWt}kA6cl_F!#-@Wx>?|e$m=-cue11+4~JvkSC{ZXjI;I z;gn`Xa63+y((88RsyjGu+igb@JQxwl+1g`vBmuU`L*b;)f^fi&B{+!Fmdlyh@9ju} zHzOhs13S>WQ8?aWa5_*P4fla2nK!v}2Queg={RNi(?dYnIPHu$yjZ~}v^3P%VWmMT!92obhAD8kmp2@JMM$Y5*a1O}>wpHNYi zdEeniwE)^hWGo&%@FjvXahDG{qLlMOJNUH2Om^n+WV8}_*xF;R)FO3vLaw#~$zbd6 z1P1;_kP}JM$i+X7T$w5cK0VQ`c8br+jbw4S+;H2vD@?Pok4U=W5Sz}qBkBL=Vy4IFewy>QV((j1oA+f`8n-wH9g9{ys0_9gqGe(6 zStK<|!N|+&0I{>yNEdq!&Txya?}oUuT`{p1&5d13j2t9M{=PVs4YMG(QDgQLGCsE|Q(eD=v9=cQ$Kg=@RG1QI6<3EXO?lVVCS)uVahg*MwL9CkS7 zBpdtyr8I5OAyx0N%Ha@YXG0Ih*)zRj&1_?gxOz5b4cEUB>l=H6`y?5+x@{R|^Ess& z93HdQtdYYLC;mO#Xp8m9g3+v_U`PwjG!}Rq9_q!3=H7Rvkr|sPIZTsxilb*5qgAI! zoP!d)bEc6Zj5)^XL!2HM5h}=QluYjOxM4Bea}M{ePdu_I6Tk3~)zk>YdNeX^zW?qN zvGjcOp-WPI$)fZIPl6aVIFKizn+;tYy3R=7eE(Ek_+M})h|LF#bZ^VzvxC^a3br=) zHH+rKfnlQl!c3>Qwat?d-P_jO(<1I392lP4+twFs>ul*+)!oBkGI6XMM?95<&Swq=$ zQG8g-9?-nJZ%JEcu%~UAnBQq+WSC6Vb>)ycy{;mltn3JOb@!mmU7g~_YmBT!$|}d{9wV)mis@%eTB6YDPVl zcXzb65Vf7x(k3<9+!5?(@9h&g9Y#W8kF0|-wW&Nz5ll#63)jWqGz(f$mv z?Ha=?wtw007TK$e_}sqpq-KJ6_4@3-B}z+I=i>I`jVjwp+>sX;JQl?;YfxKPTV7XN z8?3IaK#_a9I&2m9DpG|#&?gNd*s`>{Lv+80CY_wSI8FR{c4o5ZzAJ5@@a6}SMdPLD zI$2-#=Zo&^45!$Vn42IzZ}%jj!MnPpRkbV<8;|x66Yn1GkBznKQ&v;fFkR%lIw#Rp zA=N5&U*t&>&7buriFfk@=>w@#)S@%k-Q3f>v{$@#4n~l5bBzR%RuHI7T-4WMwl;HN zc{|%X&lYRvqm;kfWO&5df0GFsHsLSX&pIUfncZ!O!@DOPhPo6>pyF zDM$_mm$!HJjfcrB>I*Jk-rlM#YHjIWB{t1I$1h6Q86MtUnJseeH&T7rsaoFAr?j@M z2zD-CD*BfjY1y>79y~cfSxh_aRqPIB>aY28IJ;{uFyb}v^fa$D``QAJ$e*nC27Q5F)f+pv~58gD+~k-)Ms3ZM@a?D&>ExYc9@;jF=Zf@yY-h=F<=h^$${;Zs(?VV=3qdmfX zx`Qqvh$ib*y2ZNhwLzj}nP;E~t{$B)N;9Sn5Lv?lSz_<=V-xb|%R0JR(3iS<+E+BU ztTO$S9cb%pUeqB<{2TqJg{@d{{Wi^HzgG!yTi|Gj3j4c zd0DNq)pWa@YEz>oxf`tYnw>h?}l7 z^29TLi_NT{BRspAW(3c@B-pm1FTxYTQwCY?U_)a)O_(mVy>oGwvb?jm{p`-R)@=CS z9!2c9%gFMDO|dsPa@2TH_MMh0Hl`G&##byY?|}3M_`EVW^tRq!ap+njBcc1;KGSEw z4MBTSRo)-_Q@yqo(LafGm!K7AM4 z*x1~J@zTAwwJh&x?^~rDZ|HXT2_l9PH}*AD_`h^nGw~Bd*{I(Wwq=MV&gb;xIJ;>yqfLN8|&*uT=c?JQUABt zXpyqYlXIHwq+4h#5hEmxxU;LTeX-J4S=IzEGEI^03xixmbz^z3Agcz&;06wtW?&^o@123)inglD$qiW)%euAQGlY#i3Rmp-Xw=< zo0-m}Aut1HJ(_@1llEQ=>`UAG+FBL5205zswx8c7e*ISe@R8lWoD!fXcJ;K$*??IO zrM11+9PrTD#KOyryt6E3lT zM=IXSKR;}bCxN-uRLiS38I zZgIoA4`qq>4j2h}R9t(jIi{JjkI|#xr+Yh^QKk;e3p-m@iCLoqgT(G9)uh1@o}wPZ zEWCuAOqzaGPDsS2Yv561o3T~lU5pvf{i6d(&LDniE%uMbO#9}iN>X$-cBGHqymM-z zvl{MGs1H>p7o6M1Yk$6z(`Iq?W|Vy22ldHY=2zl3C1V1EhqEYL zGA!>6Pl2b_%$!yocI)ura>WrmyG?BRt{_pjS0ZvugkD66!#7B*ommi@(bHzRYtuNS z(%|*cF)(lrUu+B+W6sG}Eg_CosLN@eJt%e_CRsiqe%c zJwjiN!D3?n(_S&|i~a;L;y0Cpg?@UvM@$(TnC?d6;LMrT6{7T#3;YA52Fe2U1 zixkX3Wv3ClIK})ScX5jN!wyeMzB$8^a~FarXE?y;%EMY+^hu z)^>@Ubxbc4%^R>1)is|}Y}}WVAhI`Cxy3t<{h4B9H}(VcF03Ek*nsV|{>Sl04$%_= z8DitdSm31YSL1|hnemp`^nJg-0HcGs;9G%7hSk@CFt?Fo<)pqF9u5&=a!gH{xVF#G zopPGLJ3laVe0Y+>$z?lciQR12AZD+aFUw_-!ucm-rR~ziPcN&TDY8G-GU7R$;UyCE z((bO_cDXX#RADC zWMW`M9J{q#j==4k&hj4}*iJa_3Queld&1S@0@>owb576r<`%9sj~hkvc_^K|sHmu` z4cN_myepUjzc?+BD4x5|NX>5VM6ZG83NLtriy|6f^eC}EZJ}Spz1N>3`rnzAEOt%` z3>7`GKI}of*B>u7I`-?rH93$Z7G34Z7U^GWS)12S9hB7@w$9$R7CAkZZGdI3T=9sU zm&PXIIg^o))4Lp%=%rt<3qGx^x<>Ycp0<{*o>p;ma$s2cl9qPcgM=pqR<{=WOBN4` zJ3fK576+p2YEN1@a-4~2Q)8p8ivN41Zgv!V4$i95GJpf!8a%Hcw+y8{o=R-Yaivj7Hl!s?xq2D#fJS1)aHGJvIVTMLKt z69zFkRWxna)SD7su}MS2dQE7XJR`)OkNQ(a(V)3f;8@hM2=jv==7Ea60kagnBgnqM zWpVHFMJ=#pQT8Hcp|?#56pCxU?9UYOSKpN?4sY_5i|pH1M-T4h#zUt)pE1{yX31^k zh>?GLC{Ii%Mc;n6Yw=()ZXG7HU8Mn!xTq9^ZTSlbirpfXQ-dV2=g<9a=jo>b zX8m-O-k`^bO|VoLZ0=lT&-}%AD~zn`)JnhTni9~(+GCnqq?ZMTB~f{p4|2+94$S5* z%kYIpMz)-aA;w<&+A~&aMNS4bJv=T)ti2W+cw&olU_l!{9rZtVa5nEhJ<)~XVrJu< zEx$Gfi_V{>4-k{SnI0=X{|jp1KH48EQl|z^iQyg#XHR>+-=8k}?=up&>^7pKyE*uY zW1FzF-i3OF+RWNBYU^g#a!*E##O|DE zeylQGblq(vWABD5)u|nAjo9uGugx4hNF2E{Emq`IW8eMAlp3da=JM!7F|`dYd`DUh zHYTogCY)+7M{Og+4oeG7?S$c#k#eER8Qr43&Bs1Z;%-TbnA(mb8UjlTxE-a18NeZrGbl`FFTWBsH5hV zKA~P|DS=(kLX0>-NgKz3p`r!R~ zySsYOG2{x3Qwo-Q@8`)|4j9qmnW{ZQ{l}xsKEO(f=F5!40kW>i4;7ilwVni}O;B3HXyr7Gg^-LRQO8?jd7bV($ucvTy(7^obE4YteCX%nZu$+;qU=>2@P=I7`5lZRc`xpOd~s z?h3YaV50`Urn?6_$n9+~kX76sNge=eO)f9CyyMO0Fg!$@{y7}clZ%a5@l9o5u*>w3o3plNkD(IlIqYJWv8>^Y zUv6Yq1g4dt<>h$Y(cUTd<-|YssVS3M{;tB#uI0-p=`Ej{sdF# z8><3?W^m$*{h7sG=29XM;@336F70zUXC4$21vy|B{%Q4OnW3*T=l%_ z5!0&!nz-iXjzrOUvnS7mZPqqyz3+L}$ViQR9KyX?dxYr~yPq*K7jedTd{HAEICtQd zn@dr99wyaueCl9U;(rev=3dVipLHjS)`7K&LM;g-mCNQm-pAyi#YwF>Win?I9HYao z2%|Y>2KJ&yZXb1hfaL?mQ?H1_{uE~;`Nj5H#-72*e5^g6KB-DRdfZktH&5r96L}yJPRim52wkzlI;z%DB&OhGfiB08b(Yh2{ZE~{09aQXW&;g4( zA;%jzn1~&pU!9&A-q*nJ7M@yi;UiZAa#-J4nBm)eVQGq3aJ%P0@yh%}w+I&AjVH5D zBx3&XL}Iq6zwXIwG4N(AQ;r>Jb_)Hb+nnNe%O1lsm%A_{D7gb~0o*2x4Wd3NTR+a? z$+jNWf3xL*)yZUYio@G)^Na59rsj!5Sv6i!|72pGSi9pkuQ+zylX+reuFor8PN?vT zAGaDmi2i7AiW&U$$wV*yHnHr9lw8sMM2c6eb$Ro)JPGjhm6>^>>rhFF81cD?yzIPt z9cuJ^zL)P+^7p3lHL0sa(l+CL5gfk7D^ecwljz+y z<|gA2$Cj_3^5QRc${xh}t^0mdeQnk>JblWGM*L2rUX6`IHhkCNI-DMHXlrJ&I!UZK z=l&6*-n}DFbT8`ki$lRmJbio=Pa$${#@kgTxixuaY)N)@o+yp+T9>uy*{J7=PPgdK zfLdj&$&!kQr~hBk067ov$F_9V;_q24sXd z8Z{#!l!6$x+*cs8@T?49D@w$jVf!^3(ut{P()ofB57LS4y!c)b57LQkI$v|=K{_#Q z0k@DcF(QH(@59Oh%?4(;uL>1uzPFvJ2!gep`A0wsc;o2Af8{;NblpakOB+mLMK^Ny_jvwrSRmvk;nGFncn>`b z4?}!$_NZi!VTP15M9z{?$!e>3Z6Dq)TP?oeZL^4b1h+fHNZdUA7ONq0+L7`v;grqo zqf$idC+a}Y7Zz=n*iV*3+8B;mLOln^$7ND$4SdgfcfLt+<$%dFt};wXcg z!Xo0%MQ~3zIDl#>uvLc``K~8n==TkaVF%GApp@r8x<)ci3`d!ex)lYZk*+E-w*xKbl!D20e{Ug@qr$xV|gZ z>qYIc$=Unfai6l$A&fFz7k3vo4OSl$KbABldpID*;}y&A#b+N~n}x@yXX__I>!Q@tA75wJV-C)(!q|&eVL+VXnDT4j7ra|F=gCuiC^} z2aHoTXK&3F(+?Q&`>r@(l&jJ5T>$aqZ;h3M{`&%dU-1iu10CgKEurWai)!pq{9jZ2 z9c`F2)_?4AiJF&;3BD8Gm=IY@DwD;Hh!9ujZcP){Pv4jz_WWU9v{*HKt5>Z0CLuxe z4c{8~KhRCNVE+G-R=q)N&)u3V?i#w)i~q*%9KJOfq^qWH9CSSQ|4taXAKsC z#Ky51(N2udiYR+0-!J~W|GpG8OYCkS$iI0Xp>=k#h z+!19ksV7xLa{gCZ?6nY#gL5Pme_{W7yyW%vr7L4<^GMjiDD$^_HkKZHi%BoR&8Bl| zZR7F877yR@S8o*m_!Zo`C9X$7RC1 zw|Uh&#r8LzP8QX}pz~EfC3wZq`Fcw15Hpd~+7QwCeL}K&ujpKS78++b7*jty&nqT> zcwUS+)p>KAh<4nZ5^MeL!HbmY4zc^+3E+KhrZ?XzImact*4e}s-E0SO*0VE{CtLcH zYPX{QtJ*F8QYlWQM1h>3zv!)s{yfYw%@W@lk6UQ1m*O?e7h* zdY#ywf!S(Af%pj%UqSq&i8m5IC7#-Hdvd7S zByA(<3={7pwzN;%QJ*&HcM|uT_+H}uCf-B*jENs2e%8c~5I<*PmO_2r#QhOC#CY|9 z8Sw(~Z%zC%u~mpe#Eiu8I!>GZC*l`LRg}XxZTb=7mvF)HSDZHe@5Bd5Rg_P0sxK>} zWZ)PB(T}a5!NdeQ%s0!4SyRhIQX*<8;>ByP|7yO z&m<+Cl87~{dUY1vjXSX>aKX`nlW99}UrY@7UJGkm0dR24_b=v>M>MZE%b#y0okB9? zRpCC>WRXiFVr{D^_>++vvRF$QjpEY~XixsL%~cff3Aro*0f(#+Fl#|p zfX5BmFXXg?h(o;aCnN5JLSSYPP7J31nD`tsF}sgnSClt#pKRfJ++U8M|AW}#&$sAY zloVR{HQYlaP|#T1*>8y{yu`wP$DM*nXV0UhQYdRrY`5Wi7M+DAwzcwa(vg;{;O~f$ zmTgE3?S^o(8u45SP4xo*NA<$1hcyJA|EQr3Q_d;4`GF~i*e;N?48Ls|$e&CUWSRy5 z4rx_OO)T3R_&*jXDWX8&Ik`Yl5aI7MHIqVc0hLaZJSN?=nRb+ak^&9Y0NM!oAkwVK&6J&C9ZPgMgzD zryrPQCzfT$UCIZYMURvpk{P5&WB{iBn87ln#33^P{*M`eesTsn#H=_7^aKS;WSp(ro;8#FnhNP$APQm_OTyPL;kjVp9B5EB6+VgQgml*OhENt_H`mBg-+==ao3oLpb?!-3zSENHI2MTG- z5XuIX#%xt)GkHKCjytiPmd(JlG~OM=z3>SoR={Su(~OXtyTmqq59vt!Jnj!$Jk%?( z&GWQHpM*QHO@G0nm*P%r)1&B<{H!*PDL9GQ!o=D(TyV%f1G?M7c9)fE2c1?T)ozV3 z=z@wr7oP*fokmERY*ykE`rC34*k*+|{Rl8)Vwtfh`(&Qq9x-GOfLm`utSk<=nJw`N zB3FQb!_O0#5{d1q$Sw>zs}k9TrFb5Ze`qC7nvcA%{8s#|9ns%{Ups%=TND89ZlU3OZt8(%-i*>8Gk@ zTGGc^nDpuhdQAkKUuxuE^WBR34Jxg}3hao8xWh_7q1^Fi;VAUC7G`U|9l>)Xf=B*f z7&5oR0dez~X(?y2g(-&{#*&Wwm6Z_@PZ1+AzngWyW&+QP5j@;dwuMGnm_jRwt+cff zJToGA&ap6U=GVX>Cb$mZek%fW=|Y%6iiNctQq6}qq-R)IyGfGe41;n?5e(oYuECuS zlbCKw+6~fXTUgr;z`gcvT*gEx$KT6j0^k6L&rRQ^;1K1hs2dAJj6J8;4A z22RQ(|0l%YDa4&v+d=)~_!+0olnX{O4F`?b_6EaAhoGBqA8Fy6aX+0H{3YNgwlkh) z@zButD263*;+jzj@DFqL)oxu|k zJb$-%D!@Zb9$Eim7Sj*7^EnGkS_LLzyAVHFbhaz8T?qa(oQ0sZdo6qwa2he>)PtW` z+X;Xp*Www9dw~P_Gx2@|NFW}8JAXJ&Y(Nmh#N1-$_i~BZJH}b~THGs$kr}-kv0eMM z7X3`niEa8;(xn{K|5+uqVgT+JoJPR+xy@#gF#EfA6 z#A|WC#=@j;wJX1b&Ga0;nuv?G{{cyor-^>WWy4#|6hgoc_`Db1C=hF;iFo(H$>oN#34j5Z;bSkiTGk- zD=`bq#LOtq!tAYMEzFGQ1;{fK_c<0m3-^TNS;32<;(~eMxli0TNuGiH(K~Q z+EyAnYyx0vCC;L=k7N_C#RW$;PVG)2bNkD`&cx`43P1hUjk}NS&j_{? zOJon06D%eUic^Wf!x|H7cj1CVsvUyJ!zLjQ3r1}7%p%?5VUv(Y$DLTC`jEeLEsS7o zmoQ=oE;xE{lFnKZ+jLoj^&sFN*6xweRP{y2v39SCUAXz#zBq`r`y`alszd%?9S>+6 zx^WD^>Ayrmi8b~+9I{7TdK_zeOe{0la2#uUk7NI3$Fasfi$ltXnzC7c*%vRDbcwa! zm^c|XzsV$<#{X-Ro=G||n=ISHY#P}d7X6F}das4aFMAny$bYA#L;sApM+VG@!xkp} z-3Yp-9?#fkVG5cML7x;sXPkeAWmgvFD=*TJL9YOVq(=M^-v>ReOZ8zyi%R;QNctRNf4A_Y`TM^l~6WfVzB;889GXk@l z+w?ueC{P~m#J0>wB6xml@vySM`1|fHKsa8-X$yKi0{=Mz|CJaS49A_=&fwDsp6@N5 z65NSx`TTU0EkDU>rc>Gf7_bEmieMUMF^z{1Vq1`0%UGHyw|MA=iETM&kZ$qJws=ax zLu|`IP*KIBuVF)fhIp!cAs&YuPVtH>%NOFA$ZMH+g0Ol_f+(qLj*f*S9@Hy%Uzy&V zY?D|^kamALA~|Gnu`H^EOCxYa1g?s}H4(Tz0yjnAGb8Z)2)r-?hgu^78nFKgTyVH? z`XP-rD+gQP!N3`$gU4xMd$!7Il7Bev1r`rw5ZgSbkZ#GO4j?BaI}rmm6E$Ho$qt3g zbkJmnqCw*@aN0aI#NhGcPHf9z?QNd97EcQ9#5T`jR>x*qVllCX#M+JGskU4^ntJ$x zJaN++Jl1*f%QbkSbK@|t`19v$QgqaWMLv^=w=k zfn`HmX{#h%)M~#;4p}7L>}0ZCE&BWj`oah-o7Li>_WW1kf+HIzF`I8V@oe)IsF4=k zjXR5I(?exegcoK970rZ`^bQMam=E*Vhm-Vf3){oZGt8e6eYih^Q=5Vdj)OQ!XZIo2%5cHK z**@tPSXe73RZ%{~N%~p~YXJZp|HeuB#TM2cClxCI+63sK4OT#VLedpE*dpQz1c^2F zI~;Q01%0E1wWlOmnP>^R7C~aI(xe*}eJg^*TD3_(%c5^X5ExU9Gt7uiD`F>t#I}mo zSoB*#C)S=e`L84$jmuuL(ZbKc;P`1k*6dEO5o`S>|89$ZFM`C{e$t`;$E=7w2oh^- z2OI}1`a>4ho|Rhat{YQFM}@kaIDE&t(Eo==)@X@;5f^o zzYZK?z*hCSR>YqWL9D$~7sXfi#E4_xj))eY zU7GAwXNxrtUVt$^bAUG%>f(`s6ZEs*N=z2t9#}^nU*7oSkQIHZj3%Qsuv_#=2&)z@ zjldNVxGDnIMBw@e+!TS&jKG2U5rKsfxHSSViNGBZxZB3!wLt^?;@gFLy>@-p+EKV) z9Dz4P;432V#t0k*?7s>Z94?&1P77 z{h)02dTd)^m7#g3&1&qZhmzE>nx0D8Jsh3Glxu#&W|dUSQ<%*&Xl(q@MTX|jY*uX; z&9Q{-7m76hX|uYA(Kk5JspyUwnk}2v^NiMmxridoHEmYEF}j~)-Ham5t!-8fY9pHG z8Q6MLq`9BX>eafQZrSw_XAZMf?86tAo2t6?JiXNEJ}a|=_OR1BE0uY}%4mF(Fxw*d z8NuB1y6!kbyL>|M8NuHQ{#7s!cwJi_@PbugeUH_=orowEJXbIulXs0D6#TaO2jwXF zN{Idv%wta1jE9^q_frFJTp1lQT!^>_a-(^)=`wHnxjbF)Y{3f!-zRuA)XmpZlmyXDUGogV z*@F2QL06}$>H+f-epbvCH4@xha9hEh)#wsW)A&ds8Y6h3;353}JdLc|Y8x#`>~c$(l@ zf)@y0DtMLPb%Gxk%#T7Lt?SusjW1lJIJwaZ}?w2d18<7KzOXqC}Ibf@6if|m(?Q1Fw2_X>Vnu>IXOUC9@P z{2zy%R`KI9xLc4c!Sw_;72HYi4T6UWo*;OJ;H84s2SlqpB_a+9en;@fg1;5aGbgtI zse-cv7YQzQndNWp2G}ZsZxuXQ@NB_H1%Dyj-Wj*#1VPZu=HO-maYE#&zWZqr2c61P>5ARPZRlGX>8VyhQLy!S~zj^grVv5%H+t zrv&d5yhrc>!LJB@L-4zT-xvI`GMnMx_Zw9*6l3vc5%Z^D-q&?|S3qzD!6kw_3GODi zx8R!uk8s$ji|Ha_w%~<=?-RU6@WX<)3f?359l<9Ae-sj9@vMmWTJQzIKMDRr@V|n+ zxSHYCoL_KQa0QoH{#-WzE)ZNpa6Q2d1z#(;mEaD7y9(|pxG%VDEDjP8!vxzOkk;dA zypZ21c$(nZf*%mPQSf8s95=R>2aH{U_X$2G_yfVG1%EF1ykOpHaGN7ZaH`EWq0X_T ziwJz+qRgOJ@HK*)32rNRfZ(Aj*1{7FjuoOwDmDybZiW!e6TDdP3c+gyKO}g!;6sAn z5&W^>a}HOwi~OsI@L1(VPE*^M#|A>wQgBzn{REE?JW=or!Ak@`Aoy{?yB$_-hp)8a z?}&)gf`1kKw_s0tc{y?fR}oxYa9zO-1;-qACZ}E^qMzVW!FLFrCHOwU>jgg{_&LFc z1%I6`Ca0f81lJ^Sdvs86j^JX!%>{Q6JVx-{g6F%;@~?6O;70`S5qwzialvNFX9fQ%I3cqvqj4jvJYW43`7e|O@Q$G1IrTtxU=9J1P>E@yWqIs z#eyFY{J6u;_&X#b-Vyw<;B$h16`WA9ykud)l?2xo+*ojjib&t>fW1USso=4KrwU#u zc#Ysqf_Df$Ecm#~EdQr&0Q{ZcKLsb{lxH+Ua23Jz1UD7jNpK&*w}H#%|GPxQ9Kp*3 zuNS;U@NU5e1s@fBQt+4M95*hO2aL;teYktgMz-!QTnKB=~p1{|HW~RPHB5aGKyu z!8w{^=yUkOZ@F=G!F2^+CAf*;mV(=>*nygb@!>*ryWo2S-z!)N-XwU3;QfN%5d6O2 z&m4A|^al~~m*8X^n!6RAAvj-f9l=cmw-?+)@F2mrR2Eapog!kE;QIux6a2W~X9T|_ z_$|RF1%K%>%WvkDmog|gTW~eO4FtCk+(qz>f^QZ)Uhp)q@}9Xff*XG&XYPy!_ld|? z)fk9MJ{6*G1^+HMA-_ETX{yTB$%XM&LKG9+Pw)uA69mTvFA}^_@Kb`H6MV?wxWVnH z6R`P1!JiBMUhp4+6RMP#DI_>saFO8pg0HQD^xbaTUPN>ke3Rf2f^Qc*P4IldD+E6% z_z9Q08hDn<4S-)2d{prN1fLZAso*cwm>!;J_C+E3P4H#)Afki5g7PAx5A^gz<2{9F zpx{x0CkdWP#tkEGad3v_dxg$g!H)@kR`7muG9O{Xb`XIK+!NvUmQXq+_#44LkxOlL z<98uXEG#cy30eE>Ab5;mjDd24dl-S69^7VuGc+%uTwhCCC-^m?|AXK^gwB6tT)*d* zPz0ZvLtxt{%b)88z@5liX`J9GLT3gUSE{+q0cU8wPv|@-_zj_dQSe{jvV#?~DxBha zAh$$thUPHk!yI{K!Pg1>+XYV*I$>gxp|BM1V;5h0mxEEQMzCRfkG`I}{XJ{TRbS9BY zZ53mRkk1$V3|ZTL6c>Rnh0=FqoZoZ%5uBm5&)DRK9$=cDa zf)@$iC3rts*TgGioXl{04a`$BZvPWHXUiDn|Dh~^mq}`t8tk4 z2J)N))`K%N?-ugI!r)CZ_AK1qp}yu*Lg#Ct^R3pwp_K7A<)yU5RvSFbe)kx!?=etn zi;Xn0c3LR7jtWjHjmA3&QGdZV3!W@^hTv6#w+P-T_=wXrLX z1IJAa4sIC;xX-0l7D{ylHzJqX>P9mmA4S%F;({L&yhG?eM@BPaiyO})kl_T3BSPt2 za;dFkoDlL)h5QR4|6a&{67tJJZq|oSUAqBt>Ge(mVFq+2B4B3dB@-)FQ?3oFlXZsb z2>CTa-c(gtzAPHQnz(;2%SSh=T)*!>rF7S9yhqo z!MnoX6QOiTaJ0DGxUt|tg5!c86?{POalsdhIjD4w5=zRsrr_%Y_Yyos@B@N33Em_4 z6Tv@|*;pJ@e=&fL&+T8Z`zUov1FZykgj`Au!^jr$>VmH!Yd<#%zFqJl!CSy(2Z7re zfyB8z1J2O=BIUYUy+JOuRg8Cp{4`nXCtp?0g=B48i;N$)dibB=aNKCZ2(8pna38@p zlkwxWT*%jwuXg0?!5Nw#7dp=hep%>$Zp&H!*v>Q1$l>q78JhpFl^l6e!}5$q1Q!af zM=o{ruOe$dJq0fm`pe=BG;s`8fipBeB$T!ZeqQK*AmpErn>v0z17~QyAawo`oQRrY zMlG878PH9TrRvVd-PDE@X&)^_bbE4hC!NmV49&fT&QQT)$Vi9V1RStScaz&X`g^HQX19DrC>2)@38Jf+;kn2*W39cl#w%{gYZ97!RN0Vc$e{5qA$cQ<7 zmr$B#D>-r{JMu@s8Jf2Vofm}8Q6Ybi+}*MLFphxx?#cIzD0L!!5(ZvO6|R8~ zO#L9#B9v?WN`ec7el?+AU+6T{I(GRx3WEV;UA;GxdpH>y33gwAnNGP*c$Uy#CU^r` z+dcxOZ8lszN4d6rwF&ya8+c0?ToC-L;0o84JIxc^O7L}pyMdYTIwU-la-HymGDi6) z3xlSWyn4TQWA z8OGcO2_7eSBA5v@KmxNVFSXT;m4erjwg31g5wV4=6L?qfH^Sftaxcf}Phj`0r$DoE zr`dvQ2(C}=?bu!g#w$_I`0LCFozreYsi&i4RDjJ0p>wOynIw3+;Q4|Vf%*Ow29>dj za$Wj|njw8R;myL}X~Da+aR(T`AdFun>rB5T^xqeJ3e1FA=+7zF34c$fEzAFtFt{w3 z3n|igD0C9Ru5p-5V{DmZddHS8bgGkYaOAbY?(1dkg-%y++k_OKI=ciPA?v;9Q6WDDrhk5+=oICSpSW>OC?&TjPdJa9=wzsxkkksP#8Mzq`=C$<}xJpHV6dZV@~d%*398@np(%VzbCPvH3!Ox!~1c z+U|kv2FkVV6J%}sbX*wh6}%rz<5ysOgmP_sjI52{7y4%ee*vZ~KfQE;a&7xNS=(OL z`gZw~S|VboVQ*<Ki7Dy zFrJ`|i(oue7|#>Ni-i7a!A}Z)8q7@a3s8F~*O@p@wlfhoj1L&lCHPfvYO8X27)(cf z;V7GO?Wl&(=_t6b-~nLT-T~X;lxy2bWcMZLmBL`N;4NSpuYmDR%C+%9p>sy?uYyxs zL!VP8wsbQ5aH~mP-bB`Zwg~xdvi7r2 z$Pbir+<3V>V7w~$ZNbL{e<1iH!Ji5KO7I227X|-rGwUDQ-y$NRU3rO<1&0Ku3yuoT z5nLd+n&5hZ8^lH6TEQ&@cMyD?;GTkS5IjimP{Fqd9;?|d|D7V@Zo#tz&l9{v@N&Ux z1+N#pS@0IYJKAynALcZ{ZV|Cx@Ik?^3qC6Ngy55c&kFuh@P#r)`7f3Q4C4>Mmj!!q zitT39Cpb+oPs3fE9Km^ls|l_}b{}Lc5fN7lZYH>u;Esa32<|EP2El^_4;36AEdpZ% zPZE5W;2DDF2wp6Bnc%g8*9+e4urvO)h=?76cMIMx_@Lm|1s@fBLhwn!X9a)R-pe*q zFSZL_qb`2*P-1tzmn%S@boY4N|G3PHt}eF}jOn9Hex2ZM>a#j8MAg|Jv%RYHzUDr4 zv|}@TWp*k)-1AGnby?;jRcX-E(I6*q*X@I<$I`aBs>h(GGt|jL?Nft?Mda(M%CyE& zb*@|g)aGAMuJ_j82>wCvPlCNB^s^wq=2Njhn?*}9gs3XHiWAKRwOuX|e6`wES~Hgm z`E%868x)Ru9NLLGCbwXn-{LUg5XMm?d2kLCK?F&H6Enz z8n+M;Z3JH@m}?=q`ZoyfFL<=zF@kxN>Do?lndP712EcO!b8R%&V42{D1aA`jl;G`x zpA-DN;J3hWH-UFW#HWHk7kpmu_kw>B{D)vOp}YWzf>X;mZiLGNMxNk8!LzJT_I;A4XA^)!0u6Q55-#OH#~3;tg4?}Gmp>`5$7I7x6= za71uUBBvys(>xJTQ*d3u4FxwAe4XHKf(Hs7B6z&ZoRTKF0q|_W^98RF{D9ym1aA{; zuZ*D!c2LOQ75pAJ?w0;@5%IO)-vs|9I0ZMIT-%`FT*3K*i^=*5UBhyY8%@gtMoYn+ z1;+&U7Tj0xP{AVvj}d&k;HfsV{;|bH#5}?FdL25~tAu>5V0#@8t+PqUpB21M@auw) z%7i}_5oZMdAowT2eB{%u(nP`h1f6^OpCvd?aG_?q{B=Y`vEXKcTM6zgI3~EC;DLfi z2|wP1T~6`kprkoOQAA1VSP z1dkOwLGWzB^9A20c%|UYg0~3X;jlCQ>=j#dPLBwsHv}IOd_wRSg1-^`gW#V8|1J1G zAJTWLJt?J}{erUvR}x%Ru)PY5F2J=y-a>E(!PmK*iOJ_CHvk@Nv+_T&vcCGh@19QT zlUJK=QQ7GwcupaqO0nuZeHhmI+gv$IJ-l*%mU{GXD6499&S3c56MpVZ)2VHhEgDnm*-|xZZKM!(qRB8@3Zq0rVcEE9IKIQ?BoPaj9hY z&R1W`^)xtua?Pcb>sv6xDA&w8Aa2#GiyzeUR^$adBt%?rr-fr7=(%Trb2Zd0O%VJ_90K$(YJT*`Z7p=?pY#^d^K6${WwO}mprVeES$Fhc8d!Jk{^Zt<&)dnm z4=*6McjOO&<8B9ijuEBKkcKTC>@kIs#x)c3H?ynx}-KBy3onoGKq@(TFbk}NT3$@Z*0Pdifwa=CNsL$Hx z%6;VeV6NOpZU7#nnUy?DGb{5J&F#Qr6VWg<=!3vaM(EDTGZQlUqOn9X``b#*>{s_| zt_*%iGrP~Dn%RAL_Ch}m!8~J0*B$<4%}MMSuj>F4ct%T zmF79%?=-IfUrIvzQ%NE4yN=ib{zvmZZ~{6gb&i6Anva9|mL26Ef}@(xfoqZVOv$qy zGTa&0Xl5<)%!l%9PE2idfYsPZGpn(iW>#ZQ&1@#FshCbL*lyL#1a8;NsL7hyOw%>f zKhJz<%aO7W9A|)uaScXtLoiQw()FDFm}VxhRWsC#U7DG|Ud>G4Ma}eiSThUox@H#O zW3scKh#Q~jKmsDZ(Ts`9_+B&f@v~;`LjKgu1bB)=NA8SSZ=8SSf?86BjV86Bp%7(6Pj z1FaC4N~R^YnVOjxPlG6DVoNkLF`fod&I8r^HM6Q8(#!-lX>J96j;!~*`!&azz{@(o z1YXz71h}9j4VVB=iO5XgBh5_UQ_Zcw7s+`5Y`3MZ)rXPj(^HPAqd--n%M;3YG$9f zsF{7@H_hy)mo?MegZ7~x&L2L_9l=~KlycS(cfVxTN>y@I)<3q|PQY&a63tAwk!B{` zTr)dkTg`0C&YIa7W13rmOUcy%*hXkh0N7!qM1GaFU_nWBjDI_8cqVo>4?2ORY$Y}r)zEl=E|tlVOv(#%-wO3=APhM zn)`yU);t2-Qu9P`2hDeZyK0__^o^c6Far^NHO~VN(!2)DC03b&l(EL7_%dpbVN$@J0QU5<9@PLjmP3-+NCxIW+oCe;hnRjjXYOW7{QFBA^ zVa*-DZ))xgKBk%HwjXHbP2AIQ9TNQ@tp8lfYGfp62i06anSD)3#J*MaZRyb(M{ zGjE#StN9RknPx87zee*1;PskM@|N)%r76m zs<|eZE9A0ZyubNB&Ag|1QZqlx{3$sOrEUm(sUrq~ztvm{zNmR9_&3et!F)4;3ETq? zXy!MaGc@yq%|+mDnmNz+)Z7|8 zoLmCHHcm6rGNx#*3yy2%oH5toxP9)oNJsFvY`Nw;z)JH9@PnFHfj4R14t_%OPVjck z+~Yl~`8n`D&Hn=*C0_-=_P-$7p8@9d109hLK2PQxiS2vM)ZwDIeE)}=Uo+(q&D`Hq z)Z7W2uel4jnr2Stbu{0I^o<5O&=1^L^8j!Q&4a-0G?#*}(|j|ykLKav0h-5whiaY# z9;F%6tua>fO7J9boTXWfz}-56XF@YH^FU*s<_+M*nsP*ZG0w2>3j?IRM*_n%PNz)tmebO*8j|Ty>WT zj|UGYbI4#D9oGS7Vj8)vEjMOprhFy2y(3qeDSwj8{W7+vHB)|w+}RczM>JD@lFXin z?X+h5`2R-+Vot=*nrXn*a?`JO%VK@U@z= z!7-lyr}qG1>%|B#9re>prNNqU?qLkqTnxTdb35?unmObqYrY9QUGrG*Y|RtF3pLL} z`o=09ScixWn%UbQ)w~J(lx7}u?9{v$yhrm3;FmSO3qGou6V7{@KLnrBd>VX)%_%(zHJ5^GYaR_Q(L4s+Nb_Cb=9;I1+iIQz?hKAIu>}ZRuOrrj`)Ga$ ze3RyF;31lKf=6mT03M_HE$~Fm$H7xHp8&@-p9Rm=`~}3uA|2o;Sgx6)KxzI5{Get7 zoph7tAegHtvjAc6cFjfLXEoOVzo5Aod`RuCAH)e(GxG%Seqhp9Htod>Y(Q^967Z&GFw5xKRiAfv$m?4IK5}teGE+9j!S4 z9;Z1Ie1~SffHYMzpU|ACxd_blq*;Kv;N_b6uF$#+&i{zuM`a(@5qv`Pam{=WXq#r9 z7d)exPhalSJQMtq<`v*0nm2&o(#-RMnLa_*nLbO_nP%^GGyMnoKF8LJ=EIAOs>|=odaAEx78R>~ z?+qzd&#o-VQ#-~tPgDbM*_EnR@7>;8Z5vZDSGKx8`m$X;%L>tF2U4nKk28rm5|$C#j2tn#}OB~}|!8HUo6wJE{u0HQ1xXil; zF7u87IBI(xFCwPdtmb*HZ|XkgahM`~=4wCEr1>=EjhuX)6a0%{UYmDyQUzxTE)rZU zST*bNM69_^V3~+mFL;aK-GUF=tR6euwZ5wITDOcKuOPek-Xm)I;-%4e9g3Pe1!yd| zo#5_*2M8WTZt2)g5+#Z+19fTko&~YQs`25Zc=DcY-3#XUT2VJ4-!<@%B!1 z7>4eX0J(x|kUKg$4F$In%M}2fx;&oT#qq;Spf1OG-O~;5TBrMT0WWX5 zyj3tSX}V7x@G_>$ymaaEX>xZbFTNiOsHk;}aWmzHxi1>4_H(g}|e@=1d2 zFDPjp`>RQs?Jp&1-W(Qvb%!wCFZgxACj_4rd_nLZg1uIG>BE9^T~@K&`VsdL>{hN6 zo!0({lFnvdAs;4qyx?hq7YJS@c%$I0g5!Hd;4qn&L9p?{hRgQHmGp_vIm$KvBG|x5 ztoyuSs^BcaMdX_t|Hb41hHB6k&!d*ssMYcwH3|oR zL1dAROi(>unw_J%PiUQ`x<8g44rY1EBNJ7R&q{LCvFn0fb?n(Gku|d`hJ($7LbAGa zYCw)UTfM-mrcK-xQO71W4+l$yMvAiDsGXq($kS%s#yN?s5;rXX*hUNM5d|MBlqN}9kd)@Co3Gh zEFvv6^WyQxCm-~2~i*=KstTr8T)=XLFReOKBH==gDJ2@O2 z00lQ=naZj-Ge;E{6noW<6OTnyxMX5DxL9aJ)y(H#%u%PSOwUqhpMKJ-E`Qo6HMn1B zWUDG|UqCHw-QZRE&y0(xt%1C7@B%cjQ?s*?qpXyvNaZbLwD-9t5!LC?_HghIXdKlV zmGBkwf*iG~;6+qWy@GJ?u(!Mvd8%{$X=ucI>v&bCIbD#+m$!#gj6_`wWghLCrd=7foHcbbv($_!yTUvHxG#jd&FW`mdWj8nWs#ZU*OwH~K9UfP( zXie~QtKuouBVlKT>a?&+q|##$%IerE{5Dl)DvEq`1q#$@;zQx!UJ=<`)!m++qb|?1 z&?~m5hf@x_k?Q?NhvliRvk;N`*f7giCLi-tgFLl=CA=N{qIWoW+KoWg+Ny!sx8~sW zakFkFijaM4ICxG(w^uU*b92<@w!SR2J1`gXh=}Z{jx(}&VSinFXZwu`XB)oqw(Bek z|EnrlIJmm1arM4%FjeSuQFT|;$w{1qD-7*aj|V&%s&qx2aLp{J?1nk(Fecoz;mI(< z_-Ai>)g|P-Qgei5bsmLzDHLday*f0tb57z(r0|F8@kqOfS{sG|oXrl^*!H zt+ZS%Z;)ACo&3FTI2cJS?@7H>m5=A;sEZBI5qnqM6j3K<>D{D)Bah@HmLkpT9F;aN4pZq;p7=6@Zd zO-4a1t1cH8e_ivz!hFRQ=6~4c*?hK9nh$f$)$OB>M1yW(?QjjHi@JRuri=TR_D`$3 z)m1|ZH;Yt0ydsrlu=A*$%dAN56$$+U4<}*C_8YG5@9N7*Tz*>R2@4#Ib1h_Cr{jxjuv^aFB>52=A9Q*wA+h+H}R^|_w`S$J3tuU zDvXDqMP)7D1>@)JJXIQiC|OmT;lgdpF>3jcDmjV8P`SY=!Hk|u!gX`Q<^6b^Nagt} zQdv-D*ZkQlQkf=P+%8<$U(pt&JX_{Mt=)^Gg44ooqMH6GDzCA!mi3RS9iL*4*~}_G zXt+a}@7K&p?20Q5$8_dTbq&`ng-Wg-VUtD5ZJ;NsC|4cNy&hv2Vp%=YGRmuGiZWZ) z$1eZ*bg!xFC)^wL^9yuJ;hLR*w_s?`JuDyjlS%MH)i!Z#0UXiuk!kow9t~np_lgS>$x%dYqG`-QG*xD+(W|=TB%XlE8AoOPsxIN+MW|q^vsLD*F@2Wg zB<>F5L${8~#y(4MNRdDg}mf~usaZVtbSUV zIn5%?5W_;Z!jD@+c&MZEu?S(eLY}_D!|OQYO|w(3^u!e|N-LFTVu>2FW-#&zZ7d_g zox;X7gTukQpi%_ytdRRuc5h$Knr4|^vxcM6wKsf$S0Y=nzrdO~~Lb)hbqS7n%+)sTWfw9?KiEXEg@2Ja9t(I?a!Z%)ZcOwGhC zFS~9s?JHb}aeG_@QRAIz`~3<>TMEk$z_+?d<9`)iCc=N@%HHO{#VE%`E}~@3@5kL+ zH!n{^nQ=(PXscbgxwufC!I4)){eq}>)Mt}?87i`QA*SD|ror12EZ$DxlFyvUTph-^ zS!L%+?XQ6$coB02?@iI}8DVFCksV<-D}A%wepG4e6{Xo)uY4|eR`vLOKu+Q)Xh)q? z=KMY&T=y7M+__+nNaZ`Y!p_cq8V3K28L+Ek+hr!=y3_v~b^G2IBN1MaqPE^>RH{C^ z+#n;)htgz4XVo_iUb$xJUck?-X#0!qu08&rt%TDceJPt_*L|HU{9V9ghXv|kxKN{NZVK1xz1TDcK$&(g3%f~I*sY(SHf;7(Xg=4KD6M`@_P1 z{uTC7&2}P7U1c>RyNvySkwG%xI*vX z>xOEne3_Y#BLW9*W!vAc!+~o3m6?&bPusY0SG|E}tL}YwVQ}qt z5TY+1$G=r-=B{D6-amLUZPm}qRD&Mu5>9S-RfB69Hn>`q6kQ+Pv-rU-_vD%1slb6Q zUE@a{!5H&SNPvT5HcpBH&nrp?qH6~)5_6M+mbnC3iad^Vg6XDRDUlv{3O4d$E7fEjra({Zqh9q>dNGf-f@f|!KJ>v%LOSZEG{jW;p~y&za* zr=4hI?T0K_!+Z_@vUuwv__+B63Xl~cd%cRUrsZY@Q@p=1aXYVmFY~Gk8t}4gNs%rr zb*h)?r9_HZEg?JLkMP=QFwM&s>H?A97!&q>i$H3mC(}qr8hCUj!Y?WYGwgsBLFQ3W z-uvMcuZDe&1HxdYm+$yyME+t~D%g6F$b7~`?LcPaQa%D%cA$chbqJGFFvr^#+0HeC zmA%=>M#NhHVV6ot&X}% zHnQ3#;wY=xc%xi1&&TRcUUY?I7nhtYV&>afy4ucC7LHkNX4kyNJCu2f zn87CA8aOU=igc~aQ&XL%FERH9n|b*P9)?-gP_{vH@2@bgf+Dr{PPI_}XiIk6Hg*q) z7GaPE+uF4m4Y2*%+2xM@%U;#qPA_^lo2Y|bop^C07lDr6hR6si`8qEz14sTtL4#eq zjnFto#%;sL8o{n!jxA4w&)NrLwwBjOLI%*nSpimjw>_s0cDXGxxGynQ1-k?Of^Vpv zA9QJ1^{TYkP4L8D@WaH|WmGYL!LJfyKGX<*!JpN0A9Ts<^<-iGi3Z(bz?^$;x9NoDYg%J;xBmn{2Cv2*;C`guAe8D z%_8Q48?yG)Jk$02tTGWN7Ego5>girNwaww`xi_D`M&-Yj?%lKgkFE{9@vl%7ob>S5 zd;xP!>OpiDz8@|(kD0U$^^<^O3BzMQ0PZn;>!9TEB=S~S!UcHoROk*Hk0<$R^c1f* zarD?pMgm_$^;8_q2yZeMxAOQBx#pY4mt2U}^~Al2-Rabu%$Jn#k5Ba`dK=Ne^zl*N zgo)@C37K^uN#Fuh302w?7c#2uAYvs#fkQ>M|yHuFRBVHNzhYkhNyYW{E6#&JG+XN1t- zutLBLRFx+*fRz$@1|GekA^M(G!-;@yVkoiM=8z2yR3)PSs z`i31Y#G4JF5T7bY3vs3hhxS2Yh2|so>7h=j$&AoD=poh zUl{6#nkWkWj;vP=6~bG!P(5U>dZ+<d2dA) zQeS{UQWNtKBxyrENzKhsC_;ELN|w~ZJbEp}MwpKnCbhJi$`j_DtfW?Uz#HIjPHJrj zlESCxy^Waw2fpw-tLwxnw>yg_NNQ)ML6i>fH<(*MDedX6uQ`Qm`|fXhFj7BaOAavS zA|fL*x##=%AKAZpX)LSBCd4H7*$qKLeH18p2{WAGOFol|hRtL)lFuGxW+NStzvR!@ z(Y!`NG_d+iEZ3~F`f@Bk&O#;Ebdn11L!BkpGS9-J$1Y%UZKq6O+d&<31|0iPOH3d& z#LiXMY(qYeVkT#KSdt21-;I0@E6UF7>-!YakFqcO`f&_I`CyE%|9oTx583+EIy06Y z-;Wyc-LwHl9wVU}^6DEv4+*@Z=o`)Vu(IrCP1zDbIYVO*XN1NfNi)pgBuhe#pt&^E--|uWeIY&&wJfv*Rk}Ph7=KrU z7C`B2Xabym7Wx^<{}_rv=bz9?B=&E}3;xeYxD0_lfR76CP*rT_{4jQ5D!5LvR_4ky;vcnRMks}RkT|oc%rTShF#O}lNk;A~sI^r89bCN2F^JzOEG9e2bwrl@cd@B_ zM(zTXp`!nuleDn2AE%NL`4zeG&memud{@;!(=qM?iGLP*Lz3Ma{Il5`vW?un=)htB z!YcUZB)y0!$F@zl59=VdMLka{Bf~_)?kwKFU$*9T*U){?&uZJgpIBP{Pq# z#}T`V|9&#cGaFVu|3m!8Y{U)!Mq&N1ZEfTZgmT3H_(^KnrQX5_BT|Je@dR7K6S4F9 zr0v$p-&172lkcs}cWQ)(a{g_sfv}N#2vwQnf94XM+KzVr;>DDMPQ}NTz5eGbpx-*l zz2GFr%Pju=H1`;}s{_pWp{7)_d)~`V#_fE(LId=?S;(5t{{~;Sc9h-}N^fbU^L8B^ zp9`h9livTF^z2-{XBW?Y1sm0T>N&cyd)-IubvlC|+pe5qoVI(Wk<0hwz5dVmYP6H~ z=XTmg?of1|RR1?dz>PTPWD3u)qyEotWY#0o@Ynw>b+}`p%UoVf@cAz`Dzm%f*x4=e zlaqsFHtx@?q9mh2uD`2=v0Z7x@R5eU*HYAXly7|d2XeSZ|6>XxIVhtwpyeNrL5G8S zTzN74Q#gjAC)iwbI69(y>%hN^-9Gv!?H*vqjq)Kz|0C>qQJ$OlpJqRbR)kCcv+OL< zesp|*O&sMM=|9Xijed$A>p#kti}u4j>p#KviSj+u>;0dw8KN_gkpBzTb#w=l`;N63 zeFT5}za*jjM#9@1_`k6(61^;B+e*@eAt=O!Yp9a1pKPlE8P_` zxEw#D;C&2mlke@=_dm?_N8qlo4?3*b;vfF)nRh!Kv|t}*Zt_PPW-FTiiXR^pGz##i zs@dN&kvtAnW%9t+;GV)j0!9BDsKmHC-O zbp1@SFCaR8__nU_15+INBTtE5?&u1BN0!Zd=<#O!%=KKCE6=XCdswvbD4J7q_n_Eu zV;ze+1e#?<_1M{CAzQKW?xQQGkR9R5sj~a*a_K_eXP4N?+@Aj@a|P{T<$Pzu@xse4 zj+fOt2Z=JSwhQdIVW$7@G8XJXj?8t;Oi%pG^&geFSx0nhYTa1|dKGnt(izo15X;Zu zj?<;JbH<7T58^A573?P3obg`bn@UAbsS zvzODpyQpUN&gZV(+)WP)p@^oKhuqfajy~r->RAt+r2p)#<}Zk?aR}|?ecQul>p=GE z7j{HaBZS_7G?@nhX?Up=^M)Dy2of%yjT4G}z}h?Ddxsiwegoc7Xjw5=P2botMP>G= zovsc%wX2F1{$4nkwx?<^_G}=peXs6=JGSoKdvLGzJ#XmTw*BA^J+F@q?sh}3 z!5zA`?$v3}sjOK4#Jc}~t)A^;*Y|EexLtc18lxu;9y@N*=n+%YrSAik_VlY9`^Jn6 zpE!Q-#NiX}9DVcf!4t>bF#-Q3?P-}Go8xOgarlr4H;)=V?234!EUmV!yR~iKwLJWP z<*-k;F5Rxbv6~w5^UKjafts;9OtqtKE*|ab6!oj2zQdLFJXkBX$+xHFRk7xl#aYo^ zI_@K~nwfZYhWU+(t$sdQ)sHUV#%2j_D7d#ew74{C-l;AfI1qr`+cF_vFL;aK z-GUD~e5-BD^8h#DQ-Z$|d`a*>f>W@+aBVXM7YMFrvl_ep$!Hy&-<~3Ru;5z-PgW(> zCe~2jH&~LTDjhtMp;G@_mYRJ^XnZC3Cw08$)@X^Jvy)CFD!5Q^eZkGtm|9z-!QMhN zM9sW)XH@OKG$A#6o{+B)yg?oJCP&RZ%1lg-29JrD)2c`9tx2GF6t7shXl&Ac$+F2gS4^+Kad(+BIIjT^T7{9gS?jImS&$C15wp?h3F%}UkSdb zg1^;@nn}ufYgts?_FFA0A7@|ON-#}jXl}+SOIK9~wQbz&XuPiw4JG4RHn)*Ne!GxQ z7V_z2^n7kJ!5Nx)ThUGCe!-i_+W!uR?L$iASq8K*SHf_O?FZ=5^|&2_JVW!xLg$>| zpU64^-e5GfeuTRhUG9ox^dfGR`9L}rlCrm&LWv7oxCZv^L#;DH$ZsQ~8*m#B&d@wn z=qwPtTIla}D*0vt*{d9?aWYh+?RB(po zC^+sa6$u0TKAu+UB;?)5NQ7HYFpogE4HP=J2%aqTmkRkRGJe>S?e!lrLh7D#GYaF5 z%=kv=ULs>}$BipCWN79kK{xMyvaXyoveu!l{ex|7q0@k@E609-9=lg=@m4g@fi6O+ zk1)1Z?bOC2h0Z-f=UyRyMDUw}KOp1SmfKlJ&VvBFCby?jEcRiV=U_{K{7YpRmQn={l_Xe54Vhi5W;nc<6e_&CGkpIsAHGwxiM zrCMDGg;Opw1_`xMt-oE5hp5-L#Ljd>!?4HKN_{XW)-5H{%2hB&Zp9OqgJU(+)*1(V zYTDq~K~J4lszqt6n`dn+wG{u&3+j{7*!7+otyR4t5VvZr?&1Hwt<^jHzpAyWJQV-8 zwpL^L|8Q&dBL17FRq*E6^{P156rbI>IX1~t)JA=9bF7wmUYWyUg-M6o;Rwl6wT8tC za0xj!ELJ`7AP%1osghg9N7RyGu{6(xK5E0TShd8NXpZsr%}aH9SS;+B(_j4nxp_%F zeEf;1sxut2wKu62!=cMtd(+gzX%#cnG|D#)P)i|CdOHsfP({@9!(#=W!iMTo>JDn? z-V{~2BVysiH3)Z7505N}s5jC!r6qR9@$zlzQY%#PZHPBNRnterst5N&ydKACZBWN8 zmANdClX!Py-T*zczG`90-ln)of!MaH%7C7EiRW-?b5iy2=VYpDM#jqTXj+$hXC;(0 zEK#i<_tfwl+q7rJ$k;XMI2?InN~~4M;Fk}D4|r4kxagTQ%|ucOW}DV&2lI{8YiFW6 z`LN(wg?k64rb4G8btbB7?~dgK`#WaWQZ!19xH~p1*vl4eON8jvE^6@9SVcAco>;2- z=kAylyx!4&labe!MMevnUu=+&&|pZ?BO4RSlIwq+qkIdUSEF*fgp2vco=2y~rh4O> zP~zRFkF)r-#c}H@WcnNYhT$;z1^jpcl5xD9F$3d(zs1;Vxy%=0U6%jb3LPoGf-Bj^ z{~?ieaKumOa7EW-B+>{!wPTc-yQW80*5emv#1aZOLga<25$bNNZVd+FuXzCX#8O|z zJaev+8ux4GtoVaPIMwweAH^t6Fq6K-Kkrd!deXb%Z-VJtj@=LLx@1>HL=xCj;VL>B zfO}w`igl>tOT4>)|B~mT`z3f2zmD)<@+`PY^a9?EB5e8^;Ec(86jOUbCh~*ZH7Ee? zXPJjwD~ouL!3cA^}q))L-pw2BcM zvT9!Yq_8!s_(( zW%Wl`o4$BI)_;V{iTe6)M@mDto4_}K?!1#( zf1?+{&MBwwwof6p{;3QjYbyGPX+2)R0#-rh6AbT9^mF?@=s5Z*>cae3YWya2MAI_S zpFLIw_B3k`9C)o4;6BlshK`hEasAI^>sO2ppM_^HQ59U|*Kf6i%Yao8JuKCF1{D~z zrlHA07S{nuv;IRBg{>f(&9dfWRLrpEqu4VoUd)+g4Mfw5V1m;>?&1If- zEoyMS^%7cTfwcr#S!nG+GWS{w(SVDrR>$zgo6EJ@uc8iYmQg_wjh=}qH;d{tw7zFRt^01 zSwoRdhE*9B6|8mm+rqjIRa#KtC{n=k^3 zGCzY&%8wj;>4x{1x@%!9H_r7;P3uckqsJ=5Wi?bdO7At2#&RemnsebKsg!>6Oj<_m zUW{80=MZ7tk`Iw}3S}^@_3)0n1E0VNZawgc6sTR z?$^*{fpovb>`Rk+aA{b)RbyIRQH>t!B>Gc=H3NUWRs*zjqLEY)?Ub_0tOkSR$Duz7 z;F}9bF;eqW9yX66oW+lVag_x%5iU2DRQ5(*$yRTW#l99s2%WSZNYd- zdCcTI?9XDyPkG#AO$Ll49;BvhF_~6sR?0TB0%EheBQE7>^E~_-j@#|FCy(QHhaK=b zo_5-v@DNPWt#q}^JV{p-Quf$4OtQKml(N@0Fr0ksv-9C`te>~7u@~FRs(ZmKK=P@P zl!NAM=3^exPdTKG?R>v%>!aS^Wzk=;Z@nPjubc6=%M9Mo2K(69Z`uJ*)>78TTXsNa z{HT+0BWVuv{kC}@95_SRpYu7ojtf%cp+m2}`(aJ$=l2x3G zt9r@SlL+{%+b}dzEUtLzx4y;SfW>zvQ>{BNR)f|T82KUVH@Hr-479stO)W$>wu*7A zlwr+6*NRxrV~Ay1ToiB4J58jW#N%esJ~*0y*9u8#F) zRopE%yj&jJ-{BPgrdLMK!o96@lrM7yJotP3i*amZdXN==&&Pq@>PC7!q=TDVT(j5F z>Zi4k7k__SE3;7fmc;Vni_3Iw7COVU4*d9sKb?S@&HNX6^pEI~7$)113nxVLfI~{|#hgq8JB)5g5;x5htJ|lf0DjIjSxSnmM ztrVw{k;$>;pF#Fya%lNyI>z_1nP+i=O3LJ@@y|XFoopk0pIsRXXV8&dWs5{!%` zaaW6vm^j(kNaMIJ+{3oDkv;@H8h5pL55Xz*7DgDEg=~o@*b<&hJFidLZk_x+MfN-S z-pYKZW}d=6!@rF+5H`{iQDwNR)tydlN4x0=z3HtAada5}^Bf{haxXZ^J;Uy_pXMGT z{R0dL+|_!3N_GXl>=fJ1$161O8tF?hf^b*sr81>Ah07HaN9sjZ{x&P@#wR82J zT|6UwEA||?tCfkN;qiBR#Lzn4%>=1Xgxc;f*@RDO^_rsr@9Mr++_W#T( zN-{EVSBn=zvYoqH-(${-oMF!y$blMp2A$tOlA|%Qhh1Vk2VI2sw*B!b97B<+sAB&d zj*iF~l-|FL-9Dn2!~^WOkvNVG{Ex8bMZUmv=YN|0C^DA1&$6>bZh@`;0Gl{64il39 zFxxcp8oHDJC|fSl0QvKuVEaT`Gi#r)74W7t`3u%{gbQf-zhf;%eq(q0WjN6AE~*Ot zjdkIDhZ_IQgQpZPmrbbnF#gz6bWTN-CWk>pu_~PTI}ojg!DR8V5X0(-LYh_r{(3Av z)SY16$Hip5)(JFIqE(GU*II#GC0kqw(r2xPYKrv*yRtO|9s<@eR9`A`%=!BWI#bAs zp{J%<#|x37)e-e&S!dXSMmks4@&t-oB7J*y43x0l5Ood8V+I=X0k6!RakO;cYGxiW ze6A!MXuR5vVMG%b?8X!*3A9TO)CUC{!tdw$&Sfvh;jrv)2}C!w}k@N@em;aOJE|O z-axDpY6q^=TPtFflev~A0~c4sqJ1Ag-FO2x@(PWUmVGpC*i%NJAH8Ed--4m)4GdUZ zrZmt=b{?VwgS684WRx&4_oTgzVeGmBQ+ULf>Uh1IUNJFtM|X+@roUh2^d9Y04O$h8 z#%&)ng^yXn$87C`E476K^J*aF+O5t^t@VZ)it$^|54XoW<=G5Ld8JU}_B6|;j|QCi15Z*31F$N_O(?L95BtFr=7zx2j;j-F&FzjWUS|*NASY*@hh|_Wa~{M9 zOyVJA^&K z2OefK+7o=>aXu{&*~)r(imed&6FdCCF4nI-sRy28jT+vn*f9k5uzpg!6VYg1E)bgf zew>((VH>>Xb*Lrt&n{#wu1|TA4?yq=1i5noH+uBk9;(l!|E#Z3V8dF&y0@02#2zaL zWlOLoBN?yZeFg0lx|-IZ{7~yY*b`>*#3|H<#zrR3n?h}wqSrpM3$-IB*++KqPOwdb6>+2`!=A`#YwX&;c9Y_W@su^Q+b&U+By`(6p~ugw8S-M&{6bM0}RY zdNaJcP>G?>x6#`ylsxncbwU+F|0ZFc&E#|#`j1|XEKY|Z!+Zpp#Cg-xXy=e=ehI_W ztWbg37V23%dASx=B*hVobpjZ%Ws9-_tydelZLCVa&oyyyrs^W~$!_?KmOovcPid|%0Mrp23>|%92ORMUn zR9Wi$%`QdBIRM=H3LE2%dzy@pi-v3WG{5rrdz-^Ff7G!1NP!w{nx_eNUz0J# z=_-GIvun+k5K76l`ubikUiA=D5iIqbgJHSDwStD_Ha+H5!#do#bI+hg>5@x_D75J>UN~!*YOyo zol^BYTGewfn@)t{pEC7+%uH4mCg0Jy+{e;(i7htU@ta%Q`oYX znvF5xGqtd)gR{K8W`s)7qNDcN<}wN-;I`z?V*)Frz&W~e@{Gb>soJEKJ)Pa*TqP1j z|6-6sylc)r&%BfR;_ZvfTr7aS{=H7AFuZ!dSjE)D&Fg&8n|+D-D+QA5_2!8bP?d0* zj*s&AawTnf(pM;Hbc(|Euy&|hvoSes|xlL6=GEd6v?W%_-^E}GF zN43UiGEal-dsRzI=DC)ApDKRxX{Z$Ye$|MQdDeux#}9*Kgt$qSy~8{Jk1(#H;GsCy zM7p|wpLYRx%vOQ+7;5uJf!$Q6PWfD9nd$^8|3U=YRHsn|1KK10W^4YgZWPYIv}bXIt?a!qll{Ci=D~dz;&E@Z-92=2YyajPJS1@Ug?Q{bu6*&0JR1urM zd37U_ui_|q5dR*n#p_n!VkvJRbT^d_Ytf1mtp3Ec9H;pU<3I5+FK-5s_u+yZrY}BR>j-ksk{2vx>fNzNPeaQG|4(EP>LHR8-{>X(FOl{LrvvvY%0yn zJ#OQsaN7_i3){F)Z3?%6;e#;T^;UA-pxT-F9PkkurVbj;Rfbbh^(Es`K8j!3#{F(1 z9wwNMbj)%nX1Q!F==@C`&6#Vr#2~LqCkDr;|GYAs7<>)?JE$G;UIL%KKe3=K!a8Fy zn%YZ*=ICNBU(8o@TuW-e`5W|RBNHveeR^{^y}LHVwR(p?QFG>_R9J??Y;?iceiY%O zE*vpOx9_Dm-ggsk4HsH*b#B?M;r!`4*yP`&82UHFo`IO>$D5uXyu4wg)!|=WsE;n=k^^^?Iw10Utvx`wS2_zNk>hTyN&GBd>{-DAivwABB z##`E53=qbII{d3v8>&vW)GeDuAefD3#Mmcm_FliEIObG~i(ji@SP4VRK0nPhw}f-d zQ{3Dw;nvZcV{)fRGp8#v{V)WZyyX-D$6+?U8snbpb0cuZId%9~{Uyd)bFt#CQru|; zei0V?KJ7zyG?!Xj=voaEJ9k3>jf)^%3P&3zLdoaok!Dnw>>E=Ol_sx-kWu|TLSn8H zCfCHc*Bxi_k|vXoyCr53_N$lBBnJVUJ>f7L?~5t9);EbRW87Vbf7Nj;!gug->MzAg-p=kp%9PyTUoMJ9RXS0bF&O)#?|!gAg5XBK{%GJZv9t3{Hg zOFF?mV|Rv|yfvI3S67E$$K8sp;pTDg1K#J>lgd@p%kCmj3+Z&p0y+)wMF($G#JZ>C z63|v+3`y(g-nBJc7-fFvdo&}5PA-lTgSR3?C#Ve|rYYAzRBxCx8>eEJ^NK%B6=6Qy z8^H5PbGl0NW}Sfr~dNAXoKPVs^L-Yyfp;FCVu^6^9k!*aR)Q_Qeo4_Xwf@;ncOQ~ya4`;gd_u=U#=9Cp6vR=sBvn(IRLVf@uW@8Fgw_daTP=)kF zhFEpJk5qaEL#$$Yzz?z4Ob@EQcq7?WGd-kY`U2A4u=0r+@0LCkPWAfge&nc5`x}4?aAJ_RdJX1pX(r!-gx4M6K*_q|97C-UcUj&dv71_6 zJ*t+sHHmN}AB?XcDr%v{v)3{%33)zRRtFHD2QU<%k|4_2VH(j?fCB_`0eCi6wg`ad zS!F8$c;Zxc0RYd5%B}?9=}y@V06b+WV>ja2NZED(o>7$T0^rF)$+G~X`x(Yr@EyT0 zD~z)DKspJevgoHk^ME=Z2H*;qL0k+x_$v;%23AOhv5}3Zu?k`Csmg8ySoX3cTwPG5 zw*tI86G6I{x~3Hf@CUd+!=9*jCK3$jGm%bVXd8fIStSC1>waVKOi6%>`{Mk42+vbE zWVFVCy*Jdde-tv*Dav^SJVj{$sP);@S;`hr)YQ1M4jb&ai95sPlg)0P1;flx2Kden zWncr8Lkn(o^bEX0y*vjxKtKb30@V6!%0M~>AT>eIz-R8&JHs7@(OHI;Jp&i_7Qvo! zxIK84KJFZ)^eqOc^;wlZo}ZPx20`i@=LU9#%c3c0CY8K`Y32p`AR>H}sB#&*SAO6D zu<~aAe)W?7&=oM;a@Wpssaw9+$LjSOXU76FYe1E}@clu_O(Qo_q_G`igF_(-^9 z-WZf5539UNUJN#?14Cfs7Vs$}uYwm9VVHeABM(rwsu}_s`5vIwXH!P_Q$q>g%uFKz zXx1hB)P4LB+>^???$3qFXK9lcoz4D%5wO`3V(Pqjh^4D=SYSJNR26c^K4ter0@_^; zQ0ucQyL_IvWE6yHx1q`IbdbD=nmtNQcfzA#d%-}^&g$p&t%gAykd~nI%KTE_d?e7V zhc>^_H_zwFmHBUI-e*wx&0nPL?1)WI7GC(8WC0Pb)sso++<1B;?H1!Vmx>5 z)gm7RRyO&Jud=xxpw?$oHu=(wl0UW0bZFMa;WbMg&7O?gQp4To@fn@q z<$d$yz*tmkAWg@09T-&M7X=;%kE+%d$W)G;K)}ME0#NI-Do6NA)RG1Wv+x_69NF09 zNH0|D?8n1)v=3-p7=7TeSq=SF)mmJ>S7Ee9_G;9+(TV4oQvfdS32*rehk0gT5(F=S zG1Uq_1A_|L%D`gqC~t3~lWhDi6VTfa0cw5Lx|X@f<2z4FzJWB|9S>0*w?ABGceqvD ze&jswmhZ+rEqoe;BX4yt_`n}l%vFKu@F56yln=#0?ZX9uT<|C#vXH5K7(hTDc-vU5 z&#EG}0F;sn2-AhXnq1&j8n5cCgrZXSx!qwWNT~jpPtNX0t?{SZ-C0Nx4@tr+YmS%JSuX0 z>4$QxCjlKB4p8f}D#vDkQu0288M)Dr)P8*hk{`L^Qa5`~*omW{=g&eu95ey`H17j{ zcD98-HwPBOpQTWzI$#mb@emR``0sVVi|7J_^dJF!;R`)$eKzIG2cVQxK#;!t+T=@} zd;cDEdOmo>MawO;$)C#1`vc2h^IM21n~Qv#4|_Jv3~jTFfHwO9)cS17<~UGFmTQ}9 zpjnrH9Z0%f)D>=Y`r%Ka)AOQB7dSDb22O0jU|~KQI1f(Dg&tKAo57$eVt1evJgOr2 zqk<~@odk5`F@Rd1RXOqoC?#99BWaM-jy%%jNG&@3z9-S?DHvmXz$9o?f|tun{sX#C?!8ZkTvsAN|SfN zkbC-5;aoM=x5j*;O8#nKKwqfh#oejYN#&RL%5S1_pH(S;fXdrLn94gsQkT4&d(c-s z54kN+DD$1bL%!%W*|XGR;F7lNX3+HN{)8yJOAPXt;=~~D zQ%MZ+?vunI?;=SI^2Ue6AaCAC4D$E)#31jnzy(8vc}GZMkoPSl2KlRaVvx5a4DF6? zfqgG-fx1=+@y)~D8mNB*Mde{X z7N~CtIUe@jK>Y^Tf3)j}trs9Z(x2NW=HGOt7t z0Xc0(J;;e_zXv%-@IpHo@Wsp5rqOW>N6>8^nPb)G9^`|et(41S_TyAIvAoGJ3@PU~PD8F+Y~FTDWtZQciFw4wRQ) ztgGXUa&5lSBkqY3kV6<{K1r5Q9WzP;9$U;P*Wvf$pzi1`L_2Z7D8JY$jx$Q`J3Zo_ zC;>TyQRaI>37ukA*~C1)m{lf^D$y7Ti*r0qhE}Ew5~Qe>H-%qplgBy2r96qkwokH* zo-xx9(rht1qIvrbfXne4a72{}qFZnv2K-_lIL915!q+nT$4pno_+qA;2G|&h%iPsClnH{1aKJRb zI0heQn#?2$(>@80$qb2^J}1T(vm?fHztmixK7d1+AlQWiruoG&|2WfRCQ+F7NtRIy z%TZ4)=M0Z8W?IZ2zUjl@`Y#S;LIE|YObOtNbIft3$xNa!?UPW~CA!qG|4WQ9W}8dc z&b~r|N~LHDzc_;(XNb%s3PU~#hDx;|tbSvBF+1}@C*snNuaF?B6iwmRDxdBbpQ~RI zg(05=L!D!W_@M8qkh>{wasJLdAB7W4bK}kz4}{M)Q#T^V|J3XpekgoqT5B^g)i47G zmt$LKGhikrtN#J~-x5kpbsrs&l@kRyLy=SP|Lx_8%$1z?hO{s>z5e(72W9?Cf6spm zmXyjw^*>YnC*{fIiOmethOs0?qv7Y===b6NncM!Z<~_Ib58*bwHZRAPT6C~U=99l0 zxM8`r*~E2N$!A`^91o=*FaL`>?FX!;*Zy5*b^QO~`mtq+=}JpeK(F~b@0ZJ1z~g*v zjMu?rAr37QUdEd$^0&JGg)`IN^F^Bs+${~fB}F~S`(?gY@20Z<^0Gu$tsgQA_=%lo z{uq8FF6;l;Y|dR}r{`YXC6aLUypgFpPdXOpml6xx_{b;Zs(85 zBl67u?{<0_sUsH07yh%Rv4rw;+ynS)Oy6Db7fYd z=~oCk7f(K&YZ!j0hj<*mN#X*7AJU1>#5d?w#sx^UL81T$XMcXkL_7uG6z0^-59!1M z+-Z9w*hCCTW^=ydhuOrV@J%}BB7R6G=EWM)IZ^OKI`I&ElYS{M7Q%|Y9+=lSNaqmC z5BZ6CX#wKNWa7jQezMA?joPvgTu6>GknOf&UP=4#D(!c=681xL`IYmZ(Fd{0v@6 z^6?`A2jQ$w?D8bU`?7bFuB-M}&C>@w#6AxuR?UNXxrzxmQ3odC zkaKGOnXlx8h>hV{X3R!(cXGjG9&v}QRU!##5lWewvi zfvu3+_uLUJhB}b+^VPKu&CA~J)76dTnqDX9g9IM#Hk^ym?nFU4PvA=hrnA24EdoCv z@E(C*6Zm6+j|j}Svq2}qk56KJlYuOO`GQm5a8H2;2|QL{?w;lIpC#~Gfo~A__W0x` zfgSGd^AM2NMgHdk9~PMRB>8rJ75Gnqg9%MMNdl({+(O`74|@SA5E(@RmkHcWV6{2z zAQelaPSDjxwVFO$&_@eAQQ(sjVBas6PuMv2izH~5(4 z-{>cRZx?u*zz+z#OW-F2=G#AfV=oK5SKxgD?+1?h0&4px9lCD?(=ma$O_tBk?MQvx zR^SqWdk8#I;3-WwYRqj)7)u3SCGcee^8sYv@D_oe5cp+*_X*7X<$c*B3VZF(_+4bg z<8~OIiJPVRxUIk?0#^$>K;V%AbB}vp&s>3*Mnz(^z?TVpgTPw^zF*)c1b$iIeFA?X z@DYtw`F|G~a){s#ufEr91uhY|THpZ!^Y$NKcB;Uq3Vc>F21K7}jmWrM;2Q?lulqO;B)8;GU-uyl;7r3{;g9RQV@N74K zEe6{21nCliw+gH_81~B~=&uO8PvAoW^ClwSMYXB0)??w<9?(0f(UM#0`%Kva7YbbF z{#>(H<0}M+JUT;O7N?Rp7S-eotV&oy<4$slZ^bLw$Olz#Rpy6u3^{;R5rPBVW%fffsq$8)(iI z85awDoxqy~zE@zr&(SyVqQKm0!>1n<_^`mg*|6_3#o>1^A2$=Yjli7*t`hhJfg=J> z7I?0}OMT4puksVXmkE4>z*_{qU*IPMR{Im{=B@T8*7#$=^R2+Y1IH#hzTCtwJvUMI zaa(~)1+Er&fWX|D&X=7c@LYkHHsPqTx+!5?Ch!dcZxQ%@fp-i1lEC`}{#f8|1wN** z*ZzzUe*@LwN*9?aFBQ02-~j^jO&PwPsRExW@Oc7XoGvE1YedE^ z0&f-gA%UM1_!WWo34BOkzBk-=?w1&@#g(Ltri@g9`Jz8xpip4m0p!zry8SN2NY9t6 z`J_n#&l30yfmaHAnZVZzyjS3T0`C`?H{!rKv7DKhwOL*F3__q6!f7C1-X4sPmt zlw+tMjTiV-fw@btuWpUNmkE5mz_$wgw7_o&{Jw|1&iIYU_)TEGr`I=}D{!&ERRRwX z_(Xwc3%o?&Rn1}FH*k%}xJ%%N1%5{0y#jwE@DBp>wj*D^EpVZab5W07`~+}~!1Zpp zRkN(THvk%*Sg=`&?al>Btbe|VD8rJ ztGig>>jb_{;78ou8`@;Kcdne468&1x`6_5%kA?f7d~6GxBX9?Sy9(S_;9&xf7x-ik z^G6B8SST`92z;Si^JHdL%bNvhtH2Mt4aknZAxMV={zl;61P;~4Tj2Wy&!d9AN6=pq^w$Ob zJwg9U(0|DlW4qb9$#95xfLD5lSUcBJ@U#&;C4%0C7-z}+j1_o+;6Ia?I$8czOz09{ zAegQe^y`VW(#HjUNAQ10tR4N5SnK>o@cb_5{9!QaD{Y5_kNXho(hnroN=FiFrQ-z8 zDS|$iSUb92;M)X#mDtl6HQr(ZCtv*R1J2O++a@OC55bes7W`PI^3#%7^A{6qN6Q6I zC2)r3=Zo!qo_d9&o}xueXr=~Y-94^XOdik8#8@Hnvl*C6VtyVK^k)VC%fwiy@bfzP zHU3=id><7|33(9EC9sJx>GG4F2Vspn0sHiB#G1bsG3Fb7`sRUO2s5ABhYk_*tEY3|+?;5^I5Li8ar?0zV`0K7kJsYuPV|(e3#8PabS(9L(oJUnlJR zCV}R}sB?Z=0%vI4Rq*r^JkteUBzTq)=RpZRD}gie6f~}l(NX?eguv~@1s>B@3TXU{ zpuZ;g-yv@2@xMoYjlUB-{5{&|X-2H0l1&`#;0fmL9OWw}{EYjBz%Jra&)DM>(D*IV`+M|viFIi{7W6L!{TQ*9 z{S%maMnl{#RC-kVGqSvd(po^Q1v&ux0_B3Io8TEN@JxZ13A~0_J9;s3nOA_z3SmD( zCvIg%e=p-sA+STxcM19{#9HRN(ssensGS1pZRsW*wV! z<_KItJjg3pAL2?q{?{RqfdoJGf@wUlF3n^?pDpO~1%0`|7YTf=z_$u~Pe+db+Q3sH zV=u9GC;_9Kj|&7Y5qPY?ClTvXo=V)!E7)nk85%E(@u2?CXF@x%E|!4@IRyQBLBCz# z2L*mw;Ma(?&Vzz}gjhS#x)?aB6Fr#FxK7|x1ztj|OLiV{cduk?fHO3{Oz>P!tevnDJh5NpF13A!ur9Rfd0tPAj_!2c1r8D>+Tr&8cCz)?TrG?8(Zz#9d=OW+;E zIx0^P_wYjcG;oH-uL+*_h;_j}Y@$bvFGa>TO&P`?0>^i55>6rZt3%Lp1-+x7_Y(A> z0#79F;k7?wu}XL)xJuw{0zWVC8v-8_IDo0!k3=f5b~Kx~+S8v4oS|{Ys9@?!tV7g8 z(EAJeU_l=(=o18emcUB{UM=u?V%SpUzeQx+Bk*ow?diJ$CzdzSdkH*7;3)#H75FlN z-ExlqIz*e9(bEgj?Z6ot-%q;cd7M~B=qW*eL*Neu{*S=F2^^1wj%N$y?-@&Aw-91& z>{Q}jo}f_|%@KSbof zIyVZwwjf>ev=Th!0uK^6dY(vJB=D62ZzR@Hxr4a37nQq#GcLXJ5DnGqiATU|)EE5E$y_KX7^0?B#;>T+P}5I~S6!%h4djHVFQkHU9?i zZxuW{1b$p$x6>UXa-!sWUF5w@tlj)v;1JeMK0OJT?mr9J9MW~r3k5C}xPn;g><;Y9 z_U$H?rzZ%e@d7Uv_$)1a5Qe$1^Mi2-v3BALLEj+gw-Re7?f|9}RVJFp4#D)ez|RT% zGO-qZ9oQ4bE!u)-zu-9{a4ObazHBpK%8oP%sXY_A1l;J!7wD=5xFJqo!82Ik zkphn+){dSCOk*;R<{sFomyy@NJ~)c6Tqac668Ee_ZqP@!l5&&zl0j zFYp248gF_uK0$)UD12BjedjTuw(;mY7GZwL@&#@WOj$ng%Y7exM|%=$NBax@L7Jb> z?~bqH@T8fh34yr+pC*JC3E>rjCn|WZ68Ij0UlRB=U^=}tA6|UO4DH0{0v}P>{b(z? zDIfghy2s}W5kmn#Ed}l=a1AhxY=mr>bZuk2z|#btNvw6w1@>hZ^$^|kEWvcKz_$y$ zRSWY0njNI;w(|tBcH#xW|BB}4!@lndo`W%rYWgacz;+?T+SBiW=_!SO7d!^mRXz__ zgFfyea5rGe@`;`r(zT;Qh_$1mh@;xrI4!`(foBP(g#w=~@JeDWy9$`bD0{Ksxm@sU z5_q@3(fuOvxxiloQz;)e`hj#^f-Lwh` zU$|B<4e*#$W1JxH5`nJ}_-bJ4;j>VUq-&?|Al44uC-@)iiTbAiA6|Y|Fuf-5K7l_F z!UuqT*)IjpH-g8&;?9pyYk_Kkwc(^i3>7x-g=KL@5FK38^xbnWypV(oMQD@@;TJTUqB zymS`n9#7QBYf2c!0+$hMue$>K!o3Ago!}WG@EHQH7x+qG>fu9gH;_Jv@yF*jCbZYv zg~0tA?Z52WyIRi z9)iEO=I4Xig9Xn>fln0pBx2}S^j^ z*E5K<*Yk*R@Usx#6yOu!D@fNo=L@`E;09tG{9KD~U-o9fb1Shw{y)qF4u0Mfct0?O z`9%0((zW5A1pZUtK;I@k@xZ=p8tGcLx!{QwiNsKW!@v~g6XH`z*TS;}K3(9Y#Ng*= z8L%(ATJT&bcy92p*Z&?C8Se`GtH3R5n+$Xo_)=nBeYXnyn814kenH?@YNJiUdqu`O z0)HUz0f9dk_-lc`6Zj{Aj|u#zkD~}zsIJM0B!Qa=++5(+0_O`{EO2Lmy9?Y?;C{fd z+l2>;jNt;06nLV*Qv{wV@LYk<5O}G;E1PiCSk;s;)(N~`;A;fFUf_)a-zM-jf$tM| zm%xuJ%=qK;OkGnIyddx!0>3Tr2Lc}u_zQvmBk&Ib|03{TQIQDrYjPr4U`OCAfm;b& zC~!xC%LT3!xVOft{Iw!uu)y^Kj}dr+z|#aiMd0}YpDys(0-w_l@6hr4?i!JCp}?05 zeAUiTJ4bxb+gyg77Dlv<@~rOCG~8x^afi<|U#0Q;z}IWcv$vZyJ_>xB#z700F*I%t ze4oZ0fFIVlCou0wr+#jc`i#ar!^7R_QI)|5qW9{I@xZ)QodVnxfE!{GbGx`tH0BA{ zR~qwq=%X610p^x`_>lGm8uR>yF9s!@4`N5J(uwPk;QjT?;Q7kU z8gB#U%ScIo1bC~)uLJYGd(ycB=}wJ#?!tTUN$11b&uaWV@XH$W)MBrPqecSOk?-n^ zT;LBi=IO*I8uQ8RuQlcl_k4>X4RE#pv&O@L|InE4FtO4-o`t~J21N0%1a>s$>b-e7 z>Ys}Eba$@KxE#1ZW3J4LG`gI$Z_4LSwFRS7|&PnA?GpXFBj@8gprSwZ?ps zd;@TlOnhI&MxDVm=p7ng3(WTqkcVr{9U5-~epKUofuGcv`&T@#@pHhhYWzCz+ZulW z{BMo15{w!Lbb`;Gf3EQ{U_P2a!`%Dg2aVH!f76(&xxX~#Bk7?GkG~UeipJa@BVA)Y z?9Hbas51=QR^bzHDu_gToxzn_iN<_}y{pD&0at6h3b>EP+=0??cjs4U?Y#2W5qq1( zEjxs})!jwI^E2GWNJ^UfI-I4#X)8g(#PPY5h@ccse%JvTBIqQQR z(%k8xc0so;sY9lFkb>)xo#L7!kiDPTdzaP(-7A^hB?Z~ntL#zCE}hU4GR#@UoZD2+ zCg$9k5~&W{_p#v~8Ij-I-8+9m+I24t54uP5&dqf5Qo;K;c>B2hBKd{aEx$47PDzcl zGkZox}OqsHy%c*(rn1(enRIeM#4t54I4#Zj*bNLI;OfI z^#)VJZ=as#-j^{y=;jT*ySY1cRK63aLuT7i$SmE^KEdtcM7jiqgLFDc%bZAc+(f1O zsZr3~_(es6yB92RGePX)HX99Mb{d$jQRx{>?@vT@mZe3C;+_R@x_iGO?pmJazDQ!b zPbq1R0cS!pNRCB%fjf%n^=q1?xvR|kgYJT6tV!hbaW|=)lylPDUCkmz<{$2%W|2r- z^=FjoHx^Pu(xK%xq}RF)Oy{nJmOIm7s_1hv9a6;PhBP_*k94TMM&(qD1ABD_ z#Emal_p6y+$8JV_`UQ$?#uiR9(HqD;QPUE+NBLd)otu=4?`OYvC-M8r zAKb0{e&$sN`j-zh)48~9!Ni~BXdSN`huYJ=~_-`q?1{mwD>eSYWu?sjU6 z?{s=)SvNI5QW)3$BupCa{nsX->hsa|PdORCI=SYD9WvZA zkhbzhxoh$x9pbJ$8xxJY={5@k0r|QtGSQq4or3E7lIdN`Ft@wkZK%(52R=5+u@)?K z3ko3DWd*CV;l}z5cX|Q%rYtj!!|s^{Fumw9yyd{X2{3T_4#TZ=6Pmm4k!R};3}$Y> z&&-VL3X%L6$pkllUO}c?To`ezAy>J*3Q@|h-5G@_)PF|Xcx&2cI)01qv52KB6HTxv)V=a zTW;M%GsVq&Aw9VB@eYwg@zLkU7?&kBV7az#BGSPcG{D_l5h-jL>TP@+2)DD|5!Z z{M_zf?xceOV^EIqVus`mwZKj?f%sR~r6i~1cvez6KOKl~wIf!LL8&M_eAxEB_978! zBV|FW9sQrWa{eZd_`vqFl%@L~TICCxcrc~EQ|NB%8tInuoQcy69LI267tYSUt}+q| zU5wC$&T~^LBNfH-ro3kEj!Q{87&I zv3X+vN(RN7?w4Rq{kpGGJdBEebql&jIt{O4QNIoK4;brz9CFI~2iIgItr-;@ zS~19CK!W{81&=q-soFCTM*|gsXElk++EK=(+M{dH%L zmO$Erq?NcMsv=qT*F|1NA~QBNWu$&x$c&V&pkKJ&?bIXEF?DO6B0Wk{)FaJntw=AE zwAdqc%2A~ENt)%J1VQ`j79?%nXoEIrqI-3ZNLA_9bj5azY=hYdMhEbE5M!t*N-{5v zJh@5kn>`{0S(`UDqkMO8T8h()p<7lRY1Mgal49*dbshgNbqSsu+3x7-$P)v(Yi~jT zF9*QUh~qyv+6J*bG>(gKJdVS{injxfAvoG#QOTW~_|4-0@EUhi&xq^(@z71#*Y%2Y zG5fj|y&_qKT+{}k&amr@Dfm?hn(zsle3~bP8(4N~>qf4AGCTTiJDdSq@vAZ31tClQ~IejDgKi!cu`nBPcv0?Y*q?jWp$ z7s0{@2>B|@VDVRg0n@^KYJ~pGcaN+M_sm)BAZMF;J$Z5%C-}kb=G$OP&PZ@K^p2ES z8(X?B_m1?Ld#Q~}LC!OID1o!0CG6DI zcM#1aXA^jmogMH!#o=RBsZMz^g6w<;osM%jA6E?=?(Nac2!7=*?1TLRM|r!T}!XA|-*Cj=z{X9yw^bT)w==kQ!Rggy6Ft5^@F_=)Qwl^A4; z34MhYkdUZeyY8t@D5wuSPu)E6H=H|B2-DdM$1Ni?1*J>uY3@cwvy-jF8nXmE=~Llk zVqfna_vu@yx>hBu^jq@WaNkIFbUdm$vA;>R3F#Y{I6;Xf8u8TC2U;>N0GI$9BT?;% z1I)L;o05{r1+P3{HY6OEi@9BszlH$@0qH+q2@ohPt`_p+ts6kCoVHP zqvd2yw-V1Wc`BdW9$hwZrI}AWwUukuMGB%e>L>Ah^If=Rgf_K9Vy$@%7`)0#TxVvW z={jm38Rx%fQkK&W5&>s5eRU3@-^3YN&67rR-?r?Z@Gof$UoCEA-vSqs#xnewM(|@q zF=-rC1=}DI!-dW6G*x09gm9Wz}peL0pZE5Mtke}2= z-@}tdVFho{IyekwMxBpO#M=tc|E}4pDkT>8G)dhbrHp_P@}V zG|b}rAX5^O>Md@P=BXX-sg0&9=fhGjPD|l0S~sgH;^{R)6VUdOMp{#-DwH(ZdN-zO zjP!7<)}(~TDPhF$c{Yjh7Pn$cv6D`;%FvvZAJL>qT3R)O$+{VE+)0|ER3)VI?R!a6 ztznFE`kxpfl1{Q7XI&bhoy?kMai_JEVA2fhB9*qgi(E`fxxyo?}+(84UT71n91m;`Z63q+D0>z@Oo#vGq?HzMk(n4zk`K_cg ztZ!rdi!{G#cZ*e_O(PWLUPehvEN-s`fitZ(7}z}nXGwvxeSvK9FSCw${41;xG5&KT z|4N_#8;mPS=USb>mXwDw5XW6dy|4kmq7mwaN4<=@L~P$%9#Mms*#@;|tjj zlz?*(8vgyNi`sL7D?Ff7MAJ5aU+=Nw2SI(yj0oC;Q|b1iBt#rZellImQ7C6?_} z06R`M6gka#Cz{Wd)>CLttDNm9&1z>h>UoW`9wk2Cc@C7d&P*7%!1)vvd7*O;=odMu zP`b{!AFf>NY=N0eoWEM**9E5sri}H@DKKL=%TUdiIV14@a_1+M_X=k%q^@+TL1}Ql z#V~M{^Fj(1R0o}(P~bz(euy1$+M#6sb+{MbpUxLh_m>gOfpqG7ix4dxp^x@4Li6Cd z;nb@LwL*jvoQJ@l;S@nn3+FEU@9V5bgbG@Zg<->N{W{8FnwUnBO#QL}I|4Sj`rOKodXUrJ_bXY)=lq@Rh-lUi=xf$}4@1Fb!^3*N=XVY?+N zBeg=wCZzYJqOK~Dlzuh?QK=FsYNAZ-rexBL&_EjLZjOZR6f?EA`3j9>MmojT0?oh;F_5bxCCir+|2U_S^e4>9P^p;sf!cPWsNI@YX4!&l3_)bYv( z{KkMAhv%Nayv$)ac1tnsaul z_f~nBo=?V^<^Tvan{K6^VZKRmE>BYzDQq;~iom5VR?-u#=3L{YE>WpTRvUJ_)TJsl z#cIwaZt9sT3@2GeJS&3RqN!zVl(B&%AIrk!n@lM3+zsOE>ZbxB~oSV?TlbxfOz*3xA*1Yp4RM-yRPwP0dU?9yYM(c0p za0i!kXCPvh;cNgU)A<6N&7G4l8nkeRLQj@+I=sp@f=i&|SVqc0UeVK_h1}>}T48ry@kzoS5w)%rLUK(6fg=K&F-_&zxb{!)BxY6S7$? zc0GCQY*varoH#9;>vTKJo|2x;Wx72=^_r-W!<}_%(I|JOl4t$urN_rI8j)b zyofC$XDixxn!SwIBfJnV_d={9xdKd4 zBj|dXIBy@c+Q?nXH$%vuc0Z|zUYCNrgfgCBv#hN6bNQ>DQI89F)C!_>_y*9 zu&?|iCeYvsWTNfaS9tof;FqO$cuh!nb?Eh3Gi;9g}$_0n#hcA`Y^CF{CHh z58V-CdRQ>+)J$h1H^JWhYK-X#!L&y+{X3CN&wZDH_DHv89j1P-UAYYcrVsB1&#sYPf5Wet#Pz0wynNWE*Xtf@p%B zWcH+rnQTkR-msXi8di!*Sf27!r8{V}-KWZ*VR9n&vNAohMzmF~-Fqt3@2xStkRp=4RU|N=xX1|_MJC#)&j%6Z)yhGf9{vavv;xW<(6Scu%BcL%jKJ#?HAdO za$B?Czlqjjq&5j zA*YT*u$kQ)<#PHFTiI`8x#9FDdk{h4(kAC>)Q{y1dYURYN;-qJoB5~!%c=i>8Bvv^ z<|v4qrbI^m7!w(#MVevs4Lajm!bMM)o};p8b^@8u18+uD^PI^GV@y+&v>GR!sq9%+ zHWzo!N!9Q#Gy5=_W7L^80ErgaT!%T+xopeI-V9b}2A5lyrM|~ko-=D_OzUhD>$|!v}8wc&LMjWDu;`! zoby$qi!O~)2ZtzUm8XMiTxYfC3}M7p2>Jw%}m8z?Ss%w-gqg9?$(un4edj_LZ z&aRbPO5eJ%-RIV`c)i)ub9trEIe~3EcUU~&kh=(#AY;~4JUUiZ7gMN=hm`)uVj7Ya?EhfKY@@VkaNjWLJm956^uyk9SF2@ zEz4>I$CKG*@q&D(aa!bJR9n!2o6TC^0bg?BFrKBPXMYPE&3*xunck8yGqPJ@_)E`u z0Q6w??TBl7tMwo!Ko~WV-g-AOvOYEQx$9l_6=;`c0ilu2pL)zfhBuhaiNtKjb{Wb( zIS;r!b!TTEVGVU4ZmGJu*^xarnv<%Pv)*1D%+w0gVoCp*ZH_ zoPyB)@#%_4n~k+-JsmlaAd4djKSdm5%-w2%Z;mNGLe+azDvXR`p0$`ysyS~h(w!($ za;jlIZMFxhMJPJu0TjQEh?{Skv~UuL_#_5-MpPOtNJLHum5v|EaF~rL7{5E8wqy>e zyw>qE_=^sq9+6&8jxj~IL5-gpTdYc+U@=ZvsN*uVgL9IV&4P?6TZRIg$zEz~IRa+< zP=!ZpprH$1T)re5UwjpP7reQAxKZ8*`F|k)SgyNidZcxoSX! z!>oI=aUvYc68Z zP>r=JgxZ+{fsRUDjZ(J`>24fb%vviOg58zjI*V6mtcHnIL!h=Bj)QQjcrTdEdaDuX zzW^)70&v?3lsql~7ggDLA*gC466kWqpE0pf6q{nSAY0Wn_*a1=7w&ml$1AOTU!PI+ z9R6WAGkV2xr>NX1%q>5Re{Enij9kPT+apyNY&t#MZzn|BMn~qt$6kSr$ZdBF0%k7- z7ouyMYBFs1Uo-%-7e_%f8uqIm=b_-{_eiT(>zIxIYHt|Ts^NamcDn>>s#PcWft}z0 zld2j2$VgylG^*7`eLo=?H8>mgRPFc|HlhAZhS)!TW#68GWG~f=e&b35@3roIKFGbm z36Bjk-nk)7}FtO zwlmx0!GUW)`+%NY4Dc<%c>t;CZWS}Y>NRS-ZTq??p0`(px(8&G(J;%+E2)8n>H~gN zs8b18sPh17d{$Mct3WA#7{V;n;yl-!6e%gF1>OcNXlryCHBV2C@(aN?40-$W+>^+=-UX-_ipC^^;l<)QP*p63ncwC21V4ij!i=hdQAxmH3<0R| zc~vm@T95LZAU@Y5SKKm+Hfqi@`6i@WsUR1{H|Lx8sWy3OwD=cJ z4GYxN@HFyOo9vEGJDt_A%sdrNsA_l@nW`GTCSWz-MVLm#wO~E28p=0;au!N-0VGkX z7RNQCy~tdR%qQFqQzPA?|5I|@O=Nrwy9eO2SMml`@@iP}N`6&S$yG_Oj+L}bMdF%R zB#OCYHLq0#pG0|8@atj)XF-Rkr(#uuYcv@sRnpVJtxC%Gn5dF&0;pIQ{NIvZ0}4xe zV>>thq)3an%Ya{X`Nf1;#}l(OQfwPMAhH6|lzc zYVQ_Li{yr8K=hUN?66tU%HlY~xEBPYt|SZL3j-Om(bmky`5kd9qnfqCoZfrl=&z>t z@Oto=W2)8ct`bim?}V94mKtV+Qs$TeOBSDEm?N1ufV`@oA%V_mT+jjE*S7=91~tT| zVtg#mhB?mVOWnTHBW+rDM$&6wQ&0%xSK}Y^Z-=luV^rtNjLMN9k*9p2&U@G0I6cxf zf32n;2CKgkD8EVbq{15|-=gv%U;bY@uSZkfH-6qA?bi%HFIqWO`-TaQYwo(e@hHku z5HRN9FdIJrs~5AU7_&?iZ@`SjSRy^cP;^IH)kWn1AFx!4GQ|gTH82L^ z{jJ6j^Dlih!kfp<#{NZEb?~$ZId_2f->^``GZUnF9RzDIo|_;=PIGJp`o6KNhx^%# zNZzDDCy?WGaN`#U$~4|z;xFk=S1Y7rP*kBrRhoP}d&Bte|Ux5P+ zzpkj5g^Xu=xYJI?n#?E$gPIZ7Sl*2I>x%MKVBnPVEu_(QDa3Y);jMywhNG;Sf__~A zQ=fqXK4UyJDN~IxQ{_jI!OmEXOsUB-DiTmltIZznA16ohqT6D^w>Js1%~AOBzYDYd zv17CSDDS3X_1VQd$y$OqR}Dt)0$9Ge6I@d3jR!0)I06m(R}{x{(BEP41d=DqRrO$w z7J|Dqxm)r?{oG))iuY8aKN?>_Z83lI zHeXi1dA|%@J;<=))GAdew;V(~T;LM*<@XAHdm5g3ec^AO#n158a z%>t$TSx^cAX2TSH>S|Q(1&KpNw3P$kPj6D50vJs2BfyyIC>Yzr+9I@Q?p_CP zIM7t~0Zk2sgHC0~IEEy;IBLsmd;p$%=Q_t!$M^`*@oN7MRr^?O7AwyGs>T0b$Szh3 z+dnO?Y|~Nmsvd_zV@`kkGeZIHYo{vGZl)`;Hvub>kD}EmUa+c)JQ+ukmvbm5RQ|p;_(+q%FPjYZ`X_^NK^@ZNfq@meggnJo25KD6i8@ zGW-0K!P9($7X`Rko~pw>w8J*Tt6s|BN*eT8l|fz`D?dvcOoXH^;945=?A7@8qOx0T z_6=ShxYjp#t8Z|xZ}1Zu^jVd`UubZvHn_aW;3G{2`}zi@z0ZTF|6Gor*9GD#bqSNQ zbP0P9u+a*=f zKR}Jos|-E|N_je@Y4Ajd>X7Dvq(fTwPX^17uloJwz-N8|-=i7Yi_6BEM;Xips_}W1 z!BSAl`IsyXzSLxJV3Waq|736$@^Qh-Ft-NAb%PzAA5gS-<=8T_0EeO6V#W3+b_cVJ-&?`kr* zsmb7we=_)-Z*W(jdv|S+7lKs@dl9gNVSpN+RT-QCO8M&$roEPsR0WJ0wfmb44)`a7 zyjvaJ92bcLTYQ7OR<8_h@(n&ngFdS=_#zE9gD?$V>>D&{`Cx=@GlRRh*Dj1?gt**$ zw!3@J!bnSnKk4qi1{@{b!U0#U1{DpiA-M=F=d{ENpSgbaAo`9gpXD6RnN#KGc!J2` zz{{MGf6HNarm@rg997r26INSe?_>Vu$K}Vei%=w9I+TFH!7SzP1e{$BV`u^@ipQ|NP{ku7 zXx85Y0*}l|^?Z*NkLCsS52hOikMz#<{H26P^6+}TMUh8~ocaXt@o3(5*o-7xkiwDl zQLuh_drZPO(kq5GaEk~0GlpG&Odd%`gZ1NKmdF32>^;D%DB8I1-907kBpi|hXF^R# zLX#GH3sQxkkZ>phQUZb$1wl{&kpl<_h%}Kw3`IpzLJ$F+uS18RtC7<`8Ffn+PrU>>S$K&bQMLh!ekfw85m$c$6 z2gTPDhZ*J&X~$xlmA*LaEe@gFN3YwTUt3?We^|P1{%TsfzIJ54s7@_Rsipt;p+SZ| zFtT4z@3~}ApkmRLC7nY0$s;#r_j?>kv#l6+Ps91GAMMyS(hms_?tZECASL0N6(P85 z36}`bQg^F$k*navaG!{tdtFIQr>>*dT~~5b0q-99MV@1|u8fNjwnCdgIPSU!^{L4> zM4aY9J$6aS?Qwp6Wm`k<#cmIrW6g5+eCP{t8g^WmgJSOajTXcu*bOma?#mP6ZP@KF zV(#6?d)CmCz#om6dw$#nBMq=?6vrPLZ-hNR_=0>Gb{82j_xuJ7;+5EKG-B?bOo;bm z$1e_O#N7v6?ErQ>xk7An&yUAogwty+jF|g=qZ0D-u`5l;9qtz=#7nW`358a;=VxcI zvJ1QWTpZ3FKR|=@Q|!KhV@kNM7p&;LtYoSaUyX8gmsqjZb>BwV0cTsIxMT7AC}%Zs zqq3=!grG{~SnVp+HdU$(@zhR2^tWe@;73^_nmG5Y&$Hs8wy9)kfFj50P#Mo}m1>po z@YbP+XO7Sh4)Jiu_HkA;P>y@8#*2prsOVT7E92>EWVTfq4^J`c;9PrzO>l^ZJ2tqp z;-Ru>g=C|%Lpc!woBX=|qUG z^vn^ifkQOhaTG=W7x7S=Qc-T6$gz4>#xtW*tuj9=A-V<5Egr&lIK;yphvl=1jml=M zM*B~coF{XvewFd?tGk3=WjxPA^sZ-*z)#o^4|g2s&x(i26pHM4BFE}&qCxzJEA=Yl z;Z=MT&b3G2f<1_bJ6^n>6%Umu6!CZ>$Ld>|9e(VWP^*k)0-mwddHliZ`qkAXjdOV= z!fk3|=e~VFlBnpK6H5+alE~_O2-@57?uhfQ(itI^aLOP#HK#Pw~0l$@u%%wYm+1{==XuHwDi}ZQs0KggO%tpdHpeUR(&c_2xThd-@LM^=+S%QpdFr&@I0i&`_V+ zToU4+TFx1t4u3JRw*9@HS+7qGU36>7dTlJ!4YHwH~17%d%-4ydg!|8jCbzq+L)B{>QDU(HQP*4s`G zP_G{_C;ottJyb7zz@~XLR??OwcH2kY;Wx9!G*}u)4@yt}!``>f^ zRdP#{Ol2e@OEexf*I(wCW|K%bd)3;cio)$B{|#hM8aI3Ptg*8uPM?53S6nsa;)!D~ zo;+^)q=~xloIY84+8xD7y7c1ywJN&bRWi-dIaj9nbNlufGGy@B!3Z-r5u}$JqImj* zDHo5MJ>~N0df@&0vn!szyCl<}@jq7I+gepjn-#!(+?=Shn)@!fqAFS=Bq|dj3zBF12Y62Zx6XqPAn-fpY8wgKM_T;?a_vBscXr(}k&q3DzU=l*Z$<8PJJsM!8dNufW7Efw2jID3eT?n@4K?*z}N_~6r$B{tru z_~`iRXvLJzOSYxPo5C-GN9ZhDJk)iW`57(bWkSA2$kz+`i$ea2kaMcbv!801_B$px z=tkT{-}pUVPMrW*9>bzIV%Rqp+?tGZhOj56vGZc<3`c#2<@_RbSeoQCQy?RS4hx4m z5$wsHof&Mwo}mRs3G;*&*)z19a#(*9`x^yoGK}*14cRlwOKi{P14btYd$MQq0GK+b z*n*$0Jg}@c$S|6ZJ=rt*zR_Whzce~5DY9quPoeXV;LJp+TX@C5B6~J#Q65JsXta@0 zY6T^-XS9%V=y33BFSt7y31$B!dq%nRjF)?UEJdA;&>?#^acJ>74sI1?r%RL*uZx~D z6Nix+xVr)0EchP5`vgBH_^{wl1oL$w&nDjv^0>F)={6b^Jr+T@M|d0*{JCJhi{cqN zM;H85QXjLb73cj_@`BCj)r?%&c}hxD9Z@m>{g z{N}?W5>4C$T1=VY-GcuX+>sWI&LYE{faI$Uo}AA`JT4Z@XZ4=^D~{UUK^=dU2OmFs zay}XMm=A3|{!1_)b$aqXg86{Zlk?e~$9$}oU>L!a_UhkC>N)j-`u^Wa8gT!X+5hre zNoO9n{yiZdX7=;UeyiC(gS}glvrGx_yvrB(7zvrnW=HUn68jxFtpflX=VQG@ePwi7 zK~7F<9&nH8tD|E2x(ZrO+XJI-ElEbY>VG zHh!|F!|A_B+(cGxl!ilz>~*0XMm`F1vKN?hdR_#d7@acckiD>98Tkar$zIq~l$&_t zAvP-Hl6{oyDRGv~Q)*>&*k8$>4rjEJY(e6&gk%Jr(-ajFth|79jVl_ zqQy0RTH6($pSd;Lu1GmkQj(J1Ckdl{t{d1Ip(iGn=A|zeqK*3IB5xKmiCSMbaHuA&q*m&die|Gp_}h62sih&k`^E=C`X$On;m|&=2aPO?ru$Q?f>+mdQ_G|2ZH1_Z z-g10-G<$*&%@90ae>iGNRPQd#hSj?w`19%VQ1PQe<2k{H1s@aqmEfNQTl!6>Aevr3 zttyF=^*&!g%lK9y+97zC;5~vL5&Wd!X9T|__;tbW2tJx%R5`X!^te!IwCG#m|AXM) z1pg!0AF9euwtlnmtf<{m4;nKiFMX2mS)dD>z-Ohtamp?G%irV+< z(cC?*_rfpx1rh3y;J5U+7nVh{KN6zP1)tEP*FO-={zZuX671+j@8(2@W~5gomam3; zEv=T|9Kj6*Hxt}ia7TSxMrl;vJ*q5}-CxK{1rO8dGgm~j#|zP9!PE7@QE1_f-^1-_ z*O@CqMb`_@t%7$5-X(aC;79bjMk=b82hgSF!(!nZ!t;H>Cj|c@*r!L_^gv#EC*0P0 z<E$A$c);J*Y{uU2Kep5Su?cM?2M z@I`_r3%)AB_1xCHN_gBNc&C0XSP;cr^LOFWXgq+C&&y+`;Cg~F5nHL#Rd7$i{R9sb zJVfwF!DR_<>L&FP;c=PZD+JHcgOUoO4b7TGJ{PJ;Ug9wc~-;HiSI61-aQX2Ev}elWqh z@AxUzhw@b*FA@9!4UfMUoRnE5j|k2Y+(|HAI;ox%%^od8T&T%2y;$E^Ru(Pb4@!8V zy97TZc)#8YRr`H?V`fqmtI9uxT|60cONm?%v!4^P!-7B5-@RELE&f%A0=SX$l9Va9 zzTjqpI}7fsXWsHaRI9hkLj?gMUtYLBaPPphZkf%ruYTt`h3qFK6V z@paMo4ML;^?-Klo;AaKDA^4c!uLS=r*j81kOHXj3*VGao4fSj9ZHi`h6Qcfthw0ZY znUWX3Mu@H#%y(zK0@x<_UcrwFeopXV!N&xDCHSWVCpwjl*Gj#}+yxL!kIWYG0>Qln zmkJ&wc(ULt1uqhOW44}Gtsu4V79qP!@PmT)3w~9j3og-vF2SHaQHW*;zDDpe{dcv3Xu%dCx?Au=f}hs+)Gp17e=0=Z3wH3Ls#h-= zf@=wGD7dxYZi4#@9wvBhf)j0biSSsfU%O{j)V@nkoK%(U#1UE!G+3l5$q=6y-CRL68tdPn0s6BpMuj-7G4q~WOMVaz*&Y16FP}Lc&-T0 zpA5&Xglqzg5ISXK+>3FW0M0UexzL$MhT|3&@|8lq2A_&rUP^b-!x*|BOr!k}xIzSe zMg)FQ=)XfoFXVPy$iD#7&V0yEQf?~lcQTwi1Hy$ty@-9dif4cg@C$*x08ugnV5>_u z3C%V7&qLl+=(iL4U4;HX!Iyz^y}F!550kpM;FbERDP__4P9eIFjC&exT#Y8n@RLI4 z1+q!+t3v*+kRKKD&xQPJA^$NUPc)O?golHE;zhufaJ{rw7xJ1y-k59>+6>G@cSZ)f z3jIEU2MQisKVB91LU?$A%Y@QIvWZ}h;EjSegBkV`M7*1FQ$l-%&OW2_Ep(oyoRt!X zd)+$#e@Zry{TEE5wv9KpDK|#X2u{walBbhR*gV0Fz_fEe>~s+N-NA9sXtD4ZNH&II zU@!1RLZ?jV%o4m#@O^?m6#Qcq$K3~{UJuL6t%|rNm=SaRkNT9uace2K7uh7VFPQpV z{^LT*O=*=0o+5ZU8EXK#+YGLg%2+c}MUM zT%p7ZoYA0)y9pj5cpTY`N3(?dYA_>y%CW44l*2B!8_1?4){;#^Z!zrVf4A`11EwJ^ zAo3XH#?W(QW9Vfe|3L89f`1q6&#MZXLN+$D^U(gigM6XXoNQ8B2xfw~o=6X&(_ipl z!NbWW>{P+a1n;k8lT1b;2qDyRzU2QwF3r6WSQiM_7ihJw!_XSib# z`WFtoz#WBBQ9{XWRi%Qb3tldG8`-qfT|)kZkRKBA_XhE-ghY;>9nZcR3J+JkBH7uY8+*iU3y%UM6^_;5~wm2>woR zMx&}kLH$|-a50aX1oDqMz@%3?3I#nkI!ugILq)< z%1x%`362Z>>x_OO!mgs+*en-1d&p^~p;rixC%}yCN(6q6aufI+q4T|9y9snm;sRiX z{Q_Y#C^up237t-YFKohwZUSFq0;k)!;1z*qivVi`-zRu4m=X6y*vBb15x*k%U9u^; zqh!X*hW-%_7?|scd?^C_>M21dgy~!_p$!B#1T!qx1!+&YiQrtp{R9snGh%Fmz;Q3| zNTD=VC|x0Vjo@v9?*P*d-)Y-TxygM6*(B&mq5n=5$E_1p2i8e24eYcegW$UbKS(wSeT6v#P*pWMi}%m=P2svid@&vEV|%?a3x=XE4LMZwK}gO8tb=MS`yp z90xP-C5U(psqlL~c z!LJB@9n5I{i)cR5qq`xRQ}i~`{47*|7phK+DxD;<$#N~hodtITGa9aRGEhIoXv*kq zqM0aErwG+6gwEAMXQkj>g6{`28omPbw61$@C>lRZZxhYCLiGco`l-3}G0p%vg*9%@N_-3-n%q`%!7x;Fev{NWOF8HY6kH8Gej}}i-ZX*6w zFqcO4mYI0bCN;%CByQdB5472IF&KrjRIE53vWa*u*bBSZ)iGzA z>xI&0!H)}m8qC1_tnqcqO~mgD{zUK>WE1h%U@zq0?9BjI3nje_rJQ zx)7Lw`EBHC%1y*t@OHs>l1;?-fW5E}3Y`j}^NQdTWWEc>?IaEucp@VHhaM*4q_$NY z7F>gD!e)cLunmMxBcan-@JPY&F*smgemyyz9wy?e1uqo5lx!ki0rtYK7dl$#>=OKn z;Mc(j8@Kp9I~LT9Dmy97Tk_;Zih|9tJMQe9VY2f>2`&k(#u@I8VbBAZL# zR|S72_E^#Z^3qlDx)ca(*;L5=zkv1s~N8^WO;&{3T`2|o#0M_y9@3u z_8BTri4(4>k423(K15?FSz{RdJ|O={w>0%OS|a z^tG(l1al=_PyU(U6M|0)w$iKg{esJ??73GHOCpghm-Cu(>9$dH9Q|ctRyWrk} zO9T%V%-^i^?2HjSMewxrXqD1z;W0;Fo3l8Y?Y^66(zRN6uh$vBVS;fk zz}8NWKCwS)_tVt};BCRdLT#krF@m`!te3ni1apa4Prh96TEQCxb0t|%e`kXAngOMO zp;%D1(&GuiTrSoN@Va0wl6Dbiu&VyaM-qOtb-R4XRazZX&q3 zer@}>yzK5m#9!d^B066W`p^7m(J&zzDR`XViGnW^JVPHGa%)tNx@}y(J~iZ4Rj^5T zmJ7Z^@J@YYNok%=e)mzO_mq^Xbp9Bim#BC3yYNi^N{GJIfl}xXzkQt2-Anm0`o>iu zyOy2^X?k;v0AAQaeKSS9g{Yr?o}!C{XsrI3=92sF4B1!df0;L=bbSG@I1a0cIFu6yfoBf;(Uhle&r3wjAr zU%>+f$MnyG@fHqO!1XN66U=pRJ^5m&zu;#DbCFyx8Se@HSny|pPY6D# z+YLipk-1w{K|`D|JUdMVb5UGRUZe-jMRErT(NO(7OcZmSTu(P!nv@cqa%z6A%ces zo|0g_lZluwJQfP(vbtX4HVEblxt@Hd;5~vL7VN&6YpQR*kaK}umPCh0t*ORvr%q4d{c`v~i2rdjgL=nCtm^@_z)o zuPB?uRp)!ZhTUKNFtfKIP;lSF9RSy2ozXCk;Vx0m04v#t z{o*+2WDfd+iwu{6OUb4}hZ)B6A8V9h%!*p$4d;R<8*T`mZny<_w&B*`d4^e)3&C+l z&y+uy6$hdXH z98l>a!?;thJ~xcl%&ilK3&E!hcLM)nm`hKGPx8J-AUZ#X^^2b;{n zBJeiDOTl*<<~uI;8ZHMvXm}g=QNs^`pEi6D{G4IFn(~U_SHOo2bLpk`LKvc%V=mxv z%y@9^rB4l?1b=0iucmMsj{5x7o1YAGMUvkP7l6|+#ATXuLUqGzTl~#H%Gm(x8m`4t z1gGTa(Fz_-47UNdGTaf|-Z0Dz!Td~^b}k0 z4~CEii*t1huoQf`;nmrl2N6S>=TOOwjZwLQs_zv*jh93a?FwI5%ePB)tlAi{mEfg@=YnrA%&_YXb4`;?hWXmZR>PaXcN)GG ze6QiV!F$1RM!-eGIRi=F1AfZzLGZJN-vVPXYKAWW*D%a=%xfDS0?su& z5!~4DRp1te`Tj;*mr?(#aL~ngaLKP8hReZy4Rb~G0fu*g2OHi8<{T&!`U1GjFyGU- z#4s0LnP&K7@GQgMfak`|0oPVvXqaoOFEh;dF8I|uBjD;RHyO?X^9y*&xrEy`!wtZ9 z8EypLZJ4i7JZP9JxIAV!-WLb^%>mbZd)_ctZ$D)CBJf*=`C7yg!(8U&W5d^gzc9=- z;=VD=<=*)d=1eG;d;iTa-*Wh;8tR`OT=Ioq?UNq>rx|_{j1^X0`F?QJFc*mD*ZkB! z0?s$gHyD~4=29?)hJOTiFwFJnx)~1eCq+2@OGA7Mp}%1+5i`gze^mKG!(6m(jNvBW z35NM1!BoRsI%cNfF5s&T_XA&RnCsLpA#?mM#R0$jXCnAw0KfYubA1_YcoukzVXlO? z!|+n@F2j7bzsE3_ovARa!A}|HYI)BZ-UW`oVh$d{!C}LE-u|9pu1&+)XC~-v@Mng( z)ZW*IKLvC4nL1oC{};o5f&Vhh=kN}$>!`!EY_O~6fdwJfO4lXNC0WJ7&(&Tk>bksVLgI zJ=wNvR;*l5`mwEN9vgR=9#s1=m8@{K!**EDTv&ROW9`?$MWq9s{QY_u_pSEpySSgT zU;o0r|DZl^G4|UJ>W$q0bWs0yacNT>X`{lrY_sFnhf61i13c%B(w(luB;fWbyZ!o| zZ?;8r>C(O7^ij`ZK*pJbR}7i@V2|@^>#`?0`n7*=W<;NwQ6pI&p1eERo}ul%nNj?d z!|pJ+ddv0obpd4b)yyl$*}T%H`!b(fV^b8_C&EtVk&SDu-g zNY7=c%Snue1 z*CW7u1n8!Z&qkVBHEb0QC|ox`tY==2xSzynp}RiawPi&Ay~zpt-?yv-`XGIH!sxEQ zCayYyUsci7mjk=v5^;hlqc-cqfyhU=de`IVwVhX+39s_y$RUp{U3l+`i2knR-fB+w zkM(=YOB+_-j_I;8Uiq2L*41CXAR63p9HU|<-E>81g8>HkTz&AW;w-&;WodGdL)S+I`tg;e4V=$*=#Ln--krD| zN!YA&19CSE$EAtm-Z*xejnKnxfZkn@AJdC&D9sD*7-3t-()81X`x`im_v+W-o&MK8 zWFAd~w^gn5pu)mB{wFZx=-gGM1xan&v~J(Fbvr$CR7_P&TvhrM767D$Fm5Rvh|%(Cnc7O+}Ai1~s{)(u>A?9oo0o;W25Avu5*_ z8YjWFZs9k^6v1`+#Zj?_y3V0t$$I|M!FBb*2e#j#bG~Wg*B{>N*Nbm^E_j|92F(sw((je#+-J7R?>IN$h8t7oR2*1NcH5k9#|wl1mV zoR@3$z-6D`8unaLLO5)szwRlkIQNF*ANpQBc>Z2U?@l&eo&C#m7xq4|a8Zv|9rY_? zV|CjO4casi3WRD+DsXP!Zfz9p3?Qp zV((++q+iQo?NZ_KsN*VDv>q4x$&NR6hKdTA2v!Dt((;bm~-& zh5toKr{2V!#%%$;W!>PY@AmCJ-Qwa{wsTvOeskU6bL});ef{8>y5zm*_ZRo~tL-YM-M=*J@uw$8Q>3qoVu7Sj5o>)(uP5{omQ% zQ0LrHp!9)=4^M}iOib0CGkh5vBSV!AM>eR9zh@UuN$II052d~9I;(vu44Bn#qPmMLOyXa}y z4LAqELw?5}2w^}+A|J#j@4i*IZVFt^jQIMs1zzQvuLXm_>6hA&&P2MChPyZkp9Uq3 zb@6t6Y-(%}`do`kV>vlfk=?Z67*ec2QfR=9$WzcRKx6|cvVwQ&>6gZ$>6^MjG>9T! zu&Z8wX)G2WULQwc_pwcQa&@FCd~Foo;ULCle|Q~AD-e!l!9@5pG?T(lG{kIA7!#*f zO8D=dxS$K)pUi8?cag|YxF>wm!@LE}2=Bz;QY}2MFU*I($mca?ZcCh|!~9jQtT1nT zBH?%AFkK^j2l8Dr+zJVfhG(LxRQL#{%d*2q&@pO-dAVIX%(r0bgs;MsXx(rP_|^;W z$5l`L@RD|zO$y)M9i25?fe0Fe>!Hr`!UJ-6$(n>v1>voj-)b1X2KF0;pG3_z4!1_A zCgGVJ-~6 zhg(uej6ZxkT4^A>6S)mqzUjz%MtirM`8HZciHn@a$QVql?#~!*^CCa9*TDu5j(a#D=QuOs@~p4`mC(aT7f&*)6k%@K0+Rcnq94<2FOAWaN&-H1!Vyg8Z_eh^hZIeZ55gHyu8klU%@TM_Z4 z;n8SemxXUc_nH=N-w0D_;ck#z9^Qe|{EYC+2s<-8>s-saB7CGC?$W~5V1IVFC31IV zcyurPj&At=F1(tLpdrl(_l%>u=Y}suH1ooK7`-NZ4hnI8_y*+Z+VImg@Ro7-rFOW& z4&R9UEev0auDU3^6QLG|Z^gvvb>UGF-UJ*#c`Oa@NAFn{4kJO=hs#le%fla`m9Gf* zMQ>agZi_;_A^chZ_k!V;eX!JV_<=TP9;?G|ql(sqH&o|MLq1ZyE?hr|Ndd)IDA(JH z_s2Kcs<1mIgKYICV%=yf&Ru9*U5Hk($yV9uBAadXE-sI6wN*nTpxjo2A>3-K=Mnks zw&Kc3J8iWUo$MZ4{fd6K%T~4O4Mtwkn6;8@B2h#eIvdxZ36Ww)!iMnmA&s#fail zTMa>7d}gcNF#5TzE=47da1@vJy~t62p!7#O>Q)?$brffs${e*Eskqot526qzIBGVU z{6t5UK;;rg@%M`+IjUP5G&M(+A=#HYC_ywZ9HFA8IqJ4BYG}HnE<6{F%u!sGafYLg z)kQON)Lj{9XO3!#b~DRSPr>$VM?F`Eb3G~xP3kH~9YLvG?Wj{Bv^Ga6)Ye=_H9&+< zIm$uxV#j-}r?Eqt_B*N(>h*x5W}to!I;x<^YHvN`sN*<%)=^KQfS+^Ja1_n+j><%f ze8EwBP(Lps!Dy>5A$s(!mmPJEJ~k6|H=s63)=`_0t2Z3=1IF;fj_Qx3z3HgOVDl|U ztwmA3?Whaj_l~3bgfZ*rsA6RBJxAS+R{g%C9ziu7aa22$?+1=Lgy2UVbst*ge~<{& z)-gx@h@$w=QF+<8oORSvl>Nt!IuSn)S2U=fo>+1OrH=OhsiO+ffIma-^HGJ4x*y~7 z7sx0I;lGYb#=!BVqt+q9uN=j-cD{DhGQE%Yr zdq)j`<|$+zNjnX{8mPM;9CbC~{Son^4t{df9cVK@!!}9{JI>PN_|)A!Fs}R5QuyWh zR0)jc`_%QQp8}s+f=o2@sS(I%BcJ*Wb=TOZ_9DGaafAvv$ETj{j*;D`9zwrs?o+{Y zFb(Nbb$ei5q?J$YM8y>P)CWO4F!HGo>ZhGgO@!?ZKD7X<9et`FGTOs~bpsK1bzrU5m&C7M@2Ep^bm z0xA>2<^eSWgLI34;(|#n18NXb(JG*Fd!dm9)CXt+tpn;bglz)qU>w!e7Kdn1?E>mW zMBhH3%3-uaKutx6jse9t06GQK8B}xUfSQ9Y-X);EMVh(>RL5Mjz<^qS0CNMXE*iwV zfcgV{?3#e$@BYmXsA;I5YXgekFvgK3*j$L*qwW_4)Zn&p{=S%+h~!@vP~-aIL>W+5 zqnein)cXj(3<*XDx;~(sK4^28EIWc=kCZL`~^gV-W8CpWGpyFB!y@P57nn$0YYTp_C@6MpQ99g?7sIEol+!<7T&|2;e zs&CQp?g^@u2)`?+N|E1tgX$A>%H2WL8qwbuR7c=OD&l=8sHUU19}cP&$o;;cs@E2cET|@-t;H*X%E3_jXi#l{&SMCH{`*8w6{FOj z45}NE-xra5gm@{aKK5hih9An}m7rPzl~;r65b}E{sCs4KOc_+qpwwOusuz)pH-hRj zM0hx;Y9NL;gQ_p8>8+q@j-L8-Lw*kt+8EG->VCAxBSFRY zPCp2$>(Jzn2GvUt{s)DK+#d_75L(iQLG>`Kr6j4>Ff^nlsg?+ymZUyFOra!I9gRFa zNxh4T$w*SgD2r-Iir+hilhi0w#k8cj;+@3wBvph;zdT93iBf+vNp(d9y_KXEqAK1_ zQkS59-$_#Gi0R!Vbq_N0UXuC>J^lS86~H)mBuVu{nm$NUCy}P3II4z(CaGUg2*;At zVf3aClhiVV`zT4>jKqANq~>(NStUuu_ZH%`lBA+2y)Tp01IXxCN$OV=_sJynJwkk+ zq~1dmr;?Np&H8kbdI(ATAxZT|v-~Yd@jJTT5ihEuU9xI~9JWtZhY-9&vRaFt-Z5F# zK}?;J)s2XubFz9BefpMU)f%baoUCe%N2%YMthlIpIXqD%Tawif1l*deUchc!vg(5( z`8!$tnudw=Wc4T-+nHp=S#&E!-G^-3DeBfFT%f0@FZ1y9DMg(@vmBqIS~SCTO^Ui* zzcM#g`TYs@j1bvo2Nb)8TozFc^gj`5{$> zi*Ra8RcFwUeo9pvkcgpasxgcWOH->b0za0f?neS2Pg6%BtQ%5qq5akisWC9NFr>al z4_y>e?;?SVLyAiad>&G_Ae&!=R2?Mnzae!FO61FsT94ZODx}(>vc3+f0>0ODBBW|& z;glXy$>>|(hEyp^>${M;8%?Hhp85g1Q+aAH+S8-?syVV0Zlt!Mw9lNevOYk9vsyTv z1GtfBfJ%y7!-oTba3sC~^%z`=bVU|&%HIlJ0;`clX<#R~45^4*2aeZ^T!u78mXm|QKhV!3E6GVguAmgTft(y1hh`SJk(?6z97PgYO-@a^_==0I z$Qp85@Gt7GC5M7vqUA-_k<){GWZ5>do(CDhpHQ2TjpS;UZy$PDL~}{p>~Q4Hr;(Fd z*P$gv?sD-7ee9Z8n|Lk?G;%9n=(U3D(Ger%%(6dt6x}GYWi{lHAYbW=Y~}Ct+ z`G_#G>sTg~1_b9|REgY6kAcDCdi(s?ym%kfcjP6CV!>@p#mnTumhVd%f8}|Id_B-* zYt(%T1(5z0$B>$eZ~6w0qNUZ$K8^^iU<5T$vsMj={lSJvV$IqdLXs`tOK4p+>*l~C z>fSZm?XCxhd!o#&a8^N_cg?lY^qlZ*4x$P>@bG)OMR!s6I%LfX*F@X3!(GsV9M8Mg zWAy$QsY3%uwnzVf!(bm2v_0kkWl5J!oNn1;$xe_nF?Ja_F%x5tBWL2S{QHLR8Bbe* zkUgQj?y>+kxVIr9ds2O*$sg>5CTCB673#>)eP~1Wl)s@}`|^C?O5X&OL!DdDoa~jG zQOtGSSXb_Xx>au%8iM_tGoA<7P?45hz6}BDv$4ZxpDV{@$ICr&{DP}_8BRe6d!j2O zM=HZ2MucUd*M9`V7JL}C0xoAL({$9;JWYGK&rpF6b-{3Uc{9{}gBfFIQp!x(u{@|) zU67zmc;(|~>#xA&4dXZuvW9V#wlxT3e5~BNV90(FK~dyzcKHPeS3o07l9jubLOv}| zq{%KHiPl{I?iQ|;97cm^bckc))y^2Ovu;Qt;d9)C7t*^+2YAnQUSE?N zVk7-`V4Sz-Ib|?s564mOzyUzhebm0f%8%O@1yikhv$?ot0nV`2D3nD3Vz(v%8jb*5 z0m!#6LN@a4QHUYm9_`G6WDF9HfyB?&nC9mIm&j0@TW+*0oWVAT~A16W@LLjel_R_>W3m}~4-J<1+& z)xe-#-;JxWk8%A4mq(i`pq~a$R&nw_RzWk!Hn=t}%w@miFQ?#~31^qjs5H{nHNqEv z@>rDH5MW@!h~3KKJE7Jthzigmt$l!o?EnV=C@Lr*eXP>&kOrI&;q3A&5GK)1zO%`k z?8=GX$HxD?D;P^bANIjhHeWJY2-j#2D&0P9b4JryH=>!_6n?PT6msgKzU&`uRy>|H zS~*2j{mDJPhsT`lw10MwpTcpoYiN41+idcnYQ5S3{jV8P!h%^hf^~dFGU}N5LyNQ6 z-wWCT*pKsu1KvZ3@os=ozSOcLv;?~~8Up`}MW}{lRE7==+J$TtFQ8R4KZ4FGe(3D%VscanY;`30S)^S8M3|?+mKqo*kG5^RlE>bLBB{J90P?UXZC-VkG9 zlV@Rg!on2SM8PO{^VQ#i2>>@s&F^4s?Zu({!*dwfFz~jWH3ga3%OUrBq`$?CaaZ8b z&D-F@iC4|G?1vJ$8O8Z5i%SEB5sV4zu5&xLio_dsf;^BXvf-qhN#w(-$7lHVc6Y`V zS{B=gU49V^@W(7HmL@H=^;-BGWYk{kws3esbu(1Y*@EJLltpL98lt{rbn&WU!xxfh z9QG0@SU8a)_)`ep{ug%ZC3EQ&vpRg*9sASA;mxfn@@$uf(Of!yi*{+(wI?9(Ov%!R+FUFx8ufa!AF4eY5!Yezf;15-A>x)OQKBn zl>f8+G-*Ez`b>2}J%DRI2DlKCM-vv}UVf4BRfyTmxRr{Gvp0>g&%;2%`f+dqNB+tX zn$7O8NgQ-IxEAnz(u)}nZx}Bp+~WaX1$8CI0q!Z|Zx6B^3^#7)N@lxZlS%CgsDWoM z;Lb?DEec?KBBZ@h3ncWQ37ywpxX_2Q%dgGxOsw!s zTx$GVdZ0=Y{- zZv%Pb0UXtT%)#RocRk;J8f5;gGzu*~nt2xky{JTuZUvs#qFWLz=SKg*W4W7T}wa4W_qPe$uuPd^4 z4O3|Z?NT6^e;Yz31ZjTWQngu&BDSyPE8j*hf;8C+c#UcVgHYslTnM`MfM6k8veDSU zHXC2eQ-zU~G=gMvI?5*@Nb~atLfSOx3-PV_Ld;vwHdkU$vCDahozO122q$2=)RLlV zJ#ohi7advjH|_-KQVWY}_rX~OPCZn_Pon7J+2?nA;#^Fc!9^z8MU$K2VGUgBkfIeK zTzbN#HYo}=L&?EqmlZWdM(MJL7I953y6mY%tp*V1KsALi0P8@gWb5I0$p&B-R){z zM$rZT9N={ODGLK6T+(h|(dX!KbT#vef{2~2PLrZHP||cY3(qY@Infn;3op9Vc10KE zqb%W4yXiM0OJ?aY&$rFgAFqnt)1Zaz%jlfeC9P3*PMVD<>ICpsHU-5vsEdPSUF%Fm zYrW>BTUzU2i@iB|#;Xr!wQifx3KVB?D!p-CyD+P|of#aSHX=YPc&D;3%R#+2U9s4< ztJ^pARJu#(3iie3y70vTQQhj1HOcz-@{7Z|U*Eo&dj4j-Ntd(bV!z)1{DT|bQN|yjR5i2-SY648h%`f)!SC3JA^@~pYW&(IRr9y z8-c&m;B2eo$bo?ZNvd$@k4W!|KuhIZ2%c9h=x}PnpNWUqTj+Z%g?G3T|SY@EghFFIbUO966 zT$c`dI;uzB9BZbZ-Vn?Gf2$?)iyX&#HK5034!Er1+ZP9Qwe`Yp=U%K!k4_w+!-vxz z)N9W?i`Rl`_UWp(FDYuO2fjDBt3EY+e6e1*=$Z72hi{2JVB__K3Ae_&+eh@Bx5gSf zw*~bZx5gSdPX_eZAMU7;{j=XTzfSK<;qS^jDe3rYr}%VEd8}@F$UWfi%KKBYbpP^L z*J}8w`JgYH5`pa0H7RNO<9-cm;x}h^m&Yz}?hfid%3=NCpzimd!OiXO^q?)VMv-7j zwq>WJqOxo&;1-DQfL^sF7Sq>$JUB&vxh2-y-m9B!jkR#_#?|QKgKIl$eR}TJShM=4 zZ7+SvDamePYP)}_ZuTY$b-J1u0Oh6w%tHapLXXZq`S?n_OLA zwk?KVyx$hfOnxlxX7g3OXxWBr`&qqhTWq}k>dE%$`oy+afwR-6b0_<2pmrK3Y?x&!y^Hw#TyTt?+qiv+?Dejr55Oo~}5&J=UtG&WxTH zsmQ5_eeBcY7j~^z(ddcTN?&;V?2E_F8h`QF85d6*J7L`HaTR->j-~ihrc9qQd&;=k zmtRqF;F;K?f!dzhgozhlK4Ib&V=umZ`s|5wW{;gQ`wG48&7xZ?GGC6Z^XcR5nqe)F zHC<~}Jas5Gu6CXOQ!vJ)7kyJyzoP3`u`aeQ`)ar!CnU_h=)KY5QN7@^cF7xmd{XHd ztA}FT*_qNR zcjGtW*Y2;O^sgskf9dT%J*~2PA%X^Q?9$v&OfIMEnQz}4wQJ~gX+v7-?t4;{-duZT zNU!-eHb<9z{~Q(^$$TbXx3UMRijwbQqip@?b2UQQIM2A|-p0PWVP5_Z(#`W?(PEq^ zT<?ndhW81p1AcruuY?jN1C}%eRG69yGGg^`gBg zwRNkUoP51zNS{!}{_kVA*}8j&PUqrRkMB#?n}3XD=%SxvwJPpC9m`LO7q%*FXSKNE za@IwQv1890IvNB1)z|;Lv@l0!?0hP$U-=_8!=A3Y{2423ekXFqjk&h*iPu5*$UB~7vD~?FsCV?~ zV<}mgKez%P7tYd}Z2jk~Ldt9Q3hUJK#x>B*zOfhRj3Xs$^~uQQ zQvLeN&Bp8QZ3ooTso&YH@r$5)PoOZvwV~d9Q_Zm6Ufe0H4;(EC>kE3f4cq7HMYVg? z*Ym;pz;B_j{)B%P&RCL+E7ZhP?*VPs=@r%Q*n^esS~w((_e}r(dIPQoPA*l2{aHNN zFnn5>)&OgQIp&!q(<-&*nPcjN;jpIFoGa_=B}2!At3UKVelO}l2m049Jo!K3KmO-9 z$sH6DH=~(W41Hl8gLN=sFQ(q+7`Jyw$q;L-ImU$}j)z&-=m96~=t$o7WLm?mEykO@ zG7~q1{3e52!he)?$Q-j~GV$f@m*)6!_qfbDV~!by8O;pp1-`*Mnw~w9T3+Az-(JEo zv%Y`u1B&DB|9ZM3W1)X=O}+3J^w;nFgWvG8JL&_0!SzY)^ufr4Y(22kkXrh!b7I;0 z+~D9(^f^g`?@NrnExQbf-?VFcdc}m~!66&vX;0AuYfi}1owiI5=?{Lu*qHJ|%aG1q zbw^15el#~r?|D8uU|**1Up_VJn~v+@R$Hdm(T59e3h3-E&xZ8NCo$&UbA97b`V?ju z*Zy$!R9)|yB~cp9O6YzNUlP*O`VCCd4?lisbv>f@1tyLusTab?1#R~2PU%QZ%IEin?9Te1RekcZdnA(g#qorwl%jKl6wh7MTa+me}k6#+q#pi4d*|<)8 zHan_+pV~L1o2)_2^|^PQ!e~Hn*S*GqBx9uO7A<>3OAp$Om(5uQlvTb+?c1blYR7 z+8U}QPVaUjqi~jRmKSP`n@w0edANU6PZ_W_l+I$oRtL_$MxXcW&^&$5v)e*BMjnDZ zGLRaH*GwLuggUQfg7RhPT@dq34 zqo}hT`_+b7=vxvTcW=-37!O9~BggOuTXi^(F@I6XjSaKh+Y5QIV3r=ka!=>g0n%bc zvJy*exQm?dfB`wWFaV31?ENl$bIMJCRz`z2x3N)s(A0%q>rM1z?_H_;k1D*ZejYwiZH9#`oWQzhyjL~ILyenawdqJb~XNBbK3{zTFStfmvD8M zP%__w;MM|;HknXzS`z+XV-t%EMfo$OJV={^KiGJ?&j3s*`K%nHjJrYR7Q11$2N`b5 zu!h|#12a?15aqepyO{xVU`S{E)1xEyOgXt3_Dob{82(@*r%@YQ9vtN?6*3?Ha&vPD zIU{m&iBjQ4yVPgNk<%DEw(f9@E6&vQg&BY&VECK3t#~$r0<_2a&Y;nyyG`OEfXAZ}>^2E7_1)BfS)guV zfxX&`fSCd}?_icmycB=v!OV|0Or5{F`zH+NV1Ljs z^`A3L{kIbwcbmqy#-kPXe;Urg9y2m-;uzR(n1Ojm%|tVCe5OWb#07?FrjyLIN*vI;IU!GdMtrZ}M-A73{6)cBfra`Z z_TbOF1Mn%stb#LwLrx+9tEskN)^h~smcFMZI5xLGK;F-=C-0BrI0IY& z;DP5c7EGfog-L>^3g%gcVN0B{WG}Kj%3+fw%GFyuE{uzV3&=1! zAA!kfO99x12%V8eXCdU|G&6ooF*=-B;>-o@Fr(x&_FrsEjSeTAt~WaI?#|9~d3ZTyau_3EBW1vUi5~nJ+rg5T~?$ zHA-v`WKXF&TRU_(*Of(vp>pVuJ)HoKBct&Ln|oFV`@uPIl(U!cd`Avp@1AtQVZ@&} zADI9{jZy@Ax3xpA!0bs3TnBsRf}Df>F2niQ?>F2S`*#dC!`>a9q2J1I+6n+R_XH7# zl>L*6G}_j1+DZU6p0gNB$EUL0W9#FYCK+pQuK9Sc}fMl6npNIVk8xs;d(|;JXf+f z{QI@p{H7btQi>Gw{)<2>@dJWI^R$H?v2QZ|YTD@!B>Pz{YH=ed9g~WNt9C%~8Qbm47+vc8{96eU26A{PfFAqhzSlg-#HNIWrWg2sNwe>l8 zY_8FmBgK|;O4xi-@>X^^W{^vJclnuvpt0x_tSWg#u1H2YCKMyOTcWtP7}@5c%jC( zX?%yqD>S}Oyj`Y`W|98)%%MG2hi@rbgtc%#N!HRhA#Ck;YMt@6`Anjn`?+$6f7S*{<XBxO#4&aiYd48uL{(cHC@@TWDOQaY-EVw z0?ITVq;a{%*J?ab;~5&y(RiW8x7*D6FS9-1RT{6=c$3E4G~T80;~F2<__)TWG=3Fa zw<@320{Hp{yH(C>{DsEfYW%atziI4@uTLjlV}CtIjkJ1?k)bgk6SfP%w;$NtPU9{b z_tJQP#zQo|M&q%Pt?_3}(E_g5m|s`0GrmRRB^oc+_&$v{XuMhDhcteKpJ}i&IH2)S zjcYZ2QRBa8{IOCaYv22 zdyv0fqP|+dK#e0BkJ5O8#{9a1oz4v!-=y(v8ZWJ5)c@`}5B?&d@%S}K<9qoRF+1{lEudQC z2Q}WK@qUf@Z3H`=XEc66WBDag)j@CBa@PNS+XLqJ5bT7$(wHv?v*rKN_z#U^66$rl z8V59PsBtE^ZpF^m0@`TI?;+S3chgvYu5=Je40EL>AExn0jmK*|t)9ho!O;okjbc_1 zyN5gK<;F^lt2ExI@m7r=)|g*6u*-Z%WBJ|EK~|aNcS{w&Z0T5I@r)LMpER%&`cUJ~ zH2zxSA2pUAIvr$XX5t5LJDpgKlQd4{7Yb~pCR#v_#w|52*0__#r5g9s_$rP0hP5Uki`M$r`6?9M-s*#{3$A-5TvR?y7Nb zi>*O;g%&VW;}IH<(|D@J`~rcU*#eDk)wojQ6&kNj(gvZ>0=8(pLt}n*z|QQT#!qQ{ zQsb92eqG~tY#xDuch2^JKh^jj8uLp7cE-PI%s(61@&+0w3V$k=n8unYTjLfQ^IHOT z5+xe<(6~(FK^m89EI%!)hVDd5-U~J2+e+&*n4>YjA7E#EyT;2jUL|g0JvM2gZ5r>= zSbmvS<$qX{^9uoXHm5XxRpYZ7|4rlb7F(nA3oYPVjepjdUj?u;bK*dFi_jhAbDpT-+B-mLLM z8b6}(0gaDpd=eaIH{)w!R%rBf(bDAlmK~_^WR2%&yjbJq8n4%Qm&OM*{zBs)Ew+Zk zB`tt=zS(6AX`HQb8;!eY+)v|(#^W@W->+3;dtpEu4#za5zi9lP#-D5agT{Yo?7^Rz z?Fyu7oT+guo7-Usbh16*z8VkHc!tI|h@R<~$hT^uB^s~Oc$3C88Xwg7S&iS*_;Zba z)YzRO>u3E%m0#MjE8A4#78>I@^E#bg;vCC9MH9^-;}>U|1>k^U`Ndh)QSvLZ11z2U zw78qdN?xPMA0gu>Hk!x5e4QoDQYk@ZMSjH!kV^7Pv`YTICYN8Ljgu+{zeF2Q ze2F@W1F7}gSY!E-Syh>KsT_5RgIF<%*K>%XM&S+Xk7-^i#n%{ef~1=E{YW$4G@_VgPAN7Aj3%Ed58GJzwqq;Ev00+Vn z4Ze5T)=40%W^YPXI$2=q=NR}Co2K7M)47HmRS~9X0k>+**Fl>~XS>FG$*Q0S$hn3z zhrt2GuTriG_YY0Sj~2J}qpj#s36+qWSqXIo2Nd_yJF|Q@Ywe)?bDP_X#5hnm6h3P>MMR%)A>--`9za{L+)(F{Xx@d+!+0DC(2h1 z+dNO>Wg2fF7gz~x)%bC;%HRo2|AfZxYy35t>2Uu2Y%8aL6nv&L7F zRpH7to=jGSo2lu~2aBAG;oyLKC=DZfm9$F1BhA0}d$mQLc0{G|nTpwe(w1UvYa)r?+R$ktC5#!*fFJh`W(|B5Dmhg@pO-`C_{kb7A2 zuQmBE=OWswJmulQk<0~~DW-(?V%+*@J z7>y^0l-Gh?a-*8)4vkl8e6JYuTJXB)Nlo;;#-}wtqw%{MzpwGf8h@_ww;KPT@xLvO z%If@~1-P^8+c93_WQ|ib<_C=IcF)qdg~qKlZm)5tY~*i8F4Y41XgpBkAsUa+c(lfo zHJ+~V9E}&)T#EWHwmskqjqlRk!~n18df#EM`KDNMX>6$bhb9_H zU9o(u@mCsuqcQK0wy#F;x{vSh$M?=#~W8NTb z%Li%9SL539NfzT?B$%0^XhFY_SiEP1H+QL~v{qxG@ow?xtJj6hyLzwygiwSl&*n&zi-L|Af1q9etOS2S5 zdsDrf@>Z6773HnOiDm7&B&hAhLlm_YAMRP3oukg(hbU6~B-lQ8KTWyF{5?0|K1J*( zz8!xk)e$HWe~I3Fo!ETU)-=&PI=N6>DCq+7t|=6|yIma+e|@cO|F}6!h{Y58+mr=-RYcRjh|ZlNh{R;{3?w zF4M$!PTPeXW=E0u$l6o~TG2fw(kq&WUz_adIiIX9{;SDp$P4CGvYJA8_g39SGQRM}xmmJOTW@;%VUjxG~un`4)KGXgP8vI6*N-S5R>cxS`@lz)ck& z02h(f!r4(VhCe=8Y02>exzSrOD?C7P4k!Cy<;h0??_Xp>Y~X7Zv)v~s?g{2+?x@on ze4XL};M>V+NGw&%LabDbx*4k#bA<5r#bkbLCl8*T^r$iPsA5JwsMrfWs+bjhMloyi zoMKks9kLpKA1G!zA1h`{@J2@J1i{g7l_v|HpA>VP{97@1X@4jl0rq3SCR=+WBczxa zG*OK1HL?}6F`6r8ls1Yp!Mu?X=|trdUR_i`0Rnm|=J@TWn1gPRVr~z4S0fA23p|+| z2Efcz%mU3(49B=hF$ef!#W~>0SoA+5v%i-iF9hj|YFFm=8|>sF=?*|EieJ#a&X&XP;wm zdmH1*N17Gi137O=q@2$_hZOUX<|bUu8L%6kY{h)`xw&FK)7(b!^WgT1`4k;*Ph?y^ z)7(?>1#mybeD-;eVm{IwQOs9wk5n9WInbBN697+D%tz{GDb51(Rz+sU2d@??=00*I zS)GqoE9T(h?TM6gY;9A_S+GknXTf9fT>qiOa~MAwMdqM;O7Q?NZ%?Fr5cmbfWR80Nlih1H$rI>5}R&oabOmv6xFv25>8R2oojPNX3Z601yO#Rb}sn5F#letdA ze5RN>|4>Yw?-g?#{L5l%{r_DBbV7g=r#dFYzUMuM`&L&SfO7B4Oy9sS#pLr;%RH;;^*5m{x5mp|=WC=$l*?T;@R zUp;njb{}<0?T;$i+q-g&$7_5&87C*2MH(*^+ZOc+MXNQ@E{zXqT&wYEjsL2#eA-N9 zBcCu+EFUTh%iIn5AerKz3&jc>$ucBtc_bHzsu%l)#K6g0+l#9E+w~X2=d2D)c#9e> zrGjyujJZ$qwZ^|_%y*^QIzEl@a_BmFzQ*muxr}QPybj8(JlC$V|`z)&x*8(FFem!@%!#)TSpC9Cv~m+WMO_gG$6e5BZUbcK%S%IK{28AEdfz;p-U_>!8>=) zKV9NWFb-nPRvM{d^A81Ro7%@+V&9<~g5t~%1-=9?H0;((6Fu`${e3I&2I0mFBEEzi zEqX&Sw4`OD4J!*=_)%xcc{ISR1(BqXfbpXehYe6^k51cg+XE<~7M3HbmiQZqf?p1!c|R)mCG^(<^TY)P9!kte69aET z$*$J|^TmL~j7E4j<v0`9SMy%4k?LbiY+8p)8g>l}M zgH*h>Fp_~+bZ=u(E`HesgA74-{o9KDT`|JLg=ptYG4!u_LD6?>pQM1hbvE3Ih ziulAFD2Vcg4`K>jD96iaJFIb;IpTYUuX;1jx52gFg%?}Pe!BjiQ@(`8PvT6k`l*ws zTH3i$3|HS#mdYYujxR3fsOm~F=4Nzt;rAn4n58m_YJY|=rsOHS*F;=+09l-VE6*1* z*~RzF%kYaoC;Ad95WZTqR}W0_%toTZz27B*3!V*%@v$CXobMPmOwDhQWu#(8Fl>aQ8{RgpJ4R zr)WR%{X2P$VlHAq^^44;TZ7`<-tkEZzd*(A>jA?2skjl|0RP61J42$~PsP3j---J6 zzf#P7uur3yFqX!6t8NcH*vA*w4k~gai&l#x8IA(CxN31EFXjWNwGbB;#0JFmy;6M% zrBLIUgR^0XD0=VCMlrG2PJe2p^uc0`sy@%D2?dp5qUX=WjbgrrN}{DwQ5*He{dCIC ztnY1+j2J#6RA>b+z6~iD&(|*(R|_+7StGnZ)c(RBrlV))cfs#S*b z>k52v1uv*36K~&+BGw@IDJ$3;jrih*Ab7f5HFBfquF+!dHw#0ecH1Fe%mVCi7WfZS* zRIYJV+))W{adIjk%h9@`vaCa=y9ubNn~vKBonZdwuf zEyo+X!m%QGMb?Vq6}?srTQPCPycLxz)~wjR;=qb$z3JU9^52olm62&?rvuYXE3N!z zQZ)&_s0TFh+gaZnO zqc`sUm)7)m)P@a_+~CnTOYWt+roRcPRf=vGx5-!XLA*QmXc`>EZgR0hPopx~U4=gf zq+NSgr?7-!cXf&-Y@BeX$B>fzDqQi4jl*7OVENPU>J%?EO8I^hOV&gR+92WOv1>LO zd7YYjJFOXE)P@aj8kUJVdGl0n^E$c1@W$S0;($5eWv090)@(9Quke;sj$+xpX{-7p z=6PI_HMwYr*YAlekM@MBvr~>;t)Z9+F_n(^%7|XsN{6R1!ZxwhDjnX+i0d*zLS-aI z2`+{W{I5)QRYq9iC9-w4M;dqo#eFESQz=ev5Y04Ma&AW^WLUaz&rszZ4}|J0n&N&J|PWekpNQ@SSS3Bc>wcX#;XwXW2} z;F`5jN9yjt4{M#Ng9FTqY?$#Rk?4azh-%D&GMQvfAwEnRatTFY(f0RJ!fln z*PLH@w&I@Jisjk0_xo3G?7b%9t_>USz*a!_qI{o zkBU^j=N>jaYmCdv;n_{j($ke*50bYcTgTLyF%ytyo=S1KyYjE@?fF?&p!6L`8&D^h z?wvo>tFlTmr3yU|^FzoR0nvhsdc zIKQ$AD_Da~k+ykj0_@P`vB;}3ZNSPE+fagrj-9*WD+5mN-|y<|xcb@eQtubnZi+PP zQT=l(_pT05$6~o^Qzj}|YsTND?MR~7 zHyVG#-S=h3G*OU0Ce1u1mc%)+$E}`^YxAuBY2r)*(%I+5A>4dQyjb~ja-t}Cd=oB> zea^HEiI5lG58aySB}#WSi?A;a0X5AK;k|{GiQ@W3BMU{vF#M)Bdu!xsd^l;z&&i?n zPftX8an3}sy5q964R6;J3SV%YH!uawz+DB7=EW2Yi3b~sHmw?_L{l2#?9K-<9P(#R zhZ)No#T|~AThSrT&#|F!qz*wehoeD%>>r%TICnVGCo&;d%#7I!4Cg88H{>qP;cBo7 zZRv=O*@F$1vj97PN7H*45Zhpx8?a3SCz=en&8z?;|T$PAxG?X+AbLhBF&Ab~R5hQ2^8N z0!kkf>v~}%yzc9$^deHZ5?eHWM%?uhlXSSb%W}O;cDXm8w60gkZuePUioD9Wu|_Nl z!b_Mq9$4#nXi?{8adcZGD>@aLUYCQHdNOP|!aT0k&~)-K?wDKd2PTYxR%}e=Ik3Ao zG-B>}lxev;u#`)w;xZEdg)WE*;Dfk``y^V_o&FOrsgjL5I1wekVItx$Yg z`3Gavx%~@Jj|TohC||6AOKS$x2+h5u@ly`}#}BwgUogiE=uD+2sZpq zL^S=?sK3LH9MDpC^E%GYuL{Tb`S_z7{U@i-U(qK?9b}*IO<+l~+nl$eDUxK5B)gJE zM9p`QcAz*2;YhO*Yy^Hp`IAPO_rPNY_$*`6wWb3N>j>~Y1xcgLg$QvPi622ZX^gp% zz7U$+S0M8m2UXuztIK@{bCI*VBU-_C=pE=A?$@dL1li&4$-i>=4pY}p3c2E1arA$qz^$a zt#hYrdK;tAy%TjydEhZ<8&NlZC`zfO$KievsikZtyWEK=O3D_p+s%7vQnr#~-36$0 zN)0*QorQ6nvW@I@&qO^^9+ZvY?t(I;Jj6Qr-0w2(!^}6?U5$=N*-iZ{cLxl?ls&UP zLqLxE8z!{(XK)`kAI3@9_aAWohOc3SrW~YBe@DaXn9>t`i_~;S!wMGl2t%g38}d`3 zDMweLqRZV4YcV=go}y=!yWtKDnUrHJ)oORcBf`Hc5{Y)C!iiHTg>yZUOl?w$q9+_f z2YEwj6Op`o8tNWO=jp+4ABJ|QVIHTA`y<2&HR2K(YdBY8`i7bmA;21PX6HR%KVQmX z_#a2XO#cTEIQ%;~{n!i|4eZ!`c{_yv5^^*Ar_m>-{~{W~ zVFzEywEPP=pN*KHxgrxP?rzA-TzLUe4EH9aZ{GbcpvxUWD&{J3tUHTo-9sI(`)V|r z8Fw!|KEwIAxNdi(Y1D%zGS?PBEvB8ho>{vOATM*nt57rC-!Lt~8Ev|sKs%cofVTu(I4a0{LFk3={l-Lgt;K}&%pA_&&6lrE6>rY5g3kpne2Da!F-o- zS0HZo6t>rQ=1$1XVL6HDee-*nM~-||$qy#Aa#2i!Wi#@aeX|?b_0wIl_26F*YgY5` z==mHz=FGYfo;-~Ttm#I+yz6qd>jJm~{k�=S%+p`ek+tTulEC*xar-$SjQ(ud{*p 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Μ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
    {aEOU*VpM4Pjrr2tWhj2mWw5S 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�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ðUQdUmP{8Sq;taPO{LQeoxyA4hh%h(+IhGtX%hn}U z4}qWD!^uG-w)g`0;O|u1Ykkz`D+SMhXX3e#dX<5F$g(-Z%o_&b3ET%O(V#*mTAwcA8ptZoENm=SnKhIo;tGI=rp%B zys_(Vxt#4kw_&J!Z;o|u(G7@w4l7rkH!7+~dsAbnm&S9qQ0JB_pasxr2ouL3d8MTd$B*n1GmbX%Ag7UG!=WU*eAr90VZ(ImR{<=WeA=2?g%QDS zVGVgu%>%?B)Y29d2WKjXmL5Pj1-Lmh9Gr zG}_#4>d`CnJjZatcRqlg2}VHP-dV<1cGMJwBGa<_@)1G1K$qOvA5)8Wv<&#&N zUO9tP)&+E7Hlo5BvCH)t06kl&Giry-F{&G_O&;VEmTB`U+1l*2`Vi#zmT7;|awbn1 z{t&H8z^71-d1uASu@d}AM=}eTDs1#N-d1|CwP9g*SO)s;vi2Jw@3DFg@mg?#nR1LD zwGjnier!QKjs7iokl*N|(DMg_X;TR1KhR*M`Oh*+1;+(X6r`lh0K6+=cm8=6=ft`lTe(bKJ-3l7;;RA0RAg#s>7ABQjktm$krPKWCtms)-a z@+~rKSh0_-{xIaHg7roRX{rB)dRu_L*nrtEvOA@936S_8q`ts_mxFJz z`pY2SAtR$q%WgBv(}-!mgw#tc_$2s8>S51bA-mnRZv7f4;3nzy9|5+07JL}}c?0C- zg69doMzHQ7n-L4)&&RWe$gY)9hLPtS$WE58gzRd0K?2a90VHM@k=^b7Xsc(7$?g=r z#OhfP+4aP9>QNYnk5@f1IzYdL&iwN%yPn{LO@!Ct2-gUnTs>pKY>l3=s5)mWy|dRX zh0R}1Sm;@4Jz+T^;Piw=KB$wKuxpVQ%K!6>MFea5ry08rN;th?0kfiK!H2=D%y7#P z=B^2~Wsm56Cm1_7v+o4Y1b2ZCuS5T{1q`_E?W-e93&>8dFDfXE-A;BZ<1pGIQ;u;G z`92)rFb_4eq8VfqLS1XY?NGjsh(p#Tug3un`BgKwX4EsIf#lQ7*-;_*X2IE(mqA7? zpAXrGjC|NzWHyZDo9!1etpr~PPb2mU+0Eq1R?l%IyIu)WkFnxB(G37M1M7JM?g~cM z+J+wl z2RnG$G=SutnzI>g^(7wKUuFaRRP;*A%OSh@P2ypY!!6$k`Gw`*Ab+=9il#gX&%*f6 zm$qBp0?B`t!-CoEMW{J#_z%?2CMOVh0I;0_7_r;GAVbf8j>LavL*{?7QI`2Hh4}x8 zsOQg82M{LnUl290O#KIz`Okck;AzAE`@?@#L+1afN$^YeESO`{-$pP2{p;er{aem&$`%iM@COg)DYMUwF!>=E%81JLl)A_tp83HKa46C8s) zY?)&nMKtvsQ@z6h-w)P19LwDC(1v=x5#v}tW3c*x9Df&afi)Tn$+n$(9q+~e3h)sZvB7$M+X|zRfmEacyziRm~`<<5{Dg#L8P{6UZs%lr`#dgjR={-}pC$o#Pnt|8<^695Zm zfIsRnM(}vSjHAsvkZ)P$I>9jYRGvCqGO*GHqko?ekxu9yYrmU$ZtHEW16Rs+hVsFA-(zL#Ds= z#Tv{$)BOr&-`{0z*!OG6-A!#-W0$s$Wp*Xmb)~+^fIY{cskLEOlF^kI1i1F_%!qwS zc6~Y6>Z6ck*Oxa~J^PaEp0+Ke9)+!kTtP;jMV4JxLZ$WWvWNH#-Srt2VP2o$Cc%^0 z6KUigW*3ejPHht)mB_zFt;Pa7KHS6Gn%`_p!iIx#p3*83&Pj0|3$%7~B-)U=EfBV5ei5wZ`Wz>UGW zw=6eAm^PJ=EiAKgy7kDD6Hw0&zC{41Cv34fB`!vo<%Utd`G9vn04@&C2+lfkkgwpt z>DD}|(cB$?*&01eV77)F0?8P1(*hW= z06D{l&<1)IMhhX%|CYN`?&!CcFK&zEg#sy+XEUO~SmDfW*h3dm<-&(?w(xxJNrs+{xy&+znL~Zi|Mww~#Rw$eEY^zv zxH*`f`Yw?A6tb)*EO-R;=g|fQuvf^gSB6m!8|JSkujQ%K!=61fmE#|5V!ClABdpOv z%PS!D0s=jm-q|R@`t;ij1)R>uau0;VV78tdJk6A)D-FH=4%MG(-Oqdw$JT`{kGC1I z*5n}fvv8cG&SswFYarP$r)QY_EaW1=2;;sA5kEosri~!eyTtmFL|ch;>bKwkcMiPc z+2sB{-vY=xEk6ROpWQ(}0(IqkYP2Euw|pM=)%i9-Bgg{Fl`v>dMqvR+a?pOu;R0*J z$#jX}WtMqY!NOVCQ;_di=EU7cMxLB2X%#Al2^0vhSogIQDkW)c#x+sSUOWZD*V zfaI62n3l{vJPXK#Jvo>Hfa5Fk)Q2s*d=mP#CL}%=2E%9s?hSdN<;x&17F;Sg37LhT zVD_d(WcF4a_%Oz&6J*44D@fhD(36`OeL@Fl$ONn%D;$0j2e>FanVFUezRog)dEyKk zc4<9$cR6ki4i7MMqMhK=Ei=Ef^!ks)>|U;Xu3P$9qYEGhkzvCwB|96&u>fW?h721v zfb147z2MkNTxo5%(vpMx)(TIPrHp{lO33A8WW=r_yZw*uYR)F=;KN|{%Gs7vAqQJ# zV@8wDH5<7StA{YBAM{*1ZiP?KhylHr*i17JW&vz5+3h0r_`$vnbb1AZP1v$~7pfRx z=6MGs+NASgi^*3WH-yJAbWBASun?}7kscMCI#I2@XTll>(uch0il@;*PX7 z)K3yzX&J)Y5ZJV+DAs?QSTDoiMljM74ZIJm7YZuXfpSKmfUspZs~1~6yN>J%zRl`cVY0JdLp}2R6!JB}d&$T@ z3P}zoP-8n}A!VKBRq>@w9o0X4J17?Wv$8Xl+%@l&9Bh)qz#xEqQ^B4gB)zxhfW%2`Eke@mghiT z!|`VUAss*g_Vl}#M$oghWH;XTTRrCo*-a>1S#`lFDC{l4|0E-yJV>(J&VOrd0tqDe z&KhwNk%OG-aC%&yGkiKk82w)cSxkmL0EvcIbGBvn7TJw)Tk4Uv8)OGE(z3zigd1Z$ zabU!A_yQV%S(rYjks#BuvmZkn=-Crw*Aw~-f}SlV2m7LhaOv>j=Qa8k)^NhS+K&O- z1f^bvE$gnfypsvQUqI^3h|Q?C)t5r*N<+_HA-iq(XfV^3LS9UU4SR?j>}Temd1(U? z?3M|Pu-oKmU?yPe$-#c6HM6KkrguVCT4t-Ru)G$MS<~hr$R(C}qn5n>@Im;GMl6D%x;vk=?dk?<B>IXq`*d6QbHYyQCCCEV@;9!UK9}$Hn z;0yLK5#0GwUj#ilc#hG>s7C>dAS*1h0auY>-v;*NAZrPCy|vj6soy$5TJoD#U)zuV z-&-9(CdiBhFw=&DbC6m11)Zl^l!oJjTm<`24;}%@xj-9EKs|Y(=g>8#9^3+w4JC7k zm?oS+fP1)W89-vrOmdL>akv}dnP4O23c-4Tf_(@&y+92#_D|3TdQMn!5RIY38L9PQ z%fa)EePTN!P{0Am_sB@h2}O3h*#A-wn+}k5$XFDbLSAHf8YIKivw-G8eh8>w@<-n5* zc>XgGq!un8o|(3RaT79(qL5^_4cA=3(1v^`4m|W4ngK{ zYv2=%Xk!De5)UFweFsQ#aHvV}DD}wnRmf+^u<2si?d?Ca`mT^i_mJu|k4S?{sia6F27W!i7 zCTKnSzXEUx11Ol2f*j;SHn_{+nV6ZvR5MS-Ysj$YsFB^qWVzLI-jJPsz16eA7e>jGw7R>FtJ zn15@o=P>kiAHXvo+HgH{d9t3gukKjzuh7*uHVNJH47fSj-$dw%P7d<(1Gq|fX37ea zgCFAnHxHir0?TfST|+$zyA$#zYZJBXrr10BtVLo@`gh>n?chEz6MqGHf(#o@BeI)f zDb&AWdhTk=5T-Eb>Ds~5hP_C3qo~)iu|D75I2DTF!wf*`eJ2vI8_7XFxQ817Pn#K# z6Une)*OG%7IKW*6Pn!jhi!CpOe3%UTu;n1H$Z(tC6Ru#rHo=J9OAZb;M!J6L5UVZV2=T zsi-s;T)uKnn<#9^ZU|Z;9DWT4xO3ngPZqp@OCclJUApVQ?8enJD#64-hR=|pXE(lR znKti{t&LuAY+>1~khSNdMl$X7R@2(^g$I*1ftA@Bu@amPF2RawBka7b9wxq5EVFxe zS!S0W68dk1Uhf1^3HC0(<;#Nk)+N6Q98TE44hCSvu72Bc6#PCJHXlLK(}o#!f+rVR zcBkA~)WiM|Y1*D#UuvrUEV3E@aI4%>&$h63^dvSP~)wh8py9uSQ1+eb` z9ofAfwie7v{2g)!88%%kyR^HEKB2Fw47kJ}F#?JCYQ?`Tb9|3l=1}}C8D#%4-6u>Sdy8@P2{Q&66u7JC# zN7`e^^EJ!6AV0GFE9Ac{f5Qp)lMRHB;CIU>zznnCK`4Oit_2aR9|}F$T{#<2kAnH1 z9GY005wIb<3mfBT!~g2g2|mFBM#G2!XT(SvahCQW!)7dO$j)Y&wYdjUS({SWkX;Ww zXZ4eyC%g4yJN3x_13%9H*R2sJAlY4;|7rEppeMV_ZW6-b*KvR&yP2cwUFgOh)=D2R$<)yNvQ_13fb$yH&3-^+?+avXBg$ zkY)F|Mhf*iae#{@a0pK@9|_z>wh{VC4D?)L>%r58+(@u~-~#;s=%!o!m5@9WXx|62 zm*oebA8zw!W60b$uzX(`JQG|Bc^Mg%V9Urs-mb%44^KT?Lk@n11KbjLre)>z=MmsM zBw0f}?Ae>-U>lQ<-uc6Z?R=i)Gcg00W11Vlj$tO|vPyQ{{;kz>1thx(^*!~-rwP)s zm&oiDJ}-C7$Jyj!NUj^qzkuy$z>Oax84*Q>WLGe6TbP(16JHRn`}_d=uH)WHKY@qma3R^%c+R zyIOreNPP)LT8=&0?HLn8YymvKxmYk$RMvccjRc$r(pQpAbzhyd{9Grl(a7pmtT^h}MQs4lBdYOuu4nN)6 zaIna(x_Z=MAA-(~x<28}<1s`q6FrLdmS7RWEQ}pacKwk{{o6Re>3bJ2D{%=t_2ero zvl3WYd|^Z~AH5iZSA(1Igku8Ms0qCLgt`@&dRB<+9v10+4)n~3>^|2k0n?r{fb6E# zEb47xms@5-=8<7vz+F58?t83^WJDB_?7qf&6ZJNuWn|bCLXw00^bl?(JoOxDaxkVo zUD!OLHul0lj!X*<4|$iUWxrk*ftY{hFp5tr&Tf^^7nOHl569c5FgO6I`(TQBKGoLh zAq&`!6LhB zzwTJrFN99tbi#%MM|L*4|6sEby7lnPhl9AD<-2=#UAuRog<~g%Ewi@aOO1}RgnG7E z&zO$^aGl|4b2elzGHjTR?9Ls=QO^dDgOf3EDBs*>BXKEs2s|?)UqD6zwuT&>Vn&)f zBxiH6wP9<>!Ap&eK2di=0oMmU3}&VEaD!Pnaw5pp1Fj)FjaWOf)3>ntOh~fRcd>dF zOm^=l46u5h3uLDsZ}kO`!)bd5(Md)@YnWQbw7giP&MpypH{tqAU#wMEP7n4_993R)v}5Ks7?JtDWQ7_aREXdXROKU-A+g7i?G+&NEMao<1>)z{w-)GA&c=%Jcl8P%#u2+~9K zoK?+3kRGc4TGa{!>6x(bdYy0+g7i?8&oO!JK#(4)hRtt8JLW|5*@S)2(L?{GH9dhK zJySO`8S)l_9;)$|nG6dNq=)J*tKzHl^iX|ZRU;6jhbsH>X!`_8oQ5F12d3lqTfLTs zE5SLIuMoU|4Esfp^e*jUax0T|32iLjDtHwcX;(ugcyNi=l3Sa^_tVHSU+#CjnT*6w zLDIXl&yw4iv@g)c@=Jo>AS3NANP48@`hj16V1SD!++G@4{#ftP{XBqQywkn}FCFA3#)?M>nU)|?#6X@WD!NF0WwcZu`J9ZcE++E{KZxQL9j zZ6N7g+79H7NXzzjp%DXc-2@ktk+>fuy-PfR%b>$+7+}hobcUQ6Y#Ai zBk}!^^e*v3WbVb_Hqpj1zaQoJSu)bT07>uCZYQ5%((a&*<(-=IOvG*mka#a7J0R1XGPitiA=+5Z63qX-#k2*GeRyz* zqvY-;aUqQ?w-nrgjKp0a>Cuj5>od)Air^rldef>VAxICal>3dSI+a5Tu7{ zzEy2PkRGb%tZD~>^iVzUetE0GAAwnueUS976$i-uOe+q7b1Z))_!t>!Pe9Tm&+-kX zexYRa96VGHTU8-~^iX|iRXq@-hpNc~CgBJK>7g2LRnriphw3hA|tK)zKlz|mTAv7Y44|v<&AwN5CYdWWf8dbbCFU0f zJ?@*~_^;A(EH@ThL`K1FAn9G&4&+fLZ5P^D?k2dHjI{kA`=xNDMu2Vr6yAk~2hqs# zFv0v%5)+Swq<3jc$)io$Nwl#%MQ{ZfX)7V=by}{}a~ZhEB%Vhj%L@fBCL{3@NP1WB zax%BLa4TqI`A)%W$w+%YB)v=f5IEtDF^MgD<(7gwkdd|vB)v<^Z?$@5CT$PeSniz= zfdOPB9t2765)UO$Fo{Rd#_~miOUXz(36kEWolKr+(oUm|<(Zas`{y!%#PcBOUE&4g zNha|k+E~6(@NzQJu7IR>X;+bBChcn4SY9Xip;{P!Cf)=ky-U2Ae2Gc?6gbE7-vnE`xk#=7#w0|EHAV7D3j2lh5Lo~AdmEdD!*q?x;cWHkl zPc>k6(fxUprO zyoHG1Kjn3qb{2f5;Ijo!7F;QKf#9WrR|$S3fb-84RwW|zmfyDQL!tj%@VA2bqZBTm zTHJ`*v|+)m1$V4w7ZX&q7;2whc z6COxwQjZc569rcYzFP22f|cN>1-~iyL&3bPyGkGD_1^_fiU_{Q==8h#romOMhNN^j$-N4;kM*T&^aKWX5 zrwhJHZF#v}Byo>WJuJ9N@T-FVA^2Z{PYCwcuBm%OaG~IihRyUjOGFG3TqbzB;41`Q zC-_#u_X>Vk@aux#uPvs}ei6a{Z0tIg&vYE83$7=)h2SoNdkY>Sc#>nbf2Iq7=L^1B z@G8L@1V15oyWqbI{!H+j*9o+)8jS z!Gi=}Bsk80R_tn2DfmXgD+R9?yjk#8!EXxwQ1Bta$1Usj|1KiJb!sZqSa3VRJp>OE zJYMir!E*&)FZi}PV*Bu*h|SHb63GunS~bpX%W1y>5b zMz9imzu+eXzb^QF!TSaOTeF>jKZuB=teV!;5nNwz3&EWQ7YiOFc$VPX1t;F6vv0U&5!CM4x6}(gMXM&FkJ{KQsxSk$g!wKJIH38o>f*%$9oZ#05?-hJd z@KM3P2u{tdsYHLx_Vl|zM2r`_RPbGb9~Atw;FkpdAlM(NDL7ql!-NR56x>B{FTn!^ zj}%-gc#hy}1m7ZfwPoG@jUwV1!LJD3E%+0`Ukm<0a3HUy#o2;;3m%mx*8hnjqC)T@ z!FLLNK=6}-Ul+Vj@K=I=sAjZ3A0M;1nb|^c55c1ZPZE5E;M)bS6a0+eR|J2k*-pSC zBH|~(DfMb9mm@eTxUJwb1)n2$gy1s4iEK_jo`(C zmkD0snC-vI1;A?sKOp!~!P^Dz68w?iLxQ~qHH`@ij)JS#|286`tKfcuhYB7mc(UM1 z!K(z{FL-keCwwo|1blA@-YfWk;3I;66dY(+)5=W21%itNchPK5zhV(FNbqRElLS`? zo+o&N;LU>H5`0wf&j}GoX;jmKY{3l$w-S81;68!}3%*!zh2VLX6PRO0vEad)Q31NKBH~iPa|K^7c!l8m1aB6+P4F(k{}7xw zECT-(9B5M0vTVUo!R-Y15Ij)uXu)>~UT4@e|5XvONAM?tzY_etV6SOSMbib>6Wl^@ z7s0)oqI|dh4;B$)1Wy(`NANX*ZxOs&@J7MU2!6#e+rQfdz@G^ITJR5o8yD78`ZU44 z1)neYBEd1iGr`sC|J5SmM!|OoUMKib!G9C{s^C3>KN0*@4JUlx*93fCvznHr3$7=) zh2SoNdkY>cc#Po5g6C+qr{6UqVw2z(1-~WuBf4_Vgje_BMmEcji)`viX__`iaaTGX^SQ*Z;ptpuOZLahJ& zM8q(`;{{I@JXi4bf>#K>Pw-~J+o~Du-&GyJZ)gcVEcm~I>lf9uvW4Kzf(Hm5DR_e5 z8Jg_`yjDc461+k16M|n9yi4%Mg1;2}v*0={YZ{O!5P_D0PZ!)*@KC|y1Yauna>0uP zKO}goVblCKMZ|}Kj|)C2IM}MD1^bnU$}BYSTN zW&DKxMlwRbtfE0hQYqS6S`?+BQYodVBw8x{KcDma9Ov`AUgiCKzt3+xzww;kIrrZ4 zWSZ-n`Y%nopX~o3m9-ZYv{U_P>0h0@pG(Gj}xi zHIFb)H3#Np=5^++@TKwpNlWZAzia-~{EPWtbKYv!OLKX1t)zokvt%XK(cITO!aUU+ zn3tK?nYWssH1CUBx8Ffad}=;vK5yo4r6;bN;^s=`dgd19uI2%ORmPa7n-`c@njbOm zHSaecG5=@g{6*|Qy#HlX!SxrbVQy@0XYOSlW}akTXkKN$$Gp9UjsJTs@sato`A>7| z)yY#(!Cci`%iO@+^pes4mX|8{UR859^Nr?t=H=#%=10tX&HK$q=-j#hzYdT6H9cd( zMa!qwOm?uCxstiQxs|zxd9Zn+d3JdA!t{(_tA%!(Uojste_{U7e8HT%R&v*in9G}M zM~?cRWr;540p_vhndbkQ*O>1!?=rt=K2U31a!)_C#P{ak%{gi(+ZQsIHrFsWF?R?D zzBnTz7-^wt=K1E8=6lTb>LfSc!F+>xvU!$yUF7J1KWK@^%`ceWHXk#8Z$4+fXwFkN zxub>6rR!!T6ICtI#=OA1l+MYK34a#~r{@fx-8Z9T@RqeXMCXdy9AO*zOKWqAo)xt@ zWATgTJoV5fchn{gPM0$o*Ns|^o)wLou}YSx6D8tHw=lP*wW8kUk>=^>LHk}%9GaUMOwXl&EoITsnNn8!0GZA*5(H~afB>>fliB-y$Gk%+^IbEk0=Pv?(%b`P8` zKWuGw(>f~8B;)v-dP}^OOvFAme{F3}TKrdw^P8Fy8^}rPh!(JTVOl#^Iqq<0p9Z;t zCKexHo@QQceu~!mpQj5%o!`F{;GZba_K0Zj4r1oYqR~ zm|M}uqc+_vK9JV3V`=T^6goX>e-oT8&ufSViAJ}xk@j?@Exf_v51V(=TG0XX30fOI zO&5+fdJw)k55x2XMA8ao%? zzeicY&p}uohtuWfEq;*J&V69<6SQ{jl*Rw1wR0&=lIt%-Yv(eXVEc&;S71VWSB=)8 zt3%^Q94rmsbh(AK>24lCmx|gCW_x*@wV6)OVjFB^mL-;$Ls|>(vG^-=X)KGfA5JeF zXY8=G`J9e#0CR_0{6~wQjmNPAEdN*{r70Fx{Bm;%b2W1VS{rLZm&OWFhM31$`>8ZO zr)LSKqmr)5t=4FTHQH|RCun?j&hj*zF28JTJ~AJp@yRpGakiI#jM_xqykL!rHp2oR zMGKUsbtEd%_@I}iDx5CYw>GWKooIZP%F>PPe z#M~MV5({*(#8C4%^Ab8>AMtlyG(Hhzxf@QG@3l6M(D=-aWhdLn&m`O6A&3|TI(!i@zUlR za(rK#SfVYhg*(yOKri!5Yah_nigu9j^VBIAZ>i)()Mp z_!*0zxA=b+&(R{eb7|(XmyC_qWkox2EnOq(O-nfOl@DF4O+Q*Ybc4mmn{P2MHm|0& z?A`IWHoVmuJ!O8){2r}^k68Rmi=VLg8H@jC&e1a2$so-t70j*7ea$n>x0@d^zi2*Y zK5Nd_3Og~CufHhySxFpr^L4bI2?kqy005gZ5p3;#rt0$mBd$kG`B{b zXzgitix05)5Q~qu_!Nr==B3tV1$^mE@On$!YYRLAS}J$#CORIh&PJjqiB3^z%q_) zVIA6fjk#m}05w>Bvqk{iA}a@2iJ ze3dvirL0kTT0N))vo{COvnJN2g|%s;HrZ0}HyPGuu(cVkHiOV+I;R6m9E#c2Xr3C) zM58r~>u{~NHutE_{_L1}!`ke%HqWaK|7i7)wfTsigPySer!4Uctsb9;+2gXg@SScQ zlRJ^0R+~aF+oW8ESvagsHEUDP+@01nHvkS2Um7$RmBg0@jk8A6Y4v`V#s6pVyUZJ` z%`-GU?O=Ju`~e*eRzd7bOZ;mt)hW4f9dj#MBVad+522%##zt9u3auW`rW;2)G!IU1 ztiq7T<31r!D@b#lN=rNm?8J#hem!MnZd?MypXZb0_m)^AuV~Vvfa^ z(pu*#TAjR`#^($y8{u>~p4w)Oo}ktHJr;k(;%`{|L-PsqX&P@-SvE z?Ol48|fYas9*5-QiNIKq0Y-F4zZZY3>sS&=t)#7U{ zzMj^`cAH{;?{(U?V#m`y%Pm5>onrxq&)_T${o=Im# z>nUSyNS})0K{HDXG%uvJ(iJq`R=XbZfKlX;5u7ikTn`^@kth+X7Rw{3u*1# z1LjxFUnk6+&DK4+Kq*>1s6yi{6H5&^U2es=4t0BLf1SmLnnziisTQ9BUwZzZZ;4gr zyJ+pugXUe<<|&Ksv-s<@cKTa$?jD!c8N@DU1#hKT(&5C{wv|jaidCl7;~ExkYHnw3 zI$ON2#Rpn^bUdz}O|ZmFTVRgG7h8M-t(|_%{I2<=IeX7!`(oz0oDM8;c(0}LhJ&Rg zoG$lcT)iJ}?Ppkgw#64&e64xCwRuqSc>f=<#8bAwTNXcJ@uL<$VeuaMEK$x}iPmYVWATPGAE8h>SiBppBR9vq$^85!W5u6cs^B9vS{u7aGSexZ^;+G&+TjHK55nuRz zS_|){Z;Xdy`z-!}`2>ADYV(W5bM{HDr>Oa=KG@^LN~<%W9yFx!_|4J;PM6zSn;x`I zSs#m!Fi*BNH(7jMBF^pIW{H)F1mbHgzS-gr(%PY&=9kUin13{<^-V6D0bd&b%QAt- zZCf?BjUKVYJLV5*_26?Fk52KU0;kKTt*6lp&m4zY*>23iEl_9&-kn;K805M*%rSw9#>+SCDxlCjW>!`wAbP< zSo}?kAGG)<7C&b3?=2quWQjj5@vp^m4@mYVjn+;`?S<&fu!o0`Y>^C2_ zHXm91cp}an`OXq&6A8qBw|LGQl6zf%)=m_r@p#2j6lMo%!X>SJWouu<+Si5yF3=1M zw6R7VX&s{879T)sW3$Y6(s*`YxyRx!n%_5{p`-N&vENzI!WZDgcm3uZbg5D7N?JWG zWAUra*I1jr=7H8`w8baTy@F`3r=Y?O=R@^2YqXSBo3$3-Kx?O;Gk<74Z@yx1vV8+O zh_>4zU)%3umiYX~5_{?Cv3PmS z;vbv8GM}YCiN(tw7SB5*xv}E(uTh(d7H>F&PHft`$vEq9zvD5q{Jtx}O8x}uEYbOrF+==;U_9^4q(QmE&DU1JR z@eA>|R+N2ca;2%}66UMSO=)ec6^*AKmUeLBi>C)$n^82L5m?5tjT}t1MssMqWU}1K zM)G27vzop>Y7?@Je4n*>l-B8Z-uyDH_OHWO7T^7eb-m4mdh?+z@TtYWwfHHE|7P(E z7SA~>xf6M5t-r9viw#3Cu}4*z&_&mP)}CgWdznX@Z>DvH-)8Z3=B>2Wzmw(;@xP~7 z!K)a{GjQT-v|md!Li{~ihxCZWzqI%Xi=Q)R8?KFEJ!!PoQwRvS27WM&f@zl{*J{DS^P7Le`WEXY3o7>WA(}Ttf6iaV7T^?d>#?$KM6pPQc_^lRS5m;rD`5{~2QHwuk ze$)K1`8)G(<{TrF9Y~YoeXDMX`sM-Vx#q>Rj>>9!P;^v6I9?i48?IvUdY9tZ_%)VjeJOztm1y;*r+J)tq4{p} z4QLZgcR4RX#IcFxMZG+_|>& z`Dmp*Ek2mm#zxUPtyAg2QTyp|x_oQYCTg{e6`iM5w!nJx{pLq$ZD2Qzmr|C!aN=wA zU$r*x(pvuq*8cM`SV>~xZ!K}g7QR5^g@xrJocQYfJYx~pPH@t(#0H95yu8ILTfA-} z&gC0fqE#Y+czcUqXYqa(A8zq67N2JEn=QWB9Kx4A|JiDZr_8U>>isEmfpN)rd2>T^ zbMsL1xTJ&Fv}7f=+PvNT7Og{lgvP5I%O`MRHiK`h&Cj&X_c@DSw0QRMT&Gr=pA{{@ zuiZ~sY**#amjui^Y3dd}v^mDdu_R73Oh~lqKkQgc|NV9bq9@?QkGS4Vor#S)@B>6Bf7)ldo2F^1djh&(d$ge@7V$$(RdYO z`4mn}BJr)Y`GwZTezW#}seL+@y=d+8OiZ*#kMgsko|Q0HGdHHS6Rpf+&8y5CX|3~q z8e=`nHaJ~=BHl)gUSLH%c*PcY$9%+m%>14CjQLM<>ZIgO6rr`2ft| z)PUB`HL-YGi+7^6>>%@0^KIskPJH+GJ*;4GVYv@ZOu6xB)F>W*&it17V_M7pX#UN7 z(R|tDWcz}XaTpSZB9jRW5G+^1>2gKJb-3zTn-1nd<{Qnc&D+f{CCv4{#fmm?h{pZP zas=jJ#PX%JIYsMqoU!(QS(}1WlIyH&Ze(r^2Z?ti9W2qCzA4)9^%fsR>otD7#b?qt zM(yWVdngo#6j~>`qOCPZ!CU>)?2Of7LQ>=iQk6FN$ZFfr1ij3 z#NuV?<7!mV5_Ra`q765+cq_VdN<7it;=SmiQM|v!N74hM_&AHtps$JIvja;kra7ZH z${iM8Wxm_I(fok`nu41ln$>@KbOBMWqnYo#{g}J@Cv-vu6U-KaIF!Q*$bpcMY z#0>K+^8)iC^9u87^9J+1=56L+yH%bv?=in*e%1Vr`91T;=FiOEm`_HIx_`zJ=gb$( z7tOga2qmtMyyimYBIXk2GUm$Du>Hh}s#~J2xuH4B+{)a^+|AtAJit6WVfKG?q5@Ag zPczRp&oeJJFEg(;hvs|D_rsT-|F>J>G4metbLLmgZ}0YMJ8eE^ z{=Xp#{Q*l|_Ol*htN7q87odlnZ>;)^R@4Ab^3FBcv- zIVUycc+`_=(o3b*)=fCWpnsPX-H>!NOqTks>^Ha9Xi4cC>M)Hr2ucCepHnturAl%JH*{vQkF$e!HO+~&*8>E`0*QepK9jWdc? zu~2Pu{qX2@LAkW{7U~=xZZ$t6EZr+e4R_qRHZ^5<*r-=fuEGp!Gt0b`&KDiW<>A`F z3(8g4$xvz(dcypS`GxSOBSUaZw>INtcXslX8EIcLofa+jU6}Ia*m7aDi}O;$@k17* zR=7MzGMR2JW-b}N@K}?K3RNvs+g#t=ENuSG3%G7eZOja3fAd0SxVXjS)bOjEvs1%| zGAm}LEoEChNUjJEW>(Bd*$^IUF*zewe7dPm!!D&amP~ucS{({s-gr+&%4gxK(i=0< z{;+xS6jS}xpBA&>lxC=nhvn^VDmU@Guh(P z%*(9JI*V@#JD-`;v%;GeiqHG1GxLGPKMp&$+R!-V-*8LWjTu4iT*`Kj#}Tl`M* zUFJ>ZE#~;NSlZT}uwe6U<I0sD(za1W5G^KG^ZS;cFaPhNur#Ai1lG!oRCRR|0E*!16h`EHh zOgQ1bD;kIYtQnFT&YsgPHEob3hlK@GXO|1+T4=s`6O$RRp1hHkcnZKW^S@e%`#_{I>b9`9pJjqOyvy zsB7O?;-~Om9P(O!Tj)P?E<7D1&S742(Xja+<1>1dXQ*;?iYu9~F*h@}Hn%rlZyprR z!K%X@!(L4dZehG?wEp-sXYy?pUt-=sSBu);Yu;*p#QeN@pZV>`;jpqn!J_eb(X`T| z*64J&YGKKYw7(dt9&PjAu=D!WcyN5BN@_~UaKfrx8EKXAFqKF*3~LoDoDsCNP+N0v zx<<67{^lX(5#|}@_*`jPcD}{`XI>sTdJA-?CDxfYnIAMiY~E$wZGPUo&-|YGgH&uk z(aU3&IBx#g{HysNa|{nPiS?wJ3!00YOC^lQyI9>YW%8hmpj{${P$zRwb070a^H}p# z^K|nZTA%RUYVr7Fb2W53-eHMV;SlUst&JAiL0=tR6}!xP%+G~qYyK}Ic*{bE%ty@M znNOL|()v_0K82k&`IoiHjYpQm-}k4Q`6YOWSBdXrh9xSStDEbFXCK*{5wx&S8*^uK zck?jwDDy<~RP!uzeAc|0(P3N?#k<67cUYq}=DW@JnYWrBH9sCsm{vEV=^GY0Z2r(3 zpH)x$^1a1>2@g*yh{4!G@p<;t^s>v7hd-aWSU7O|-i)SKS*VJ+mbsp}i8(7QbMNYm zaM|{~sYQoce583&cn3C9bhd@&nOB5c9?!@K)-zNqI?nf)A2RPSKWW}$e%buG`GEP5 z`P0bJHTZ=kzBT_~J{KOt{)XKO7Hk((#j|x{r>{0QFgG@Lple5+>|*X^?q?omj?WjU zWhX}Qaq%@xwMGlgi_I%&-KDE79-6n(b)ubn#Qb>NVg3r+GXkYwwe;KOcg>%eKR174 zK50H{{>}W4IfxZZ?qeakZnVEe%%#oc%~j1;n;V&%n!D2VqV@NT96bm1x5N!$=cxrV zf@v0-We&_s%y*dAnC~_}Lf4PBztjAbIX_WOGFOSA6Q+lXnZb4ZLEbg>JX+)%%9PIpoQYIGpgwri%&4$ zWWL!vFFgL=eHkgs!k_R@g?pK46dk?zyp8fB7T+1BG`S1!5x$NZl8sQH-rMA-bn z)_Ce{GCXz2MT_UeJLkma^Oy^niCwsim61SUInC~`k3}40ptnjdfcA0mZUkJ-=Yn@TyZ413?{?L3h zJd3sV`p!aU%;(G(%ooj<;d7-l2Q*$eGJ9Bq)FY^tN z!+W>2&e?vbCB~U2nP-}3n-`cDh0SkXk`b)2&?fU1^F!tx=BLchnD?1qGaob`jyx(p ztbSsN&&}VMPnzR1rE0YK)#87d|25|*5-x8xyhu>6Nb>v^HkUM)HCHuXZEk38Vs2?} zYwi{qAM2uA7p|Hypj^|@mLG4v$$YbUo_S&TLNnYzt1J|s=T(Q~9*b`a=lr%fBiL=B zz2=w9ubK~-51EgekD0$SpE93|9A;cQykHQ^NFM$i=J?#Q+V_GM&op0Yu3(N&KdWVH zT0A}#t>R6icr;=*w?^&Eoy_q$YPE1bi^u1yReZR`Czz+0Z!yo!;HM5+c#$P;H?J|@ zZQf#j(7e<9g!vis3kkFT`x6!TZSx1_kIi40zc!yXpD|xFXUj}>I4>OL$QpjdkRlc> zW-e>K%3Q--+kB0=nYl|?D{FX0O8>Aa{s~4}W~_OtdAfOy`Bw8%^K$cAb9|m(o#4$; zJo=RX0c*6~{Fr&K`FZoJ=J+JR+Q7Tv9gnomm~hn6$IRcEPnpk}e>4AMjulOww>;*w z@GK8$riDtG%bBa0YnmIF8=G60+nD1s7&qdmiEmen;w|Epq1I@md4hS0d8T=GSYkU~ z%@I`by;1LlX!kC~q|KWlz5ax@yfZi%n_(Hx)5S|_JZ6pyaZ>#fmP z^F;G>^DX8j<~z)5&Fjn$nRgVo*URTD@sjxsbA0M-_25&Be_{U49G^K`?fPne%J?=!zQ8<|^hU@p;I#KzuTExve$oXdXyk8*N~Sd9-=Fd9HcBd8r)# zx$|;M+-=@yzCSF}b5cgp$1L=u`IWFc(!n7M9WnnvXGOdHlli>)Pjj|X$@cN-*|lt% z#S5B?M-Jj!C}oMO%vH>F%?-`hnp>JXo4cF)ng^5$l6yVT5>w4Lo9CDpnQu4WX}-(+ zkaBYZu5Tg z+vdaO56$12e=z?NSmnI=A9Jisa_25Lb3U8IPM0v3F;_BIGuM~n{lCT%t<3GrUClks z1IWh`FazGVDl^zfw$zK<+C zyP#7>tQ82Hjg%sH{WQU z5sv9Msd2E;LYvJ`n4dPkNw~LIcz`Cn<17MVIFUuY`(=j*L<6KiFuWIZNlvTHdfk1hjhF73G>tD7tAl4 z-!Z>u{>c2P`A0ZNZ1@*T{9*pvoK`-$qXo^G<}1xL%(cypk`6nr?~)d@N(N%>%-5Ow zng^MOnP-@1nHQKBnO8)PF2dE8*kHcbyw&`O`C0Re=GV<{ncp{mRGt^1&i^q>95?@J z{@t9jLUP$WX3pJ}SZ9X0jJZO>?Elq?3S7tB+T7mU-Q3GO&^*LE+C1Jo3%+y_29{W4 zzTLdue2@7d^A7Wq<~`<@lMZ69Co8d!&7YaSHh*XS!~C~7+f~U^kjtEAE*N)o{l!XK zqP)4P`D$}Ra}#q*b6az7x@|Ph^fwO;tTNI(!92x$i+Qg34!T{mfmPXtKR2H+e{cT7{P$ISa?oC9tC;LTE_0f>pt&^NKI(CKa}9HCb0c%p zOGf|OUaG`m9nC$=z0HHo!_DK&lgzi8Z!_OP2kOBpOWbYVXnw%_ka-W?AvzMznO`yQ zH-BOdKDWv@=9A{L=HJZ!m}8ZaJCWC%-(1*SG;(zRRkg&`=KAJq%&pAr%w5er%_GcX z%r{oT_7jJ0h9%~j=bM+ASDHif2J?gFht1C=%>KWWsK9TS-!Xq+{@DD5`D^nj^Uvnr z%zwc_qWAnw_=Izs)650UW$2F4MOVRG&0N#mz}z_LAl5lqiFG&kGY>QmH;*r_4W_e>4AO&Q~>g3NEJu^}eVjN|?)=E17GX z>zkXJo0~hDyPAvkv&um8sPNH0CT299W1(BkOU!qe*P7Rb$FPd_4_Ii2d6#*Q`8o5e z<~PEWKPP7N`oKcpm`|F2HvekopVuU=x18qGuqjp@lwzn`bc2*LS2x!(w=}mkcQ^Mk z4=@ilkBuCSMH4MCkM17r&_eU=<`w2G<_FC?%)895nDlbi?Ej;Q3jDlzpZP8GLGwrEPtC{8-X>VqMLB%>&HC%%jYc&C|>a=-$z}Uu0et zw?^!>me^?CY<|SN)BKeA8S|^=H_Y#v-w&*E!u-AY7xQ`Z-?YA=?mvrXubu31KJ(?~ zB67U{#Vk?9T*KVd+}zyW+}S*U?h_sM!RArsakcsGMUAFeVx~DTFEB4NuQZ3|4dzG8 zJ1-gif9g^N-^Xs=XMWB6f%#+em*#KGr_E=~f6#$?|FyTg(rccbK0xKWl#3{JQx) z^9SZn>tOqdJ^I2DznIUP|1rnvCYQa8)~%S&;+LB<%*7LC|H~yRa7A+sb8YiA=4R&3 z=I-Wx=7Hw%aFFQzWJ}C6&o5?WUgkeYi<}hy8o`VL`!o= zb60b3bAR(t^GNee=9|s)8esd09xt@S?dBEcd(HQoA2mO2-fw=}d?aD^|C2-o{>gmS z{FnJ(bB>1SfWCD&H?7l`YQDmpX|4zdDTAZ)U6l#Bj=6!knYo3z2R$TOPjB;J^KkRH zq=VR`WF>a9d5(DnJv7?DYV&&YJ?35J-R2j~uf!c)f3X9WIAs3X{GItH^I7x1X8!7W zVyE+&FEGfN5*N&=`0e_{0tL*)%q7j0%+<`z%q`6A8)N&44Rp3dKl4EIDDyb;4D&4W zZRREBwF$HT>k<|Ce)Bf-ljc3(4iddTV~KO-f6e>@heZ1{b3t=) zb18FG^VLZQu|~;Ctf{%ZxwCnod5C$ed7^oqd7=6CxTEVYw!#wknC~+`V%}+f!ThrM zP4fZsXXY;htDH2SHeaBJN4L#IbIzv8cph_cb18FWb9Fi1|GJiFXzoCdh&J5C+{@h0 zJiZ>L4AaJ6lW$MA z>}3k4@E0mrKF5FQ@>g&QehSZW0{^AU-@}P-X#A0J{HU1a7yOs_CdTt{I)0+b@+baF zd>!IHa5{c$7B4A?<0m#OK@L>XRmsf+ezd@n%D7yBaeRKwas}gZCgb=ll;ujs<yB)flf68x*h9WC9-}u+(KjZpb*^!?HACT+U(~@1Iy&F)p`b91rX) zofvNrmK>9<9G~4-1~4QKW>dWSu?%Ni9?dw0VV3cXHxB1kD!3v1?S@I|g&tzERg~Pp zWUH`QWh5USS~*{_^iEOYdp7DE`A0VD9A2zkutDW)2zQUdIpD-}*0~w)8O2i>?-|w@ zR=G&g^j=Xcllk6}uVg+PIIMC;keHse64QO7bTy{snvD00;&mC98#3NMiZ@|g&SL!f zDBg;3xgFyJqIf69BL}f=Obm ziQ>~3muE6Q6hjHiY$k?Ap2vh9cos4)FJ@dL`ZC7lm5ggVT*J70H{%))H!_|W8yVLK z@<3-MRC$PrvC&TKU|inC__!#(n{jzB;~Hk3XMB9vrFWH9t4}ZKXdrH`;?-Mh_@AuwUAk2C*f5R~Mq5%a`Qo`oX;Jd+6!di<4 z@SiDBZAetx64h3r7Iqp^IW1MU<}_aY;mZgYP28dL7}8z2FrGdePjmlKRx+f!a!ov4 zW-*u64Y`>i-H;E&)7_EImeM4gzc=rbX>FpF@J35%6SjCJ?~{q&QL4tn+%-zqq`O6~ zYi>yErfg!4-wnDcc{e0((D>b;8?zJRayMExX>grY`qF)(4G%EK?*`qfyc-g?aQtr2 ztva4@c`~hAb((o5ty^_=KgOiv~Jan=FRlr zsACV9AIgU9C+^!FObm${?V^W9-fiAX>sEc&LI)S~&ykMbk_O-zo_@iI7H6dz5eMh&f}tsXh^a>VsKvaMykx~fO^F(5r|8ljyKX}z@dvA)(=DP#D{$@-e{b40EQHLIM7_1C{(rJPuzWKLZz&pNC7!FThVoIknfw{tO8yECI;g_;1>I!Mz0_Mi0}qh@fQQO|!K3Ai@I*ORwpeVMoEyGH zPJ`#kMd1HM4q}<8EK{Nce5YIizFV#Y-y>ItACT+8kH`(-U2;?SX}LB0yxbOkMeYQ@ znG5Hihw(a8-c_PEd_=w;{!|_Ye7fmnhEHtrc=G1QpJ&!#x@fZ;&UzTjbgBHhDh$sJs+@ zQeF-}Bi{|bByWLVmv_R47nj+yGV(CEqC66=DldYY(Ry>zO2+nM9pntSn_La< zofqey3*hM~Hb4nJmJgMAs7K2^;fXSLZko);##`hmFem=uI_JQvXuU(?j6XDw?k1U2 zpv3N1g**PRToUF~KwO|AypP7SI}4}$p}C?1GDqw8Wv=HFnd|vn=6cT196V5dg9BE$ zBF_6m^BnVyBF(GxGPw$zPv&_oNwWb8C;y?jo+>hTsHV&vsxNbgI4Ka@V~6l3i>xq; z(p~0?hSMC{P{zuPPn5Z%x6-8nltnVz+#$2gY8jVQY@N)Dl(PaADvjgc6qN^+$bz@a zJok^wJjZ+F!SHkPQ21S%w*bl!nLF``%%S}UnqxD{KXkds*#aD=L?xHZE4C!xQr-n~_8_kRN%*|{3VcC+6Wfn*`XDws0_KvB!Kw1MFrNX~<|jB){u?eQXUA(n z6}c2#Q?3cum-!;pMD7l^paZP*I#k*y!FMzLXkMZygJhn+VKQ$g&Mj1k#~fw0%+oht zW}C%wIe58T170K7hlBO1@Sff*H-@*$&0tPE#EtQectY+5@0EF8UzB^nugM%G-GI|2RJcBcJ!ST+pS%zrB(H==$alfx z;D8(3g31&nUVvxFZ^CnA4iO9Fui+)~Pw)yk5ANW#azS{5%pXT?k;}l_JDEqO-127XCy4ZkiAf!~qGz=vf%vwkekgOAB;;cw)-;UD70@!y2X86`Hu zzsV26d?w%yJq_oR`B_6@`9rw4%#RVu$fx0o@>#gL{5M=jzAPKwxAGyF8{lUI*UAOp z)^ahpqkJXYT`mdtk*mT3<(lv?xjsBb?f_4cd%@G?;09FYsB$B`K)wlHD$j*i%Jbm6 zWd8VKqr4ctPhJLd0w#8BIs6QLHI63AOESlm*9-7P5Q+S#yrTpjzG8>vO7O=r?}%e^ z9r(E11U^sK1W+!>d`XBEjN*I%$|aY9Q)PZ{K#Wr_ap6WtWXfD=Nx2)$sh8NMCtOA5 zU{X^a0N0m?!q>_iS6a&x;EwWixI4`cL2pH+j}i;u!SZeJNO>hZUVa&#D)Y9SDSr&l zl|P3U%E#fQ@^|oZ`Fl9n!b&X&Wt+@H_o#dYyjLy9^H8e*a z!|{KCDm*Mpths>SZBj<)+mT}NxZ_2nEWADni>|#gYfGgrT z`$UPs@M)SS80D-qL zP(N|&3$CFB-x zIhjvKmF0Hu)iQs4R8Q^&Hepr4CeoWp2bJ`~!q1WN(LdWsAkm$=Tt5W&TJfdy%MpJ~)q@AHH1XqZ_An;yTme z;xZrI%E%Srit^O~D%DkK0@snRg&WEI(M?OaJKS03Piy+f^Wh=#B6yU%1fC$TfNzx7 z!*k()d%78w#Y$|2SI9fyb@F5I{W5<`934U3A6MjSfARF$# zgQ|Rn#0T>CFz0#V&Ygz8l+VFG$p6CU_I{0%%@K9vLKf1E0RBQZse;dOL|oC}^Wr^3r*{+_{V zITOA|E)G8^mxDRq5_?|>eq62t@1Z&VH$vqFC0fI;%KSxzx8xr1d-712vo3L^W8p95 zweYtxe|6xrd@p=f-Uk06{|N`#ibgBqkLOe6%is(-6D}*4g)7VT;Hzc+w7s6(1J08B z!X4!6;qLMcaG%IQYzQg?l^6*RllfEiG4g77lKc#Oll&4qOMV^xpZq4gQs&RLL-{bw zNtAfxj>7jB)%gDfDi1619n4vj*yv}NGbhn0c%FJq&IP|GXTV2g{@nV6%%4@CmK(yq z%31JVa(n(<`9D=U!#RsZ8|w<^k-NiJ(%0ZA1Es8t(-*5Gs&B z;4GPs=WXDCiC(C5QeqU`L!Jr`lxM=j?}z`A+2jA@oiOK4;yT%5&YeU*0bfb;O(sgkKowkP zu^KX;^Xtk5;A>>Oz{Rp;_OgxK0PZBWfP2WT;l6Tr_y(De;lt&iA1a(wiF-5@=A=qA zkHoDsj~mJ|nLD~#=8kgmB(}*9-z%4fAC!3kZkHRwkI8(G@Jexx|JOn&Z!!Vrf!~$+ z?)8YwbIeJV*ybwuE4enzNtGC{3;!r*!N1Ba;Xmar@I`q5wjaxJWwh`hB=X8*VNSNh zmGa6jBL5FACa;03(^&vY9hnzwBbjf-TgrGrjCGcA$H#ioK^86uRQf5wUJjDWz$0XS z0zOV|2v3oDc4o+JV9vh89U2TTkjKMI~c^Vw7RfWCWAkT*HmFL1w(9Hpqy)t|G zqRd{tCgZ(l>}{EyIV5MnM`R8@C+QYE{wP01mH0c;b8;r)f5|vqvH#>saLy9(g=4(G z^T|9a1!W!;&c1{V#Bc8sGB4_KGLJ;%64*W)%|YdACFaBR`Ac|?{0qE5=9|t%at^#{Sx@uwM%gU$7TqfI z7TqCV0Y4%00^AD+T$qRVMJ0I7-jaEn9g;cVd?Z(czmj>&osyfvzsMYLewVL<|B(m5 z*{~6A_ePHYX{t;|;tF{oTufd9SCH4h)#MPaEw6{`%lEO3) z=~zk;<9`lxlJAeuatQ`h4Mmple`GNKe6y# zs64F1CYbXyaix#JPsx1o*eCCW-;jBs9h48iAIL}Hqw*Kg&)Gw<11^*%c z4gV{r;X=z^D%zo9a2}aI?!8>D1*gmW5Q7sp72=45QcdQ?SX<^xIVNtx_>V?~P-&(F zhsjnl{)u&vdC_%~`J&QWt_2T}>%&9kM(}v~T6nt5hn?B-D2_k#RpB{XEKh-#%e*kx z$aCTK@;rF6yb9hb^Yn2>Cw7cu!xJ*chQ0D`_(eKEqgPPjj80sDgTveM3HXrw6a10< z4}4rMfJ6PgTnPSI=8xR|lxxD-OGoQ(4(FBmE5<=#RjxzjO1VE=RvrjfmWRPLD$j+_hLE2qP+mJXr>VzIZC;Kg-Ft_6Q2^Wyqk=8MhOGVapY_cG34 z>}RvlDTv_H}yjtebsweYKX)L#d zo6B9`wsLQ{GaPVZ15xRz#2~nzJRTk-&w@wDd{rDLuZ5?`9FlL6H^YnR4gkt>nWtcl zjPW3dtycw4&ausM33#i_)3HOY13w}2bnKOzz%R;t>U~Y_3UhWR?nFQMkjxH$6gQ4P zd;GZ)!{M*xQSkTj1o&rp4t!o-249fxhGV!=xiP*V<&rnSsq${Pko+{98K`mqm6GzO zaC!MFxQfj2pr-siTwneXzDE8T?o4+CP!_#GU zV2+IIGqzZ+0xy@j6Tuo)xUuze7Q9*R4sVtDgtJ5L5ATr&!>`CU!3X4dFlVmf&Mk(& zl2^jtMaJjb+zRH*RsmPa zbNP-EgWR2-n-w*)8W(d&G1>7_w*k!JNB=9E1VsJ3%7MAoJU^A@&9sFHX~73 z-T@bvcfw`l=irL+0l2#SFs4K$T9YJTCWu_sDz{dqExzzbfAd zzbh|~4pUJnw$L00#Ntr)>`$-P?%`! zC(C%ah)tI(!n0+Ldh_L)9RC-q!iS61ax-|7+!}sBz7Bpw=4iM}9soZr^DcN*2_KpUlCHvs^Jg7~Uz*gm+iO z`DbDwD$gph2;L_zgE{3D+pK~Q$PdEr%e!Dsg~c|{!(Yg+!zbjo;ZrhSw0@C4;4t~S zD&NDL3X3bc2xmk0XueYAmh;1$3X5?LTvx~(po+=W;F59;xE9T;6{Ug9quUe?nBe(t zsRSPm+sj2@PKCubJm39g-a?!Ti*dfFOqR1?&VI!>AGhboygL@i!{H_JWRCwURN)KB zT6sRq>94q=mGBmMBfMSaUGuce=YwZuzD97yt3rJNlrL!R4ax~KXSOQDKZ53=;M7)Z zQ~*xFrJ_2)QD|Y51c&E%q@7?kbFlV-6n}6UJD|7rug;)DwCU~WwaB3@>gVHgX zr{){EFwB{)*rptOMy>(>CO3uumRrL7t^>C32wx_5=lIVlub9BK7UPsx^dz{9JP)oU zFNUv{m%{brJK)ChU2t=mN3^ZH5$5byT>rgrPdY$l7b<;}coH5| zELUuEC49SF6~0sEk=Q6-18$_;9##RJy3Z?=Ig`(nHSVY@-UdQR&m24;qT-z z@Q*Stv|r`h;D2RaXF0HkT$ay(c_Rn$-`^^r!~;kak$1pX%6wHUD?blkCG%CW5q$%I za;=;Sx0VaSoVAK=cq?|7c`Np*iu2C|M%@@^t)d&j!(`rm6J#Eh8S)I6Q(Ce8T6lrH z0p^rejNcEhkhj8|(u#3*Y=gWL+mCHgnpK{tu*}zvkL4@iV{pJd;)jLbC~+nHgIpf|Nxll^C{<_>{zb_pmw{8|+A#kfgl(F` znQ~jWq|BpOUdE*m#Hy$=8i|@RUz_X8Yv3mGX1ImS!`n{Y33rj-hOd)9g!{{%!Gq=F z@W{Av{J%wIyb@>Osq%mDOgS%lKUe0FSSa)5b*WqzUMV+$?~?f|dK+c_THbv!ANd~& zROyP!PMOdAyXC>~vob$^-6v0k_sdJ+1M;2l`|{oJC-Ob;7xDw}2|0KO70$ZFbG8@$ zQ|7lNT$K5R2b_V6ZT^At%GvN3UO?t=$8iQOwn>GrlncRSWq!v&C7F->n2ZbKKNjE@ z8`M>T&;QrR{4#?qISXzhw}U&$J>VX4U%0Q#?AUN3(FZ;_9~+vF4QqjZ23@weTcRN_bY8Tl9Z zC7EA(^s4+j%-OpN4aOCU^0}NH{#xd!_r06}|16h)&&y@t;7?V`p^^`;8ij@cCl8VNKYaF3g0Jy?WscQ1$Xw}gnM3th znM3ttxdl93=BwOnnJ-}TA%!JB2iYHgSK{Qrc^ zm+!sui|~u`Tkvc0d+^)x$M7NfQ*1x>kt%<{oZE{#lr074Qcj1zm&?NEWDd_4 zb+jyh6qifppp+_S!Tf6*uAc)@CLFNR6P1!maKI@qPll_=x4^aJ3`*taPFGXib}(m%e)Q>%lts9xXcfv%E){XswlUDtIK?? zsUrsiP-&#fc(|#|pXqh`KVR}m>C8$%rHq9MvaiE zhK44MjK5tW|NoV`NTLvuEvb-7QYiUTqeiJz6y;qi^`72u6}?rIO1+ieYwdH6S)cp) zety?uuIJu+?X}lld+mMBJ%5SGSNIIFn8vcoVj9cg7SkFKw>TSoyTvp`CtKVVOz#d0 zj{@NH03Cm!gcAvRc^GjJEG(u)hF%^<`5E9REv5$ONxuD?vtlWpNAe35#>V-&@=Ue8yt@r~GCy?fG1=xHH&MXf{B*-d>9< zz=p-JTZs@SUlE72W^TP?m8JlxhvAQDp?&`ZLIgWyIMlR@bgQvf!%I3L`~VjAy!i?0KBw7496 zg~hZ%>S6J%XkY1NCCD@VES>=FZ!s-UH(E?TJcd|&2Y7_VcY()PJO@0%;)UQT7B2%Y zAf|D|hu$5QPYLQVy*!NAD~s@Rd5#H`R%w9o35jbjs!?%l%C>;0x-Bapa{FHqP&I#!r zQ~pCHuOp_P1o&)v_%BB+AX3p9A<)ACV|8s8A^o@i~S+^-+mR9r0R|PZHA- zkIxzWsgFxEpVRz=$qLp(b)Csx;`JscLX_BGCg_Kh`lQLUTB{pP&Lw`zWLlxsr%mom z{EW#Z#G6c}t+V>9$>qeGO|B$<&g5$1Ewq5)6Q{)UX2C?_7fhZ>yw&76#M?|>NW9(T zWyCL6$iN1WcsA^WcrDrzHf3hc#L|`OvI_+kjWE?KQMVF@rNeQAwF#K zLgFJP)3-h00>pF8{8Zw3CTEN7m}a8#`8xuMK9s+}%%{zYdY{SF#0yQvT)s3PXA<9U z=Fca7z+{?u>SB{=F4(h`!qA?r6an^ZttDP&#T@n9p009cS=03dGrxxNX%TsKA=T)x-zP3gd{a zIXsitn#1#ntvS4mm_iw!wZzsG-b8Fo;T^=*6s{$vDeS}FK}sAEuiWQoFZSNLD4QN> zNgujNO0~E%<5I@ujH?*O8Bb+Ahw);@s~L-$B`pGpZ7ipT@d3tkca&{m9plrC&og$p z>*Yg?V~ptrC+NIVx}b;^lrS!1T*-JOMgHm26?WoAG|ehZ!Gd ze3J1w#LP`#uZ}uEZ9DdWzA$fpYbxrYZ-51yn}Hq z~%iqDcmhnNx#~7brd`2{1 zyf_;4`q50tG%q5~_IorccC?GP7T=`5Rv_-$@OXuo)nre0TDmFWLI>^Vg@+`IyI;Pi zz4+sus%+7^&5G=_W~SguDztc=WN}OGl-_Elc%jXTuHuoxw%K$M8GR}O5Vg3P@i^ja zQ)VXP`I5yamo2$r*ULSdd+{=X%a_!ut%Y%6Lzdb`bhxmgeO{hfj~;YnKM|ZBZe+83 zBDf`!Etzb z2N~1TP1HiMX8NM`V&8{V1>%qCi&E1%myAdi{T)?;+@fD^_ zAI24ot0jvTvlb2QY>6IZ#q^8=Tg3^+XBb})OS+GY=0qCTi)J#;W87I>yQx<+t(;|5 zF^-F-zb=f5qK~Uui@BS6HB8j7!UK$tGOlBMn(=wYE{Z9udm+X##<`4(Og3ji2`eaL zT*-JOorqXi8RgB||r!t$jOQn`S9^-?&rironEUd|Oe(Q>KI3JK*D~J3cn9NJ#s?W6V|;@6DzlfO?)eFK zMM}-Y)EEjZo+I|o#k-GIizW9~MvJ#m$E2UYrjGGx(LZk}j%i+87*Ipv z?8SvqHCN2tABm1HXSjBzF7k&GuYp3Qh6ac|SQm5kRh-XhlL4~-`Fv#i6!eavdd z8J}c)j$~c?2uc@pcpT%IjOR06#&|99HD<$`81Gp&z$ zR5=#~f^%5uVlnAJB%0XBvbHgb0hfE3=+MjAJGzq*N{| zC?dXIW-BF(%NSQO9?5tjJV<7JH3GTy{^2jg1C2N@r0j`nTq zPOySAj4v?uwy2knFwSJ0$G9`&QpV-PH^3{@|0+8Hjx(Ohcn;&mj8`+>$aov$8pa10 z9|b4Wf#%rMQGvy$8J}nDqOh`LLX2aKa~T&A4>I+aFfOa-gi=|bP)0JI$apqmx?9Rt zN;gQ^ypA#52xY%qX*c8jj1NmT<4-xx3QjUU$Cz$Fx0MDMr!vlFT)?;+<35Zl5|pSk zT~y6@9Amm6$$q6B-GgMaeC5J>#8XA)PL4dgNI%(#?sc@E;=u297a;*6&f4>6U_VZ4|z-OgjnY-GHRaSh`Gmso6W z-p@$XT}tD`0ORwFT`lX|2r-T^&ShLge2Zy!3F9)xl_q0@i4Wa0V^^RXWo(`;9xL}p zb5^pfb&R(#-Yxb)G;x?^9VZ@YnsJixImUE}tt}H^oXR+xaRK9QjQf~u&Z!DkP|bK8 zW4gD*ZkX;Tv3VI|x^KkJr+YLRc1WQy9k1%^&&3GK+nT+Q%UdEX27qIng zV!VTKt;MqcbdP{t;TYo+jL$H>z}VZizHWqZCgVKDory=9oh)suU`@9Y<*cBJah&l~ z;!$ShIgA%GUd?zT@vWx(HpVrV82vwRDS>`-4TKoS80RuBVq8K@ z*NxGqj1^Qe9?5tjW|-WPFbJHnTAWX9#Q# zFivHh&A5PZH{!7vfBN(>6OtiDZz7&%@($wZ zCfDY>keDF~D{=Cn{JMB`u;K?*zG8zen{5rzas=hiD9LLHuarVyF(?wlqY^vCHvN9!rGVBs5q|__+?Rqm^l=SZE65E>H6%lpU z$3wxjkf^XE{Nn5t8ykvHc|0KIoazt}1?7-91Bq%&A|SpNrRl5QEpv&o{M3k;0|9^e zk9H&C$9d%$qON&?ORS~h!&HANiu+jgL*nZu-I|G&jT=NnW`7jcpm3&D7#5T6+n+8% zZCbcYiMrzzp-0nE;&2Nzkaxqph}d%ap^$&eB?;jlG$2DvoIBJdcH}jR zh>}4ALcwfY4P-ZwDw=!mgzxfKxJ2!|a`aHu;R8qnEF+qTuMf3M7v=X1OH1w@TV%n}*4T3u$Vf#2ksI4D_kLN?8HVZy3s|bXG#~^`YmvR&` z#qz@T>0su%#I0X%Z8E42nlZ9TjG>!d$WU$4Z0-nI@fc=EurVFb@*dmT7Io^A+)Q zaq^!PsiLj|gR_`b&l9IMRl{@lqWa38jfjXnTOA6nhJ+nG?QnTfmvm9PU}&m1JnO|! z@H7f-#}tUBkL*Yn-FDQZHvP(pn?cZK3I6C4`nkS;9mL$vpN4xNC${7jhJrB^+DeMV z5h|>{4>oMf$N0|v{r-@@1QMoqh4I>$j8zL!I)BQbh}cy4dMH?l(qm|ZWU^>N)y`2-@GnGH!7ue4=pyz6Tc)e)#PW8HqT+P0Whgiw#oesh-9%x#!iHl07f)x3 zk?mkwEeh?x?k=_;xF=mbYN|fd5s~9PSFgH6^sGVTjJr1_Rpg!T6$)0NkWN~WSyzff zTf^xhuVzB(s%>Go9c6YnmWt&yHR+=C;{~bWL;)II%_?3kwm-h6p{P4j<`t(49!y>J zQCY}$z^*MG`E*7zab|niCC+t#vkrecBNRMpm!jQkL}7y_4Mq8R!@H`{^@xh;#St;_ zyb%i4LCSV|nK*Q!B3-*Pc*V`)sJ6rym)F?c!qxB3nb5J%pJBX@|i9njpLFs6W&R*18E zC#0*p#gSL8ii&NQ!_D1LY}-0W^n4A)`^EO@#Zj@Yay(W}6x)MTDaNa?7)!U>qX0 z)x*WGzk6YngSyvU0y(dgTV-J3+6FN@QbvkBM_OZke^=qc>3yl{^pVzBVIfm(d49A| z|Gq!nO&18|nj*{kF9|h?;nFgDg^aUKW_d;9k6O1B3m+UD3a*5ZJ=Jd$!_MzaSGS46 z*D(w$&+iQ7pG2|U%s8fFnD>7=iY^-p$hMnSp$Mr<>p&meC6Gi5bhXZO zTV2LjZ0A_v|ARJZzCTMf4@gNSY8WRdnJVj(2d#e<`wy2E8IQU2zHK=1@) zY}ZZ|&ptmgUCk5yFZPa#wl<9S5JsZm!Z|8KU9T+6)3jDV2+riK9H`SG>bQ? z4`2$g;(21g`>~>d+e?`K&3!^vN~@u`=`elmM#P&b?n8dU$BMdmk2;x=BcKj@5t$v);>S^ca3}Q>$3@DM{5wVnH%jkf!vKN8YKaP+j8w>}Kh1dZ(~8xLdNDg<9{1NHuyuj$6lil8?~kj<_Hl(IpqzycemCdPi(v)vrpb z?)8f1w>{H1+}Fy-&W8Nh`PU;K3y+eN-$-8ngnSIQ{LmYV-D3N$S&>Lm3n7$D729X^ zjdVi^x3L>+B*oOlP0&JR5K-1AX_$|&>m}WP#oA;QZpWp4#m!8`yOs(xAU_91|8tem zE9hm9+=2>Jx5s)5tNx2s-R@nTNcr=bXj6K}Bd@*;)sZDT@PgR)XupP{s#Pa2so%kQ3yOGKo1kKc)z*t*(ZWa4-G?DPTNJKE zSk^3jB$QvJIpp>G_o{R^y)bc&X#RUu zR(`3^acNg(H*0`iw#Z|0rh&V$Wdp_UCpAz96}473USTT!NKz5P)oL9~74!y1?um7H ztdZ@B8m5BY;>@imy`-XP5Jg-?gcZtqQ!%fjF=d#kDmRk`og5@N(k5No36MgNyTiaFn8v0 zj}}w$e3A;fs_zaO!w9{8l6zt$G}t>c2bhM>lQb+7%g@Y+7XKrudH^qDDL^%fm-krp zzmlqNfdOvWhej>oMLtYBP-M=Prp-~rjqAp=9}<6!k7JpHbVGBP3U0^tb{s_PDfl5X zU`kRer%n5BPikQ%s%KmFA7Rz$t%}@8Zwl^9Gsj?Al8Uv=f{&RBiWaUS6Dq3YY;F2# zl8Q}Gu^O`E#eaxD`eBPPJB-`F&3@*UwGZW&;JyXBpP#Z;H28zJvJ&-Hn1<2?vfP_x zP*G*I@)=XnGD$@)uD@$yHr;3Vl2HDpl=_X;7pz|IqOXT|B2Nll-D3Oi1}WGd)w ziQM{1sJKx!-Fjq_3NIdPP=TuCqkl3Li^TR3OB$*|sOjAz-I6L*p_07=^fjyWY*M>@ zBDf(>d_C3Munk?R%DpxbuN9(O2dLeDGZi0(#Ju)Twru)dl6-B{Avb0u|BX2EH`a|* zT!E&T>$K})RVY86>X47)A(8Kx$`*(aWL?^((q(Gv%z-$ct%veQra9z|JXG%#t4A+9 zIdmGY;>!q)jcU_zzQYYm$odP%+C?F+52{B)wk64@`x;`W0z=n@N{} z#Z49WB&n!@3VXBr6I1bAk`>3HVx{ST&Mo19^QdR9$!A%;50mQA`!Pz*dJC!E7ToAl z0D0>5FRb2wlIrb1J!@C@TNH7}9ft~g{{1Qzt-$7&E(tTGMa>Fqeor!y-&rf2FeUl$ z97Vk$;>c}n8x|L$h_`YMD(JQeGV~9oqB2QEQ42iUPIj>A4M{4Fw{R$PP@Po#SIl|{ zhSDki9i}_BJoHG&UzP1pGNp*vIl`OarnBjj#r6lh5%I$aZ-e~VIrYPHky)|Vvcle} z%FC7$eo$IO6puu`-K?Gp{nRt^*|$m7m!MviX;0|@>Io%&vD zij;JG5{E5XIxhW;aEl=%LMNc-m?Fy{l7A2)2Q4ig*7^XfDM((5%iXAVjjUIEEsDs< z68zC;b*p+q=s`Yq2WBRzpwq@phct&PV5VBjdV-W;4P@%E~YaL+mbZY=HqD%rV-C2sTf&UKVzCQ6^D{kDDCj< z9I2w|fg}~{pkkagq|LMG5YXq}vn8iX5im`Xm*39cTe6EZ!KQ3+%ZO z=R4JJ$LOK2R7UH>KtaRLo~8IxrPCC#g6971-67fgjsR8kRvrDQc2GikOBO z$r?K0F&<{{Oiog9v|IhE(}}5gB1y&k%kdx{Q^lGj6}yY;*S5|~1--ct$xEwFpU!m5 zl@`3>ok=QobayCJl{(UesrWoe#l$OcH@g|a|434C8gF~F_vyMZ6&I3J#Ici-V|L{C zBo*CC>vu=HGZj(n>mhlmBg>$|JakkXMiCE-Wl&+y_!6e#iX;^^P_fzc1>JDLRa}4y z?A1$OT**{aC#i^cr|m$`W340Ik~9Q*JCr)qByUo9*mH3~l7_k-wD{36)?^K*`_ykV zuVxyaOVW^8LI)w~AX@R$Nk$a)tv{aDhp9M}q+$zHJT6regH&obLl52!Iq_SO7UMJmIuF*cB>N(eoR%VWY?X@1mFgpGAdj_eLWB&l1uX zuKQm_;_)%A~%i|(R&mBkD^ZhXHmHC|0)u%tzHz3AR9ixp1#{9i9Nnd#x9wIZ%)Ir~5 z27Mkh^>tE8WKvP8hdY$nV@-whv_d3iL!DhI^+C3?f+*OFAszuc+N&BUaFo)=+T`)QJj z`)K!FZ111mu=t}S73+F9m35Yi+n9>)lU3jWk`IfoQ|@h8{7sUIl0Hslf4OPJIHuw^ zO9f2``oxM=YzWoVqnsLwFlC@}mI9?Js@8vsIinmlH+aTXd-a zKRHmeO!{Sf6t#F*xE^sT$1vB(FO!%>t*vHlEuY`5DhII>YJbQi`eY~RJC5fnkR0io zB9?E&>4~Ses5qQDY-0+}n7*|yCGfVYWMT!K0f|pU&yt=o*O#htv*`I0eqng$#lxPW zjvYD`b+}A4pBGPcbu74|gGjkWZ{?^c5~JtE+o`G;w!JzX|81Wa&%%HG-x+hG$Si19 zX>zH^{7*;Mu0!|4hdR_3cjYgLm#OND&)jie+^N1O?z}(#rrJgHcp&}+{`=@Es1v=(WUm_nZpND0{UF+w|kX^j(NxYU%C!C18p~WyO?>;HYz@2 z{*$F|c)R@nO6S{0G- zBOYv(pPE<-b~-%&!o5nc?jlH3vsuHGgOND+6wG_;9m z`cOQ#{WkoncipHCCZP#9-0K>w(sc5NT+gZ4b5`^(X%oFgJ%{%7V49fvP`pc%3E9Zo zF3UA~rhx0bN=LG^k{og1p?Lr7>)?2I=3Z1!*^R--bT==<#0U?ADt8M)B^(#UE922b z?@VOnG(wAkFulaj-I6#I-qjG?iVj;u!tcP*?p)&3a3Q|kt;v{JnC|g+x1okJ6rby3 zwB~aiz_+Uz-0W^^X6!|AgQ;jTM3vAJI99u#D!DGwdz7`8hyxKVMLhs1<6sQsVc8u# zcCHZ;4P`<#_G?H)q$3sOTiWZrPZhIoj@$HRt$1g@-WL_qQA(8_Ev^9t4H}qym&q7ky$mO{|=!T9UoZxxD)G+}==~*mwD6Xq9-kv4& z=oHIoq7d>CfiER;Z6+<&uG0ul&ze+Zxf1Y!=ds?v2J~9z(ATJ_xaitM&&DB?JDzeA z)OLt0Q(W{W2hU~-L!XPf<2p~>*|Ug*A0c5WO9TP3wZUdP7qZmdy)RSlTXt@U3{+fa z@$Gq?-Vfc_9PL__G)Gp!^$8{7!RV@y_aijk9bmsR(u-&DkAs7 zG;icM)(&6fYq-fDp@+}v5xU_b5NVf1!%gqZH6jbLVMpY1Ka7shwm&7(3g6+#n_hS? z(h?Il61fRoY?MH=6ab$gD;g=30YHz?PK$g36-^?8U_^RkF2*4i`7btlO(XP7%Zv!U zgtl4a0#sy1=zYS?Bi)Pe2;#`Cm=9Tz2N84G5qecePUKo>ZW+nMoe`}f{m|pw$W=JZ z&^mH80=!Kmv9bexsYhxMb9s>$(2x8Gz2UW;63{#Y95J+Llp;1gH#oM@7#Z}OA5Vo$ zI2G+Va{53AdDE|XDjnBAUf)3SH#z7Bvt9}hcm_*7igq!G#LbRe2nBS{Eshre38P~G zxkDW^wu*5#4D?jXglcSr&7NU0;V>4XGoIm&OlWl)^a29U2wCDX9wh}MW!r8=Yk_&= zi8}^Cw`RZ%o+(l+km;G_pnVu)HT>kc!*Ncw*N~n}>bX-I>o9vdTXxQC3`AIX?vj;t z<7-S@&)udbn{G$J5{jJMk5gUvfe5xu~-NujePn57ZbvfWdRdYO91iaMmH$ zAJu3`VeqpV28yjb+J`xLNj3HRx^Oo*^>fP&E2o?YYHy(6nQivo~C3c6T_pV}xY~U8e3CDJy$T zUyqUrpQ6pAQ6BB|L4iNj6L&rW(52(XkS07H`ymR!+oVVJlQg_zWw&)d`C^MD$%Mn`Lvtz9 zB@a9r`)QDyOI3d3crzqg$b@b@N9#hCX}U2h6Nzk@2rAkklFM-oLPO|PD_0)k+Q<

    u6Ia#z*Fd&F14p1vxC(g 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

    Oh~G>kx>e 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

    Zwc4R zx{)_1;f4|}k#I)|_lsZ`YCOvPWn-^8V!rtgzO-GDB&57#rd8qIz^4-HR|zZGH!RR3 zoGjrI2@jL-Bnekac(H`NKjB>b|3-;?ke34bTy-y}>wql&mcNy1qYZki*t zQJIv`Q^La}JW0Zp5?(CfdnLS4!aF4VTm)17UycyKCnd~h``XcTRpS3EVP6BOmJ-gA za8n7FNw_C)%_?M=lt90`jJU2+!iyz*uY@;Bn9ugLjebtzzbxVRZs4$T<_4jBC*j{D z?8L@w#GrZ-&XsU;33rfiUkTGok0W}fGR77L{mqjSmYQqc!3e%vVjYt38xsCV!lK~~ z-2n+_NVq`4ttH$|!hL2_KU1CldZq!hcFQHc#pp$$2+w z#%J}~&D%}l50UUh30F#ZiG=xlUR%$@5`T9DQ~eJ`2;es){E>velJHdtEBQB!j+JnV zgmWcaBH>QJH63Gsl)xwX+E(*PzBcBQd~N)YB+n=L+I&9A*T#I3uZ>Sh@_dr7#Sbe# zNeO(CubqKU^0jedqZ_s4lYDJHpX6&}KFQa{e3Gw?`6OQ(Pm}b}&t65L6@SWdDS=P* zwKMRkzBcAleQkVHlIK%>Z9bpsYhymu*T#QH@}9;wDw7bF2tL)<&cLVo+L%xEwK1RS zYhymu*Txl+o_{4AQ*fiOT7=y+4&Ze%!12Ib|BxhlicOG1Yv ze3WpsC4ZdcZOq3B+e%N7jL(w!h-7U1CGl;UpCy^r^pnd-LJVQe%IpWGpW)IUz3(+5 zQ=hQytz2`JIiyawj99UjD81t#-p0M9Y$GK+fw13_pG@*Lu9Re!NO-k`Hxjms-)!-% zF8rh z!nUQ|CH_zekC$X7OZ>SKULwidCGpor_*8#WO4u4n0RJfoza-(~lKguT|Fp#aLgIfV z@qd>1bfR+26yhwp;g%E$x0LWe30F#(k5sn3xSja6tM?F&vt0c&aO70D!#8BY%4s5O zSATjVLHSDJUn6WQiY>l@QwiIJWf6|I3d;qK91&MWd|Q7Z0lZ>GMtt0-x3ZryP>p$gvUvEo`g*a z?~?FI!tfl||8pV|EZ2Pj961#4ds~Q7t`W8kbv3_%`P5>&3DSsP+tO1XIC2hN0r72_ zmQvoX&7~=%mn1Y)5*kU^RysqHxrK1RDr`P*yp4Ad-!^oQB*TXm+cIZ~&jz9XUlCEq zQgjJ8a{L<~X>414on&mK&XP!GMTsSB^HU_u#~a)H0^-~H`KV)CXBqLsiB`cKK=8}s zKpK=_XXdkxZ5fmJHr__qRiKAkzgy;3EQ=)E%7rY+?a3(8S&Q?I6lNs zX(P#WC2Z^ICGm#?oBHRolW3cn{+3c=2mpUuB*EQ;v6D)FPXWi<_ytMkHNtiwZ%h1- zB>v|T{~L)P{y|FkO-lGn;(J=&C?JNgZA5~E^9bACYf2b9ru5ewINrwPl1xv+jjTaX z8DSBeVXP!HUEGFyMF_PmpA061JP>7Ky(o!lxiyDkW@+B!It_u&wk(N#<3;*w3WDH-Y1A%!f(a z#$Ax)`Cw_Ae_hI(-db9OUOr3O(iv86mlE!fGOUp>{X!vP#2yJBAZ#1-ro_J>@xLW(8{}zo1J@-SxsJ^u z0=t9smkS(k<6;)F_+^Cc!g@=1j3hISF!tZ*ZzgcOjrqW7JMRWbeoL4LJK=FDVIN^^ zanaxN!0|RdCds@**v|X8gfA1e<<+*pcJqZKTw-IaZ}8J?BCuCQf4wB3(Gngn;i+cN z^VkBLE3s~q@Dd3xlkh4DuaWSB65b@?$0WQ{!cSQ^%=SJjCA=Wvmn8hUgx{9%DG7fh z;d2tcAmMK%{6kymy7*Tq;dcpNm$0L3|C8ru$Mx`T{!~$rSE(|`bkkDJqwY+Xc{$I> z^qxdQ7f$#wxG>dRRBLLY*(cx7y@{V$zg(>{7Z0e)Fbfv|ou@}WJoRPYCIS&O4GQ_b^f1uiqCv61O`=QFdsvC+$W1p=d4pzkfM zQ_avVtzG6*hh9lAPc}AmtzX?Xj2!O+k!UiUG^W`Qm_;iib2=8sF8&<%1tqP4y?R14ckt6;vMN^}<<~nnunhi~n{bF6Ss<1JByVbu!cj#x#txZvI z5rnw1=8?svFmEMFPANjkLy*9sfs&h;i#xx716+%Y0&O|?k;*nTYwf=o7Ja-O?NS6! zY?cy>&Beak>Y8e?k>faU#w;v0dO41tF_++5I|Dfm7AS9N{_@MZy5=8{(=JK;)@H5z z`|6r2pFNytj&5e?cw5A*X2$Cd-&wP?IdrM#%oWXzIaJ#cqqjr2-|CO% z_w?Q2N3*n@F~_m(M{{30BiG?AGtad%(mgw_Vf(AZ^pqRv?v8^L<(PF+Y+1RXyFJ4c z<#V&ij}79@3eb)N`R1+VMwa-}+){32I~H{_-va6O&OnozTj)U9%}tAS$Kjr4a(nR8 zZpK(_KD`a6!wzYW?3eqPQ^5D6FH)3+h31C#M!I;!JeJLMP#E@&we6gj_G0CQ7Z(eSqawnQ+!UYpQI^?dbe$S zAF|C2wF`S1kFqV4<0;L2|K}|@(zr0jWiHyg`8E;Sf25aDUx+O8VsB$H&XAqZ$58g>^{(J`CG8ZS7iYUdY=^q!(TWv! zZ(hE6dEz^t0Gn?NHnL+Qtn3H;>EQh{*f^bbwy?{&qjcCTD?r}m>e^4D(z{lZZziwp za%TV4A#kCqdg73%4W&mCW5(dM%bq14X-m{;0KWpuf^b@O$rHaoAr7O&JT z+~-KynA#n{3RRbS>%|ho`Bsq)zM@MVXZ7@DwOxKR`2mF=$Rq z`UhHh`Ni_iEslnicU?!^Wcd~}+oP5#zWBm&>M*`!i%uh76rRdhP+i_WAAI=Bs%yIA znt5;v?8-FbrW!f@C=rENiDNw%-}#2LZ^1hp9XdHWx3fjZ^BU8fmDhW15jsul1rucW&L{eEb2Q zrN`%_8*d8AD0Ehv<A3^FWS=0!l-z9dZxL0y74fo+<1nu*7wDrj2Ma^a+&$=3>bIO z{CS3v8l4_^(1SQcw3>-G8!6e>e0Q&Yh}!IEWF%^R1**CKFUd*Y_j1p)YeL^+B^@rg3xhwZgrN3W`F7sL_`*jfP-rvy9H-yg6_d7CUFm zcV-!vkn_3OMn^=#U$c##`08pPE~?GR20B^3xy>*p;%ii;5pcQtmFJuFD~;5;)e|e) z`W~_>TeZZlZierxatJ^)2|4ChViY`Mep_iYOsLMvOwYR0^Y?LI?PYOF`6;d3b7W< zHy>pF{GuGlOZhi88x|Uc z-fK%f$?$o`c4=X@Txg7f4I394ZA9k&&lVcPMRN7-=8t(L|=+tKAX(HX>E?kY#>l|6MR$jm zbfS3tue7{7(4ps>OYcCCpD{Dof?UYn|Euz@5f^fn{Q!Wkx1sZdrzj z@XY?vcOe3^iv}H_u8d9wty{+xS-1%z-HGn7Hm7LyuA_xH#pXZDjo$u-mPygPy(4 z$i3krxUg_+6SLDgV+lmwTxW#zYlAB$7Jj6a@BN}|xxS?RHS<5~jAs8UN1OG=JlMN` zy>SR%v+p;y*SZ!p&gF~mgmsvcynr#S!3Lv?sBg~RVBCQg{cVGBA6j&oX&iEz3oevK z@9(zJnBg>iUk7l8ORO_?|H+4qcbwrFtLdE>^yd=vQXk)gfO%zj`w{W%KL?IucTb*C zskmHGPxOSSBkBP5eB595z$;Xc(131ey@AwWAo z?%CKRb0pEGmwQ8Z!pV(DUUlbSL&Bv-U2cajm%A}$0+jbDcD3*|r76CIx(Ig&J+1?g zk9vX>EW~D;GXZuh?nUOrM~zSidWoVle<5*t6(CRA8wB6R)rTwn1I`i$nDHIKx~YI! zM+p9y1ekM3bWIb~3OYTe?3&K6r&RO{ zWY-KPgg&?{h?_+;#9g|EZ6nuACRBa5+4nIcDVy%YxeVqdC|V4f$5kojK&kd%Jn$c^ zN84_$dCce+{-!1B9ct;sTiaJgDRf%>TfpA#DBhh;Q1PBj0nQ-o^3u6K?#z?Gs&^6^ z$X!1KJAB>;@yM4ui?Hr3hqv9?WM2Y%+nqx=(L0`8+~8k)rg+=KDtB%*ZR!UR5`Cf2 z-dacRh70)DoCWPJ`apaloCjAcm zj%FaHxGg6obq6t(2~~fOVsIK0K1B-`B62*_-SlPkpjjZkB_{2bK$R`EpCF#kE`@IB|*_%7kq!PeMt)PLU zxraM!hisYRz9SE5%c+K{OIO0MM|=-_DDEWmpRl^^4Pt*nY$`jRx`g8X z9sNh$MPccF95qr8(t9=HuGdHrLW7Z&aelan^D6EyLXbU@3`SgTgd0z$DeiHwO?}A) zZXK%ukBSjdh`#`xr=tW$z*-T=PNgQyLFaS^=7H@BG{z3OI}k3XCcKVr7!~M?C{zPu z(ZJroK?GoQU@0mR6Zjs!^#wK+Q47)&z_9_kS?&+aL`&&`I$6|$^ay!eU==Rg;{&zO zO%uX_O!T_ifu>|bpg-<>*9kldOA`Y_p*krL1*OS>J77fJz!tPXN}x6_-RlKJ7j&FJ zS_8bUGEhfFzYTnYQ6?>LQ!l)JH?RnSk`eg2Ep`V255kl610^UdEASSYI6FW`Hsu6f z=!92r1;W!1w7G%r&_fyqK0?&w1*T)j%MTPlMI*)UQTsU-!$N%$qD$@XNJjiBx)U6A z026pE@#+w$fev_6N%W{g9D4zh{vr9Hjw-Zf(!ChI)nTkh(SD+6yveZ&LjD*vJkk*l z^YwXg;Ev)qrYgD%EuxNQLg+?5h%rn!^qVOx#yT28t5Y8guc+fV#igGo1>?DFx1v?S zk!pqG1r(xnf*VwW#rz?4zQYao>Oa6w>aC7{!>Ep;&xJ44+t^r#RnrArIaNPGLA;PN z$LQGz9`$x6e7cF@Mh!Ee>E|)rsEZu6VOOmF8bUx_Y?Y&@q8ZgCY;mGKj?BN)(HLQ! zr0eJ=YIrGYNY=e%@iHdr>Zj4h>RpahcqT<}nhjz(r_|GbBC)%f2eG(!uau!DwZ=Y{QS?GYq57>qSKq})GKybXT#{6>MwR- z90pgdFi^C+C{TZOq#={`FzL_d7dvV{VR};=Imu7{M77lUIcXhFerV|&39RVvcLveQ zc>oRK(r1CCwstn7is;R{;IoZ$BnY2=2!z>wj}Zv}NO4i_{1xl~3P%4_J2>Ycqu-}? zcGi!H6wpO3psQU#6lw0x_NY2*>cN_#74746B=vHBOPZYOQ0LehO~Y(WcVbvl!#8ow zgr1%QY6KHFFQyHK26d#f2{OTsG0xpJxyQ)tSZtF0$??mSe zC`e3HE1cH>lGtUFNmE!!`ne$_rm!!Q+|;mmWiJWQVVdeRHaux46)>I6P_*q7NHd%V zAf(+&W*g1`dQDs!KH}*EvjY{Q^&=k~U`w>;Da7AqS81Dx|EqHl^wiOA#RRTK^Gjp> zx~jS8%_sV0^T#KRq=_dmbgH_G+FRAPpiR|UOhoHFdw_^z!lx%vzldiQ^dfaEtJDP7 zVCeD3s`Xs-?h}0iI)oZzc}0IS1R|9Qhu$&QoVM4%8C;FQOlKuAdOp=Xg9)Eb&*G|? zOlXR>mgMTYULf_ln(bOc>StpqqvqJ^xvU1ZdM+!M2^Y$OSVI?$%pR+q^6WCU(4*37 zzEy}-d?O}MAtw#Pja_*t2*J?A^?6N+g?5Row<+tj2hk!IO&6-(9OIo@?8=6z%i#HlmzDui8u7QJY_k$|Z51SVqyiVDPmqXwQee|Xv`4DTcj3A|cpj8R4e zHb4@6wH}$eg;&D8r1zKs(GtKYa=OsUBg&`s+=}KQA&dK+&G;2I?jEAhM;K`m#H&R>YQ9WLu8Qw!BKV z3?ipoPetz6++R}eKI)t9;WfG6l5@W;=YGeo$u!8S@AB0Lj^vEP`b0h94w_ers-WI6de*|hIv(|)i_Q?&k6ugmVUl)1Zl#XY1Z^DlDdt8(UF?Rv2p)v0cp^Sde9 zS?bQ$+{w`3k5d0|FSk^ge?4m?g)@h|sy@bI$8f7}6#oJk=n9IJXbHK}s}@V{<~ zwIp9pV8uhxk~FF#u<($-lSZTgJ3Q2KNu4QHoF4LDQYyL3eNd~x`gOfqda7lqV1-Ioa$K*LR&{UG!MNFhlh-EfOzV)@q{qQkgeM1v@*~=1AyZu zn_oU>B!q)BHzj&*A=Z8Pu*MRa(D~`8cwP%>f09(HXCp~%Cn<})u?*~Deuc1h7v^fU z+``LgS)D4Cm);T!e03ZXSSrWS(q_EpEhPEfYK3P$6>_yHn3FlPqK~Ela|#neKS3kMR1b|0 z4n5EZ#552n->F}qt~lK@4I>gxXisemYKEr~)cI4?*`AXCwWd{0#Z2v?of1WNQ&UxX z-hwJ!UrHVH7SF#(NVH0v!zCu`wP`gqmx;QH_INu`^E^vQZK8UchhEX6PY!#)UErZ5 zu%ai@Xt9tBaapQv=iJx~=|j50o->p?L0#e*jNFz{cUVT%8b5gsmgsDUZWXqVZNe1>6wVUiuMOAQ1^OfgV0vh2Y%Lb5}14DcL4F+hiH`_jwc$X zP@(<;^^hkOYX~?IbA#Qm?9jtZ=(WaIz`IA72w_D+)5c4lpOH7QKt1N^fxJms)JtAw zJ#{BQ&nuQ5?HJZA>Typ)$Y^~qDyeUJ#@9jp_`Gdann`tyU?V(p4`SfpS#Q)Gk*TcGAh@e$J@NboRk2ahb02PVAbddEJG|g1GmFpuE2wkcLy4y)jdjB3sQ}$Ili@} zje)N-#$qHo>J=!fHGRxHMU9D~4h~}S3`O-Z;m~_^fVjqlORrCzHiy&vT1h2=w(k_5jHbZ;vJ9jy~h(0#ld z`!}f}q6y+!5zyTf16fRAH4Js%iuGhnXNL9C00%HkfIDL*5cKOYi^M-k@V`Ew5txhZ z9oyQNh+}Y{03t%Kmkr_$K~;C?9pKcMJ2}Ore}j&VlP6iJZqWL88517eO-0ufXv*d6Lw{>Vx1`oIJ@^D%u%r9^vT8!Kk0d zMdKuI0H&gPk^O?~A~3V93#H_I;K9!3NKU3wy93-<9xHK!BDA7yDu!ryf|GXEv;-`< zaVQt#i-;8*$weNFTTk*d*~PyB+v2~Y4|*}PVr?J#roIh&==Ujo2828+P1sDfBxKn|k^ckd9&GX&j4`av9OD|~h&EWv^p2bY-n@dB3%S%u0 z`{wzPs(R^#fxh{~&#^rKHhUll<(M*kw|+!QulQEdndaW7(ZhYKES+C~;k%bx(K`lV z@4Js&IsMgMHgcW{vk!7vRSUuk~(6{Q7pJ!c*(LSJQxZHbY@Yy$Zt3_XO!b?xnNRe7ngZ zUwQdA-@ZN6rkA`OTOi>{+8Miy$fLmVxW?j>+S~p>K@?CXf*9>WMz&wJPV_X?{&-d>&eA$(CejopzbGNy2nM;^0;V^+Fgc$ z$M+^xMpb?9(u<_Lccp`Mf(lc-bwa@J5q5Z=Agw0}ySyVQGTtYQ?hrt+z7LKguX`uv z3}5&H)!2Qx0q}PWZ>IWQA*i*Y*zxlK;`jOL2?Ncp-$ZR6WUT0Kp!@q$`R*@E(7 zN0<6sj-_4EhJfd5AZRhDy@1;I3OFV12QaL0ot;vz$l+@)?hnE4doWt~O1LtLPUmF% zT8mdw!tjtj6jPF~jK!+;<`@lq?Zigp`9psM!<4UFQ1kp9Y)oCeBa5Yo;B(X(omeg; zf+wh3c4om$5!^vl>LzH=>>z@7QWSLO+iYD#Fg6QR52kvEVE9$?aZj-Y#q|-v*%-Qf zy}2p_MDR;W>mwdV+7J=!Mk85Yp`wPvMeu4HQ2j-H^smt(*ajj#EEyxk#J!Cv2f=`oeBf0n&MDPg`9VO-??XU=r zrTUH*@u1!i!SmFM$8f{HBZAi`=Eri{NfCUQdd~#02R6Mgf(Lqnst^s3FV7KtuPdm@ z!VlGr9Km<#m3zJ^;s`_w90(IStI^}4dpsUjL&$hsbk8ORfufKMj{p=-Gmxg$qS0om zpeA?E1lICCgG|g5ilTfU5iV0wdkC#(Q}h!ry^l!i^)HeYZ#%T5*85+?A9@Sz@oRl3 z!R7rJajW&Ekn?zJw*l@)+YCN0?Q?7W%kk+C)hPoWNb;%(eTM;F8$?932wmw2VlWXt z5ju;SYeT5$SP`1%0x^`jRh9@%M5}4ThzMtk5On};IE@}TA~Xv1)kaWK0}&b$0x^9A{3nlVh-If>msbdmlD|Z4*rZn16)M1`&4U4 z&L>}|&J)_5FT%gxe&ygTC8&5m>kho^IIzn*nu=Jy5wg1XKa_6;b*cpKQA|By?H)=f z@~-WHgjJMK;_Zv^UAvd~L%a)`0Tgq6=lFC@sE42BfPYSi2sI{ZsckkiGL~VeXkV6!?f*x+1nWo(jK9NYVSK#@K(z3 zM<^fu)gC2&q6pCzl=c{fMv4g0+a73n1%&HUG~`Mo3r2_Fx=t@P_qplLiRm+84_AYwVCgZ@W15PnYSqUV=_ z&^e`teu~Vf#bYq8%o>A8;Guhf{!@JrwFT9pQm18(7GO)}>9o$#>JX8y+^WwaDp9n6 z+=3vT385tkx<7f;5qy<=n=I%C*V~TZJ?1a38+F5HsZv26c27BiCn*x}pdU>Cz!9Wh z7i-p3dD;<-%>#w!l#%wKBWPgo)*3SPkt0aI$kOsy%f~caQX|Ju<8_4{91Yk{Nurt- zh-qMJzmT$aVse%t%B`HN5QozUhko5PZram#$TjO7wH&-^()lcGX%{fie86eqY?>Wx;uCtOKR;F z7R%AOnseBzJa>!Qt=uRT>ASMY{S|zu2qTN3%Rtrcumno|GEQ+wr{S#{XySb=7`Y8+r z+6qB;BKqnccuc#8iGKR6V%5L9$JFHd`#373A%EPBgm8h(Tvd5DE;>G#wF@d6Xs)|fmV zO1OmDigt=x_lUSa1ypFqL;>8+`$F2w!rDPQjm;nJ6()53Gc0$s<4lBf{AeFLGE5Zc zyUD26nFyEhwwv~*cnhOIAKrG;-eOk`;SDS8Z6=2Cc9-@JhsJQ;2-DtWVubz>b&?ZI zjMQHyU%$u1D1EXA#QR*~(R#g15T}?JkB&fX_kjq{Ln%v^XI8gF&!)z>!eYx6 z?LIQ~s%S;#H=@4$4;NIggV3CgT6w5hdm08^j1_%3HM-kTCl3n~m%f?iPmcp}iL3cP zLLj0XG$#A>?c_4mQI8Z@y~oS<<5T!~1udG1ATOY`7`{&(;>Q&@vw zY7O+ys4}q*8gg3b9T7!Z$dN(=bE#g@15`TS-fyM%p}@&-G)*_JzheX)eVdxWckv|b zPP6&Dc(k&&Ir3d>+S3gbt*e9Pvdw&-MeF9ExonHR$cvQj{1CxbeHg_?4<;Vfds9XG zveDc0QN2O*V{5kagAiJOeh}hu-AUyS;5<9@&9y-cWn!m(3k~SQ9cnK8wyW0IX%iG} zl!F3ickpR)>1YRCE|rMj+cbh!u<|kyq$9pH>zLqnBIsxcYC3Byr@5B8n8!7c`ZRex zA1Y5=>MjHTFBbk>20WESr3Gi>+~KW zE$oOz__o(KnU9??(!wpMJ)X+P$31MEKTq4`s3xs+=#usXV@0P~U)$}VeX^kbDe2k6 zUbDy3XB?Z5C0Ebvh?Hl!?1or9L)rz^5#z_ua^*S4PKf$d?SP|*j&j$3#yGDXBm#xr zM1A5ATSEJ`??Hp6(ZKhDLx+I1`==do&>P7D(~(mNs4z_gHo<3(0KI9%88A?QEASA8 zUw7d4_V8sS-E^8+??p0~s7xiWqkX#^KWwsDo}46}VW2 zju4oK$nge##|(rA7nbybQ6E_@3uzY|Ls2)qH@W^ISD$WbnW2+LVh&F$-!L=U>Sy0l zKSO8YZgz>gnXa!lN1rs3`ty?d2M4XGQ}9?qXDGbv_zYHSbx>RFZ`M<ht=$M2U`;r@1!?HJ>?D_ zPXLwZ`~=jq?%-t_7?PZqK#lhVb7-DU=1sQ+o}iaPtu9jwJ;CouOUU^dT40eUNH0Lr zvYfAkuxO169waR}{3JtObnv?{xu$`W#`H$fLB4#><-}&uLArmUHDskF(ZRc@h&<;% zXui_u;AToIV99RL!A+FbgsC3U!LNyG?xZzHpXeZ+PN}ta(hQiRrHz?68EXz_3R?6| zEqHfb469ma=O3ukHZ53-I$T$0EOPADf(>a*>+Yn*_ETE$G#T2%NgeN`7W|6Vpgoy7 ztp#uD2C5fRpJ>5*JfM2B*=Mxi>(r(DIBCIrRts*@LG@+ooE99{8G)|#WAY0v_y^iR z>(A7AWTaj(fT=IF-~wv3A*}R*7Ub?boT-aiko)flC-vX2wBTNpq>Xe^L|1D;lX~7L zmb|6~Td1H$J89AVn--jdSPg4qxQ2gg!7#0J#Jf@!!8(PlE$C?iOZ_h_@2YMc@LoLY1?`=THtc#TF-gQ+GN!N;f*R61$n zp(rERrz@yiIIScj_#4_)o5NI#j9`;?pyskVMiZfXEIM&)7lLYZ?6M=~!>4iEd_Sh}*n5fT z@UDcfWACGB(&Zh6_>5gm*b_Z{rlG{HA*?Fy|G<;6Yp0<&wM*;+^FevPMTEvaNa>3A z=2YN^C|DiQ(<^ULVmA`s6vd@V64b0DLHTl#FiTO@`NFw-LY4`$7o#F?v?I$eWJgC3ZXM z?4Y<~TY-4|4KmsjyZdPvZ5j6@r7Nwh8tx^+;hkIt*{2BOveFN|u}|NL4DMGE-LZ#> z@6JTr$G&k2+_=l8_{c~Ne~vYRdog-(?1ywU;_gnRpV5jSQ4b&11|A_a8u`rq4914o zizMLwjokNr3zF?xBTE&+Q~Br_vA?kL9JFTa@7%xEI$ePllUEeg6qaZ@qM*Yy$#wWeYWk`nYTSo6ddiAf+5^~tdyip6vg zDS9?#Y9{D9Fr;^&x;Gc|L1gNuqCk`gdgWLS{Pa5fQ8e1xM0sEt4+lud?S$~*nU&f18MSli9h;7G&(5ulkW6Sv> zz@fLrj33*c377t~`On9g>ee8?b=$_@w*={d3GkB==z!=FfqfVb9D!lb;SB8H`F?E% zHP$kC%oBLLjOP1Kk%~Ta9-YB|)3qDgMpcrw7pVmUO$$id&*h};L-aytfSze_1+cXW zb&5M4QvQkUkwG2p-!%^r;@uMm))Uppt$6b~0`Dd)yvL}VJ%k-z6Gi)Jwy^gQ0#@xadzj`GHafS==AE2@|FOa0GNg4f#ypZ@)XqrJ=F z1^)rUG2R6Uz=sI?yu(o+Klhth?*KpW5sFmZdljRN|3w;g6TDs91HVK#(VK(l_8%pj z;%z{AU#1B(YQCMi2iNVe&$e|LS4#0_{5bf2Bf|=$XcJ#b5m|pu?L< z1zjWTil*7y|JPD@9?cLU?SJ2ayy@dwD9SY9j}y-T@CLp=o-ds7#5V?Ae}X`J(-llL zm0MfT5Q0afQM^CEM64dAfk)f@Fy{msL!L?C5s7gP>TKzxi5v|Dx{Bs8hLlC2nAt(b2jyRJv{|UEyN&n<;(g)%2X=GfcR1WfGXaSiJ$Z-;GBs{Oy<;DT2pHu$&FYjewOUpxUz);V~i@O}^~FPVX*~7k^UQX!$sVHC3-IAc>iK1hUjz6 zsb`G(b?-_8&$`XMNPnLC$X((eWW7^=)qLU%E;VmO)cfyYD_810$>dc`+^drz{(G5N zt#_h`Ud@)S)n`$ouVrGLPNxa`*Rey^>j!&)SkK!K59rU5AMY1VOtn>dZA!t+g?QSm zU&B=7e^{VbhLs)qkMN2A5iV%AzKCLaGpl=2r_6Uj)AO9MTmApd@*aC2%hwa)>jI^jKf6j}$F!mX-=o}gY} zs+$P@j_WS}VWx27YHtSW??1x(9KA%a1G)7jPQ-1jei@*SGSyE6AE%yrj49lrYDj*0 zOQgaTxT&=e*XaJY+0X?PXa~_jJuVucv@Vzi{rv@no?rD3;i%Eqkx4@tD`EW@=^Dlq zU8c@LaA=uSp_{})V872lS^NT^Pp8f~#mZ*sm}=$H>rxa>V*^xuJ7uzdONYld>8t_& z4Dk$@9v3YgJT5mp>2a+Ej@i-*{-;{-@)AF*pn@7lXgq2A4+Yl=VbzEdGU!@L+{HsK zS_{*ZBC4h!A@g3;QQSq>LHw8TDqJld_;0~=HG&V2Ao>Q%&!|j?Ct+Kza5j;eK<5;i?!7ffjG$PnxB)!+nGV%lo-U()XpGroapvw@^U&&hD z8{ZqFBKc-=zB$O3&6V32MH%;jo81=!sVx~qkILy#VlF*zqz>IjRe2YS8f>X^?pkee z-NL!w<=mp5mG@mPNu+-+?E#DFwdopH49J~{sz<1S zd32R0ZnjFi$tr)QRQ@b3{}C#`L39d4pG2=lBaz~&R&E*PKuu{=K?*X!T z3g;6;l&r@)fc(vxA)sQjz~fb->UulqnM76oO-w+y{1OyG!ob)EK~B|N2aYv{xXtW3(3wkLp%@=9hHJI7)a@yHT%EPlm=XEPBUZ?%Q=+}2G60VsKwo^cLwN!Imq^^ZEj^Gz)}8fO(3TwMjG7; zkLsH8wM6cf(9mQi-prjyDVIqf%vMg?`euj7b5P`Q(KUNk2MobtM?yqr2%@5@QTs@p zb|jF_ECh477=fvrff^<2VrNKw9*ATb&6&QVOmtroDfFaOXJpEy`4BYChoXNrZHS9A z0otgeUl-=mUL9xzDEeTtnWH8s;#`3Ah(Y-YV1A3z4uYh1Gf#evc%UKR6Z6W~MsoO9 zK-9%S-txF;t1v4cYXdQ-#;zG`*Cz;E%dRd6ae5fh$0GD_i8aN)KS8?l6Bxd!+Brkrb z8O%m=&Y7Je75SpP)^d(D1Mr|@lQM}?2O(t<{x>4k3XrySD9CT6 z#N|lnh5x~n^)~>~h0CFH&YK?x-Kn!V;yVm~xt7B)^dYQ9;-eUhsmMhQPzhcIcxB*) zZ}1A{gV&uiV$2j)Z=o>}Cg$T3Ng0H+y|(;Zw9Gm1#@OuM)RzRepdu}*+JXFv?p`|9^e9GOQzab-$zPbAz+65|1=pA2npi_nCRK|iDvFF+DEu*XFk(xqdl^GDZAP;p2W zRqK(>8g`=b2Ec>g8^O-+*0Aad+I+kK18EUZPh=xYGS>D==?Ap_DX!6l(Hy!wT_d`R zkb^K>@URjy#kq1{7ytOHJ8M4TakAG?@k!b~Oqp z!j`Ty2VTYt5vP;tKg@-fjmDm}z`51tzRN~NU=XGNYh`tUtGkYheB1otvQf7U{Q^b2 z$CnynptahvsX^8d{T^T6VHD=o)=8!?3Kvk+t~5LRXp{wx&;)dfZz+MPpxdFId(4M^ zH0pYJwL2uIcCPv2kNAlDZPJ=ABef^I|kau%3BUoq-5_#LG+nLK5xB93?{X2!;$v@!tdRZ7EK z@j-p8c5k!sFGh-^X>YS9efRBcPQ`clW(*Wo_8&O=Ib>Ig3t-fTlwT=b)dXcH)?CS9 zpoF=vAeR+PiBZ%j{~(vuvdPx9+5aArT3sn0;J?5DE4q_0JJkIpbJ!{UmiZ||EH4j}iLW#KZ zqln5V(g5YCPxHPUWaibYM(%L#U~}wxSl3!}qqwUNY)AtGx(AjVR_9$1MLw^h#Xk=k z@*vzYl{$M?G}7#KLzjN$ykCvKrpJtaT(+xn+iS4lM!e_0 z25mn;TXRc*R%!*O!22D%NUOAJhY?Hs$`#E=ny9)P(z%y&n9D8DuYfAzyq7aMjo)}F zq5ezbM-J8!E$K2_B+=AKzg&QZGtj`DhU1_RytU@%)wpn1>1wNpC21KTs?z#LBB&^a zVlfbi#A36U|6_V=b&X7;-_0n>YF2U)sDqX^3?%cgvS*q!+O? z{gzD0FTzJGeDwiR$;oSaDa9aZwK4{?#0=yXwPL}rr`?+dSk~8yCF^6cQnhwJ;$!Kz zt=Ro&ORts?37lL;ovIUZSXL&-l9erx$Fefnocxveu-cDmc(mzlHNJsZsxE zEd5;8x#oqiHQa5BrM5nabh>%ZyASWyl(Un|`3s3nM$N>0wv&}5lQ9h`mI?e-BOTtw z;{Cw2#CNgy1d?iZCq58}2`~%Z5zP>=WQ0=u5E6JrS9)7>)OSU#$iO@U38LyfWXO&} zdm)7`+?GOHE?;S{s701XmQ^cj#b%(@#lZYHaFgNrc~(&r{rMsAUPYH#YwrEss2!%R zw$DnAbhTST6xWz6ra+W71E>vo$HAI1NsZF#cRz|)O(iHKC#n_?f;rq!tK+C0ML%mu zT^q+?+@A*u3X9qhwEJFuxCD90hDOYkdM?UUvLIb9NyAR133$V6c+}aA21@>Dq_jfH z%$gLXpu*N*m!-5yC#%lJgRL~hzo`0sP#89|OV9FcT5QVEVx6z5Od>SMz9ud@s0CR)9=D^FMGZD7Bq!`*&>lt1T{3( zJ!U@pH=dDv)BOBzBNR@C&U2QOb4?GAl0P3}9l^ZH%$xY?{0MloY3;koQfG}Pl_=;e zQrfk~wPQ_+l79s}x|dKS@ie%P22n*e=r_W2?wO);dYjHBpz-easl7e@FE4wMhe;eXHANdzsTmrA|%L>h{XH{ z!J``+=@PFQ8sKL)0&e7RbJ%sGg}B39f89t+rP~ghYUHRS@>*+z8HM80=IQH3N%%=P zOjPY0L4Aa_;9iWT9TxhrQ^ng#}1*fmBWi3|h_AdJPwDA>-UbRS;M`BO2v(L({E zUrfu^`0CHI^lQ-i6c=RQ(?M~(r*H}hC+2;qJR!cJ6q$5`W4cTpJ(x2nUb)kr-Bb938t zWtu1Tf!Xx5HuBPJ^(#`X39>a`&?khj1veVmcBAN=VLc!?i63mtM#7DY(^oCSu#T`6 z8oXenarskD2=j(&{w!o6n=f0^qJ@%wH&~AQ@G+XJ!t0qTTP)tyEH~xfYV)SsVuecnQm`l-7h5bIRo2^L z>us?DrQI7~!MX$H(~inenDoAFC!!V#JWl3awpjnmyn@;g&`?d7!9JoMPo`6-Hn^iR zygHpPR$vF3Zt$2$BiziFWF12YZ<^G|qxs#?3%O$5Ax8BoP?}QESWqc_I}17Ba4bgyr%ji*A$$U7TmGzIrb(8aL;-ZAE46d67c2STB{Wym@n#x!XKcp$Ei zOHr;sIA;p=j6-phRx2&COnJdt;0`D+hKP7Ejy7W)d2PtCuf)-BLmg{I@^nfK^0RF? z#?xYQ23H*ML2=zc@r|?UOQY=sFe!3UEgov$ZW+nVR?5ejt=*MD$GCCk$oiFaN=1p1 zzZFR>;e-V>8fb)o$95y3GZI$UBq;f>f_DVQJZV1Zu1w_GQn&U zRhbfAn2!>kaYhFJCmm$lu}QFvm&MQU_UCdGmdy*ZXZT%(+ll7U_E~;d`E{asw0)N4 zFM-bG@%C9BZ^a<17e3FUZF)u|ocBAUso){RIAmUos?4~F7Rl#8m(4>x5+)*nhvT1l zI8Mj}GoNNyszM{A)^sv@mVjP-$rteDcFJ7v7JxSjQE}5mbBtPPZM)oNr8{R!1FR@h z^3On)M!1cUbZZZ1E{dTG%lrn^*3k95oxWx`?o?Y#v<^s`i=?-tqUV7}(R0?~VJ0Zv zNw0d~9i}q?bbtCkb|TtNIIIhvShyb*b3#3aD=&R(MwwEJg~8mKRf{u_ zz{*Pj79%Kz$eJdSCR*A|wN;_W+2Gv)v+w>dRdj=%X6f502QpOI8Bq2LuxKKATGCwb zfGuZ-eQDhUMA5{W!MOw6DymjgP*9cUauN+|g=kIdVr!zyzS!cJn#At|#O+*;s7btS zE(TihG|A;nHk(FQW_#{~)nh8m(b1L3j*b(|1<{om;Z0QTvYK+~QdU&epG@UavCCK$ z{h}q83tDCsgqtI@P_R-_EC=o~6a?nL91i>CY#=4@wb(|K?SNV<`V`(|Lw`1dG3Zfy z8Y3UQB^ghdu>qezvWRa*zQGrYuaW_5&>MWwDePMSZ}Da0H&jRiWTg3M2^T^S%GeQz zB__AX{Z{F;xIjPWDRZaA8qPgo1DG_dzHBjB0WG`=_Sp$!y0sd^lB!kPcCh&mwwd~X zsJb{MV)Gwt^M7C!oM_heRc3`(BGKy5cv~BWt}XRpa;a@bZzNjEtrZ;&wG}qcdi(=J zEv*P>{$FrIxBz{Dt7ZpLK9sT#9{Yc6-3NTt)cZg1q-C^p_d?62>{%#V_HF^$d+)u+ zy=4;=5JXlH2x!?;_OxzM9EgAdD#L*Tl_4OC6NLZgNuKn6zWjfAy#nv^oRgE2ljI~f z_x4_=4E4dVty=OGcWLQ_w-A!6#VM-rGGaRr%idJEhcfD4^ifU>QD(cZQ$ zaNamLf;D6R*hx|T3eITW90jCRSdWY_a*gTXhNQ1kx*&G=vGsVjJ@sEkr<%DUP{fcc zwwd`NmUP}ck`qg}wcawEK<3IwDK%c0*=DSJ17NLmo?e<|yl0E6BaK)bd>P%!4UmJ~ zj=YCuDk0n5A#0omrvoMJd^BQhq`Z3fOL_}NRr3X>{Bfi!hGM}&nCp+hg~fR%Bhz^n z`i~TLo}6YzzK7ouGxC>3sm9CkPk$73Uy5II>g|A>nm-{!1|1_A2az-UPDU~5^o(xq zWn7Nr=d)uNt3oHq!0HUCu~@;|=)Ar5!DxRzOP+j6cSb zTMTW#QNOWtbH^xbno%1?&CJQ;++EWVf4yrMZG*h#?u> zoqm>!^6OZG+t1yiq(=|qAGe>oIW?V=puBNp8Tp_~DDGbShDPPVit?00(0Pq0Pd9EM z*J)yRjN!Q?%^ft!bgjO6?Wkt@B~ zFFS~RhJLh1#o|>~6P)Sh^HC^+FAtFp88HE4!w@79l`mf`kCw{K>+{ZLwMNRld0iDH z7yH#nyIr(8O1_>kG-IAs&UyT5JLP|n^3Ds-HBN_KE{|TpK5*Yo8;{;`JMl%Q6AM)E zI`Ktk=_inO&r-Q*tuWs05v&4tM#zz^YVHK_=z5-|9W(+t(t$&Q#pSZ@PtttpE%_MQ ze96b#y`dRPuqX=Dm*X$2v5|ZLCFHnTq&0(xfYd1;#Tz*%FBpf+{r;3W%Han=?BP> z-l!GKF_Ocv>*NiFR>m24#8qCSzznDp#`-g3h!3`cG8B9`oyOhnhaJ2p95zKb+8Bg1lcWaVf%Gj_{^oybB3m#wkpP9Ez+UGF+#YV zX*r$Q91FT5kL9dsFw()3W+qBIeYpagg{NlDsj)5?#3tK2^7>=d{d!)1;r!Cw z=iDN4No=wgi=hi{+IRB$^W~D83EyNpPd+}P{dn9O?frs^iTPgMbIfSYRY%g zO8@LeIrpV(>sWayn~8S1V{MyQXRPg%TpR`Ec67R1CD!RaDU=2+abq|+s<%WjtTAMg zy*r=3ptVbS#*lN*%={SF5BJ@vUCz5xZ(=3x=RkKk?@oP_z0y5#&PuzK8(A9*?sak> zA=mvR-ah#vB%?wy(#`|&{c-Yuyp^P#TgU@(a*sO#>EtKlQBvODYKC$1@rZ=2>FG6Z=L%wWY?Q1}Wy)40BDCZAY@PNHP!C%$7jEjdECu=a|S98qF zI_YSZb6myg`&(r{Y~YlU>(>G_sO(i4(&OUqVVQT3cKg`pJ|5^=ZUMU9%o{J~=pV=} zSFSnI`J8m#%4o10(Q-}d7{JyHkY2{-;AD25Tqe&05k~bn- zwsx(X{rCqzY92(sY;BXP06sJNq5XEEzj)O<*x(ylqcdolRh@CLve_5=yJj7<^ghpA$$?SU2pwP+3arg{Eo^;7|%Ib}0hO$5Ln){f$sF4GE>anf=R#%kh zX35sa%5K2cSIjPLB$q=>+S70(eDXQ_(pB)f z*ZHV_S^fJ1_meK=>8}bZIDb`;ijw7=ci<{IZ@%_Kx~S2hR2x(q8sHU(vkIpkAo%AP?9&O(#bd8uFKI9pGKqwO68g%YmwcK`y#Yo z-tS9tV!dz>cscU$N8V+tk)2~C%Q!O%v6d8TiwH~5~bXP>=>@Ca)&4t&dUy> zNm_6X#g=P@dnmRJF?p}>gY1|z6IYDnJzDy5c8-z!ik7~Y9m8#`Tl`&QNh88$x;-ri z{ij+*VT#G)Dp_Hz?3lMg`Su#ww$|A>M)Ez4^`n@9Q%U+|k`s%Ot~HXQ5R_^c+sljk z^W~TK7B>c$X|fX8*t751Zx;0@<(EH2x~RF>)FvBo?qR1rklaFcY%zaWNYX4h1`6hB zl7tfj{n31u-LROySdzRM*>9G&iQX>Vj6(8epU%j0N+4wN>qsGn>GFIT*w4B?e zzWD2sD8qOI71l0?T2d^#QgMF~s|D(EMt~&jG_<&8J!Hx|p+@~&?XmdW2+)u}_s1Uq z;e;;R3s+x6Wlvp3Wo6gq%1%dP_m*{Dfy|AN9WW4Sx7+4B?{Tg{S~~xk2)UJe2dPSy ze8r%-AVR*qBP645xz`IJxzJfUss@hVf+#4@qJMOn>AbZmcRmt&=(Su%5NSDTa_{i! z1M;e+&>Y=1RD=bb*O>J*7Qkyu+$Py+CH%1=z2?}*68(AYu_gTBAv5RLQ%j&{2l?sMA17=`gKV=e=YWF^qFM5v_)Em3=5~ebAsZi{}#_R%-@_>zJ)P9Bo{H< zvu?jOZxUjS5tC8lcraG82VxJK;IziRbGPvnAbau;E#;R}g&wgPrkkH{E-wADrH>V; z8HNI~S8BHe8qbyYvI^yCBJUz&#|(ASNtV30ojq48a1QBaM)D<;kv|n$k)2^A%MWMD zAJ=WCSdI|+v;{tj?Zu>t|9i_WR|033`2pEaKY3-*5%WSUcR%L9o^Uq7X+d4*o*yqF zu!yv;$p7Txk;ac&SJmtcBjp}qa!7d9$kP*}{4v>kt1x!pDGFx%1qv3a;JlBzDj!~a zV%K$YpI&6C{&LPFqxQAO=yR8CHikA)fJ$paU_F5bcG< z-6QBg%sr%MNZR@HB{%&B((Xm(P>gefW_2r97~`UOBu3sL`x@EhQl!a8oyCje=F9oZ zI~lhN&v!RYj-VveT?8jW3dI^DCP!6sipgVG`OB?-8k5@|_mOE|WEHPMQrUM$H-{sS>NjX&~Ys88KHNd1G;#Aa?H&+D{mDhqH=|;)rACRIvI9;&i_yvXi;hvT z(wx@lG4~QWDpq#LHAy?yhEcJyL&9q#J*$aRi=-|;q^XoK_wr~EfaJ8xymmEekQ5O$e-FSmP{kPC@? z-upo?Gr1$q1LtHfyuj%K_oZX-g9^?khU8pMenktWYC-oeD&##yePJb^OOs3bP_F=8 z*6}Mi?2%bs_{sZ{2md!4OUf;*3{hvjbv^cy@r17I zYH($rAtdVxS?C?jGGwGYDXmA1InlGy`r>YOX!`%OzGewz%P5&FmlxTL25vdI;><({ z1KXg5*%z-Id73;C>I4@AgE@Q6L`=@=ZQ2Cq6^A_Ya~`-Z(%kp{Cs&3f=gxKyvgP=` zn4N7jk#9T3njbhTDQL%5^yhTmV2Z)PiQ^fKOU{wQ?Za|zC`3Ng?A%r)AVY2|nrMbT z^}y>QWHiCa)m1a(#B7dOTf`=KF?pXlG<|0Tp6DT~C$cuWS@!#h{(SaJ75%aOWF$MH z3j}axCE>*J2Fl>Y@wg0aClYXU8OX<(m9z+F7M^0BaQ;g7Ar9*b4e$@ra$e#65a&kq zq@7p^@6i6^EQtMv1=nN2vd$UuPlB8wMW66)8~<@{8#`Ajm4t%#6EblugkN$3 z51jQ3L*d33QO^?8;y&DrPb`b{%g8WN=HVZCr%gtQj9wV7yVSs<)5|6zZj`}nX8w)^ z-MiH3`q!k%g^{rqef+)sZ6!SA9g1#}3UF2$b*opxLK)eA?3&`#(dIdCRLMw`QROqN z+#R-8x^?y{7nc{yt#X!&#%02J>rYPk?21E6p}^kkij$m*x1nOo9k2E}H78?Px90s` z&DF6T<^gBH;s0mN3*`cFJiF$WPR)tfzOpxEoyVO&SbYYIRv28&Ny{eS_IzDQCuK=d zvrE(1()jOvw;K0$`GnJiLs(L7mp^j){e7hHnQ^&THTw|zDaWah6fB?Xku&AqiK?5O zuY&mLkd_ihX-rN$LdMI%2s&Tlk;DDhsAH|kgB4HoBO@nH929N~HkbSIsMVqJG_FNT zJbDy!>Y99b^96Hk$rjC9p%CWOvJJ7Nm}5(&6-Qd;xKbf$6R~QUw&CkOsa19N;1Gqn&JBy*mIX*D}wsKy+%B{a211l|zF z9QShCS=>Cx9Njat#o}^!U5hz&PZ;jTG3ObO`YkTp-`ee~;Bx}|@v2Vd@II;Gh&uD2 z)cP%Puwu?rHTB14cwK=x&-}EK*hZOicQMoChelr37{t=CJ?5)2td5aqeJ_Ty3VEz?my^%)23}spu1#^OR4Gk3zp=&f6<>L?Jve z!knjlYPfWo6i80}svW-C0CT=y($-_mGRJfYNn6|sJ&!r+NNDP!0{GlC=6pBPZlIfG zj_DMV_P6{7&EJ?~+J~fl&<0OZFvq+dl2$YgBN679jv;9~>){nQ=BRf=Q^yuD44LCL zr20`*=D6q6?qLID&K)pQi{Qne%yGlhcBSCczL>){gr|jKXp=cE(@dLz^GxQr-KLfH zM|0e>V~%^n#QNMR%omf^4ugoyQN44deT*%VId^|EP3{?G4tq8{Z2&q;=7{OJ(zX`I z_jqECXp=kb^>Vl@VvgHlrX9kuFLT@>Gi_j7yxhecx6DlYG(WB+`7NyAaA?}o`S3mg z=BP0_(q6{FCUfLlX6owJc+!SB?(MX~7|msl+7+5Azh)?NLc6r1*bbRvI)tQ^PQ~L4 z%uy#o)6S#mGDog8(`L262k|lI9%ZJj!hVuD>P%?b{RAV)z&}RV@;qq;u`gwgdMh+- zD7Hi9sKgw0@uOApWi6}bUm9)K9rIj-J@>nJ6YQ8>#d6sl=FP|%j?=*iHKr~$?bzhr ziT21Q{wK{f_R%K(iD7G|ZK#0U>h>qTB1P=w8~RqUW8Xa%ku|@me@uKyw8vP5*)%$B zz<+yO;$LUNh8lb9IrsV(v8#6V*D~*Ajp*uc5n?XN+SlFxS%mpV*4)AVH%;@atR_SK z*F()cSrte68-}3VsL}q{a+B8cHO+llZ72D2hyHK6vuVDXb#{usLavZ=`0M3^ z3lePKY=0y3mfd-_e|^z?70pmHJk*eX@#XvBdC^GxG<%3NEOd(Ot= z{ykBzl=oJVBRtB!d$vY`dDA{R7X`BHU+4N?!LOT{p}E6z;on^0iCIVI`5WYp`aPew zkQp9rAMCR&!CY%6EcTZRIg()CUHE>2-EFbIr1`r&eX)O%nPJ~r?0>@CWS3cj)FONB z5`QOix&6x$|1k4wyYo_iIizMT^*1-?Wxcc1pEFm>aI7sPJP-a24Ucf__CXAsGdw5$ z&4E8J5lduzco_cmIXx7~J+#mcTjd{>`_lxcwf3fKFZi++ukwExV!mRJSmVEDW@L3- z>u;T-@G~fpL;4wOqaI#a0Gn=Coi(*k*12{5*G%)Qy<~&`NYwL%@EF1A5`3+o{ayRs z1+s>3^cOMB-S+%V{uAaOcDv2~h2}~7!e;d2uB`Yi{v0M&mbld)W|~K`lD7H3H=}k` zkY>rI#)Rit{m+uTStWP)Tjem1+hce8E1P%i%-#MD<}v%$Zht@XOS{b;f8CsO6QxBH zi`MaFt>5F%2r+MErR?`#G|g3Z_(AmJfvjo={ijUxM%JT4{+~kPPb8b@F50Aj?7xos zr*S2aW4rNV(g%(i>SWmKKO9^>YyKzxgCT_i6NU`*5A8p6>foUh{3FMY8#t!_ z7^z_J*a=xJ&iO}$$4>SS^p70ef6~BlL)@i5{km@EEnvhc^A2HEq)DNqgFdD+^^MJ;Y&Z zcZ{1@^XT%xm|XVx=9A*=@1N;izYWRhuDdC2FI>`DLgD|L3m(K zs6DgKxJdhr9Q7jY4tv5Q?O*cuh_p{7Cgryuowp%h^ZZ#Gq5^C3*d6wVN9L@8Q?!J= zY1g)jcH`WUrR+J$(fPCX=MRjCwI|G|5NSXE=!N{HadkFu`7>t7`HVRX^K8txJUa0u z_`jIlIBQ0gtQX4%G8)>AzVj8!YCR%=ab=%2jKuKdp$z$I0tFmf!ucbU@Sc;rn>} zXw8Dh^5r`ly-Dgn^1o@z_(TJ^nLq`p=AHj7V91vddy`a9>9KSxP0Od2@k_Dh;K%Z3 zJeFShKWSV6*ZofbS3gbTs*DOdn5Q4h|60?yA|t<(dHu2czchWs$?sxD;O0f9uQ12s zQ!~XhEwNav-)NwLZcc$7W*07i*jP0@({u;q#T(E^P>7TBd}dGs4^%ruW_ zS{~%ZJXZeBW9eM7R-J?inwIBK@%T(eIWJ%Kzqo-H&~*F9()~4!q!*aG9$WsDrc<2!XU(gc4o`9d&zTRi);$&Q=Xt*9yhyuPle#&x;uZ%s z=gK;=BCs`gyc9A!U~lSVKCp{6k4}v4=!S5Mf+wSyZ`zGA0}1x5 zO@T2{@?Bk+oQxs%pPK@m?UAcF<Ig7Xd~8m2eB^QMci9RP0N03OQ2p3 z8KLZnZ)E1R*EQY~nN?(Kpt;%L8MjL3Xj9|Wl3~i<&tY=5Po0FcDSwfN$=RkZ_WEss zG;^l?)3(6ekddZ6zHYaC(WX2k$J7I}xxik!J&=h1oc;UecI=mD?eDh-`WMhrjippi z{DY}EW)$tU1IOS3d$#+Zw_v2X*#1C5OY9r+-%>kzXP{)r0@J=z_=NL2XX5{KJYR4M$u3XNx^*PbJHbkp0-xX?OieN8?d!ghluZ;b!T)l( z5~F_SJ3Ga)9A2zD%gR_Fj%edHrmn_i5EMtq=SMKL!7S^FR7d2HpKZs~3A4Ad?rOP- zoFv8q(j(%CC*6t`Xk2N$Lo> zLfAb|1?Cjc3qw08@hN8fFOKMB|8@$eM`ye4=|DYiOx~=eD&c=|L>GJMX&g>n?L#PK zcC&9ws=FP32IIJ13I@qCXWg2`5k0fooe69)&E8qReG;%uvrpEdvw_eM4F5~d2X^4l zto0cx>2LS?3?uUZd(mfs`xqCV`5dhoWS{vQN8(`nCrJ&-s{BRZrfK%dDtIw)-o#jc z`%>V=0y@?=#3tsw=#Kf~h!OVY%c!c8z5YwAW~80^6)qE_?L%Los-gD3Uty(V?V?}f zzoB;1uLD06(2I*48hO8TM-y?xpsa@91ag}g=2Nc(MimAgK1#02}KWb0_} zbnw^i0pfJ;Y|VgMJS5HwS0E z`*WbSi7WBH*U-@&vua%rSY`no$I&<=?+I z45dqNqs}>5hi+qy1#~!{B1`}5j*8-lKK8C(1D!F1Kl~MYppRYoZeSVyd+RP5(#J0P z8@jExz34Ywo~*2p-|rcXic z<(w$H!0wkTy)*thlq>y3b8%L?-09d2OYCl8={qo_J`77=hRmhm>Ge?2$?){{vbKT| z=|1VW%8^*jNV{KTdLoX2^hne<(*9S1U9u`fr57^`EO5`9dAPOB`y0OO0evBkSYQu| zM$I@QqEYj5yK+o=$pSiDcE$i9g=I_;N35_%#W>CQHzs{FhR$KJSi|b9)v@U-3R|Hl zVXj3{OtIu5W@&NJ} z@-*^t@@m-fR;AklPm^u( z7V-h|`(*i@9j~4%*~a$&lAXZcQj>GxhRRzYFFA=^liZZtp4^8#lAJEK^x&FH8OzD* z$h*i{+=ASR+@Cy#Je|CZoJrp0+CBf?ri@eMOXQ!( z_sF=*&fZNG$xo15kUNw6=fV2DeLR{n=8)wJnY}VEkav)ekmXsaSN;t7EAm~>vi%Re z1RQ|}nBKzq$z{m($SuiT$%DyL$@9r8;Oy~#17++bze_$tzD)j!{2TcZIRY<3ybUWC zv}M!?CXB}9Hspciab$Ts>s7jtyo$V;e1QDEWB2$o&QZn{@-O6n$ho3|EB29#lWUQi zkvow4T9gS_a~1bPbX(O zc8@>jBT(Lo#GPc{BMv@>%i~@;$PV z5Nuqe+S&g6lu?RYm7GfMOdd|2NnS`^N#00)HG#(e_bDSOG1$_Y(!(au)fx{G7MfU!PFMm*k(xzmp%4 zBk;uEt0$3Ml3ayc&$DcQnwNk(llzlLlc$j9l9!QRB)>=ggnR?ez6wSa32s3Fa%pl^ zaszTJa#!*|vV8v2>!E2uTgI|r!g!JV8u>K&68T5+UGhV6c+udB^OB1>c8@=!0%bHJ zw;}f=48*>Un&@)hze^8I3T6%0=bR+LCCO|DLELT*p)OCC+0MqZF@yefGw zJAu#k+7nw~P&A4M+Y(96PcB7HA=f9jB6lMXCQl&Ga%~whEusvYyp?>A{1*9R@OUPQLZTgeCQTWPo=-=@&N zc3evwd<9Dd*Ib4y-}&fmazk=!a(D6|ayt2G@>22(uHAl@?`!l{c8L5I`6T%Q`6~G? z`5`%?bg=&Xt;yZs>?`sh%9ui)N6sLxCm$kzNdAoc9rOZd$7s$Vm{~_lp7c8GdPA1nSr&*L3N?t%- zN!~=>N0vV&@fv!9{5|;&`GMNm{_yg_g%ijn$yLdz`vNi8A() zUnid+e@_0Me24rWIlMw}Bb^_faxOsF{z{Zlhn!08OddcUOP)?%Kwe4SMBXR%-j{lv zGER^`Cx1`ALw-OGuNd6Q1ae7o3fXE+iSFbfI}pBX=P8C66LcA1QI(9XMwvy$W;Jl&n82JqOEAkEU-{f3Xg7xGjmvHTNYzk#G zB)1{=B99=aljo6FkT;UwAfK#)^?O@+kurWF-y?^l1k1;gi;^pm>ylfNyLp!FAL1q8 zN#r@?rQ}Sq{1v9R0k4ohAb&>wp8PAEeJAsfG9s%6E0w=o^j1)gT#MYC+=)DZJdQjw z=!V9kV8U2K-cCM3ezIDyLEY_xopB5YDD)J033)Af8~H8rS@PH9KgdzlgR3v#+C7F# zQ$_=FSMoseSn_o8Hu53zo8%MZTh-}F@ZXdXYJc4&J+VQR8o>s)CU+$dAkQE#up4wm z|8Ahr5%N3aGvqJH*T{d6Luv+_6+@OU3-XS)@~++ftwkBnkY6P4Bp)TeOa6rX6De3kqgIi*3c{-)$M z;+z=tW&1lI;gbZW-c)F)c$FI;P4R#@w;P`Z`_%KO%u=x~yOQGT#o_L=P zORNjONpa^3xFg(!KStcA{({PUOUwR5@n6MJ?y~n_`2ZUx%XmbE!W#xx94%h!E>M^( z-;HC&xbcdxPhE@3G!g3tq*A;i#k)Ci_xLjgQpPY^U?Rn*P<*yH-fhIwuur{&%DhP4 zF4hL^7Hj$a780^>BI9 zW%Sexi4PGci0~~ouunai%FGsPr5P08K;BD!oqVp5Tm*FCix*Omyp+p ziyF?93H#JLB(8NH5?fkn7G=CE*7%1MKS%Kk6#t&$zmfl({I7yj<{}FKC!oDg334jA3waQECfwSq^eM^E74IaUAYT$|gRYA4_*159u&HVTzjiDm9IeM)5tx@V_?gxbPi=?k`IvI zA)h2)5o;r^i}6T6rdzO2{Wp~fX^Ap!k6K1j{YQ zie08@uunaY$}AJFlK#iEiZV8e@k&^xt*}qMpUS)@)??xX`3#l0B(CGu^EK>KU!yX= zTawU<%vM3?7VFl;i}7+!rUclhmM?(x%2X0-Jyj{*h}>4J%l6Z_v;89_ffrXYjfH*c zsai+-by|s)_RUp{G=GKgJe3>3g^F16PKvaRk5z@I>rAY=fpYXRTNDw zL9Qd#UTiGJD+-yK!#>B@{`OR;msnTapW@@l0dYgOqG_;CJ&(#fPhKx>`<>k7J4e2}=Y+lXPXPi;-4LNmqMh^HvNjQj$X z*-73W>_+!ait_yV#`&ZP1?D87f{Sr%oyA-3HW zyhDXfQJJ%1-LlVN*-E?xWL&2*x2eqE9gzeE6q#Oued^;>=q&jw zu{Q2Iir*psM~>(itUm^p`io#)#U<{&o-Ip-o)BwSHxgqUkf|B$Q}>j(Hev*MtXP+w zA=dKC$ZN<4JIeU4g-%k&4RUCwV3|_nC&;bDy5bIEoN6+4fqm-!RA#JKM$W%Ql#wAu z_sO&hmV-^EjTC>0{JIzis!U&twGmgv*a(@f!9MlxROTUUdEFS=Ik<3~SQjWk@$zCU zBvUf%Q#X;g?v7L{-;v_oC_Xf3%kWD=E1C*RrLkDSVu@>|8NmgNOp0$7>$2NnSynEL zuThy}ROU1CH{!L<_=m40mjq^+uH%27`ag+lBSN~!0&bZ&auKl(+f~I{z7~~fLh&@Q z*5AjXLW9MaWg3qEed-w!*GlJzwGqq7FH)I}V$3pa#s5-IDfktMYdt5_&i0>?1ZJ7e z;eS~`E(bqJTo?G0{6LIZrhHw4E+*E-RS;vAsWSfesq08w%QWvQrlM8xTjlbOW3FGOlA6swa&qAdH4LA;wGG>pCfM|A11#i)`or} z?(MGlJnU0{LuIaub;Y+S{-8V7?^Tosz2G^YSQjWoE>C4@i*0wst*A^pu{L4^*&;vh zxi6MK;w9kE$@j^{(4AhT)ybX2+7o@necT2OgnfPNUeoZ%dV$1sV-}0ox@ByNXHt9z z#rIG=i{fuk{6mVLqWG7t-Cg_>6}m}<{-k)$UcrXu5wCR{nvdcIDPC5rdmx44^{9N~ zUWq8Az0yiD)T3;3OwmMZJB3b?uaJKyM`6!;RTL-JB)1~>B~Kwg=i2R@ZItmU`84@w z@_lj)w#REwNpgSkJo0+-p+0i_BOudflA%5RrC5$lOjlr^`VWcgp_BtL&*5S%Q<$7W zZcgsuS+;+Smw@MxSCV&$wQ&c<{iSJ!aTNBck5QSA#oEwMDgGtJzlANYqU(~O6+Iy5 z>=%qjlM~4)2Qj26Z5Jr7{C3K9u5<$+M}2<`Sb@leB=@(slO zk53axRH&j@yFG;#s6%c;?jhC{3>FV}S1=s*sV7mHSz@PtZ2!}gu_QYKzr7>Yg}0MG zAYUf`Kz=~ZhXdEEr#!j3*t`F!D~S0aIu!3K%PnE=ZZ(V z^)G;ZYHI}*S|`?(ZKn8MiXWo*G4g5hS7KekujGHoQG=Z_&hcj?xe2Fv&B#N@v&b3b z{p5GaUy!epLvZ$ZjmszJzn3US8BdbOke?RoE?6QS?RIGf>{Dk_nH^&7(LEH;^5U}n zZ&1dEUIyY{kiQh`3T~6-RPy3U_ z+D3&Ah_!J?DSn)MmVAYLL#)f*5o`US7@ItofwMpFoh%s>+(zJ+@C=_iP2yTn8?kn8 zFY-_-GfJ$>&LyuV?+V&7jt3LQC9$sHTk%AeB)p$Ro+K$V@Lx)@5gjC%ea=@e~q1BxG8w8RAS@V2juF=zhyzZq8$Dp3dW^)i z+b2?ai@a2<;-zHxo-zJA) zX!aUi0=B$FZOUj(?oS>m)~%T!o`M!*^20v$LW%1xSVHC3k#`2mSjJw;cqN!&yh-sB z6hAH2m7RrU#f8y`AF0d@u{QJ%ir*LOvaz@hm{Z*2&nW36oQ*N+k^7J*k~7FV$j8Vh z#oCCo;;C-^pTj=&bxSg|yKd70|4{rP#iKFCdzBUt>#}vlT4_UARuG5vb)que#oC}j z8h5sTgd}v~S>*NPx5?+pzmW6d8sgPco?Kn5E3PY^=JrIx$?_st6RoIF7qM6q>L1?wzN69EqN?CoxFm4kbFw4yWqTdrrRsl1tff$_?`;=O1>}FtuX?@ ziXz0`R#LnuxjdDrOz}Ey+&%vqN}a zNX9I;TUx+Abq9%S*Yy^!a?1>$_-Kkxp!f`m&!PAd&$9iQlF*fHgk{AsCVmasD}*vf z#Jb|wsQhK}ZE`q9Ij_#biQC2>oy`ytSjqI?n7mUQ+y1?r%-&R7ngM`pp3;{2I4lwGbz4{e3Z((M)CJ4 zev;y!Q~WZV{c`X}%D6}VN4(bE`W(0)^tL`+tns`QFF^4!V%uG|3dQRN%UebxNoZHM zB#$J|BHQHG$)AvaC+Eh%>eXMIT+^|xxD{peB~K*JC$A;%C4Wf%lKclb9OItXpduC} zYLlNN_a{##FClLtzfZnI{*PQ7Lyk1U+5Q%qkUiC(Jej;ytowVdc#gYY*TFvZPAYR) ztY^wA6#qc1Q1L;-}sE ztH3_T_A{%~qpcRSOlw-EE5&<>b@{>MF=UIpg1nvlu2{GEBk_E9Cm5%Z@XdD{c##U- zBZpvrc?(C0bwlIDx@=Xl^EVF~??B5s?}b0(uB*3&44)>3Q6YI&;;n$Mn@>^v87iMa z@zoUHMDhLPBVHN&Zyfg$@EIy}UaXD#iTsEhHYZr7Fu6XtH+hP4PtcYzCzvockPnkDkiR8AB*)_b^;TR?tOr^Z@dCq{ zs>42YL#GV7Ql?gt&;zQSli|jDQoJ9W)@g5qCN{5ts_ zmHCI_IWP!$8xStm1{D!ony5+{Ey(@J)5%N8o5?SePm;eOKOkGNIOn|RH>cSjp4-<{%pC_bFxV<`A;nLL zbz{DD#&Atsr;Pu|MR0n03zQ+Jk%y6|k=Kw9kXR`RRHms|>rA6~SMm_Y?(t`grv?0Cy`x%4@ugy2*#@z0*>>>~ zw?VsLpZX}3IZkDMAm6j7&?E6ux1vyVk563y_O_;|SXW$$T${?&7wfWZsZ0;?GPnLd zun%^&f0ATqcTJ%M=98CGnN?z~XgifTC|>Ta;3(`529)o6;j2Opthn+lc96?X73Xi^$8!&)aP`r+2nqqtILA56CCU zXUU(Fzb1c2zDE9qe9v_*r}2N=Rkx%k4h+T7(Ju41p-g5TI^ zLZKGqHslWE?&RL&LF8fNvE+&5sjltnThrqT%%zM4t$1GZB84`PcaV3J50PIc zzeRqRe3E>I{DtcZ&ThF(8Q+nAB>!R;*@pK1O`!+m95^?uf3rS*baFqJZ9lIM~akeAwHx1$5sQfM7{ zD|sjR0Qm^{4e~MahvbjR=UuxUc!4smkbfZGB;O(bMZQlC#o+1f-Q478a{My;=^gkg z{2~-9O)gJPA=e<+CpRXyB)1`VA@^|Y9`yq#V+eT+d4kakpDfHqITjSx*$fR`qwrMPrM2 zkn4g);UTVD6@#T!nAVGjyB?ebk8r(4Jks@3#o^Je>z07Wx-MA?9_MsT_>A6=XVE9-iWQHckQWoxa=^ z;c0HXX+_!Bc)BT5S|u0{8D;8_4C8T~Ox3Hvc#0*H^KHFYMy7Su5ufAGI3>oD44I15 zfbqIsrkUdTuCv5=Q6iJ`?T~oQU<|=rrw%f3BQMh+F>ae>sv^TLZYX6+Xb9srN+##q z!*HJ=(`Jd|!X(rCVhm9-m1qRx;FYOw*1A$t21gZ0gRe#!Mtm*9XbWFc56LP}ZHiUE z!ZsTrI0WMR8b)n6Ox+ZYR=0rjs=L4i)ji=Pwe(dPwKT1gT5cIr)SKaE;{E_8{05Na zBtnsBuNl#>{2-7N$_w{aC&KdMKoZAJGlr|tcZU2>ki;9olhx8t`OzSW_ku0;0C>K7 zm>i1FX+jR04D~eFR?AM39~qL0WNY?`2LYIlsAU7*R!gHlP$$4=)kWcp>LmCZv4x7N zB5_qSWOvJwSFeQSXObko9)3Z+72c$N72ctK1Kz7X4IfsYgI`r&h2JiU{V$dNhs67u5pLoc zk~$tftIiK!P#1;2R#%08P}hO4tDC@g)E(hJ)C1uA>M<4)W-+%Bli=LyS#Xs4IoPLO z2^Uarfs3hMg-feX!WGr$;Hv8HVfmdW+2CK{2CyXwBg8P8Xht~PMLZO7O#ReygpW|i z!{gM2V86OJJY9_e+L)u3G3FU{U3js&Db{bS&_ruwtX6l2UlI=oFzr`MBaW)$;MdjV z;CIwD;1AUe;M3|h@OgD__>yA_g9;K?G(%3OAJuYT-c-xja92GC{!6_M{!hIT4oz|! zeE<$uzXr#s-+}X~--8QTn)n2X;_A=fvg!+PvifVdy83sxj`~lyk=iuz`7CuL{G>Vo z?x-#dcUN1*k?5_7lJGdObOR=Tl56Sq>1uhAJ4YP`Kckjmd$BqeUal?zZxPE$kLjf( z*HY*HBpLsaAr&3fj2QTJbs6{_btCvgwOo)+t7XJIukH$8Qul?gsO4DxQ9T*HsSe2a ze^(PTknxv#A^e|u4IEnBZS`h2T)h>JQSX8CsrSK!)Q92X>i6NYY8jN0#TK^yQzWWu z#znY}`dhe>`g^#A`bYRl^{;S8_1|!J^#i!CI)`Z(^6O#J({b=fwGXz&YoY)W0d*O8 znz|OeSgf~pE7Y?8)~Lhb^=dgSx2p5PyVSS=GY+WbI`Xn>%V>_o8=4{K=)39;@CkJf z_>5Zi1b$c?`(L)~Bog5zT+68#qdp5KsO3~F zto{Kmp}q!}Q~v^2R?Dubrj}E*g?KE0=}C12)^BvwM1Hutx-vXST@N0qZVQiBOAk#~ z_k^EP4}lk`WdL2Go&>K^%X&A!mbB=3B(`aW+~Mq2Z-Ec0O>Rg-%U*vM8;ip5%@24dH6qdeK@qF+l{T@aJ5`gW7HGieCnxi zA@xkSxOy>M)-n2FITFd5A(zzZ>H}~cwOn2sso#cMs6T?ARDTA`uf9o-egzLu%Vl@C z`e%5O`UX7B(!?DkJpT>P*LaQ)+@Pu>;S6;GEI$(`D=Px8Q&)husH?#*sT;ui)h*$p zYO5U*uWOZrOS`LcJM|Q*Vb8)w|$A>OF8}@i-iDm};nHfNG@92e(q^m+`-YCW<1X zo4PpMM_m>kq^=JSQ#XaDiN^z&EOjn;zB(3uPAx0WP$$Bx#19>Pql2bxrsKwcJ6SQul(-sr$ee)iNG@qYl89{P3Qvcrg+;)NA0|>YcEO7RJl% z5T@K}Xk&1erdP!E8csd0!Ht<=)$ z_Ud_XSG8MdP`wf!u6_X?tImWc%P$8?tG6OCO*6K`milFQzWNyatolUm7Qwom3`{M@Da5fXRoO%WBtZ4O*{d=r)~*f5X+!wX8TnExV>LY)M7cktm@Va&1mlH-l@a+rf3!o#Dpn-f*f~Zn@g1<#wTy zS~jwWT6S4K^%AV#7@~<)$QY%z;R)(>aJqUQJX0;Z=4tgS@U!YS;brQ#;Z^GQ;1|^& zz?&SSX&)o8Lo-gpd)0Cua9AzZ{#VuC!tbenfj?H?hR>?ydVfLv0RCDnw_-o2bHUdw zO~fK`N1Ye`LoHXuN9w|GI7TDcW!2yqbq!d4XHnvEyH-eD2QIFbD`#1C3piPAbwHxJ zCOX4))IH%w>Va?z^)y(1uu)dF2=1sp1b0`z2KQATg9ocmz$4Y4!sE-z_>YP{MWIQRLo(`8( z&w(qbWu!|{FN15TYIv2cDoflrCmfqT+me&H?Tw8{WM7uRZy6d326`ZA(LFP^M2>7^qA^eeA zw*C|K4)}BR0r*Sx8TdQ(7x2&Ju>WNXt|IZ9X8Z>Kqy8Iyq?VV~Im^4{!{G>Z2{=w& z9Zpm?fs3fq;F9V#aC!A;dHz#H6Mnd+TJBuyspr5=)Jxzr^-8#tIuq`t-T)6&Z-s}e z_rdamp0dFQ;K{HhiNi=t(+oLZE%kADzFN-L=hWZA8R{QkTYVQ^r@jYoQ9p!VQb*w| z+pEqOg7g2FB&MLBF@2zxQ|^>H4!)q4gXlYTDfpUNE?~FSwcvYdxq$tveiAltZpyma zg1H=H|93?qQZwYL6|a`NvHWVBrAATpEVz_fZZs;W*T5-ixlq+o%Y(`K>bK#hYPle_ zv^4P%67AG-LF%HG^R<^+4o3OeQrUtibm=g4UU-aJp7TsnSAo;j4d7?RQ&9<~Wok>h z`UOo$S8r7pfOo6$pK(;348N_G)AfCID*Um!6?|4LFHA3}WkCB{{Ve=L1sVU*BI(BK znz0tXqdo-xp*{iMS4*!vQhx`>V?>Fc24KpsmJKVaj)6<5^T8F=&i#LiCggysrIxL% ztF8;T70&=LbykPNJ=HSO^;gTaV5k~xG)AjaVEGMJsYedj8Da~GhDglU47s&hrtSx? zQsW|Nyr^CTZ&Gi7cc{0)d(|@LA684xy{bM9%MZ9pBjhI5dS4TtBk{5NGJID36?{Q` z4gOj!2jdUw`|x#jC=RqcYP`NThXP-Gm{J$rIJR;Ua3e z0V$~-0+&~hgsZ40!Zp=1;CgC#lHN%D6x>NX6D`KnqY}=4Nyt^JpJv3uL)1lJ`3YJn zQv#l#mSZJdE&F(;T8^8i)v}KltJ}b<)qUVhb$_hi*sO^`@J{tmc%OP4d_;}W+IUSp z50;;`mBz^#^nrRad`i6=KBqniUsS&Xe*;^x@Np!rYR3EU4fQ$rSGC+M{HgvOexQB; zhhVd%o;>K@FtrbkR_BBBs^!s+{GP6qPmbt$-jIt4DKt_jP}|H`tm`zosCZl|hR zPVf3^IgOiDmhm48j7OrCX2_jSd-Zy_t6FYSdaLCoWuW>DJY0PN9;?0zPgef|PgBc{ ziKYHW{+?*QCPHv$@|-#h&QRkn#jw>$@H%xlc#FCQ{F1s4yk9*EKB}Grzpj=CUhjx4 zZ2bx(PHDzU_?&t*d`X=NUs20bu^-jD;hXBW;k)XS@L%dr;s4YZ;m|7XZn_6s;hG4+ zIU&D?EW0B&Tu>bj7gxu?Wz}(TMRj3VekM77HjW=m&DC;+Y_ImgJ=IC@0N0lDz-Y8) z)If&(ezH^~m))n-jp2oAITe?xTf!^VZQwQPcJOYo46m3Ds^j4-bz%6;Dkva@N+5Au zGtg7UN9q*#6LkalvbqWUo%%`mXLS$wmRg4J-_;}Gf7EiX`$+w)G%yd=B8^xI$ElaY ziR#U83H4sMym~)eMSTRWseTo%r+yDkRiA|0s?WfkVM|v0H4;5F<0jl+eH$LBz6(!Q zKZK{L<&}`7j)WJf<-tXUTE=|&k!V>L#(ZOox{{3l`!rD%8AsLfwBne$IsBoz1AJO7 z_Xii%L*Xmx5%3N5X!x#r3j9Dl9S*H34ML0NBN6Q+aFD_I)z8Dl)EnUn>Md{$wY;Qi zsFtT5E!6MB9n|vFqnG*|JVgBsJlfL4H6+s2H{m(zzu*OG8K73E3&CsEMd1zV;_xP51wN>53}>mW)=0dmi4O2_^#J%I^-%Z|wTx(&)nniv)#Knh>gn(w>RIr8wTyuB zTS#&o$a?{~YcE4UK0n9xTHP| zUs1md|EN9&-&B79-&LQ1|5ASg|EInShvGI^cI7=dT>Up3?&4mw~IRYr%EY_2EY9)^ICzf4H-HG~BZ~S|+UH$Zg`RUEjUB{F1$+po`u9tNzB2RifNx3J!BkFN5ZeEqv2y}dC~cv zIsv{QehR?!wOU@-{Gg77udC%%@b9oC3lu`)p=K0^bK*KI@p5p48n=l5kFRrqv#EOj z|K8`E8Dq}e&lxk!;20xAIOCEeG$c{dxRqOsYe??Qamg7{B=_5rCYMr4$|c_h(HBXQ zL@DK~qEsqLrIN(|^I7{jGb{D~?U!}-`}wSAUH4jRU(R;MN*2a+wo-+W%*r8817NEs z%my?PP60O+t^&>zZi4cyHe$3uM0;VL*Er zya+slOcC20%{cbFN?9ZkUhosb@nHU?c_v5(KP&79zbJe?c!Tf_;5}qszhiq>n1|q~ za18i!VP1fI9TtP#a#k33R@TqLm`T<}VeG6c!Y#obl*qz(0TL^m4^9%k2V6mzJr@vW z&s{GZ?gyiR7`#epB0L=2LU;_gweUFb9l{}SzA!Eut$T#gsa7xH+2DS{E5L(=p97D+ zf$Kk7umwg)B6ffu7Tyh>CHy{kvG7swO5u~>=Y+oiuNOW8-YonBc&qSv@aw|Ap?vFY zF)kzGurMF59T(AG@ZI1F2!-YZ-ed_eeS@L}QB;E#kmflmnc1Aier3Vfz9jz0(BSQzIdVgmSr@FU<$ z!gIiUMVkIgz|q1_g5!i=0H+9V1*Z$|16L6~2+kHh9)?j{jI-ce;d9`|!oPr<3I7Ui zC2V7jZ7a-+kq*MK;4Z?v80jXQ3Vwh*0}a783LK`v6|hhu{NRU#tAZaE##(JXCY%SJ zCwv=tiEtyiXI(0aq4o z3a&1E7r2%%Z(4%FylJ^X_&)H>VKF$rTM7>Y-!426e3$SvaA)Cp;O@elu6>00-OoVb z*T5r%ITZ_qkASBMhyMrTF)>bo=LvrYULwpX`lK*lNLnq-Y5Bac5B!pF1@J4vyis{w znA7!5;au=LO}PG}d--eoDAC z_!;4j;P4A#+zVraFs}ptBRm59U*RI~+rpfd?+J5Seki;Y{6FC*z^8=Qg1-?i0sr7| z*y4QsMI!ct{}BEJd{y`iI0_Gh*h73k;T7g7J6ZS&I8E5XfXxz40@o7eL+PL}r|}I< zx&9;5IxudQh{oWS!Z(9&7v^`kcL{S&cNXS6?k>y+(F26}<-`NRoYJF&CxIskPv!T& zkBBiF{J1dB%?pGTSPAnq{gg20{WHSPfnN~jLx~N-Tm!ZV^FhQL!ta3J28Y@DqcGl+ zh-2Ung?Y~YpYT`UQ^G%hzY+cw{DbhH;9rFKo$nvQZp@CW!hA&|>Sm|cQ~3R_SBy%C zNEYTfK24a9St|?I23Hqu0In%~1Gp)976t*fJYn7~wGmDSw-@Hsb|=j^{s9=>Bq9sk zTbNU8urRK=tA?C;S@tKf-&# zJA~f??-4!--Y@(y_>l0|;G@E4!N-L!flmr^Mtm(CPKR+;jBN1F!n}&TD9o$aE5gme zo@P#0w+F`x_W>sf^JG>*xCopn%qMDD!pp!p&A9&Kn5~9UPa-yg8wu|MHx=gS%@gK; zZ6o|KxVshjc#3ch@N{7g%vr*X z!SjXh1uqpY02d4M3E6YPMc|EO{*DBncx{&mUQF&4einQ{crEy_FrRXLBwPYMA-oIx zh45bR8R7T9=Y;wE|AO!daQKoKr(jrk#LdI;BRE>vhf`Rba4m3(a1(I4a7SGtA_(O1k@Gf^E#?!cDH0Lw!7&z&1J4pp2hSJI0527;11=WkL#U^PTZ7jMcL%>L z+#kF}xRB3(wu|vFc$e@}@IK*}z=wtT@aVYk2jG*!AA!FX{seqh_yqW8;d9`>gnt8j zTHqU3w%!wkc?^SG9-JWT2UjIOuI_lGuoC(T&je`C#&bPzYhf<4cL?+TAzzpmE%yjl z2KN#UfcpvOfCmfT2p%q+2OcZTdyFY9xK^OxyI?#f5xv0kg(rZQ3QqA!CJSF2v*`YVOHW!VIG2x!Yr(-a24=iGOyjR4Hu3E zj}>N5Occ%nKO$TM+-|lQwP7q2&IKqI5qxNM2;`H^lIVVwq2<1*jo5sJEUT_A)g6q{I?lJh2?Dfp^}NO75234De9vgg-^zWo$3r$4_zLgRx*EQ;cB;Cq#Eo-1*WRuyHSB@ z>dJ6-mSl0$n7AGht9s>ePQ@>t2NeTDbi_NvL9EK z4xpa1Rf_{iJ4dafHCG)vP*`ZsQ*GWU>}=0h%ik${KqVh6yx+B}gPM4-u!HO44(b5+ zmpiCR?_wWww;Ia5|8BMY-NNy%z}>3Bp~4RFgYS0fdyZ#uR!mT%qOQwW`r?Xob@KC@ zlj3J1j^m1PNvdx!n4yZ+j!IXDe@IA*UuHz6D0}2XK9%=gVQ%~yL-(uXR&6qtPIxk1 zZG5jVDSjj3I7XOZ1-1Iwf((_^xPSW6!-zX+#HFi_Q<`R|lj~P_RN$2new7c8*rfbO zb=2#79t?K-K6@wxcl zF_E6RPF1_^p$ru$c+<1=r&s-|=zX-NncWlYLY8NA_j_O-7B17fc zo6^ydO-a1@2EH6k0S zO^tB8@(-bpijNj%$8Rwr8>_wvlQPt>>JOza{Sc+@>ZnpaM5zZ2pQh^6`34zk=7%Wt zV?%GIMtLh`Ebab6x;oFar#mXwM@W0w@X1phCw9(I2Y-1rUCsXpHH*Q6H(qn|z_(H@ zC$#gaT_0hv1fXO3YQ42OwPOMjebFmj zBk6MnK9TAUR~?(o%ZOTr(?@&Nak&e}f-cQ)t-3|B8L3vo#XhZ0&Fzz>l0HNA&flxD zJ}bOV9iG?6qb_Vp@v8#L{%&eCw(X{}wBeh!ai z@Yp5gh15$6`(#9og$L$7t8{W~)ALS3U)w`x99Z(&w-kzpT zGD%EN^)s`|#}!bLQ*`brBpchaY@9u+PHh_CQw68c?*(eq4amBPK5O6;8BR0RPM;Wn{W>cEl$Yia1t361j26T)`UwRtC?A|KnH1b)GdIWT{IGesLOjE0%Ib1U$op&VrJ6wjO4^p+i zgZFIJk!JQFHIe2jwVGz`Aa#J|7WEU&W`k6v?_us&Ex(7^c90rM^Q>Axv&$g0on|j} zisr|IRP0%pAFKLjVYa?s^`M!grqWz?zgkCgzB)p4N}btm3$87$)T$0IhZF@Uz&Ljs97{es!cS{JfM!##IXMnX8JHy z`$w2tR7aY*!_-8YezltB+F|Md&FShVnt=yZrSmYis+Q+rwti3zr8!b9py?T|w$q%A z6DrJ{;VSkgm}gb}pJ1*Zu6n?XI*Pl6Db9dd_7e_IlaXp2-MXkFbW0kgF3}vUs{ITz zbCkN{XPCum6wUUd)N-1K)oz-TN2%{$4gz+5#-HT?xikJW0Lq0#C9%}n(Z&5uW`O25MFrds|AGcZOCrCFpF z(CjrvZKt_WouavBjEemY=22DuH<(Aqs2(&g;3NyvGghsGsm8{Zq^mQ(p$8U^RhQ^6 zT~+%X4qL~nJAQ{5r$*7dJWegAnT>NS%)of{9nJPC`6A50<5km(FpsLfG(ClC7R_w6 ziRR2gb)06Lvj2b?GeOn<17P;wP> z30pHk{Y;O&@R;wU%)Nw^M<=LOm!Nm4geOssUIaaMB;JW~E(6r?p)pmW)*`;xi9gJA z>nEx&n67mO?#moK@F(=PlT?F0p>KgcR4tei^N*UGpQNVIBY<1IhEB>|NEyFla@qML zS3UI*&L>^qQdtUp20gjTQ&q}eklW*i@nw~~B-!t;@b}*8GQ(xnQ3L-ftR8h4PV1aHtYYG# znQAi=udR;nmenX+uqR)WcMHaz(DNMsBI@VotA*5a zYT=s#HTC+P|0wCgLiGhby1?V2ZrzeV2tBiCNrMnN1~<$v>zXea33b`xCDWkt4SMJ7 zzGN5Fy~~!o4>hkYzOHck2a9u(EBgtRWkVkZ9TSw-Nd?r0J)uTZ58zS32}j>ZeeiO% zhx%pc_h@~o3-X00Rf-F8mmu%?bT;|aL&d5e^#RaFIGwwS`ut+GnflTC_|Dtuit}1u zsa$U8ak$s7CkMj~|NW~}C+f{`-+zzeKc9Ni8uc`Fz6Nkf{q**A{$$J;^B|pmR{czm z`FQ$shf}j$4^n16uUdJapMbtt4hHqf&#Q&hN8W^QF&+Id_48}h7t}A{i-tyeaH>F5 zC@DT2uSgF@fjkWlQ=9q*Goo_vgeKo9Y9w4-MH|$#C?pL*-=|JpZh*^U>Yk12ed>9) zmR_SKMMKXnQCZQ@yFtIf$)|vN+Y&XJ`h4hX9epG9`6X%(^(L+Hh*j%L%R%0;Ri%`J z9D-cksc}B_i(6Gc>czL?)qFW7)Ca$=Hd9}G2fnOwvOiCK<{ssWfqoeJt#V9apr6>I zI#KuIky(~H@&G2zeCik8R8LcHg7532oP16~xAW9bF(I7j52{M#Lp-yzEDv-3K{b@- zMYVwDu7hej%^Y=#X3V=PHWp@ERX-MHlXq1Qn)B6EnD%=00@Y>js`sHr54aEO#(Z@p zHk1{$|0|buQq}N=sz-hF1D;E&O&v2Zw7sau2e{ots)U#)%Xost zvGlZBum;!J&qceezG_sxs;GRf7q`9HE^8HrIKPlX(qY$UdhqRb1+{5SGHy2$LMi1M zHEhthQG**)wP}OXqUtxO-?)())p}mdlqUZ{5;q2~zDCZmezDZl&mRt|q7AEdslfLQ zJ*w^tt{By8cVf)a=@}liGci=?y7ajkIXyS{Z}H8#*=Z$>l0x5+%ID$nsY=fX z;dKd>mk~OI{)t3Y$S$Adu{V2MMXx0XUMo^HGei4(KE7~TitFZ?v!2*o-kMh4E}EIV zeP+?B3rI6-7WS`BbnRaD~|Ds@K?Q*Vu{I*ya9aC!E6j3b-?St*pQ;wyz>>nb$$ z0sa#;o_zzXnp<6Mu2X+yhMvGPMAWfnlbi54qk-$u0>`Z4nE3XR zfS%5cByMP-*R=ufTdaL|MLcdpE`ITD7V&OoJ$hS&Z?R@@dcDzA2ESjv0Z&WepsyMHp8eM!AuJ5)LRfsOI% zD)&x2c6Rh0KjL3a!v6+KX^+Ob?U+F+jE~ArL_|Jr7hM(jfY{SN7FY=rkra06Dr`Yw|lx8e^3&w$vxrhtl(gux<_Pe5mDj!mR)h_Xr@$iuX|P)^fq4h0Qnh zvXVqaE&g#7^`Jc$ir)kAec>6I(s z{?9X7i%E$wbRVM)zvaz~Q=99A8VzmkLltuPUjQur_^B0Ds|M>)ZV&FoqiWBF5@UJB zqu8kH>mwpMDXQ+%*q77k>N)A=GCHU`wA?-v8I{XCVw^ncGmkjSb5-Tn4OIx=je1%> zzRYd=#>3ZTdE&5`MXyUll7xil${xPvp7=PrE4qqjKb-L+Tc~4nRc*Kuw`2T72RyCO zJD$WH$RWC#?!VZ?LyXCCIx{f_^^dNujkv^J7;e$oG{RQA<^3K9F1m*27)tbe>Y#+^ z-cbuts&ALB-2KSf_I2hE^({fu+`iA)b-ott5+C0OiS`|YdpX}+6d&VDg=cxoGZ9YZ z#&ZC9x*}Cfx7olHoqzfIUorbbar|z`R~OB(eT5kAF5kUqr`tDy2hW#-e4>1NFax4} zGnqd|20JyuADdv;f=ePhIyO-b|A&Z*O_IakjxotL`^%L$6%C6`(Id%Yd0m)Zu|E5I zi*L%Io$5gk+wY+R zkQ%`*E`dXZk<>Vzxuvm=_7PpJ0PJ*r<8&5O(e7zCMEg@ap&RWlwL8i~CO;yRO336( zor&Fvv)Q_+lk{+n)(LY__*GQh<~Q`{2n4&hCgvs6{rvw=S0Cx7!OgbO2&O~-+r@n( zq3vR=|FysdNccI9u8pT8*w!G}#iMa(*jhY`N4iGPoYtneI3X9%zRVu-xp*9QAY}9# z(ATp4E{;~$g7#@U!pt*O`yZ$Oar&oe+XJ7>Zn&wjE4eraTnjo?hNb@?Y$8goGGyoj zmR;3V16n=!rtLsCz-C?e9-&pWJw80u@ahu0E80C!AUa+5U@zAg#COB>qm=}QyTxG) zJ69YQw71fqW^vWjsa&kupI`*oRZtJ-q+}OY#H?ZKtGHR>e1uG{bapkj)YfTymYa?D zquZRuS9eDmuSZ6~z4bXlVySm_+^nW#Lg%$D7U z4#H77&DoSk4-4(XQTko#nWuY(Z`wK)X(dOYN5+8umVK*>>#J+Qy=h!S?AH1a`~m06 zY;qO{3Lhsr^=hL#y&__qPH&^L=Bo`>W!4xo%-UD#eY^JN3l3HKjKtx;U3<@^chz?I z$U!4c!doAr9=bXATIu&7rjc$Q4qT6lUD--p8Kh2wr;P`h*l=%z_C1Puz~j(YXSd_5j_a3b3ooY^wXFTix9%5JnkTr5cM)<>wI=fan zyJCzpX7_~7ZWY|C-H-VRdq3j&zJinelRA5z#xr>eu!|#yvoh*qv4pP3$vIvt^%1B8 zU*~wO)Op_t+p5|K>#8*pl?kiw8is1PCRbC*jY4VRdztALT`^34*-Z(2Waa`S>@P!x4;gt zA}q*C{Rs=J&DY9tPC>AXwt97j$+#Y@W=%ED=hjN+_6|~42qU|jb#{-jj=CqCNAXDi7q+vE zwTN=o(;k`mIC}OiI@<1}X8|7mS-d83WX6 zVeIjc+^>_gL?xW&4bk}-^3 zrLO1EdqNk-d1V*>EX6&ci@OYOr}v(W^qyYk*n|+teLcWK@U{JMqk?-bv5X37Y{(a*y@cst0~CZsmA8NRRg!VR%duR z)!3q|@j_`ewuE)!{SfpEEmm8z$jTUE_HJF|a9w0$Totg$-8z+pG2#^Yh7{Q*0FMDMCy@zDkKuLE!0jcuIMxfK|Om;%IDsZ}^P+!#Q3sT0AztN1l( zlUuKX=U5LtH=^{a*97y;89dR^`;nkK?NO+`T~6DDu=(>7`p0qCsH#nI3LGbWXq@QE zaqX?Ii{;tGF8)JGt*=X+Ra#0zo$ET-0e+o7Rag2PljP|&2u}x*dItKD$05(n<>9l^ z)VFfY30pNVh0=IqW4G3eP#4;~>#=Xs_7vK>k!|#%^%8B~;n=rpdpB*~SLXtoKS(zQgz9WZbvR`Q>BfX{(TfDu6Q$jNem}t6#u;gTkTm0T8cFi3ndA-( zJbSv4B!F9T7Bk&UvdK)c5EIA_FVbny!Khj{NwX-D1|Ir%gE2tt2F?{Ks`n9+*sG0n z^CjKte@oY>G+llw(rqx(?N3JkvyvPBEn&mbgpF}D?L#`D(}#abfrldL*oAMKja!T! zvp+ME)Wh^-QJtq?dhs_3NOq8FXAt4LyJ+*dEh6JK-G+nLb zK-oC#c5|Jiwyyu(n1-x>bDbmxgClJM=T4rkVIFOLE_3YgPzY5W32jk&!bjxJZma!qlZ4 ziu~;WyfMWJ7XN}GtMPFRRGy8}F?yUP-JzdG9j6`U85<4-n5`EnbYR*$b*pa0fOKwg z?$S@WaGUFNb_bo`c1G*R1o`?=86OjzL^(WXeT_yq=irAuHDF(YuXDzJSQk|hW6G*r z*S7MtyFV@BK2N)MM6}~RPrHw#JAZe}8i9saeF<Ndr>cs=Er5>e=RvWn!?M^n5#H$60^}rp(AP_ zf)}ob@D(qLjOCj%eCF{(n!4HwCwBgyk|fyWa2TAGoLS;YLEtgO;2y)O%KuWryU`lj zrH4EADhgZ+k#|YAl!;Cy1Dg>u3GELY1bmNiQ}tWG3@8H~U*67D<^N;Csn>1INmom6 z4OOYd2St~&L&?!@o^m87Lboc0(m1%m&o%ir7%(Xm@uk*(3Cl4Pyz7IRV6^Da7kPBFe zlGB?AlrD6mAlL~W&R8oK?XioyVpLVT-jO-S{z6X93`}rlU}vY?WL<7!)Ws<`MVGq` z#W^#yfv)vB98711HuNy({jdXFko!7RConbwi#g)7v?T&ZBXB{WY7FYfd3{SI^ls>lm9a`wb+lg6u6Pp%7bke@5k*}mhP|ueX(VC;!;=OEQy<&XpF6PB;dJDuXs;;iIMt%6h`G3KK z_0iJ+v!xlb-vvDx_Z{qXEFe|eKsyMnhM{$W_A#_uN;Qt;vGC?-KaH5qr7>1jUdNw@ zcE6#G4nw>Qv8Ys(sW=%CG1(aFr4d%uN1^$ltu-`0-{Yf$9c5bJDQI<|Rb2;Y0{FZ% zGE%`;5z`tm;XnQnwHHzR4gHGfe5dtg^K%?BJ&br(xq%svo9L?i?}hx4{Whf$R^TgW zoRn410|q0qe_3SJ%ly5lF%Tar6(jYF!66DGM*Sm(Pb~Qp{F|`KA*QU-I22au zc#f*eZlKi)!7jd~a%7TTc8B%ZN@nR5H%EKfEVcA(`HQnb&r(~@mYP^7^yKUb=Rjm~ zrspAVPFI$Wg~qCJ6lX2_8IZLIZMTd0r<$(IEP`G9HV%F@eeh@KuUt~AVGOQ`v0Bnik3m_X=h)99 zL1RQaV{Wd^Gs7&}X{fb5&z_C=cVX-6vklqmSi4Y8_-l@<|JaCYqNl_r zyB6eSzRV%DRm}Xf#mLy+rmN%5!W6{;(0`MnCfqrS7vym^F35MDitR(g99y5L^YC5T zekAAs=eS40pmJ87@+i-9(A5`O^i{pp%}1T;OhMM3cU=>x!xNj<>wSphY0tjTg9EVw ze)b%VS*-P3jhl({G~SMZV$at&4aeGEz_C`3m;3g@VwPX;C3gBEE%(PjvlnaJfFW-$ zAqMY&%8;TRlNujx!`2bqBx30c1${&>iIegJekf$Q|6w(+IDB5{|ipHjgr$ zesTwwAt6ITz!MyUu40IuSuQvQ!-XMwQn_FPTaJ+Up)1I1FNTD}?%-)mafZYruHY>g z-V6y}xr3un8-~P>UBTW+#}H1)_XKC7#taE}dxD)&Glql?p4=zkz!2PrzGO&v&mA0u zu3<>%=n1Bx3m6g)x`G*qXGpl@4z9tTA)&1&I2W~LNNDE?Rzj^967KK>cO&E7iRk}? zJ3T?pO@@Slo?sArhJ?F3!KJ7!LqdB`a1*+NA!)Q7+<|$_ko2e>{1KI5Nc6jdOQA6& zO}B$RF$5WslpVYWV~`;+;I4lF6=q289-QYv`TPm7#2k0rYY6KsRS!H|&P2{u6oFeJQ-9}I;rL&7`m;1KK?5)Qh9 zxyYI!p_wPx0Aq+DVUQ=-7kh?;=AK|08p@E6>u7A?XpjepU1agWWKA6P7cEqz~=j`^bYK>8Ksd!=54OBRlv4Tp5x+u!FoYWk{&v zssAQsB18Or!L#Vpv&rn)qpsi^7!?fumTLEsqRML3ux&4>aYG(RR|T#6C6-LQJ2b^s z$6Hp4^EJbjda#~#OT}gthbOobntE@JQn_tvR93y))QBm$zGEmoIs6qm$+kLi7mtzT zv3{{Ttt9cT2NB%i6)1@yHE<%h8&(=Y;^_k^xGO4+AU*6va5twkg0$VfTPN8L<|UU? zI_VPxZ$r zX$0wv6T#i@2ySbvy^?T)u0a>>_$7zd3Bw(oJ6^wPoxp~|aIcgW_)zc=fyH^6T zN8Q#0S83NK{H<%_SKbSU9uX(P7=&w`3ZYGmI1v{8i<5%3JmR#Rk1JmJ7q1d%+aq3t z5B|mJ7_{RNC&DlP;si-=F)|))`~@5tj+k&(wQHi?*2EY+tvO!Z)})w~B})c{szs{- z4~BeQIz#M+fI$bE{D`;?N!BSL?NO9a!?m*w9;U_0o`uUbQO}s;oXuY?E$BtN(>UQ!Bpb#@B!NL2lep#O^a3qzqF{JdQJ`nT}xxt?8%{O_G{|p$)VP+4`Nld z!Jbt68x{LdD9iPPSJitcbYr=VUfb<1?^b=!490&5e<+mh+U-@7W{<6^wmpP`9*$E# zJ`}pi-lS?x31y=GZKi~BTwllO;?)*qbyMwk)Ul#a(2i2&riLopZdGGy=!J?Nbh3^6Hg>g3 zf3n-{@^R{$si8LbFK+dwh3bXp#^}z_G3E7Vg7(dDeD$YKE0S6($^WXLQ*~_I|KZ~@ ze4@)IvwBhG{pzRUcB!hc2#5Pr$$is8wQU^snGd7E&y?(ZIMl-Bn&DP|JrcUb{!dBs zM?+g}f8PP)`wZwiwr`&?10S@yw(HQPeq&1=-q5pJN#&WL6Yk_O{re8byI-UGKG z*uG=OjZt}v*H=|(vqO#5jM`1(6PSU-BL}s+^SFR|aCWF)qE0z*c;9}*1~PMXXm)6F zQdx02GfSP@7D_MaHzzdOjvqE+`27L>F=Y7IMJo59;@&t08wSGymb=u>Yrd?Q))ToSroH_&LtBTGUnQ`n4%CJlLP zPbjOT&C<~CQM!?4mz6Xt4*hPcyb6JswkTbET zR1Y8AQ|D!CCG4{h_>BW~a(nety#)MH#no1RHUFi&B$XS#GEUw1<%~ExOKqyzArq>08X6mOp0iP=FP(4#^bajkVfxYQ* zYTk>XX6mNv=f>F$)yNf<+4n~>yQSIH)JruI((DY?cUjl8k{j2D8YHSgdogXA?;94Y zPHqjAQzu>v^-{xM!#Y25ODKwFoQiuhl&DUQ8Y(V`^{e40LgiIduiKKGWIf)bcJDaH zrDW%hP*FKm^hU^|hVBh5RXt9G{0UaQ(F2F|tv7lECwD#7@dVCHnQw%WRKdMC>zAv;Y%08fa9t_or;)&6vsvRrui+=(4$J}_1bm8X$%2%)arbw+IyR7%E z@5Sb2uuFA>OFSQMam&-GMjb1^K-GS&a=z+tzImYJvzU6hZZ+|>$^lg=c6Lh1up^HTLpr>{qX`4_{+n zxW-QAxR;I9%Kf_?w)hk-veBX6HTJY?>=oD8uU})IyvBCnR3F)xf9=27ZE?T(Hv!L( zuCb?IW50Zj{XcE1;aetG7{~(nf)lqzILs;5QR`N*sWHB%*u3{ju|Br=g?(gW{3BxX zUBeVyqCR^~{MM3pKMKu^Qcs)+b>-N-MLoMWl+1Zhe$loAaV3eLhPFk8uRU>;**NR` zb2&B@aWGe8oucflWu6+G<=j+|eoS4S2LHa||LtT0pU8RY{vqR4-jl<#O3r){%66*? zUt>Nu|2kBT?Z^9b{B*Xz@g_Cg{d8J9FaKq;Us3fQX^^JgUNt;U{d8ZFPZgDaI;zIj zNIWvzX7F~0@pQ?;bzARehNr0^y_4e9gc&%o{Dtz>$!>F_)MIt4gtlj#mNsTYO*}fM9>C5*|xSi~mk5 z`qW~7r+UvyORM<3BXL==&pND||ATt@v79vfM|H0Dvb69|PE0nves(yA%$quFbr5Wx zlCbGU4{h>xK&Jh6?M33hRanhjmNki0Fo%b~4qC`_19O*xA23JdAwN z;gRG&93D%)@)h0)W1C6isz&|Sx@~<8gD>3l(GG94a$uBmj4h1d{W7+#X*Y1Hg})nTrLexLJjD_eY+ zmh3IT2ex_$Ov@UPz3h8zDSmwTr)bt|g?F1;@nfhu|E?`J?YrIKrr7zRGjFo@HGHW0 z=R+C%i>H>q$cZ9*cd82KL)B|c1!H3ky|OTH!SYX|>U=lneO>iFk9Wx*cBEMBy#IAL zfSn&Y3nY7Y;RBn_VtN^ScRRcnJO3kP?B(i)P5VDu#@;s^=IHT5Xa4&7$jcnCr6Blg zI2X!z=&zmFb7b$Es>)BH>Ro4mvFQ%l=dkV|=*&-d&|8kK%b!`s-u(_=hn@eiGWNc$ zmLlsKvm7aao%evlIoSE3Gi$Q<9rYPpD?aW->kdBXup2x7Y*p#!kp2Zg?BZuT3GZgY zLu&ZX=x#_cFb7eRGmoxjLuUol<;_7PHeKFfhZ|t$ht7JCy+<5f_t@Mr_P+0MW9aecPQ)TS^%;7BT{42`X`?>zPqQ_ycdmeg{ zu=h(V2$TX4!5OX#IIU&fo&KlG*!z`Q_$y|70rGO;7snCf7amD|##v@L(zLEV{WTN_ zi^o@@{*FCYa(eJ<41OU+=9e_>$jF5ozmK5K$B0FSKF{El2J7Vs{@F;IhQPGB*oUhb zMolsbU>A|SU*iKC#9 zpqFD<{jl#N%$xav!tBez!n~OuBYXn;@xt@5pDa8L`>^mZ_&*}dzMm<482Tc5u|^#B zOC^F&1&W2A#-0O{K72y(JQ+Qdi9I=TZrm<<0DH2RAK2bPpg+5vte1N1IeV$=(*upj z63Z5`Fg^|WUHA<4ynJ8+j##pnxnWBYoyU?K(W{Ey2s+ujkKQPddV%w3f@3O7gU?p( zVFU_j0w;3h)I31+X3)uzQ!~4jX*u{f2$?nyKIF*xWufS;p_9Ga0N9=u9b+S`jmSBT zUC)f#!-?$uM*HiokJOr9w$UdaQDkp#$A`x=;`62WbU_r^%Pz$Bt@v0jycMi{aQwR= zf<|OXjYT92=mnkZeT7N!as%}Or|Yg0AD9-|D;L=}89uGWX8?T25uYsB{x$f(#{Z{a zc?*cnbq6Cn!rt$+tj`bBV_-Hwi0GBTeoh~3wGqfn%R@+}|DD2I;n*Ag{?0R_9-{O8 z181p10y>Q~oF683u8f{!1(*zj2{K3p?i6z1&MLYBg|iypxK9pP;3kMj6OoQ_LG z4))&*bF^O&<_P~?xDoce_GK&C+KR#)q`G@iF!QN_5Xrv-8UA_LlfC+$0{uT+B3ffl zb|Rd=0?Gt!q0Ke)m%-FINXZfZL!xtFk|X*#(Ys(zj_ABQ@Yg^_9Dp=%#?hOeqtH13 z$==iIP~zq^_27Gx%Bh0n%~2}3#}1#`o3uGuO<2*;=bR>=a}w**7?=a03W6WZW6ZAc z-;b3DBQZ~O9`AO-JjR`b{n+;;!@mV8P#`*w@i1W?<8cm$tpH$(W9X%B1{sNGBJpg| zc|3T*!3x#Ep4S0n9@po|@aKG9FFKDgPcro3F@8;$4cRT6hy4M)hQo=+Pp_+B9{$aMPVK%-o??MhbESc%CYCTEK~0VonM}l3pj^s7*5f!nIH~( zedPgOg?QT3d5H8C40t^_RrCz(*~Rpk0)N`%0_>{^*TkMvhdSSbq#dS_2dFC%4Y6mp zQs)5D7mr|eoj!kq$3nkVd^iT$2)BjaUYO(IZsEbuy9#q`uxFS*dL?Z27h?$agM|66 zHf=i1#(sn_2hC{VF32<_%<(fxxHt5v!ZWa+F3dwPPnctAp=R{|`$(`%A~>*~6g~lc zwea)UuMuWO8-&kd{~zJku-_`o2D~nO68pWv2e5xjcq{UMm&c#2RJOR;W{v3RN3Uh#75f1+h!-GI4j#fS*AYZ{gNw@;` zz6c{z+VtTl*2^cDy`nE1z#Pz7;=`V(Lw?SAj70YShSIS$=Bwb080;99my0yEJV`K2 z*n3gS`qdTskA&Ht8U5ktyy&1l7ADzy$r-Q=p0OBFZ&PMEYW8Qd#`HQQlfM4lJR}Ej#wl5d{|^}m z8`+D&#jOE?AG$|4a#hn*^cd{P5j}-ETZk=>4FfZ672b%^h*7KCck|n8RSSDUT15y+ zh^>dk&h=qnPP3v)PvHv=Eo#v>rQp3A9P6PQyFyjAgm?NJ0o_m=29m~#=l)$xICDFUMB zN_1P8D-gUj@qrD8hS9G}bUw_N5xm#q1KXjG>pUDh%V3hdcR4y=?V--ON%nSh^!}o+f=TvvcJwgc`C$T1PO`VF z6EQ|~L|J6--Hy(8f#}b^V{4^@@! z3{+S5wF|^mM8mmdA|PIG0nO@MJA4yARLz|@ox2WeC#I=wmmZ0$FJ5`t3m@28BSccS zHMqTIb>;r*X<>OgDI@X8g!y zd}$rIGDq^@5sxsBa)ehI%!3)xajZ(22Q8xWKt-4bC&F6|4(~9GT?X$pc)!614L)q} zQG-7=_=LeH4L8@ zx6d0f7Yx2=@MVK7T((3y$zw48Ph&)nGdRg${_jTd30wR{zeoc91-l3b4CcjlM9(p} zj=_AHDB{z|U|wHE^kxRhf(TZVDJEg2OB($ ze@Z!0z(|9~8XPhhzmHz(Uu5ufgJ&8%+u->IFBWct8E!2zB8m-OW$+q<*BZQDvq~6P zt8_r`Frs%Eyw~9U1|Kx|u)#+S{@CCX2A?!IeA+P17<|^?^9Elq_@cp=4Yu569nQa3 z9XVJr2J<&Vp*v$K$%yb9oNjQY!2yG_4bCyRj={MGH!`@1+c>Q!EFt0 zZ*acBT@3DKa4&-kBFy#=h#26(1`jiMq`_ki4jDYz;39*k8$8qC+2GQ(Y`zh(*x+Rb z7aP3F;57!XHF&+j8x7u4#$jt~nPKfPc$dL@4c>3?L4yw)eAM8N4L)J;NzJmBoi-xQ z7<|^?^9Elq_@cp=4d&frWITBcjxjine-<+0lw`2qVE#SIh)<@$0fVy*&M}yGaQ+wY zfvpjOAD6;6V}BbN`cU{f-=V>X0iyxhDIfc6VctsfW{!z@-^C1=I8NBhCr8+r-oH+x zW^baSCs2P-br?1?Ei=iH=;Ryj++imP`&GxgI{4Mw0atcBqUu0qz#sgZ(##+9Kx(ay z)VtNMYWYQXH0Z21wD<9ItGc43J(=bMk5ilL68c@#+GT0aAE(1MuVR=C^m^DSaSKcaNb4THskX|mI6=4SAT$Q({VF=CPs3z@ zv_hoIFc}~n7s-#&%>b!FB`0AWm<*6QiPRb<1Ejek^@7O&sl%Ul=q8MX$pGn|5nZ%2 z8zuv!RvAwAYhW@!nj+E;m<*7%i*ytw1Ek+XIt!Bl(!_l^I(sf6dLcm%Wjfh&InYZ2 zdPt;3kQk8gYe?-d3iuPz3^tfsKDj`n)dlPm?rv}a8U6#XXFzttr~Vp^;?$Iea2ta=8QjO<(FRX3c$UFS4SvSp?FNVS&50De&xm-} z;8O;lGx$$~W4N|SKB)$085}gYxx>!=V9;x*VFGhW{W#f1q5Wvcw}KF=mqW zu;Db*NW4hvYQ>qIxX?jCHQ>9+@ZD|jTV$!sDT6PPrSezFK2{w!R=7Lz3G3fGm&#{C zkNDRlJ9;InjuCNVSp@z&-hy6D)50SuNq#d7*SX|Wr_6<5pYU_krOX!%|5puN|B|iL zeV?JfLza9#bkaH#;RFr&hVmrXCwzgr6!wRcK-b8Fi5t<&lcg}fp;t8Y9J1tD2h9AD zot4Mm^p0e7n~@-&ECt_VBrY=eDZ_sanHNde)`ES)JE%)OyAA(?5uNQnVnlpy@DF6k zC_c7~Ym=qL^~v((?G0d`u>Mg)DY%2--<>RaZ*Vx0(GVkIxRGFjp-&-80W%GsdF0Bv z@zx@+PndrUDWdadz$0btAy?J@VQU`~IEMA9;dF*9HT}WRFBg&(3W1y3{l=NS4zLx0N9pKfbJ zY$8jh`qyoxrf*Z{8iMUzuuu53q5rPl&8wCcPQt}}q=9MVnohC|uunKhUFzG&@V~{- zI~#gmvZNgdW6^7_Vtc`EZ8Spg}St(I$64_o}o8%bmu6yFd}X>5_B;1&W7IG(EF36;0Fz#vE;f= z>4?)BapL)7tKqbhEG^h?=!eL4odUiv_!qMHUm^z`pDSRWa7qGn zR)X!nj)p|=f4$O)mEiBgMQVC0Su*Wl=v~N?cA(*-|5!$Sr{Iy$eZu@tvXMNW2bZog zn~jJPvLxWoS~D@9;k{@093@MIJ~#BQ$ddM3Fw^2BZT)5V#3zvONCC7#s7OlKTj6_OJT#wMjzWZI+;d+eZm!~OQu!Gl4&hNuV?5t z89IN5Fyi0N&^w5(+uz-Y=xrnzV(7ySeS)D+AxlMP8b0&LH#v=21ojE9GxXPzjNAP^ zjJVlJu#X9ZKQ;7oWNH1cWIoNn_6PlilakByYGm=xA>ZQo*8%%9qy4uU5#5ah1>}}a zf&ok*Jju`(82-!1w>tjC^cQ}`(BC%v50k^UISKd|#C^iwGeY>Xk-&{b+`irMF9-Gs zS26S;Sz6qf+|KcDN`K*wh92%`Bp5=z(@F3k69`W?^d*LWG5IdXe--_OOAMbk4WCnn zeujLvUjOhM6o&6^CnGm5c_S@ICW~Iz&>N9EI{r<-KH>J%M>%>&!@rNgLk*u1J{^P zM8%I72|g-KfZv`p^l!-0vhTr6TNjUXuNpp{H291|hS(Cx(y&x=xIpVx6&k|z4ens@ zAcLnEyv*QD2ES+UIfG-;%gPET8^(18=Na72VE$Zrq@sfio@?++2ET9c1+w(SpX7eB z{$GU=`K~FpVwqFA!8ryuBuh6oG4xvvy)C())4LrF?qTo)6>ja>XOpGi1%|%T;B|)221DO&=>LuAoPP(5i1#89(2pDX=VYne8H0Z^_>#fyN@f0W z2B#XF2M$Lv?ZpUbWqfyYOqTWj=nin?8`Q3bPd|f)k!7q*FnCI3uK$whOe12Bkysgev7tX_ z=r59`LR$>pY4ARS-z#Ob|Km~vYrDbU8T^aEmko}pQdV$+!D$8u46bEx19Iej*PD%q z)&}2Y@I40iF?g`SqYR#C@WTerHaNV*Fjg4+yulj{-e&L~gWoausKK8a{I$V9I_%89 zi$(;W4n~e;tigN|8PPKhu3>OJgPV|LY~4a0<_y?d!I5w6J5&vqId!L#jMCm@Nj%Kp zLc?dWq0cb%*@mtRy_hVOcs9aeRB8(iS=)D#dpb2eK$c1zAwTHoAA%$A4xBW6el+-s z!Q}%;D-BB^OFlW^aKyNq5mMOw28RuvW$+S%R~h`G!LJ&;+u(y`9JY>?8P*pD|6uS> z2LEC3Uj|22D{DY`gOd$THMp|ou%)+ZMno-x>l%E6!8aM)(%{<+zRTc_26s33zOZ2o zG!a!J7=;X7Emf-!%AbgO3>ep~0W> z?+Hf+-6_R;VwBqR1_2tWKdBM zQL%%f!5$knK(QC_BZ?gr6vdCC{$H=z*<(I_e~M>Wu~p-38t>A0x5j%k-ly?X8b7D;D;mF1g6CZ3V)6I#oD0RlIi*>(!CqAr+41r6 zoNVN!qihrxYus4la*f+++*#wU8egh$e~pJ}9G6c4RK$}s#WaoQXuLqT>ZN;~mf?q+k-Q{Bm zRYLNygknCHu>GWK9MU*X;{uH@u$lSiSD9@?Z8h$oaSx4qY207q!5WXzc)Z5bG@c2L z+Y$5oMm8_gn4gZb-LKSmoyHq978>8G@h**bpXa!-_q<>{rZK-*Wk+16@#`8N*7!Y* zKhpSfjla_PC&^a(Gk(z&e`x%-#`25os_wbYft@(6f@yP>#`1IO%6}uxT|V4V?&b2~ zixPTho_cBAU*o|VkI{I%#?v&Osqtcss}#EpY%9d|Q#VE8H)#4BHNIKn+cdsMHGWOww=A}*;$2N49}ua+`H$w#4++~5{H?Kvk2#e8WR3ZuVcWgF#*H+- zfQyXUp2{^vTaCMD++AaSs@M)YOyjW{PtbUt#`1v@6V3crYl@W`uhDp&#y4qvv&Q`9 zu6;xJ0gWHkxK?9+llLM!!26own8wF7{!Zf`HU3L9pN0h{ydlIt2^qo`&^S}$ERE$e zCgs0GbLTgFZ95$`?xyiY8uzu>YDxn&#b}MkX}mz=B^qzmc&o`Xp|TX^JPr_3f%66Ao%l?`iyz#{A~9 z{U|{`%TkXO_=#To*0sq;O6oSYe8#0XAikVcH6$*dT&bJH!|7G=SdAxW%y049ewJ!n zqwy+@*J`|8<1H3j$KNfQ;!ch4(fA>aAJO8n3t5I{vn3id!_kQ{#Iyen{g-G=56s=QNfNuT>SiuDQRH zi}>xj`9M>As`2Lc4G zwKn+cmyNV|{kRqndlI#?NW|qQ-9|82LXx?ZGfUNGLGrRO2r+{#xUo zH2y{7KQ;bG~EXnc{zmuNgl<6#<)RU9|4O;7@PhQ_lsUaWDI#w#_xO5^J_-l*{%8sAl* zjsG9i6niy(LgQyNep%z!G(Mv7dm10p_;`Ym|8En5VaVwf*vF46cxa$E)Is42Q>e38ZjH6E(*bsFEGv7FhW?8})gisb|r#c?@CFujmD=mKBKX-2w~MUt0as4vbgXJ$;Os$==tz?ygZ5qqetJE;{cFN>Z67s1HmafOIz4Sx_vd=2L zwq&agjK1U)%RT-Sg)~bj;d%vl%*icIRyQs8k#VD%+YvJEI&upqfpH^*+eKtt1aVtV z#$brsMlw24Zgu2Bi$5S2%O@OIl-diSp{3|XZfx<@84TL>^+fk0B4UI8Gj6@jmip z7Joq=ZE=GD_;OXcZ7Gbm6!P_7bwoXdHeff^>3lzRn&oE`nuC2K`Bm~2mb-kqt=eU8 zJ_Vg^xpT!5u2jP9AH_~^h8vx32I`qx7#_$}G$o@NxHVTy_pW5*f?H3;bRR)RV!4e~ zO!rBO(IkyIit!Y|Sf;oD@f%#@gn`*au2S3zyjC%r!bZg%!9p=>|2D;4!FMX|3+7jp zX>%0#VZ}4SToQ%uo4^Oa@eC9nw}VuGnd-L{Gu6iwGu2-!E&%_in2A24n2G*Fv22XsB|2L&%D*!NF4DpXD#1$?vly==Mf%70NPzqeu7*~;1_k68l8r?=_7P0MAO!wW28QDXMSwj01qbo4>E2h~u$g-P9 z{@+vr4Sh~724MR}G2MSu%m~gXW_|ym824CZoiJ=Opa-#&2Z95N7lSht-vSPkh%Z+{69_em z*+4dun*y-iq?i%xCNqoJ9#TyAeTvz5_bXLtLze?l?yo1&Yy5jS|IdTkXi@0BjYC8Me0%^-l#4p}|U# z1s zM==kxeTrLvUm>>zU^}Fk5pXdax}(Q6PLSKt2R<01n0`(vW;Oi=j?)v1>kp-1WLz;P zqXPh2x?%<{A$O9_Mia$!??jdzK6+5abRSHvwEPcOOm{ArlhIAO$Bo%apkf8NhZSJ8 zV!8|RMV9-mis}9kxtHbsh+?|GOuoc&e@!vnkCOXX?w?6U`BU)=g?^UetYW$+`{6#o za!*xEcdm?+G01XnteEc26|;C-D`x3-P|VV;P|UVGkVB=6As}o+71Pi(GFub2*^24D zP%$G|s+bX6M;-ydwm~udZ&6JD+Z5CPPQ{$wYV1}5Q}lphR`YY@%K+G3R!pOBC}ziU zL@^Ju4;1sL`9v|t1V55T1F)S@%%k8BKl^_uc*wCMAhUn=C@!G0VxG-16f@Cb#XJz2 zk}n5fYp$3H?Mfa`SA6_OG1|G&S8)l?e}k34PHLp$GVtY!F9c6kd>8l%#Sen#DSiaJ zL~$KBruYzemEt$SYZQM3zJVMck5&m`vr>Et-mdsF@V$z^0q;?K7W}y4Kfq5b<{Hp1 zD9!@Es<`1YSmlv5{#dE-^ zig`tushDeX<|w`vTwrnBxE?|yrQmgCsbYQwwv}RD{kB)kt6wfh#Cm-M+*2{HelJyA z3m&NWMeuONZ-K`seg`};1@%uu$01BtitoX56dMklE*0~WzsnUj0IyJ7241bWGgy!( zqF%7wrkIWKPQ@rd<6gxP#BV&TgeKre6|(^zAWs5dJE)k3-d0RQA1dal_EW_?B2Fmo z2L4X*Q1B_m>?(c(#~A_RIHwegzz*~lbYBYgD!vk&s(3RvQ?UT&D83V1pm-mc>n71o zEx1(ii{Ms@-$ndJdnJ4T1s7CefG@y36`uiLs@RLF8K{`8eYj$-ay~|JI(WQde%@{& zc^Zsht5WO)$0eiuc}QHP6s^E(6}JIzRNNUX6n6pNrubs;or-&d?^Qe){IKGo;Kvm6 zsNsT5Owi@v=dD!W<6;nAQHtr{Ly8xG-%-2>{E^}qn5#O`Pz{)?I+3pif3J8A__Si) zcRH(hGnlJA(SQ6l2+lN1*a7w_z7L$Hn1@_Q@#ElJ#rwg9ieCaZR(t@=m7*8{54qNg z-v)P3{4uza%TvCXT*aNig^Ig?8!PS!Zm#%ZaBIbV!Ccddk@W{xDjo{H zNbzuRAH`$9gDj34JZ+Cqipk)yil>4nDV_!9T33u<4tTEOMc~DXmw=;+W8jsFYrxki zUJbrp@zvl>LH7SJx(>q4N^t{tyW-8@yA*E$->-NZc(3By!L^EafuB))H~2-x4}f1& z{1Es}#rxR*zo&%9!JjC88hl*wv*524zXbk4@d5BJiVuRh$QCnm82pdocfoFq)9C&_ z*su5~I2|0P;!_9_r8ohuulOr4-|L~Dli;R`e+0Kwd7!PhG0 zHw4#9M)|jaz?Xa&@rB@96?X#Pp|}tD9>s&e4=Nr4=JH_-dl{JT_>f0~pHn;m{IcRn zV7}u+KQq8b;!2na;RD6mvZ_@R3)xJ+?lFxM@kdn<5f#T~$16?Xy;Aq*T zueePfIoJkbH&>7_dKY^K-w-LE4m7WnF7g|+CJ%dTxZP-&S4lKhkgv9Qjo7%OX(Yat zPS;vaJIL2ryqmn%;yvVb7VjrtZ*d*@28&-MuebOu@&=1PByY6%GxCiVe?#8HD-mp` zD6rST_B(d-CW!$2ZL!!(=C})6kj#{00GwiV>NEnY*u$KnlS7I7Z- ztrYIH6g$ZGS&XmqqCE`Df@ChUoJz=57MGEiTilr(wYWDqX7NyRwZ-GfH5Shj556)q z5?@WHm6j9h%UoqKi^^_GOr_nH_K{Uvsw1nmbdY=v{$cwNySYZ9ae}NGm#kyexX#gi zt-MW-u{N`;S{J)LyLHLRRIQ8MnBBT$1v0hRdeU9BE?H-)b&U~)#nU74MO3S{B&$NT zrFC>yZAq5CYD>H5uG-QbvT93DlT}-KmCORd_AXhqrO(K!DV-#5mqQjbXbL-|f5RmT zf7lr@^TdN+CP%ur!5GVKDP75`rSv7MmNJseI>0uWtQyKZ@_pj+s~s)HjPA30*LJw0 zYEe>ry!2>HPli_UB8_>g$#$2|#+09}n)@z|_h|gI#; zj9}ZRah=8o$&)NUAA%Ea6P?f$ys2V);*AuWdGo|(-Y~J5H%V;feG!{^FT`fv|FD_& zJQT;}jSgGEdmA>(b(d92c@M*Omk(a2S~=KC_h}aI(s+-?Piy?D#_vkD+Mn^6rZ}nb z?;5)>7O*1=YMiHW6OG$w+*RYg8jlp|H?6@E{hCuu<24#@)_8};4`{q!4P|OvpmC|j?KSSH@j#8oXgpoxMH;UNYQj3n;?sw!TH4pnuhQuX ztFgYT@n;&J)cALeT^JwRVdcWa%8p#xK(SnySaBQ8f4r+E^woHz#$1@#j$od~av1_; zbdBb|S>qiVKcMk`i>+FDNmIxbiJjd^uoyYqs;W?lr?+&KgB z+k%{Ip&}ltc^a?rERE&M`pUmtyjZb(DPQq6&A)v4Ub*kH-I@P7TL2%__(P3PXnacJ za~gZ`@XgMQd^cW2R-n0;YRpBA6BAZ@YKnmx%Xi(Cq3N3YB8^vQyiVh-8t>A0&v}j; zPoEczS2dRJqpOHN)7<5P#mfD6&E1uGKKF8wV&x}Kb8n(?8_AumL$0f)=&SKajVEg? z-y^?5yzod>aYGf)4oxlJ{8sM!rMvhlzvayGnO1CNAtY6CXYwq|y|>0gC5u%BEnAi= z^#(f4w!CiBc(=y;B#ZKqW(!epX-a$F!T-poQpRbqazRBe--ih?eaPT^Q84b}EHQpn zPSAHEp_sj|s+aFnLVSkeIf%SkIW5eg2-dY><1A5k<=&vL;4|C&*vH_n6e6#1PKyUA z_Jn8!`-|fAgy(*bLtK>be7v?tz6dV6)g|g4uPX7aODKMzzg>x76}1reB*g0}KArG< zjN-cqZS(yQKTC+!6i-655_E`S@VK4a`cFV?0udt`q<%KVHVN?=id_?)Q=Wu4GNBzy zaWX{9@`DuDBs~8`aYw>)zo#HRkPvU9xIZEOK=Gx7Sn)K(w-Vy@6ptpvV-&whh|QmY zcqSoMQ#3xeb99JeAR*R&7GhRHoK3MLAwEN~EFq>m2eETP980lxLVS?o(1iFG#qkNT zUme6*3Gp_H%OF~<YH=TlUB&Q*Pt%@UZoo9>%{EhJ9FLV5br@N-W|nv zqH)+>#8t1MaSR-Ny~}K1>7RxP-+1V)f_V>mH)n#Wj0avv4Evy#8Al8o#9v>c%1gzO z?>j|A*;mNbxrFt_uOoD4FIGzu^PhMzQ#|-Oj)BaRcB#G$wK#GArfd6mDn%_rP0L-x{mr-LVp+a=f)IfiKA3(PAGnb z!hIA`rdr`j4?+DvLVeL8s860($DmGm$yOuLcZ=(9ABTE^mo&>l-RC2O(cYl%jO|6VJ&Z{5&Z}n~MkIkB&o_n##G&ouSXCQu992(@zs2F&vSS=N z5!;J+4;Ii%Ce$MECQNj;^+@L)F?$D0^ws?AppBunAF=pN*cfB!gP)9XiwEDVN(;@h z^{}xIyX;CudY_i{%vqxFzxSXf`m_xCR@>f0=q;F8VX6AQg~HsHP)(s~vpD@i4;eWs{5g5&grtwy?@6*u>7nd{E- zV_J+=4+r}qUFU2s;x1a41$7Tgee?(tkol9{wtl60&v|v}+bF<+P>+Xk9g)d%H80A$%3N3Qs!)%52TX7dGNXP= zGx7MpOz`5ZJ8plZXLkOVg|ffS=l^ZZ!q@+@Fa{PjS^59`UnZ8pL{FsZG=jgYneg#i z3bLL5Q@FY)701uDs#oEHO3%mBrfKl58%?~gnP{#|Ad7O#LxZpyVMUXFndpiKgtOp@ zCO*V&m*%DaGBFP(RKLFMJv6fi5Y9exd@KqFwXBySqr$%p@ah#uW}>;BIoUKA{{~)p zpO8@;)uOmYMPY~AS|3mHOKiz11WK#^mE`fcrr~O8+4~fFJIR~=Wp8G8%p!3Z;?C>+ z=~M3hmooDr%vmVs<%LW>#?vb)fCr2& zw`BoCxY+l<+eR(6u1($jKon`y+*yqTSo*r`MNF!KIo;*XnHrslCm_3B6d zWn$TO)2PEmCQbY(%nklr_mlTyO=Gd~);{$_UAv<6z_WOymu?t8!^gwo`G^hZ(5!up1fmuiUUI7=H)pQ0_p9_jB(?p zE}k=K+_;i*nUcmkmlwp_wbz`PhW{1YX(9sYo|&)z(U$+O=hpulVe2;kjz0L}i>_aDA3oxnX-VM@buTLvmds5sXB4_&EbFP>CM3YqH4STa*>&bX}(- zX&Vl0r|GFii*UVyx^`sr#eb*iU5`fKbh!CZVb`bd>j<}o!o^1~j+|2Z@w(?Cl+&A( zinil)xo?p_Nds_nxm`|I(oZ-rJT5*Wgt>=d!qtQ}L)~a6&hLOb3rCUXGbzod5I3M3 zb`|a<9)|~4(SyWVm~<8IC+P{WRLf{fEe4hIw$ZA(&;*gbE*+27Jp_%FKF@-gUmKxq^-0u zXt%C8QZUo}C`Q*@^CKu+X&;Gx+0pFy-AvsA=@v}m6kFFqDP$UfwMd|Ak+~F(!C&w% zeH~4@IFrqt&pB!tM30NQ)Szdodpr_YZ^mT9GtF(qK97YsT?%H}FQ^R93^#`jjx>JF z+jE8cqee0<6XKA1|c?+{1CsVS`a!5qlKZT5wt!@T!;vgzfwMf-bipy2T4A$IS2)~Cz+9n$07K=$}%&s%7CH~knA8*>02-Y`moox=o9=#o}hj)?L}%~+_z*H$}GZ*J>OD>iVPqw zVd3mHwo`z_+}7tutjcNDpp?J*69-gCW_Xt~?n~%5)0@GpTd5fX-_hX-2;GH1eEQnrEcp;N9 zqzXySa=HD(_~y6w8k)L{Z>t;LbdggS%`4r)l#F5Dm=y3&e2u<}S$2~cx#8W%5R=Ic z?+apLVYK|x5|q7v@w@ctO@?{@5~>5+t_8M>qCEz;fSOzbi zf8i z7A>e<-ZXm5AwJuc9TCBg_XTU$ltv#*t?k+=8Vus5>7YK*0p=ocN1x~`xR*SmFQiw+ z6a2{&zJB=GAuj6|U5fiMM=0$Ph5hk!Qq1R1o_M~0w3&ISSlMEEy)6TxLELCc9}sQq zo>qjZcB0#tW<4>G&fCQVIK$Sp{CQaHrKkNEX3Y{~w-gndxxyR>m&ql(vU-p%nPSku zXw$@4kE8y3whoM@c>YFl1e%E3$40~PEn%FR_)%DgeDBX;dS_!8?r^wQqX%~8qBI=g zfhZw|BdH}zKNTcg@vd6PES#+yS&&!yB z3nOPYTyeV&z70k4^FA@RHa%N>c6qem^4>@hhGE;GFjD!x1BPJ~%+%RvGZ=<)Z%s%*MIQcS=JD>e+h!}8Dm%?$|M}Tx|+-4;=AB_;>HY>R$ z@QiWWeX!w3eHYb(ahsL)wMZ0(Z8?;@so$csFm9s|z!ez^9OJfGv?nqh|C1sd*Lx$o;qHq(g1SzQycohk7~#a6Kx8LsG9@w- zeo`Y(BdhqzCA7f^A2_E+4xqp@A|sKedXX@anHhN=F@_?y4TT~cc@cSvM6QRStVly} zcBB;y?{-#Jk>@v23w5JCC=Bl|s#|$DL&kd-E4+>8ZY0QiH@)^W zoF_zJQnaP{p6EO&n$vtZ>*2jG;myfWulMMGki2?7;a?{GXOfVm8vHnY;>tbYc5 zI60b?x)-&8!A$`igQ-`GUX!DZa`~=ZN?UM_r$w8#|9V+?$(_Wg z>Cpx~K1927MDo$Fosp?9>x%G=2Y2K%*zg!BdH%=E-t1XqY1PWoGE&>xxP|vGSyT$L*qb)5aH12-u0S?Mk@E|6m8+_`{o{(TM7U>1i{mNCexSGxCezSMzRcd^N0<(jjDRn9EKtV7*z*qqwv)Ys z=Mt1bpbOdbT!2yzbR|1HQ|PA~%hu)DiRKdMPWE`V!)BmI9oXx+4^1Y}lm2}kexo@c z?wK9UkFTQhCG?W%xspLI<$d2Q4;Kdt^daYY7Sp}oWAIbpS&L>A7{HX3Bu$z+%?J!) z_uj-z6cew+@o@Z_b;9uafOQAMAUn1(}fzfm?HN2bg za|FAe?=krd=MzlW7`~h44g@Ch-0C?X7R262l3rE^4tgF#O$DmR>7G+e;c{j&({T0@<#VI?DfMY%MLtTpz~dET z=SCyB&oRhae)y-%UGN|H4y?Nf!gzPV0bclIed@(oLDtI5vnSEHq9kCZL6%FS_ z%X;UcPR;QzAON?P*v)Oc72k-dHODiBtFaf$&=VPYC&i@*U`}E%UR)W4o5XGNqK&OM z_K{Ttr^!Xfpeny{*Pz2_4t5GV_=Y$2(ezM;% z-(u+Y&^DbZo?Q^lHCKs`7et$wQQ=$|y~6Au<}5_N-$Sff7_Fan3)7Wi_Cw<`hqn4c z>{}Qu#ngx6mX|-_1;MiyMLX7)1!bMi%)#a3n9eS8kZTSp>mlYXiq=p6f>x{(_QyEd z+a4CTFN)qBk+WhKA^={0XRvKUv!R?UMlX(*rmtcKaNVDa@4U9hLvwb%#iM&Q<{~#5?U2ty(%kOgF^QU$$+<%&ryhK_S|Aoiqd%K7#MD@{DURX|G4#Ou z#M74a6{YV*Mm2OxMd#}1Li1;_ry3_X_Mm1PzAbHC{dS(qUhKwUD9sAKa>zX;+~p$l z^4z-|LX+TL5k{=sQ%6-yN88};9#AD<*OTRPF4-jB&59<4Vb{9E8Mh_cwA?rXoq){oP%aZ=kHX`#*M6vZ-_To6gFI zkRa~<4$ew0vcx^C>!^ydO`Xv4~k+CR5P+nVR^2z0(9`j^AgtJ~0_<9dk75s?P919wID z*B6z?>*Zr<#uh=*;@8Roks7%5#@cUQh`zPN+#sIl5Gyu^h+`dMjomkl=hgikA3l^R z>UWH#xeq|zZC&mEp1e0GhIWiKG3SWtjI?ji|-MH9l_%+1L2IAWmH4 zUyP#)*ZAGgba9Q}9bud?u)4*Rke~!zU-k3x zL*lAmKH;&i`aec9PF(dLrd9i@e=82c#8v+=8c1CA-z%=|8_N%K3A(gnh%CrU{&X}D zT=H)d&-RVw#{WcUcYZEfWj$iR#hHup8owHlsbAyIg+t;RzZ0w^uJP+oJ&9}l8YBVN z_>Uot-c&wGIDd&BLP9*V-Hl)m92FiZr(xo83@;S2CTHM|tT(!#S)Gr@2gf~AMKx@Jb0 z3oq3Rb3ud5@NaMrg`WY3!(0h467DRL`^PHGD@5=9u`=@xQPn@zz_H9L=1q)-#l!t$ zS=l2I-o9Su>p%AOa;o^Of2?K766D{$UfwG52E=+d=8AjXH}6JD(jUjajQfy7`Ok13 zrRu$FkpO2*tQ`<5FrN_*42U(nge&=ZPcw{j5sKG)wgHltE|+AqE{ORCn)mNEbnVG} zNuzv}Z6pss&T)~mE6*UVYG`R$X#x~v(U(b7Wv@eWJiJrkSL1Hp zaPq5hcL`aIyFK)y#@!WY4}LZ7eh{VN@4*4T;su<~5DK*M0Dk z;o+J%{!8dR({q{VHY64q*@xEDkejD`{{SY+8glyw&4m3Xp4D_8%qKn^a`X9)Gl(4c zhkTF!*}V1s3p26<|NNJ=gWB-8#hxLtyaIV$H|7WwZrpnBg!1s*#0V!bJ%(qJI5{L% z5$71dzxZOdD9^9VsTx_o!g$rlT9&06S^LoF{Ay&)1ql7i3wZDu&ic%DjCb?0S9|<5 z93CW1oHf(%$BBmL2#v33i2ntipBU*%j)KMRp|RB5dNjJW6Le+noI=?1uj>P0ygTOx zab#$0NT53lZ#}z++*?H1uvo~PA}$^lD>VNS(}%^{_nQKZ+1SNbUFS1*`2tBZE2RVF zHrUN=#i-R{mH{;P!DTh}A{n%s^ogk|DE@r$!?0MxO4gTo)>#K9%n&mgN`L=#G758W z(O+nm<{wU4;ZhAn8;}F@PbUxAa>{RtLBnGm%}2$$;jxD490Qo|N$m~LHk=|}7#>>? zxsyqWqM8lkPVDBkZiusZis&;U*1{|i%SXgEm@fQq2V!6F#?&8dP54!R&F;~!N zuAn`~MsJH7=yN3xG{?q3*_7HIV`Ib2Woiy#U7DAE|%ZC6)jpG+9S%mIwTeHe3t1jt2H$@WosHyG)l}I zhmzeO){Ki)b$FjeI?Y~g*ytinucK+%cBjcmZ=}sl%*!;Bow_-s%@ombd@Q%mY!>qk ziIjDd!Mzw^T3N9)9Gn!t&OF>;QpXt?)}gRLCMq8$i#CWI<70z5$`W`~8k`E}V%gRo zHQCm$p*MMCJSKyE0J$w9G@`JHgP_@j*xKAw*2d{Xf;h9p+|~#qTNKri33gFg9;GWK@iLvZ_nZhoz-Ibx(^JL@b;$Z7AhoHuq zOp1*(9}+7k*?y-=zgN+3bG8mkmVTd@6su^)W!KEr@_LQADZp-STaK$hs|;7m;9PAI zM^)kESm$(^f;+4fpuxa-&g58;nJqR>j%8cg{Ze~{rG1LpW8%}vu}J)GIJpiv_+>HF z0=G1-ebBA|F_c#!`)rpp#p)qyPLPa07~vjnO#!ae*!n|-X&)HnaI{mv1UrFS^RgjMDE_N%?|6) zSh%N!J8pv$_x8<^Uhdu(&5qxo=D2tGFEYU0-L(C6Fv;C}h1vcXoVX`7NNLZz3f#R9 znjJ2KP44cY9ejwHd$6nn7hC+Kw$;>FN|Cr^O>FA<%bSPR#C~c}yW^hNnI*nOOHo3w z85a{)=H!bV3o5ci!N~j4#g`4L2bk+b+x+SQzCG|%COwrm3E^$EUY%TGPkwcY`I&eR zdULX9SO9NpmZ9&L-u6y?0Pmk|DsqV(1=S_K2NH_sN43x2@>*Y)I0bjS>JutN@PL@Y zpAzvHe`X1H5q`FbVfb;Js}gq?RrmKjz1+5K{=-;w>iMd+5+!7hvGjg^|WR+F-h50FE@U})gR#x52yha=^t1fol zJHil^!W$BK<<&v+gqSdPTSW8(yYoh3F1>ZJI*YolqPo1gvHJv^hl-8Ia_Whv={!pu zqI3HxSXWRS>4=NpJW;%|HyGr6*<}Zii9KKzsw? zFaz;d*uca?u1GFtAYKd8i5ZByVZ!A?V0#AQ7f6emfjEjuv1TCl#Brx)AohcCH3N|Y ze>DT~LnJFP192>b#0Wl+Dgnyyp=_cS&2+b+Jp3FPfBcwQaC>;aRenf zDX}1~=Gv8C2=Adds=^4J!GANvnM96IPgYLoPo_FF8aZ)?Cc(uM;uULBs3#10L!TqT zz7QuPB!|`^J^oM-egdJsD29~KG`OUOcq=dr?g~- ze#ZY$s2LRD(EA7$3Ec;;S)touC_D5tQkY}7TEHo3z)t*kT_fhUtInG72x7Bm`*Fl> z&-S~CtS0-hm$xVTaXRGxbF$xq3~=LM#KXyc9IP)vh{n$u^q$f6Vpk zO0#ON-xVwvHP^2Z{r}HgzdI2_BX0{auzhu;d>u;0p6XYFjC$2nzoAUb-G`A+O!ebh z{oZ>XLO9o1v9&#V;nm`q_SHF<-ST1k>Slq7Oy(CHuDNa&X&tI_iXu$G>09Vh%D`v& z<%M8<{8RJ$=8Hb?7vIU~GtHCm7&uIBWHL}{skgcLEqte)rDF@pMp`{4s-?;2=dQGu zP<6P9{}qBaEeo}Vt9V}D2hwVp-)?!rUEnjQXpid`TUrRgsFX; zT9KE=sld3*&xTNtc96+$XXZmFN!ufQ9jga~OBr8Bb0AE}nSGpWh0b zdj^H>i~fpmu8Cq!r)qs>-wQ00Gw@)~?E4!H#-C4TmzQ_h`~}jBm;IwXv+r}nW6$j4 z?Beq?`|f5WoYCSh;h>*0``C4RpG4B_nSC9TdqGe$`!=Jj?3sNhktus--)9JI&+L1O z_SDS2!(=tH??*AVb9JQRM|xEg`xY=YYGU87%!!)VmxpxO6Z_yjF|qGTvA1*e1%*#j zJ>(r|ewXTE3~+Ah zQr)@lSBTQ=iZBLl>|@0L3XPwFJ+tfWKy$E>!}+Y{uoLuytr>Q6TL3*q;k67qjD5_d z*mF;b`jypr-Q{O_WCMqzx|C~6?+fXDF3%K?P*XGo_AyP6mz8RoU@@l&7Uhd*Wp$CK zG1QHd#mZpU2BP4nqH4Sia$~7zQ4%c_ec!~X8u=~IHXd~8G>)gER_U`loyhkKoH4=U2L;kCf z?=Tf^@E3~*=2s8apAux(Hds(SCDruRu3k|s%+9lUGtKi1%GNiBFC!WrKF{;btpjFy z&Y+Zh^T=V(f7xTqC*$!o-4}=vtE%hA7fyqPoXHN~(q{0H%gN%tWp(h7n*xQe>RJ5H zJw?~$ymyn!&xQD+9qDSKsrX`7(6v7?PV0G`FX3B3%;nuf-%56ihI29g`BuG#aBi3H zs!52;!$5K0)pgJqo|f?CyXG;V!?Td#){vcs^9LsU+6(a?b9j7W7gH%?zFEe6n5n## z_N+u~t3xm=5w{U>dzF@Np93FhUSFz7d*Mz{_|nYhx#};b#jwnRW*yiSW-fi{@(HRZ z%$qH~4D&cNNk;Ok>@n+^Ja?y+`SQ(~NN1Q0+gAWnwB(_WLh}u2X#|s2WYVBFJPJ;} zVskj$3c|9uN*H0>D6wK}C}V6C?#37!NuhC=bC!LL%_!WO7|Fw#vL+^LGWi*Dne>KS zO*i*3Deuv7ri{Y~^Mf_MxhhkeXw`ZO;xUrnWhxh$SHcHY{WX0{Ob)KX96kG%s^F}5 z-!gLyeq3P=gnd;e*EMyA`7IdVa+6E=`K=5`WrhRcKbgmB8D%j16eFpTLPmHeO|LNd zL7mL-K?*Bn+C%X$2VcG`trUcLpTxID7HmQIU7EX2S{NAKN@1-`+|aOx-mW(vM-(H& zucADB>t!J=3+K_>25EamSk8aH(d0y#)#0C*o=q~$iTanYa5lqRTV&6yU!R%1NrrNp z^;s@HAuHWu*1wtNw@O`-S-(9?;%0H@Rn;xbTWa6Fs`?=xuFqDkuP#lQ>?nT)v2*tw z5YOMV;wLd+=2JI#fNM*UO9G1npIGmf3Fw_l0L2416ia_!U$YO0dlMLSm2KUI6Q zyk@gg6x`7gFXi{RGplw-+ZwMa%I4pTRc7|3goM*bAI_nkVpW*xvcHIT7!I^L1?n;5Xkgu+I%5hWE zT|_iIzaXT$nC$Yr#alWhJeIwlGf1tw;rs9s@Vt+x-HpgW&n~gPLrt;yxp=fgO`E1Z zhwO{|2$D2N;yWmrq?$VTbrvD^q`eaRh+xN>oDwefl+;1Cn9xK=QiaJEn!@}dSyC61 z9*yv6(Z6F2p8BPWB^_%n3&s$2(k13fv;~)uT%05R)3K(o!i}O!>ThxtkSy34Zni?j zrEY+jG}7ewJ@qtdE@_lyGkGCOEoqFI22aVQS)!s-O}=?rjO|pDZT=vZcB(0Zw7XNy zz_JmHZJD_P9<#mR)JEzdy2i}SjAK3R)|h{iPvdRE>Q!Of5vc53Q=U|b!Z-6? z5=%SRbWP(LZ%Mmk{F&i;Y2rZVnr4~5pgt2LV= z=|)(F-7mvB7`9tQO?ELKbtgR~humpdNpQH?pX6cv?&PR>ol!`*)I!>SDTpA`js`EtfEVCusO)0n^sv9#b<|AN6FQ)YIaQ%9`e> zopIPD6*<`RvI!lnteIn8CHi!&xyJlfywkO&U+NgN?WF#WWgHZRFBdJk)wDJr5fi)B zTsD9&1SE}-fiuI~n6t4m_9j+MTrPzRkUnU}Nue~HM|0yH#}Qu(Be@e>`UJ;r7*GB| zBzH$nKM|$fYl=GU=l#%yj?OsjQ@L(=(js}pV3sZmXR#cer6eUSb!?>%>3f;w`wMYx z_nNk7na_2vX>8sjzV2Rgu_HSuTK1?Z33NkfZ$4l3YtT)M>rs;xpZyF3&lD7ZZ;mVm z51Wxa-eKD9@eap@_IT$QYQVREL30c*k6*s~65%&YTn=B=3h*swqb%eL`MxOIRw0i_UyKK2AzPv~4k|i74l3-*G_JhV zg_xc9Ay2+lAHf{QK?@O?M+UmO4qDt1fx;dJUBKAvVbCiG?TcS~F#;5D9JG(glri5d zW1huC+)8^^BDT?G1G`?)zN!qMk2l;0xIWc~Wr*`A$ql zTD+c}u;csk4g3#y;wur__f;K)pyz9rz}Msq!?^{m)%VSFG~UGb;|3bPiGF_~8lF$k zuzjakV=m9FBL7M*ihFX=$@zZctojnq z=P>O%dmM^}oTdTE$;)Wp@43LVHa>@W5)k$=-%dGR!BCI6beY@GIx@r3nA@bavaqz~ zk!St#a5?jqB)jldMsgi%)ob37iqWDRLtco67QT~lrI~yY0DTm;#1L{LoDxIGTzX3k zA(t>S^-Mk-kV8l=&l%<$l^8-=mTsY74Faf%@%Tbwt1TNv?U49R*a2+LL@$B-C8 z${6h-WD?`BhmfBz!;Q^rQ1lo=o<;ACA!K*Nn#^TZ)DW_`7!i1U7n&woYWRKzX=m0k zPvPb~6530_5svfbsIP;RaH86cquJNd@eK3S>#LA#gn91ub&-NA zyo95vO4C3{Z+HqL>T0s)+FRw{O_qOORA&n8B&V@SbT`Rq0bfru&Ka*^KI`&bWRi{W zFqY88QgDTNrS0n_lZTfkT@z^|i7lqLIR{+43Ws{o*T+mjAS;o5C96dClY%QOTVH?6 zO!#`*93Y!Qa@>hoCq=46~U3(eb!z`h}COIwW8)lAWRJ^C=8!lNTe}oiV zR`N$m!D}V|G8r%J)kDx^&WiAjGV{S{cyD^Txq}7=vmR&4mSBYMrFDCx{|=9?#7KW2 zTjC;fF2Yy?eIB&o+t3&=&}Ta`!aZ3D%S^6{>_DKI` zgiMU|hcbS9q+iTdwZg1JvNOY9(VH6Shc96laiu9!5at^U80fS47lcpHfIZOf#OAVA zCT?h$ZwO$Z&zpiH!|(9%07m+3%ge%lvS93y{yHZ0M)NGft`2u%CN{}HC$c}L1&;KQ zJu{o13rP(0v*jUg5A?G?U|HD%{cKLj_uVW@8+XsW>?6){ol`$g8%elHi0G4$2`T&W z;u`(mVsdfTwD!K+O|AqQ{)VTP?Xp6R@F_O^9p-;IBnl5@zh_DAl5B*}!mjVGxXI-+UEwXXd$-J#H~cGW{2n=Y420#WakuR3f^x{| zyH`eEV)an>NuiNE<@@fJLKAt)_dOtm3&N#5xE_>3X_&W!d=E*X1&3jA!}qWpLzRVJ zVAbxCNhl9DVtV#Up;cIRKaWVEb$Bpy_NbN5@cTTR_sODB$NOVaGcWu)^ZK}~vPI!A zyPR5SU^5N_mU6(wt~@#ZHS75alS``xTvwnh(pW9S7~L5Q<1>@5P^4w}zA+!6C0-Z!tbwIU_jgvh z!+Tg2-%G(6oH%&`&i^N+T~}Bhnm@=xGdWyDf2U-5`NPjMEvKaru&ViInXOc-ntzc( z&`9Ppe%~3hHIfiA>iK>%&mmxN(WHqurAjuk`=gY7zsn=Bt1J6m^b>L4A7%ih)6lLfoRoh{F+f64Re26y&Bwv>O&yKv}jc4yCK;bMr5pB?V(Y95cK zV-kWFc(XgAV0;coDRgDt?6-Itb2->c?eS*wn`yqdTZ;R<*_+tSdK{hMb-y?JA0E0% zj=qpaCTDYvW1rVC2GX+h?6y2Gtt+@4>Dm04sV~`4hcxX>&%T#Atml{opS#kto6<^1 z>e^&v$Jrz!j!O}J`;2U!Abq)U2Tzb)GqT69!RI+*2zYUZ;gwAkEIR`ymLfr%%%R;` z@I=I1*)n@}Cf%0VxS4ocX3J*srR+DnY~V~}Tsrs+FIx^Hw*#wid2~+j!SR$)UQgELc`W*(&mV#{6>mV2yG+2 zzGhywU7YM+lRdnDJG{|=Bi0xN;0u=*n4=sEy%%80{Q~e9hqugVRto(j=;^u;T#|~C zH|N`NmB7i|wt{h;VO;Z9h|vRTavgKqiDd(78qE9(y=6nTD)R<*#18l=ZHqEBZ=ePf zyLdfguCId`u2j(QAkt%ri|92M#bB;K&Pawg=B()@LWzM%U(t98_Z4Q%BWNRwoL$=*mMB|?vqbU~_y9UnJ zh?xUx^5U|DK7<=f=wZvNW05SO#VjGSr_q#WN~#ar>O8BclsXG(WBGk+shu0gc&J~5 zX(W6n*0IawJMuRi zZnbb5skzO8+lz3!N{k&;(_{**?fAdeu2RvV2A6@SOA63!)|KEGF8+JDvNMm|ZZF81WKJ z2J15vJ_UurU#YY4Q*ibfFC0>y^yD0+CGAY7C@sqz<*e!M^+(I@NcrJ(wW$BKIViNv z0K9G}nbYVB6yh1!TpO4~T15#|?dJC9>f=Glf_~fw*~KsVC?@z3fjw zL7pePD?I!TM_CVc#iMpNwC!%h%lUFp`*E9jpJiN6#V52OymDL4BX9djy(^o~IDdDK zp9r8yuEooY<$7`+(8om2F|OC8XKYSh9#WQI+Ux0g(rXFUBda7IGWN5DTG2Y)&m9r1 zkADq}jI(mIGZ)&ukZT0I8h-C0_x00frd0d5{I+n1PVZQ6q;Y z^W3q(mH%6QF~0*lnI-Vcubc-DY8Aam7M~88nFrjVwB3MxmmSl7zZMnRRpm{5FUOqy zkT`YlrPRrjEjytvzZ4=`g6U#i(GeaCL0NQXaW5n+M%BgR0XG3!UISPUK;!Lly>b_$ zNh-@m;N|< zr}YlVFl??-vxX;gT&{n2<$HB{7LJGCnvUUBG-^m09QyE)vsPG+3vLiQPY6g|PXo@w13?gu;K z$g3UCP3#`dxSY=T9A45KhH^i6cT?RwzfamiycyoB_QcLScxDP@+|j+$R5cxyjE8SU z{9)+)ral;fY4R8_THrZ}>MtYtImq&BWyQQ*cNj9O%~-A|3u-*L4KjS)w9xn90_{P5 zBi{3%7oWzs_TWODeiPyq+JOrlmmb8}oB^4g)CKd+;@-;QYJc%=eY-h4ELc?QPwl_O z+J6C@aC-h*qW#y5aqYjQ+JF5K_x!gE{zEatYTQ?+u=KzDSC013e|cyTM-5k`v5?V! zT~+?5WWyj`H%9dsWn4G2R7?E=0f+;hQB?E?PvzFZHX zUD^df)Kii`og71LQ9c{X-bbfv2lO^FPNTCSdk?MV5Fys=t{eW2E~O`Qy6$ir*amZrZovH;0<`kapUN zKXfVfD9?sJwGEHc2F!SELlVknNzsSd|8!JK#v~iLv$!M_rTDAME^Whun5o|CQk1eE zlJ`*3X|pHI!4XOd&k*=3DsM4pk;28G1mnT$$zq-UJmb3ON>Vs@H=z=*XG>GKI6TdG z8b`I;DrGJ{KY*Y;FNNc>!L6vkSu;)_*Kk-5fHANC$yfH+{WNyI=XnFd)QWNT|>E!RL+23e`?jQW>Q>beX>7aXLq*spD%u%|Pl~DEEHd?!F7GG!V z`E88$+q+cIejBU(#;cK@-^OXbEk;})uFx+Rqq17Ro}TUIa!$Mt7_Atlo)V0ktQo5WIY_J{}>$Jz}VuqCSSG%sgKIKlR zpGkpUMsL?H2yf#v#y3;)O1eXSB3zTz>|Y&Cj( zGBd8hGSjDTma4B> zUE4^#J|P)&>Dh0!7Ef{E*_6nIj#aWBx^$?6#&g8tT(RZ5ka2*UI7Tp!aoSYF8+P-6 zzxY8D4sP1YcX0Cn%lZjzsz}S#nkT3+*qh*Pv6snGndY9KK@CeGi`$Zo|q_}KidSjP!31D#-DF_4f6eotIXP=U)Hu$ zAHH(N|7B!!Xm99o#%G{iW(Kz$57|`h5AGM?i2@j652^7)KgjUwu^LYd(VpNlOv-pc z6q@^StJm5Nfwx~6rn7#IxOdPpTsH@gwt$EAzWEll=%Qr(_&ij4zh_9w<)7MC%XUaF z>!h|_l+2s_bR0!5h1=i=YS?{f!L=wCZ6)#liP%XonkX}tH)7@57g zukq?O3(N8VJB@eywJl3vKyOt(F_{Ri1Wr=tPQ-k@9k^6Yo0!C7dV!p)`kcTnhi|sz zqLO=c|IxH9+O(x;ewjY$xHrI4nF~-sg}y3vZ-8ldtcE_CyI=R?E~J+8xf%9W-S3|> zuE)g#y4(?HBj1;0?Mg@WCD^Q|2r6?Dtm8`2SCtbv<}Xp_1D#Q)tErQ)K)9Hbc0Lwl zv<919b#)m`(S_#+Iq2*`?X)QcK@KSxrUzVMkOOWhDsIn<#&%JVw|Sj4qskA`&Sv_D z=v$E7?i;MBChn{mQLfKAng{ozu7gN++v!ed5#$NGvu0!omT)~TTfq!7-b$K6M$dOQ zvNfZu(|bTRzD9>GUo#53VqTgW2fynvdI)*^lrgAW@2W?lPaX@wranP*EvJEHc>{I` zy34!1&_}nNW7Qi!eS&)Y46aaYT%REB=wlRD?2r1z;9#{vH>8h#2a!F@>%M;4XIaSP z9qpaXDlLA+!9Nm>S=p%7Zzy&N){#z_6{^7{IM_Y`^pemDw#+*WMI+IM?eyzRT_Brq z5Sv}~F;cuH%+yV|8dZ5sm}#0&rj7RUZ9uAL=xlB1(~Rrxy`0_aS|3oLk4NU{ivC2r zU48VFeT6O_2R>eZ&(-}s6(iZ}Z!hkwxj-*JT)6APGQXMFSLyz2VPu>vqwTidwXknG z!9zO19i>mIIhlWl@O&-QS1t5mS+KKZ%`heC1sv6xgRzo@CeQUIofnC{oHrmP6FKiR zDOkTs)2f z7=NgNzsBvSkv`hOVUb6~bh{EARvxFC+!eDz? zxLi%1jEfs|-0hwQ_j)ZmAiW2Yjn}O<*KxSMR%0;c01R$=8VuHpR&>PJcP;xZJ@`B60dqvxv&6O9+!aP9E0rUkfyX~~ zRT@@q&reqBen{4#+KQWUwI?I(;L(wZPaOqYZr5v9)mmRuz8U2WPyju-+406 z?Jc`P%5{`l9Co+^5#({1S~Vq^;dVlQ;sFkRV@E>SuKEy0d$Y2cHhBta^nBh-H}6Ko zD_+Ll4>|Qo+7NHo)I62Drfo>|W@)i*-z$vk_LS)M9A{knyfoEi#Zeeuk_ljgcB5`H z0(678j=o}Kdfw?H9JJCp*Nhd+2&+v)95vg$YTCi00J~~ld%qpMbUV&MMHPGmoYAxg zS9-nHEAQT5N_Sa%Uh0m!SiOt8K{gWhSZ$jki~VK* zXf4@G{V&&DYIjZ;K`q4`Igy3y`fVB}eoQ6x6@95p=ZpNng zv9ER7WSlF!t5aLyGMsny_`LwH9$$p5X77~1J!L?tB%-9DXW&I_0o}hEU#hYYg`Z%bmWEM+3ZpSjn#ratpgox8Ja) zaH~8WW1U-gxl`%>h92h@KHI7MG#8iJv4uA~m3%lRx9~!z@+zcr3(s{buSc=m!q+;L zv+Lp12wQluQ~5X!@wkN-Ih7p5+`?};XB)_R+hteo#H`~M zzQ*asN0oA`%t9-;g&%P$`K(=T;bBgt4H>uaaHsM{9AI$^Pjb5P?K<2l8=`64!t0#M zTr?rqWjm5+H*Dn={?Mu9Bk{R~PdJq?qJz1Ge{?GKBO>XKyPe8Akj^c<#i?uz^SFhF zI+Y3Rdbow}aViI+&D_HKol1U3j9V0s0DBsr+`=!T|0keuZs9}D8SkKN+|o~09!4v; zh4(s@L(tva>dp#O7Qrpt>fYp3^8OOHx^tb%M=+kag{L@YoB?les~4;M24-;!&xUD8 z<`zEFsT_;Z#4YUJ=v4B##@xa?oyy(t7`N~Sr;>MjxrMhom2vonTX>~Y$p<9r4K~~a zuW}2oaw;!|FS&(#IhDVo8Qj7>oXSlok6XB(Q#lIl<`%xvsa%GoH;ezm^PI|iFmSkq z*VKO5U*XICjn(+M*9=v6PF#Gx>ehXGo@#;z*;RiwJDF{xm`?4il)9bMx&-@WH%wQ_ zgELFj=}Q)*+d;MW;LLorb`T5w@1~h&$UZab7suRQm>Ef5y)wd@ornA_|Xzu zigi`ryHveFo8r~|7bn-$RZn%8lcpZNW@}8nzB-wz${(r-R)4uF`I>_tl`r04XRDWP zPR_*7;k(|Fyu=Qvs#}tG{a37Iotf~GW8JDw+_Yd)b=AL?OmM1iRmmMG_M@uT9m(O@ zfpE5Erv$>O`0s>s@&8P<{f=bZZmD)oJ}qJ2rjFl{oL(m-+?Z-=XjQU(`Y3$+(oRX$ z|C_1_<@>VL169de?Z4C+cfy=)YR8?)L3om4%7$d;Ccg#klscyP2(sDX5dNp&(K+OL zYRy+IVt5?;WgC(U?YGs}8*nNU{6_zy&B@;O^Q!sX$?n1LBQ~DDJi*P5t0i|Qufb#3LtByq z>gR`3FflP!ZQBZB48r4!qiWce8wj9OuuAOzv&YvUo>IPd1@9?^D&H)^&5##*xzlYW2==RK50tN~n{&!bR%)U!F~M+K{OFtKgxidVO(ej_Uq+IODcG;b^sUI9U*CFlW-0bK3kr%~Gu&!-MZL zm&X&;z28kXvQ_sJ*^SlLSG4c09=`9%a`o_@sTu0kJyWx)`>!sYZmX5iHZ#>z7w_n< z-ff+gp?~*Qjo-b!ZmZHdE6Q`$T3A480wxZ=TdFqvb#`j?wByO{DRz1FL!Ts9Ig_yz z;mg8TS$sbM!x(H?)&jhYL`SWWI)1gq7iIc^rSbPt485^s;c${a*Y^X{`IAis9)@ID zi}8}tC%?CwRPXsb`E8xp|GP_6+VXhgTR!}-fqL!RuYRbTC07***D z_Tl9~B{$Vki|XwPdI^WFjYrk>Ri#n&+53rv3g1zhQ1@IL&sN>fUL91kE-p;uj`PfD zhY$M#k2{jbt3O`oTd3CmcyTm+f+z1!`Gu znq2*8)E=n1E!Y=V*LTi}rcd?qV$reiD2Bf~_Kf36g0B`1jOWkvQd%)(mdEAf*&er3 zJG*ac)f{U+5D%Sb-!of%IeSN@`f4|uJ%3pp_158$h~CsZs*d&Q9L29B zrnfvR9=hBss7N(>r&Cc^fB5AVd{8vlw#fvW1*(a}+8yqmSFaczaUH+q$D1lnswg$va5-?HQB zD}-ph+BG_(P@Ni;Q3uDP>;*581J~Z*G3O9&hyUHFmDdRM`y>p4k$qQVP`)-AMvu=h z(POrg5DB?&H%h2i&KOch&Ag^PfZuuLp|08tPgDV49MN$m7=ZR-9=N+b)>CPo$MjE58;=VF z;gcJ4)1C$>&97mV;1))Q1CpFJO8sqWU@vr_XtXN$JvnazO5!TApCaRy7r?A-FG@U2 zh7N}h+4stEBhSYt*_ZPLIMiovlGBE%KYmXZvTel>l~FWCmHv?|912k@h`LiW7J$&# zID#~dozq;h>AHeB*Vyb{)R zMG_|?lQ|a2zAyB|g%10luA)v3KFMiQRpV0_H4t%dcBg2XI`34nj|&l9b~iYDe*xul+(v#e~j?^T$FQ&lKnBF7Y9y61id&I9)frdm>$Q{q?ukOr_Hg{Eq^E5 zxJZXR))|ytfqw|2urVLqOir7Ne+Vu%%IR8inps12*{4H*&<$ITVZ9*L#Z#OiyIja` z5v+Qi(>c>+EeLu5Bg3oULToIE29wi9;~zpxY<$(jVSK_Ct-}V8eJ^vuQfCZ4&mp56 zHiqmwbD)v4F{2pqy~#|>z|lhXdu57|H^e77Z7TjDu*X^1YJBQ3j=cGX(=K0I>K68c zgac;}Hh&Fy0?b-CaLE1|@~n|_;E??_giXxpxb`-;i>mLqiH62wRLjA5pqI#L3-C{U zFr!&qHMHHP6-Z*viA)-be+axpm4nH39G@%6(4lk4X$#eK+l^0vh<>?)BI+YlV`H|H z_ayc&3;~8W;X9y;F3ynqr}YQv}^GXK|8y$mi6#JG>$C?a_W<@ zQ{Ql2=Q!T8=mgxdbfhrnXr|ntx&`1!i0IpkDY_B=5T;?{TbdriCq*ofEh49_z&`{G z1}lea0s`4LpaGb28bF2tdjoEt3W(U?!4z>aA&kVvJLT`=^8zw-XdOB2M%5-V-%>V?|vyPit7YXHv zlrmwZrT*C)JXh_g;|9~aQwLAI#Fo=t9jxOPs`=;Cjpi=UVsAg)-E)@d-AKqCTmcdN z^nZMT#(x93_62n4FXM}qAvZo0BD#k?I`G&BW&@GIZ!1a@tz_LtvhqGc{_)a`R!>Ev$ryR^($#Q(kf#d{C7& zll=*(i#W^EA*ZcZ-6C#bIz%j@fTG*g^oSd;gowGzDY^sy5V-E-K+c@xv?}~VU=QW= z)aacZ^;8E@Y6V0rqAs?y4PJ6FK5{UWnf){}bXXiY?JgBdbIU3rV$+9HG!Op}redQi zYa;udnly6st2f<;swHWtna4c{5p4cq&4oLs5q?d8&pa}80*2v+qb3^-)=u99Kp2mW z*<$$AMX;v~W0@+AqBe+FlJ?%+I#ti0oW|Y(*y#}EK!-(>)3&H2vIY8p)uv0H$Wf0* z-J%LaSxO-_*5e;SOKdq!ym_y?6gn(Lcj>*VZn_(HA)*7jVN1IY{}9GvW48VHyqF9f zdX$`YKmH+1!$zG>_?%0I4!ukE%UMJ@bhhDh85uhCG&yZ6{voI>>24;CK&M)_U`ykk z6oDPi4EcuB9t0q4!Nx*Y;&TTXIz@*4ylhZTU;INL`}+w!(DJ>}1Lta;06uX!7)spp zs5Ms?=D7EQ5L#i&$;YiTd~zJKNESy

    %^bXEOo*&i-(h;krj@nqiw?woVb(nU)ZX}xw_ZSY~a~l~t-{JGP;h*stAw!=PlYK8X zr5yS+05)po9ZRk$l%I?Gb)V}9xDOLhP}FeRhAAjzC-lDh z0D6bYq1SI3^tL9TH$M)&$-l6?yP$V$7xdw+Vp5?+-{>L{Dn89^5NosZQ}%ADfk-I$gLB{9kx?9?kG$@AyWRM zDo$S-w;QN_r!OsZ&%j*t%Q{E!c)^zm=FN9s|60Lo1wSZwpWwrSKk``3d!jUR!e1hR z4^j0i;9FUIE){&H;PVBK7CcArRjS8LJL2wgA>y-q{i69sN}u^uHlH6B{J3B~7|z!@ zD)>9WzX;}YW1-Il3XocxnU9V23*u8_eda}EpZSYLpF0RXOYi`};{;zWcu^|$Nq#{$ zsUDq{#w&M-bUy3RPku@8alzjR{zFx++!1fqs7`IR62W{ZtY2IY)vM|7LichZnlIQD zyj*aV;5~v52!2KI$AZ5T{Flev8)BD&{fci_leGhLK#o4lnHYvJmmj>wfa*f`1Zhi@}vHxJ*?# zx$)dVLNreBRCRUNrG;(R3(>=Z4+?%&@YiXoLFLi{)iDJw{POl&qWvz!-p99*kGk@C zvEZ8ouNQoe;GOD~H9O+zp9s;nYH{+0xEn~XEw!HD27=24cNKiT;L(CF5vpCI7#beAogbixKGuRKjpl<4hCH%O$I*=Q0_M6ZS)UCBLQ!u{8&~0g1`Vb)+uWs5L ziMv+{(K5kG@PmT)3I3Ph!-78&{Ec7-=hA-9)brSDS3{NguhMw>=_0+qdU7q+?2Coy za>0uP-z4~U!S@M%MDPK@uL$OkseJRk@R$eqI1CgC4vrOlrMiOi1Q)Btskw3YOd;Yc zSp94l3BFSBHG*#ze6QeLf}a-rvfyJLEBCq5;Ly)S!cT(n)SViGas=~Rq`sjY1fL~% zfU4--G_JPQ$&KbN7xG&KZ&D{(4DW)MN;WDU9?uP8_4P~565K>he!jG@vbPZNJ>kCU zc)@(mpfA5l@U<%a_8o;ow+qpef?pDROmHZ>wzx)uO9h{WjK_=Zc@ z?lXAbzUfgU-!GCMQFnHq5zl>1h~5|cmHGk6l_@xv@SBn$xRKye!KVxEsa`p2X}sA~ zAzCi@7QvfTBRsHW=rcm}y5J85^CwHbMOOVi_y(21KrSWaAE4ZOxKJw7l=_t6j;30x96g*RKQt%2sHqS5gc9C$u z;Jt#M6?|CmalzjTzA0W?{(8Z8lW|O`k0|d$gs*F3;E#rUgPtIlc=Cfn{xaEHb*x z7{Fy+e$kmB1mp(E6EdO5#sfd@ds! zA9W_Sh8TZMd& zkU!dp^U1X4S&?u^WOz%+kC9C)zY%QXBCRja6I>>^qu?Gsv;9N;2>1%Ys|2qTyiM>E zWYd6W$m#41+;IbE8$K*_J|LU!I0>%VKm5Q1lOf!sma_!s39cZUio23=62Z_NoNf3V zp)-tZDjr=cR|~RpE8OdA1=g)XalMdl5%R46L`Yl%^ z+(b65-y(RQ;A4V+7o1*Do42XpmSofV4rH8dF?0sI*(TCUC=DPRR}U5P@j^aH$Y%=q z6+*sL@JgX`ORe0sHi(3~YZI*9f}avP&j|UeLjIB0W)8J4cnf^y;s3RU% z3LYzXmf!_s;u?r7}ZE_Ch}yjSo6vN7>FA%8>2 zkCILKUkm0J;(Z&k$T%-$h=K8dV6TUo3Z+(LQ(1+OpCR~M!J`FVOg4F^l1*i<;LSq+ zp=Mkma1zR}6A9UdpAbsVlTD#-3w~edd?Dl~h5T0`|4Yd0G&g0k{ZU3tH^uz~$QufI z3nA}9HiixqJW23$!Ak_+CU_fotY2|86L5aZ@HjZz@N<+Km$s!v+#f#PFLzfn~?L~Tbk={$l2MGC4As;W~lZ1SxkY6F> zi-i0dPwqKkwMbYiGHev`d&s6yj|+ZH@F#+Q6&ypO{k&ZT4=v$5GlgC*60Q}zg>1aM zos6?thTY(7!%qpFLu70WuL}7wA^*^qv;8Oi2>4f_^p}v=DXlHEzTgIAV_Y*KFBS6k zLf%=(dx2|?NzWDuLq&#BWYfx-f|m(iCwQCSw*-GDIHhGxnXc7<5x)gwoKiECfU^y^ z6FO&*;TeXWLOw|F1%jst{TV`jm6m(s&vHe=4I;xTA-`S7?-KF{gnYY@KPKc)lTBle z2>wb}Y!Xh1gv?g884Ae8L#@d;-)E=*XB+M+bo!8uhx!Zoa3R0M@FW&AO(nIq4TkjeX zj%$4{68@}B&|l&44dRc^d~PRrDA^b{p4`N1z(jDi;Tb~bDza&StL5}R!c9VHolv?{ z$nO{OhlG5ekUuHpF9`W7LjJzsFN%cHNs;g;*|eaZI?!ot-0fOXD;gkprr;X{ZxFmo z@XLZfAsYvNOU{Qg5Pk$_=WDc1c{-k_LT#aBJeUyNh-?Zf7V_3Y-ciUag}kqjpG!6s zUnKb2wy57vxI-jtBb$n=$v6vUcpRK<_&K5T2H7;=sE~gw_*=n$`pov%Ijy#`Y{3PB zTa$5e$xs2#Hr!R{^dTD~`V09e!Iui23$B@|iDyZFF4T-N~Q}6$v7EhXaUYP+*asRl1&576!LS0e2|cj*X)fyYpPJ1 zDU=on`63~|QOH*d`5i*Ok!%dzBluOpAGwT}R(?&!c`L)W;B3Rc3!Omw+E#|iCU0DD zGr{FTzdhNM+0U?U|8$XXCD|0p-w4_`Wn@?i&NjSK=u`=QK=31E(;bfq`M-qx&Gy(+ z`AR25!uNuI5t*$HwS@-B#-Lom1%f*WK3nkg8bLGf`1U4emV>? zo@*w!Qtf#3qc z%>}m++*WXB!QBM+7JRnPZ2urX0v;xKoZt%uPZ2y_@La)H30@+2x!{%Hn)Ux?k#M`< z4TA3$e4pU$f_DpkT=3I^pRZ-tdZ{*Iy(#!@!S4$`F8E8qCk6j3_&34)>bu|F0nOg{ zv!Ws)LvTWHL%~IYiv^bpZYQ{_;O>I^x+2nF@DRZx1dkUyQSdauGX-BMc%k5>hIRX| z6$z^Z-y--9!FLJ1Pw<0+cMGl-{IuX_I&u9sE8vSF;Z?y$1-~o!W5J&b{#Njhg8vZw zcMYTcshw*FMMQ9x;F#dXf(rzf3T`8~gW%4B&m>Pat?w-o&J#RH@F>CK1Yaz8is0FT z=XO?Yn&zIN?(7+DSv}``cSMf*dG(4!B_CJsU&#GP@aKZR7R<-l`}&r8=*K7H{nFEG zMLB{Kg89^YKU-_T?F4sJmCvp#RDH{;qC*D?x&Gd04v#_bvsWSKn@;^QrwG>HCpG$4 z3c0J+lvTx5&zn~ynynM^D#7;(en6f2>B+eLh-&)tlZEL=MasKsGDNw2wwZ6hDZ%M# z=g&{Z)Ads&jUD-FeR)-(eTK^X<;l3}|J=H$I$2&7O~0^iZ4no%tDjp}n0}2AU9aAF zZe85IN8PjehC=o7#qOkz^*u-YLoLIp^=dgHSigVS=;W&d&##N;wiL;H#J*od4>hZB zNf-70-8V$>2&EI3xLwk35Xmdm*caAyaUT?-?Sl1tEKEgD3i-2wUl6RnZff*D6!NbG zeNyP5BwM))%P*MGwa9)6|_OpN{AD5h;TN4^wMqZzxP(EJW9+HIv=q zOJkl-?`DeO2LwMXc)#Fh1-~TtHNhtYf2LYb!7mtp5TZW>|1Fpg^Y=~35}YfzkzhU! z(AO^(TqgK5k5%;)w^8~~kuXx7n1Y}2PZgpWg69h6Q!o8`77M;c@Cw1J1uMaK2;S^5 zj-(Op6$uXs-YIyW;3w3hQ}O%jFQ>ZEiVubSTfsjHJ|);zn_gZQck5@>wkcn5k>GZM zI|@Eaa38_L1&d*i=Iw6sMM97b++!+`U zeP_5)_fH|$55_ean+8jaQ53Z;0D-)YvBJ z@!X|C?OMS~oq(1KT(u$5jBkqY&3H~Q-x%S`kEzKs-Qte9-k|uEDTe|l}g<$Q{S z&k0qTi(Olx`X+5Re_Z$bO#CRGFI?~yhNzNR@M2Xio?JM7^J9thYenLXYR%@y;&?da zoeN-c-)$43>it=6LjAS*v8eluP<&JH+k!t9{JG%&2>wHG5R0;JSy*tc;6@&+(;k}8 zNbQU6j^_3iseCzvU&3g0V76P#mn$*MXNuuPf|m(iDfni=>jmE_nD2V<%iJyaF~ROr zBJ!Nz7X|C@N*m+&s$aj*&jo)i_$R@?3jSNL6W8V71{6Y?7tvf#Fy9d2-;XJXtGXAo zilw&}vNO~N?@o=Y5pyuh&KGjN+QGl`agpFDf~O0gQc5_*%hh1h4hjJAu7x3D#dmH*&tC!q!B>-;=!t197OcOw-b6pe z49~n)ciy`qp1WD3Zx#HIN^h|?p8Jdty(suqHUCO?aAh4VFn&#Gg0lqcFS#3Q8Vh-W zI(4NR&uuM4?FDyIt>+_|FTnL{=r4GH8jECmw3@a2iFmUaB4wW71%j8TJJF)jl|pp0 z;Pry<)U3wczoN0bkDTv0^9jLxL4_|rEciXa9|`6QEPQ>wUeo741ph5Kh+EpwDYF>D zUPN<-;2gnun$`A)hTwn8k!Zw3D@_>^G2j>6Z^6`U`)NHAYl z;p?9+_>6|A-%mJ8B%CAoe8Iy7j~2|gQ}{P&rVGA8@O;61dxh3#`&ao9@NI%`7t9x0 z_!aCBTrK!xG%&ZEei!mng7vQsj7|pDX}_F=;D&;W z1Q*wGH>@7iIXjnfeGmPw*gh{q@VcxK{~LQZQd-;osX?BbcwW@a6i42>^_agFw;cD=!hMxt$W%yceSn)UDm4<%--)#6d zFdsF-(=LVw4b!_j4dcVAc1;9jSx*|y2R~!D9r%#pZs6Ap)1^lY4*>I~7AqSMK4Eww z_zT06!QU933I4&bdpRO}+zC&87$SygX@=n(aLh0Uw$;!ucU}dCn}drDcL29B+#SqY zUM#;CxTE1d;B)v^xh%5_l@P2TAay|fIkYV=m2*dQsIKv$66AiQPrx-2*&jh zO#QVja~j`on1gz|VeUsBHSDrb-qmHHY$fmN zl81udFiiKpZFoHR1H;q6pBTOZ{FPx2>hBD5FrSji zo5M7YZ&&2aVRFK*{-dyEla%W9o7{Ejs$$cO@#?Z3i|VNIc9&+Vt=n-+Xk@!f@yyFZ z%YRkxTspj~${3nk6pkMD9!s=t4w2BQvWJ-G``G?*vBQN7VDxPDZ2XVy_~5AEHAL^^^xPdSy*?6Qfm# zUa9N-fzg~}eo;LhMYJcPUfwl~URo19fvDPc-^7r;PE|aHq#a1|yt?=?_vvu|cm0h0 z9(Vhs&qQ=QYr)o24SedEJaw{b8Qv+?<)V!A*O92rM`CZa=Fu5>D)fYl1Eu#MNbxfD zRVTi0o2N!-`G>}2B%iG+et^e37N!XS+fhB+{*aoSlkE8l8skR^T6~~qZ+EiQ z>Zjd|^zNUVUPiWYDsxNEyx=07PVDkj#t*+NBYh!M^uUM8cxC^*H!sK&g3p!x-k2Pf z-Y--yz3&%zQZ4O<%7v=OFKzRJJQy9ODymS?qWx}0c+QvD3F)S--|sdF&cPl#;Z-s- zZ)!$*5l+Rli74S>b?VLjdBGJ>`NLBwf2)5+`ZTC4GL>AaGM}EG7rYKTlq=MxYcq3H zucznNOF#KxtsxuG&!?R*zT ztZq0p6s&@tF=9tUH2E#)O=B_G=BV^eiM-&KP&w!o)xA?9BitRUqHeO9{0wT^mW6|L zFL~oLsA>QAwWIP%wYdGNyx`AJ32BwgN9y2u63XU&h~Y0a>&3I;Dr57Wfa;nY7H!?} z2eTX?aRIgfHgv4@&i`Z_k&U-M=rS9T63{6%;q}cpj8Z*5v$N|TGI{*8(A_ws*GZMnB1szGe~GQ%{7Q>%!RGhH z(f=uePq;s+4m`LqyU`o}Q^fwIwsjKIm_@8r_Ug2};K@Cf^^tnxqvnO-m!GsOu6pa$ zfqFZ!92~;w3sbOqyx?ZlX?I%N4(-~uS8vQ%ln8V<{j|0!b6i>rr{Pxh;nMP$$~oj_ zsCI|kiK_buyGX5L^!o<&x~lKv9a7cDhumsa@siuyPE}XF%e%d;!n5j8*^2eJEyE@;)@KSQGbX?Je(oUGbMmhqN%;Hki-T&lHYwxzE^FktvU=_(8WDrRp3lL-zug} z1rxHPPDzi3DQyRaO4gKYD%n|bpyZ8c(U}9Ykm@&KAa;=hb09dlF=N-p#hVZ0EY{6O zK_gOj;yS^B3{NoVNN{tn)gtGhLW{ECYA=06${_bhFxogeHveG$t^-9i3717iq|81N zgw~Sby_O8jDY&HYl=F?#D*Y7)YJTBan};^oJiKSgiIN`*CS(*$$SjzUb>_f^qCRbD zvCHaAUJvY94lop^&4QNvYbGjw{3icf-_y5U^$^W zJ2693ct;_nek&-Xe1>Czl%~Ci{K`#AtKr1UsnvQi@lr?wO|K`eLs5Z(TZz-45GZ_r z7!3l8?;`$$9Yvr7duUkgY{u#m3gwW zgqk8ZlmE6KK{{M_FPxJZa00=r;5>L^J}Ss+4l}dU@Xt!&qaTC$dElHG*uUlnn?3+e zJp=9!77(q}400hkka`7HqF~Vua47XdG$q*VC{)@-Qx9h%(wvcu)C*8humugwNu3H$ z2aCxG_yAn8AKWl?Ra6aFbamXhFRV6oS{!pn^GG0e0!G@gFdXN^veC|zSRF2wvEwW~ z#z#u}lKbz=2VM<_N8JL_=lXZSG^3t=pz#co0|(O4x+OOKrodEMCAD6?MdEbg9T zH=^~KvENWmR%|Ou$d2)w`Z=+57uDB~J&S}`jE~8W$9Nc-i1C}pxv>NaY7l!DmF2~< zP+Y^<2za1TtOAW|9OGl)o5Ws+XYylrBeiL41j;Fh-Ha*=V-LfuqF5`G-z;_`{x^?x z!H8=SyA7ok$8LrDOJdih~@xqe^{+Lrq7 z)E01K?0K*iy9E1sJJtjSI59L0{(2f!1Y!Z?3&#G9CZr-a$8KZ}B6Y$JhegWoC@wTm z<8hP_O76$ZAu%{6Z&GX}^ZVL|?6f$YT1MDps++e)bi}9k3#Cv^aFOeG(cCVBj#jKXTV~&p}^? zM%b*Ut~PL#S5#yn^~cyH(26|A;e4@fT)ouLWP39!*4k4{#hkUFsitB+D>gLEJ^}j! zi9hf^beWC>t;jBn*3fi&BGlvKozSfMHr^_3%9>qMmg?4ZablGA#ueHdsd>7Xxw@Ef zP9D!iLi2R&0yu_O6+&0q9A^zs>H>QV3axvH(uLaCy6b3CQdfp%svTW1qh4fhF11G> z7ZwFJahY8o8NG27y3W28k=S(@wswqfJ8)urlxs?C1iB#*YspD(MSh_FR%zFme7D($ zneRRfH#=5QmsfOVxbM5XA_~#c0I%sTiJ_u+b5xK zB@WQaE!s6XiQ6znL-*)N%!&-8Gw-!OM0NENq5XD$X4V7hfF4j*f?rh(9n|_x;wd)q z8G95;$9O2<1*Oolb{;Yr%RjWQL?m`AinU|BzwE^B#l%k01Lh0+J|xyX%JKT89xn|q zn{$N~`bwAXjh(MGTal}2=D&4mk;mB!zxplw)BYZ%B>JEVH}sc%K5VfP6;wH;^E!!@ z?ApI|<2hhO&P&`)#5QeUe? zwTkg)Ix?gE#-Vj}QE+Ham=mh!v_huzL@3kYQFGmQX+oARscth`nyszyTAa{X>psqE z^BlI#iu_4GH`4D^uU8&w>fmV4N({!*6)G?`=&9ot>byDLtS{1)C9KF0+R)6|j!cn< z(6ga3=QnUxI{G7IkO9tAM52isY2iR;79tsm?=h1@gPeI0-T%v& zX|QuOk`gd-JPM2k=)-8>ByvRqd>U>vKtDtSG&mY~0{^pDYzoWv`fHDjIqXlAiDqsKWeW2N3;zCb6nN<4>RLgO9!qm30Qrg0OTRS-tb zVF^?8-l<-l&@`tI%TmUL6DMG8bw;uu5=U6!be$IqO9nb9G{gA^dDH8JW;+9+Uv~zJ zzg*|7+sS2#b99MTgtx^*S2$((fciX#_uD=7D?Rmm_S}4<{S}%Wy2=>~rD%XnkK9bj zGDqKOe+c4iHX)mL=dH*IX1&IF6p=<0A7=Vb^nbR-cc>K&(86ed6=Uai9p03VHoeCo zalK|M@i14y8=Mdl0?_2`{%C-eMgC&#H#)rcp7JC9g_|^kQe$E?&;Xe79!Fo>M^I5P zCvsv1M5*o&xGnOrKFUkog072vqIZ?4GhuJ!(^BY!Qmfg3&t9T|si&d1$mjdP8L0s* z3Xw0!Syl>vsTBFL3o-SEkPeqebCH#I?}A6ZDl zRIU$^pU90<=h34-lk-#ik$)i`JOxdB9$ZB6AX%E=vpAEUrAEi%Zoz)QZF;jHE~%y=1qwA}`V%A-fTZ zs~3vYwRf@Hg{-Td{T1A%uV7=q*)%ecxPWU&rp}z2coic!lBJ8SV@0BDOSa7)R@N(z zxJ~SG48cSRy^wE;8p23Zee51c@XlkTK=0NxQ~|M$?2>W}`so-Kcj_MT~z>qR3y?L2f#;*vTL_R?%6c<(pT zTSo$kRCbAXAQ(asA2RJI?eA-U4Q}!~a%M!%v9D(_FcR(WuOr6Fb9E$;(4+4>-ONzp zVitP7c2mSNa)356O)piEfjSaJb*(vOc;O~8$R^jzhzzxlv8si%c$j8m{%{>}1D^dO zbS&iAKT_Ar0#~s>eq$pt%D#gIh9Z~R4dKqjV;s0s^+ z_Wm6E-^d)#up@Kri!e_UcX1reLv9}bB>qjEEA4XB6G(Jn|ID|!oCXv8zE$KZoBO!5 zgdUa)^stO3mLX&0YF%YUqMY?7btEg%AG^-TBD*Wxos;;1YKyfo^%G;cL@d=7#1g$Z zD6Vt$@Xt@AaUk8GOBj$?MC)$UZ5xspLcN>py|8gaq6v*#rN{D>i6qDHYF+lCL^sZv zo9)X{#j?al996gIJfG%q*BiN2s|D;lejOsRR>y*N-YR}eCZco)rrLQo&=Ko&VjX;e zl4>vfE5u=gV^@iv8b>2_I(7ij%P zn};ibL?4`5L^ip)>ULIS1$%n4y$YG?t&7}kzl;7&d`DMq(QGCD;8?!LK8}PyqL_p1 zUTtY8(UxlW>2sWDVmzI9zh3Mz^r=^5tFFEX^&#Z}9cixjzmW%Rz5gxN``?In<)Add zmu^KK(t52DT{!|C){!>)usX6`A6AzqaO=v7?9e7uB%WlRojTIiTYh%w$Z3g5v}d>1 z%mkl88rh>=<4t!r@`z5FnRu0r*sJ?&PNFWSY_%@oR!jrBIU3+v9=V$R{HXmh{S=72 zZpW}bcrANF8)Hb#5oIix$4) zt-aU*()eRGE@N8t;*t04JDFSWf!^1{*h-|((hqbbl*pp`hkEX0cy@fG?Z8oWNA~Y= zo6B##tjL#kF?Mz69@HQ4P9BWmUweipZlpv1ts^P=5GQg{mmBcrFw(|IP zp~!D~4t5XZ&Ekam!(IZlo`F2Q-~UsWwk()8kK^($?bz#rdD=Or^bU1(Fz*wNk$>!_ zX#B0gyaV*D`vEqK0;!Ch)1zj#Bnwwu{@M_KKeHjaJZw}5z6B+RwSrn zdqQ~+a_px%?5TaByj`5Lb)18Ujfmv^LSsVCVZ^S?%zG6rjCfZwHfH9{pi3hTdfnQb znYW2+R<`SW4Am`}d8sU>zD{hHm3J)%NZhH5>N{rTan~5hbGT>ho|X44i)rZmh5rbe$mT93Qm&HEVj^JCb$b?qx?9RbeitPT`R<4P3wJy&oNYKzmBKj@)a6EBXt~C zL^yI-xv$SL>A+qSk1Rl1q_NWuYWckWVvpv@3`09?b`@hyc}>P1td+Z}X z-dQSWj7Hhxs5y(t(Euwg{1uM3mt&0Ud4r<%L!n3)wOo$|dr-4CSkQ8P_P-i>ML$9v zah|E!Lz?SyueVvSJ*ow4aB=Ak$0hct)Y%v)|1>}?6|CiXT?@Jhwea}EtL1r9OUaCx zRN<+cJ-CQRJN64U&*AJLUWG5%JejkHmg)*$(iK{TozV#UxGtHO%IvD2;*~gb)H=tt z&Q4U=Tz`xGV|^7OWzF%cn%{*{V1J^|_EXmUaaBvYae5QWS{zqDe2Jecwp;``={*Gx+LniPKFb}35x>c2|6eSy`gKT=j9 z#VS0C(Q0o))Uvv`_-9w~8ldMSZyC1-73r?nrn|x(+)R6EoA%OS)T_Bs2Z!BBzCuHvr;n{t`8 z&tY}9VRI|=2t0Q`6r45VTC~FF-MUCq7=*?4Si3EXj9@a_H~38$q>J3bB6Sfru!w3D z*;Y5`2G(E?E=zK>-k_T^#B0t9Hs=$hvN?F_&P^<_0s5pxS0rpV?U}9HbGhH1)AnK& zv$sM4r%Rx!6R5aMcf(fZw+Hb%VR~fI8}!3yyPVEA6Fq(s3%#9>DlPq*ZM*6P%#~(b zZC!|YY|;t!x6_8_>qCK2hCn{XRSbJrk?ynty<4$| zdlR+Po2Y|Y!a9osjK3tLZEVwMXC6jPbKV_gr>F+EopkG`wS=wO`_&Cp{z_<_~no$+JT52EUrEh1=n3f&6zU)J93`AC1yk->Ki4?2FWys+7(;O5Z z4e)YqG{Eb@<)_iGcYHHjGgh^y#>{tU<_EM(oB0k??7=NcpvL!kum-*{H5%YWUAM!t z97HFPXzkSn@%L$Edbpk3Pr;!7kFfWEkE&SzxX;<_CfiaVVRuu26j}%+0i-4v5D;n7 zn^eVuNEHDE+1-Fx5Ctp)2m*GcNK-^CU;*{o@anaJg4cqI9Xsm#`^}k?Joo>;pU->p zIoa<#^UTaM<;*#Ic1l}5SKFulMaM9wBu+7jziUh48$QA|#x2;%{C8}9W8kbfmm$BW z&Fq+p|6%d|a00$N;akQFAD@q|95l&}~yG!3#ZB**Ivh9nEtTJacs^UBx_5 z*(zHEg&D}-%KxKam2H5}n}~a-@zKpyH;nNqbJfY`;aV-R@dU+Pw*|f1Mm;vA+2^n3Wl?>x|#R!HhS<0c7;{84@#jz44kJ@7+1?Y zmMV2s{x|X5cp3Z1C=}9QE-wx3Z}(tKtNJ1)T8y|5tyPu_-4f^)YTXO8?l`->)v6pG z`d;9_5$Sb>x4!?|R;LT`JYkoh@!&ZGr@fwA;xyHLW{Kx2JC05o?WF1JXkt)10To^^ z&h=m7ak@F@`fuvd{n9YL<=5B$1IA*fvgg9SV)*d#f6?(_f93YN^zIIC_QjuRZ|xK1 z^}zx|YqQEOheF#zJg_uY>EFg1$9bn=nOq5Z=TFfBysvuNAcE9?^wEXiCOUJFw)Ztp zAIhPJL(3~F`P9;hZ+4uT>-t0vVlMYw2F0+K&q&?Yp6+HcSr&N}p%z656NvY)Sb3Famrc}Af zg>ozBA!j`O&AgQyj>Xg8(_48rYKo`-15f28EfDb~IQ@1?<#SNr>5rvUa(oR>f0vZX zJJ5;WvA4~4@z$Qg8*6O4o?Ve`;~B6O92On0wS$$C(KXb~r|v%aWNw%kIxpJ;qsrCf zbq(^>(OZUw?U;J>_VM}Z@@doRsYHVdGS!*G1M!p%t&XbV@W80rw&9{|RroF@Q>{r&7s>F}+ooY;J!_eMSKgIXks&K?ZL6tRXfln>{YEndf`_jme+V$0> z`gcCm*vnPm@ast+v9YUqv-t%PwRqv;kUG$PZcrUNewkkl?i%p=Z-$O-4Zm5P-K}4) z>b^5GH9mrEr!P*g^^-kfBPoH?wnp&dah#3^Kp!YtYaC9G)nOw)C*!oOvHVzM#QaR) zgqR;oaZ;O~3Ma(;Sg&yiM@9`U?qtDQqH z$ccOLlwt?G(yVU~y``h{nJ60|EyX{C+bM%Ts(P-8t+N0Qs*A6X{&Nl61xL)XU?5` z#l#s`O;`5UH4XNDn3DJ?#W!o>oGWLk7k4fmp#I*K$WuLcCrbAA@+YDx>ejax$JC&0 zvF3YgLWxTIw#3I?HSFufIqJ3l*7Q>0^u$%cDHmUP(VU4_T{U%zn*3=^%e_yeCmP#o z<-XjQI<_-bs6Ohqw8`Gm%*2l#wcLAO%f0#a6Dw_1Ie2MMHT<%sgZeN#F)Vn_`GW>c zJf~-mbNZ`_oJ31iZ#$M_Oxc_~Yww|)M2@W{9lYMBHav=by&E1_e74GuBpy^BJ)WJV zZq3TdQfGg6QI;CKV|$J&Z#2Mr=hF@R>f~!%vhI9+OIYo=HyKusUVa}2p5*ijtChZR zSS2Pl)f7`JcWjTT1JS~mdbK1YtiBu6JFMQ!9UWHHY0zubc~e-O|Gf&Uw!88$c+Ng2 zrkcePSEx;=pNXjnxrs{LBG8HBd>3a2RsPFGC3|1VO+1AHc(y@Ujo!OCZ0D*rQ!a0- zHg#FZF8au}K#4k#F+8l|1zBPB^Ms`_XjGJDMD27{ulcs9T~EC+>zQaeo;EDrjW^(o zsy8<7YwP1Pf=6AQKe|jE*d7S0=kgOz?7gdi<$cam3#01$-N`gH>8XYJYJNeYiJH+c z;aAT#Ozc;0KA!aMUEe5yF>gbkU6`X9e|BA(y5iY|F*UzYqG<2N#)&*zW$l_aIG{76 z^I{(@j|SQTdBjx_o#!|%%cl-jz|t{l>d`HY19+~{M>myR-98$)-Z*=!&2Xx$V4L#5 z!$vkwt-7s!r@&Lj`M5fATl;9{8^&3HPur?e-FjzDRNEiK@><*XOv_TQ^WUKFtI(GG zZ4Rh!pXryS@(MZ^+n=Z*%lkA|;U;dlXtv#aT7`E9el zRc1|8t9Il^14Fg5wY5sweY-?CA`QN6tzAZ&y>NZ2y>(CxJb8OGz}~yQb(Zyws`piP zW0iH*Xn%k`czvsj)j|!KxwNr;j+%Z>hsLT^O|-DyI^EkkPiyt9Zr0hKe|sIP67xIXnFT=TeS2YtP`VU}|d*Y*UKz82HZ z?J<1#u!+NP@ejo{`)9MnMYnZ3R;p$;Phf7C-5G}BK<{c{HM=&?W!V!+dJR8;P)5_1G=396UL>ha1?hray_*t5)7O!>0nbvEZ$?Hu=;EFzBE<60YS(AbbHu7SKa;ZR#CNL)gxi` za`G93Y0^2Y&ikx9oX-2HIqWWK#;yyac0=`yKRv28|28OF<@|YFJ+*D$fHZaB^zA-- zkZQE8MbxfRi|?Be{l6*i8!$PXYjVOT{G4V^#I!i4nR=u&(M_G$yFR8KZiRdYS|&R2 zS1K!~g`-wYMsU8T87z1P89FRYKF_#1yoXcH=-(D{z5#M|x{*!%ZH#^xpX5+ie2d}H z2`2-r#3vuB$i48%q9G5*C*9ACA{?QjP~` z@RT|akFgX_i5NIoCvR)yye7$^N&t>?C`ZBr@Y%=c6hcl8nM%bYhLuyQ?rxQc#?hg4 zffG;iR*vC_V16~vDRl~&975DQbOp6^m<62!W<_L@@sH&dHQWxLG?Q{NdrgcR)JaPYKk<&@!{+MMxXPIWa1ht5$ehcobz1Ex6*$ml)#;*$kL z?vGD=#nxP{4nC2e6YmKp4r)<@Wlb$ID=YE9|8S5)z0ptd(4`Ee>EN@~&Mj9(7qwf zv#3j`Q;vT)$RS=5IJ6GCcpU7ma!@MFdvC)_@i{^8G>7B*d%z;$aWC0K#9o9~h}_TY0n89Jy`&F{_D47d<8)bH zsgSd@^p%=P4L%7#2U(=i%qjI*ie&dHq#t!w;2R+?-B_T+>YSpLoH{0l zSSL8H#py@1rYIORnsJf~=5mRg5YZz7!cj^&RO$*}qZ+ za;|Qo-f6Qgrd~eXuZjBo5j-QToz)6o<3BhzN9{Nr^Qp78Kz82gOE5#VE%bbMOlYEB zB#jx?wTZIJL4oM}kh{!Gq_cgv zODPRg-`x2`H2rcRny-dz-Cq)C7F;d9oO5}TU^a1A{mS> zB^rX8K%v^)abnc&ry6!x7tI|jeC`*#Qw@Z7{2L+qU2vMGF2XFqQNhgxw-el5a6iE# z1>@B(4R#v-4B>H&;AMh2F4)Z>-&MKHu~aU6b=>^y6;{Eq9Q zO&=4Y=LDY+{EONN)$}aBmujl()@r1tSEIl-E!`7tI#9^R2%aH$p*pq{`mK8G3ETIo zBRji9Cm#~t#|3{Q_)o#X)Vkyg1#`ZJYgT8$gVhf;^`rJYb)@H>Xhn_ixk2zPg6|N# zU7a}GEULnt*M-$@hns~}jMQq`o^br%LhYpBp9Oo;>Ws<~+*EKo!DkER=wmlSmk7SX zVKx8JjC%GGwV^ZWgk$(!-90LOM@BULKSK0hb>#G-D5eZIU$%+zT6Nwc;<8YEWwinuM*7F=Un~w z)sZ<5MB`ll%@uL3kIPL3w-bD}-~od5@90gP#=KU@InBV0bGP6F4mZ*vUK1W%G0hEd zQdRBQ9~}`1)rq*qnd{v}aBsmw1z#$dOOUx?6KVsZuG%g{Ck6j3I1`V5Zm@j8&D73I z#zo`3glMqfae^-s%-Kk8bP2&L1aA_&RqzvnUvSv@8vUm5I4bz0;M0OFd<}Jt;GAQZ zn+xVTRIa>-;6Z{f;Pfq5iEB)`%yEn^FBh!$RWa@4ej(p2_$9%dnB~UviQw;Co`M#{ zQCF@K-k#TTL~x1V3c*!^&l5aS@I|U<&W+KE#X@wGU?uoI!8_HE&NHL&e+kjYf=>&! z@eJ+eAVYAm;5LH03GOR+gy0Jub{dHOaoLnR7c6oUTPawthG}$m3Hh^vUlq)?h1__4 z7VN=yBv+o9b#9%bq3~!gxLPoOopb|_6@01s>*Zz9ilh+TBKR)BT*b$Y;xV=J!@_8l z-f_ib?WpkP8a%G*FM?C*)ycC|kE4arre#9ZMew%3ZXrJ? z_&6a) z@2)Spgag9kHNjs9J|h^v5!EIZ72Ha27r}i54|ka@eyZyL>upL*(Jc}3m4fxQBW^Vb z`2oSN3I0OxX~8zWgvQ`%MoQB5ZU7_=%V7}pXbIcLsF6Rp_CgX{PN3$rd|7_!^5K5I~V|5Q9 zA0l`%*@UeTtT)dva?U(;b>0-rDYT9p`9DpExt#ta;||T^AF#W|iQeJD=)~~K%+==_ z050ndD~!<{g}evZ$or5@{1eE0-_AqtMqv_|Ll4}ec+3N58(vPiTbE>`zd`VWLT9Ux zKQ83^$tKSDyF%#%8T~kq&%oJ+zZW`xkc|=l2zfexq&NDdWMf==GI~uOoxs_KdpbJK z^*4YH6RF-?!UUe?DCxjg37u<%e5sJ%NHz)FFLbt$(ev?m6r64N$y}uGT6$P0eIf#X zNk&J*;~NGx{F~58!3#<^1KEOOWRsa@f;+g({P%Pn;K70?kWFF>1g{aSH-j)bFN?7M zCgalN@h&*q@Fzm&6gci${e$rMlWeMkKaIFKNEaL>8=aOy-kEF?8!C9F(7Bq7s|!cm zx)zRX$6?(dlva~X0!qm5BOCqwLVl2p2Fc?^aJJz$h0Za-dbfwBPW!V?)59e8yHHBO zt6f*_C!4zD!mX}6D&)-smkXV<$i|?Ng69txj#Ywp34V%f5`LbH>fv!1%*Mv!Eur&? zTJhvf(YW3x!Q{!)ur7)W!3_ns7F`*g+B4h7pGV;h{ylTDU=4i#0!h3<>MS_(nO|Vs1S5jWVVZm8~V}c6=H*whM*;@#Y za&>UUvZ!j(?~#@2%-;+9s`B#_*D8Bw=WP3!D(Y1oRpTnUg_ZZkl6tMo9gl0VyLZ2O zf*S~Kta_A;jM^>LhKn0S)uLcUSlxWOD%_MmqPt-S3mzr-0@d*Q0oWFGV~?;sUmXip zL@SmE@9PC~_Jn)STqk(5x^_Zww1P7s+`HL+!OsakB=|K|b*KcZIBjnhj(;KK-wFOn z@E?Nz7Oa2%Fn3W-Om}U_6WmBJ*C}#!S~{%GZ{N*V!5IJUwTP>8mudarkirXLidS5#4EW%N8w7jSPH z`d1Ni134+=rv(2^HvP4S@8b;zRPwU&XcgxIxFY@ghVgDGA zm%xo~ym}4Z>bJnN;q+NTK36@Rg~2v2)h`aGUoYg#RqH=1qv=YB?p8k_iVDs_aASQ; z@Y8}13Vuo1BRfa!x7CmdBctgY^6z%mU#rbGbdTo#DnuN@?slU=_1fwI(T@6u3DdK3 zM7!% z3f=kEM!$WTTJ=CAs*YbfB&Oz$Oq9oOX6okQ`!%xZ9y#5@ZHKS%O}YN*51&lL>F6+YdV8st&cA(Ow`G!#u z)-c1Zz+4QWzG;+K80Po#Ifj|h1%~-xve+<vDoE}H&NAE&95GBI3Ji}27aN`kZejRBFn>jiGomZtIGY~kdhTtQR`)lI zpR}wYhS}Ce8Ey<7Z@4-5GQ(^Ka}2XYuQtqfz~$_iR&Ra}y3ROQq+EfH9>c+_3||c9 zuauNe2R}qMoy~T`G<1(){DNXVX&7&@tY-|Df{&0{%sAfFjPhqAI%Yf=?|%)m(S2!{ zR)1%ht(U)hG9tE#KMjuq^KBC4?3dCEPX?zOo(krxE9%Su=f;g=795QYF9P#NQz|9E zWrl0O6^56BI~iUE?q+xcco5lqi5YH~B{bGBt8bFwIQ968D+BO)b4-Iq-VJ{{>?SO7z5t^lLcyvo853@OHzTv9`-F zXQaJIE`S1#e;G#UTSpADdwAC{+O>7eFgvUN8g35$(r~qPHtN+lSeHK=z8w6g;W=O% z&7TRQxnR*uhpz`)s$OZIsH(16w^ALgS+`AfxxMWqmD_*)aJAwsY^nTvv!+ed!>gzC zRaL*_Pf~&Z+*a;quZ?4t+Wbcrc3vL*9Clv*14Hb?cTXx+4?jHsBbnxRtyJ|2E1IY; z=VK7lb+h|ptkQ*vzUs5t{VUa&3(rHu&kQJ6tB!Svsm~^itW+ENJdBZ1U##z|9=>Zx zx$>>*)fdB*D@NOG)XFJayZBLqye@{TA1+E@iTzq&^()36%NfbwdbJUSqZ&KfvVt;(x}$;(=K)s7BjFzDLydVVNW!gIKqeMzG6oi7jY zs!98vf!_xhgI~D2yVs}lqb3)ZH@d5Y=^3`Al-TL3jIVx)) z)^^_n4K^8;RaC9&wejsO|B3jqdDpkyjPW+K)LPKW6wh zOY6-Y*BP}oZ&z0Op4wP&8&*{x4bNAb5R)BumJ*-!(eNza8R$$>n@cOQ)z;4|{3n+G3aTB~H)(>dz1k}ERPt8r6uvv8Ig@*NiNp9Gc1olGwMu3c8{6sWW^1=$Hv zxVfyaPE_p6#wx^mt^Wn1AI?f&iMv9fQSG8mv|E&K4^T&*s2^2l!p*Wucg(b`1Bij; z)lI}S22rxSP(b=Pu6E|0A8p9x44GK9BeiDXHlwcvxT{prf0nuL`SJUF8tTe1r2LcN zS?OD$x)RYbrL$Esm{+IDdFz$x#HrHkJ4?~vE3@wn2P)^{IT;-!`n{!Hqr7)4__NhZrR7=aH?PF<`6y&2*o*r|WUE$NH~D?zD`1E!+TArr z4cxjZ(>Dcoow=$Qbf>q& z6O>+}yuk4s2F?$$q0$kBuecJ5Ftk%EXQ`aQVhZ17ZJzJyy6Yd1UEmE5^ z^RgTA0i0^pIC*Tk7haID42L*twU5WwrRLNwNneVm5{lC0D&Xdxl9 za^EFc;7@OXia&J{bcwaop)bf-x$nvhI8JUv0AGvHx3fZskHeTk z-x00UZ>Vcl?&Df=p}4bjU#d-|9~ntOD%Tea{X}k*dK=nh=rp-7l}k5-ekK>EzQuHY zSp!p>qy`Xm=+_gFbLBqfC*>WKVCc6$ftelf{rXjC#4cdI+?D%gGI6i{1qX%Y#B^*v zo6(iWbad{@eK8tbyK-L=k69tVokVn*{!oU^Z3JVPDE?5Uy&8da-(-c{mHX;55qIUj z+wdS0s$IG7V&)~=eowE?SRQI@-_EG&vlI$VRGsK>SMK9BeW7A|2h#G#*nx*iY*tHQ z>>1kRuH2_nbXV@%iM)l}mHRkEHB`HD--`^?!Y<}_l_00Ohn$uB3i%Z?HPq4O?tHPI zX@4i1C64u_XurF1--E3G+Lim>Vj*?4Iby2t8nl?fp-P+66Js286spo}#b(pdT|2z7 zNvxo=?fzUM-5-05302#yy3S7d*R9;g{Q!d;{u1hGlQYAiUizoTSReE(q2A8Vjsz|T|$dTYPKBn)1b9 zJN%CQbu0J%#0bmS%E#LOFhYOmGCRQt`EzP$nr;bJY!HjUUAZrhm0G)U-+$O*=Gx~Y z3|8(7&9e_9U<~uA;#O$B34T8-VS#-+D#083jm^bfx$g(&&t17sH%oWrzELQ$kh^l< zPb_tJ<-Yz*KVffzO*ye0RC8DE>%~iViMAjTi*H1JLRc9ZdWEqlTdccsUom}_YvYE; z9-w1|&DWu$V@GM6yK>(xEEjj>zEWN@tL=A@yQQ(^RJ%=w`84l3M(wWLm&X-SLtMEJ z_3yLubZxpT_vLYTd&ph6FYiG{xmFi9SMFmU!RXx;v)BcE;kvPM-$|;kv$oR zUpen8dvwvn&GqiC+_#*WcwE=n+}PiA)UDjdVh(%Rmj}7-ZfKv)h%&vQ{q}Td#xmKk zp3+Rkevk!wu?;+Jj|4;UP5WLd!elGtEb$k&oc^YEjlXHEoqyYL2Jna8v5zx=?ql^D ze{krceOH%-C$^1Qsa@iai#&ziw;yHTXy`+`B`Vjsxg6E)-HLJSUg(&1_+#(#%V)@4 z<4-rj+BN=C*%FT1rx;cJ&`J9-Mx`s#UE)vcyG#6C#gdmx{Ds^l{`AG`F7fvR`!IKj zKkhRa54mgnZDHmAsI!&fw1nC<{yt+Np0+!}1T66v`o;by8~rDj_zV52*~)v2=KiKH z)@pB_mjV8;GjsR?Hcvkw{HbGJ>dR}!)^kRe>kYoVxW4uNrEk3}eR<1SGymAvA-3Cn zc~7x$El*=av&onDISsTu=b)Ag{duif*&a_@_?7$fI@0C!@Q%2{pT}JoLO$)<TjTSGAqpjGlH!odBVs=hhVI(#=?!8K#2WKZd? zuD&@jDgXM0c$kK?C05&+<7mzzel67yfZg84IQ7)Eg@jh51{eC|{jaD<;($6za>%7`vc(ljxTdxdI;X1(-;$? zgH`$_M6_?A7I9fNM%B(LJq{1%VVyd43zkFpQKj9QXr6uwYQ?(HqA0X(wl7o!RP*46BEkrf`y({6H8kos=pA`)6isf%+qDCYP?n21wH}%G=5CAS((VU z8>oIOk;rhAt&_;@h-&f5M4A1UdIUZVzr~9?C#~0SP4Ho}dsfw3oyhaig!feWYOLt-x$3<-QDmQ|E?u4I zg{*8{joh}w7v1K3jce~Z4>%TAZTkg?q8#U8_5JEZ^ujJkr}YZBdlA+GSa@Zd0Y9R| zO@^(~LI_wgA7b#0DVf%7AY-u7D&zTEooDF)$XI7FHTAYcewN>2dEhb#t@9Cs zlMEX+$`H3XE+gEOJDAuX!>xblve)-UY;7-MtNxhxB))?$*Hw3dPZaj>7E>+zlgFUG zmHA{ueDe@OsOHbBl-m=L_{rMx_@3p#m))&bLr3TRZh+4F0|3`bREJf1E&j2nIgZ51 zJDYg9)%rSkumG)6^k+IFO^k|r6?7g8j}BURfhU02%4R{ZQ*FLIksTimxmmZXE7$Gn zvIe~?*6o@_In;1ydACnMp>j_Wax8g`mQ=YC{yhC_e3fg_Yw--N^;G##5c&|5O zXE=UF=wOwi+OScm61<&Dhzn={Di#j-~95=I#?BZkg_? z{#(6v|J_m5V$PCqx}N4@3O=G{&q2yubKh0vcN>?-2);xxUy-;vNwvbaJ9?g;y<%eB zDZHN%tf#XW9WIOSM)8^8AJq@Dc1G37yPgbJ+A(|^V zDfm{^@WmIS>05+opIR|{C&uXsQ4klDYXEnhak;7Bu7b}M%!S%r{mFv4`LruvD3}*7 zwQ&s2#Y|(8IdKpq2MyX)p{n0X*vUi$5_F01t$gH zBABmS+}uAT_;JDS3)Zt!nC=vuKMRi(eBW>*swcRy;MRh>2|iEoD8U!2gOA)4%}ol? zt%5hGqAfQ?o9+{$!-C%t{9pA$aCbDm5;q&y$n}CB6ugU!PM*i(V0V7SL80?1nRj~} zM}+)i!CwiTUmUs9X3o%od$m3gi94qv#Cx)-(wN|;g4>dD^5`Js-G#ir;K4#?Y=dca zfhP)&sUpA(vN7%k!5fAC17y6b;qeGK+wfyT=XsSrCmzjxk0RX6c^svx;V;zqd!LNP zIg-iEG8YDSRilErv6?GCPq3bvVxpT%xhXomd^5fr@u-13+wcmZqsR^P&&v2|TzEVz zc(X2>JmH2d7TjFu=-Dd9t{#q#b7ko1D#l}o2s}~*o-E{-2>EOwpC{x=AzvoscL=^O z#+ooWdxjo{KN9@22w=fT8#i?xUU0VIOv+6L^2nwX8w+_$A#dx-ng8x|n21KW9*|EW z_3RTo z=-DoA$r^(?O)Sy0&!?p<&%a7G&3On1u)jK5Vwu-m;l3OC*k zHfWS=ZVy+JXJCBH@J7ij`&M=E@S~Ul0`?sqh?mo9@*xbUy1!AflbxoHHAQ0QD5hZE*(0n~yN=?I^E;#c5Feh~uZa%?T;kAvsci}KR zR0Tif7K#4UeF*ICUHB6u!Osssl9l>8?f8O>5fDG2hJz=$00{RkwXL+##$Tp$a37fwc9yCin;Dx%q3xCHeDePTXgb1*AVPpGP2Kvd^ zm&~ENcVPphQoDCyZ`>rXcOfg@AN!uIti)!u6vlLgyCWcUitY#qz9y^PyKoXSTss0{ zD4S6Wdm2k_0y9-^#~(w%mT(9-_bzOS1`~UPEx{cD(Vh*<9RcBG8?GGz(U-N_)&3c= zm2fIM_b$AS5v0+hO0yOFfJNC|JG`+TERD167ZHy?HiYTKt8G?YXQ%w@MnH6A)79G# z^t8!(@4}ZD`&}&F-Zt5aamN?zT}X#Fc7UL?Fk= z0d|}YW92~Y?g)ro%%3{~LN`ly1jI6A zq;~H@4-3d00WqDeDq(*Kt8-#MQOz9z@e~`y5}Ou8Vi|PYfaZ_uzcBVB3(Xw?k@4_c(oI3*ISC)%A0)jsgWADO3XfKWRrkdHiFt0B!hT0Jjt64?v-i3L( zGUK%)Ada)JYDYla&C77D&En<=2=)<--u*$5T|l|(#t4WuG-sXt4%GGDh11~|dz<~U zI|5=h8|Nnb8MFoL5y@7m2SCIvjDYCIJmb|k0_nXAuSfmHIR6=Y7m}^mURLt`_6j(> zu}zHE9RV?nCGL)Z&^ID?1jJ#6ks}~#_b$};C}#jfyhTjkrQ8t^!`W8d5fG&;S9b&i zpOmq8;S`iadF(@0tvdqZZ-#M4Kzu^*WU zcke=evlV+6vY5kO_T|CzSSkDLtF`1dl!e~G@MV@3qQTCg_5pr6eM#-;hVBgYZ~K1g za|gpz^nyptdc1JhpTCN@4z`TcQ7Pdd3-&J9SnKD!SDty zn}{6@&w>|*H|V>6?eK;I=Io3vSPXB_h4YubtzvY;XNU?r7`~2652G87uxu?)Z+u{M z!=_B$|839B2#?_n_cB3`-ZKZo8!l(#^XiS7F}$G>E77N27~as5Jw~eMVnl=C4X0T} zX`ZX#!tjP&G{*0_4laytIEF&5-N7)ATd~*fV3@ZFJy$%K?YRT07~W9EXljQyT+b#M z^_)Tng5eFkL1G6(-XAf%p%pK{0?+*j$KefZp)42OIba9FXJIRI=yn#o5seUTcI-5r z{&9@3^|Nu)dN%-@HtpAL3~yiyr;*x?;SFp#Ox)FHn|!R!9h?Bh4u)Sq+(eJM9mH17 zrTOjkFCt$}uY<+*ppA%Dy)-a+R=lPRQw!mNUoTVUu34ymzHEs-tb$WKR_TifyBrGV z8iiG>7h0w7K&T*ee(A@CPpcWqGbhI?{RUo};B~Fm=VnDMu_qIvwMw&K!d7@~aH4Vs z19<#u(V%3yj~@HgErXJ|#ZLgOCKF(vodj8rXw%=sRqmLc+^Ak2lx%2Uuf7^O<$ z4}~Yqzv};*zY^hT=^Uf5D&bg~g$&xgtkQDCP5+yX|CNkjoZZ(dy$n9g$ToHD`N@L* zwC|9kqzxa3pLok2f{wPfwO+rHL%uLZ9;dyYKNh!PFK$P5FK!QQqsu*NZ&aV2kFPt7 zySvI7oXoSgsDN^HCYE4M~Q7t$}BwvPUGZ zp2W)Bgif=RO`4g03}50|o_YWS4Jn-mA6}Vn{~sSV98~$^@Mal&W4!hFBzTlRM-TPE z2-M}^Lf4RUwIOdKMW-~+g(0~klcW3a5`O^pve@RXv+H^&ti@bfZPGa8DCi#N0=omt zcFsCRR@qF3+VQw>)2D#g0j?(`E3Q+B7DatMQb2W=t|qBeoTDr7hH-L^j!eDtBzM zp;ov|bsGyQb9SQ|Gd5YE@ey?muoG`D&zCr*=vH-UHA;u}ywwifCvcUibdi;L^m775P!pdC##|?CRvFudJroi8i3#Iga0JHF$dh>#0jxHW7 z*M32=QOj1S88%DZ=Wu}lUe?uGsQ2tE&4r9X$Eb>N$(#;O)7#D~{3=9>#)`_e*MHN@ zt>CLtc;#M_?q0c9rEFAJk4p}3!fbFG1vY0>5lGmBtF^Qjd|2u&)DPp5B?FkHo?4UJ zBU0%qC~blg4H;P*hgG^AGR8ZzR;I5*tMqB(aif|vKH0!+595=Kn?9{o@eojHl@`Eu z=J!Z#a0^AtUf`MW$riCz&D~5qm!fZWLpjtLzJHHTHqYNqUwvzQQ)k(|o4$z*S5HXx zL#MWULK1IL)Yb{ft_`1P;g*o?WeLqe5w_<$8*C2tgi4v1Y!hc1KT`ZH%G^%#w#P?3 zq*#icN^dwa4{gjuHat!}4LbJ)qUNc}xI8SUQ% zkwCzsk^|$aZspgWa!)_V!(KiKcjtsIyB$4!`nvHSfbwkk>t|-4)qPPtD0G{wCS8~; zD8A5hb|G$IJgYf{o@a1`r}|Mu#WVPfy8FUpGJCMz!|Orp;bp6gM;2wNMo;xE+`DUkvgcV?B*y-wC>sA3{f1r4a>O)o!G0L& z$|Hiy1a}tPTkuf9lLTKSxW?g*I^kP|$9lmJ3w~Vi^J-xG%cAj*gy<{5zX(oY$7%AH zCAgvBGQph$_Yyor@C1jQ_BTz9e>5H)akKE>ELeBkCjI?F{)XTW1)miBvpVwIoM?I` zdL%as1uFgbInmrIAsQ-pqI&1oqLPXgLZpX+83XiCFvEH%nBiAc)&3>eOhW|wLvR`| z6r-9WxJYmt!F-wJ>h~2qLhyxxXF43$Z9!j^CNVum%&;CKW|)Kh-2`?Bep>J=g5MMT zx!}`+J$m?;NkFe=Y#86~YZDtLc#_~5f|m$hDR_h6M+EP6nLY0dt^<5T@JDKPR(Ul3 zn-KYM^KuJ;i?q1hSg>Bm*yKYmWbEci=nNA)N$_;R*Eoz`8^`U!<59s+34TS5{{y|t zDIxk@a9U2Cy#<2xQpLu`jzWHp;30x95qzcKgv08h25I%wB5zsP-lH1+SroNjSF@Y! zi>Ci0bkkM3uPhob#SO$Q!cKyF3mztTvf!D5uNAyp@LItS3f3dMit!eR$MeF2X>>xd{Bd zkpC>?>3Cjr^|`c-JL<2!;J$+Om@68={4W+BcME<>@FB7>?p3mR3gFtn*@iz9I-ikE z2K1W2CahjE*vNl}PTY+&6L)hrKnd9d;O5n?ydBvjHcar9f>#LMF8HwEBV;H3X4ZRj zq_Lp!H3{sFVf>;_$@*C(YnDah`S_yh+EPe1!Oj+}hdUYD^>8OVf$-47oeb;YPDV!$ zcQOT{hdUX$9`0mV4|i&0+NvJ!WIP@c25lo7`4d9^w2;3f+NE%beP(7~e; zk3b&Vs&Q~zF*mVd!Fo)TF`^sgCTG<`r@xTvMSG3@1wwwg;F)gN0kGm4;lY)MTjD)@}hNyUS>8#Y8X`Dh^I zd1RA(Yr(x8c6uK@tjZ`&7fMUWCeoY8cp~L-3)o%zd#%v9k8CpYu#oQ&@)rcZoR9R~ z1l|@N?~A}c3i+>OV?+eEO_!Ss?k2c5*<@ezq^6 zLVmlDuNCt9g#2M4=eobHL2rTMZes5Wk59a%LvF(J z$#~?)5!XuryMs@c2_-#B$`su_LcT-rGlE|g{4UvKK(8X~BxaowI(iUOhHBS%a5Qd` zNkti8CkXjeA&<`&jzvQ0dLh4A$d!<*%nht!S;4!Wc`7?Z}I_N8o#^*!i zR&ov5WOKD(C3Nl)@&|={ui)o|&S4>cOUU1KcA^uXWMNhg~O)EDxGLS8K7tz9|u zU*$T$J%!RhAs;H_7Ya@YUM}=k3i(|^zDdZpfNMLy9rQ4{d|mK2fsXz`@-?YTAVYAm;7Y+G1Yaq5t>C?a-xYjZv(x^p--Smm-nF?U(OPg1 z!D9taA)}OdOe5oaB9ED1ce{pbgwAzj(^hVZ3y(E|?-feB1wSEl4hcRYbUq;)BkX2% zTq^h+!#e+?gvTtwHwoS%_!+@(3I3LBO5$fSzIF2W9h`00i}#AIPW|S%`MFB1g+~W6 zz9#bM40iX7I7jFV5qvq>6zNPMzedP!5`1f|4)VWFcx)t_gdeR{!b+fIeBa~o3^?2H z%R=XEvN7U)A^%j!zY_AF$=tw($M0}t8}_zRZp6|lQk#XF9U(@g&>0{o-C3FE#L zD@8by@rGm*Un{bSuaDsK1y2#YMDU}6-w|x%-HID$YloeFVT|yI3%*V8vx46f{I}rD zvbqd37kswhA%e%3A$_~6Q)+XB$6|6fN4`YJuNQo?;FW^c2wpFEv*7z(X8yOi4)9LF z`vgBN_&LFc1ivQuh~W1H9~1l;xb~I6m%`%*!9NTBOR(LluBZco(*-vWoGZAfj?cH6 z);X+Jg3ASW7F;Q~m*Bpd)!*0T4ca>{ShKXZeNvq`zvg^L5QZQ}u@8V~3i|kEhg5ewIZ&Yrg{v=$6U3F z9|?7WA5W=@5jBVHMe6qvaJ{O|8;OsjYArwT`zSy5s4k=Mk)v+p$7uCFKgw0%#WMZ@BFw=op%8~HmSAz z$ife@H5=^(>c(+3Wtao-*tnV!`#1IexSHnnrOF;()7JKA+?#})Y15r-VqQwM?>{>Ao|u0Xeg<5ZeS?4GOMi!Bhdfp|w#>G|eiTU9ABm-g3zqNP=1F3# zk>460j9l(3xVit6u3+m2EgG~N8az;FRei7jROa-Wh7l~N|FqB53Hwu15Y-`Dojtv# zWbc&eHJ^Kjy;@T|+(NK$&xYUM;Cc0>u&2(A(M~V;M>g>PuWWTJt<&0R#eV;pp{ry5 z3Jl-r63*?k@6yh(_4l^Rw$~3+@i{e-94nmCPRHEv`xdeFyNc`E>n~L6=hVa+*GA`Q z_&quqWcY^P!uNn_L--!`(VUuj(e{3mk?%XFjJz#1{79ch)~GcT)wC;XdfH9Z_A6`h z3YYn;&M7zlRFj={{bQ@cj~qg2J+cfjh97AiWYp^9l{Ft_)NgQur_T@zW}lnuS*G5e zTXS)|PiL!m^Y?|NS&`?`dv4lvZoqf$SDw_fte%^z!K1+Kt)81ERiBp?8E!TI%G0OZ zy7|85m-~0@IQ{N^&!N^(#8Swio}1n}H`@pQ$m$?!@zj{&n7{a~cMGde|1!5_Yi|$B zsxIEt!m|l=84R~uh9v@9hCQg0@uAYf!nwZ`V}O0@ASwmk__X;M?itPrhh7U!dSS`* z@T~qz4lfRb1&>POdTIl@q*r`F>%Ts>FYX(pKP7r!* zKSx@6Jid#=@L1ymM;OH8Nozw@u4m=Ry$}+w*Ee;>Tq~s?_4DRZ$D8&vz5TxKTrSh& zPpg3mDeJ%~?7gj&>qGcgL^D!OGPYLe7Oa$B)M`DI$W`vVMK==Th{{`hJFyB1-jYX% zdx$MI5})t@OHTnkwudVw`uyHQT&5{?lUI4(ibon=2J^iyGYW6&>Hz+~LQYNX0*kzA z=Z=Eh`uxE(r3R0=-dBHuU$9-8n)FuuygVJq8Q`6<3^nZCX8#NR8FSLq%=oo!;vHzm zPWxpf7rco4Hx>z`C4O#vQP1n~`W{3HqDY=Z3iY{NOg8tGu~Ik^+gF$m&e;~k@8`av zN5H97r~_Xy(MruAmyo@wjiKXfvIFc-or(PTn*IkW9m1)1AzoiIIS zMA~9%q^yGBX*)H}M?Iz;p@N_81}Gpi&Ng@%Y)|W=3!}k>p0q0a8hA!#GMer-lo3f} zBx5?8F0`)8d}>_R#j%VdjI*cBxcrglRd7*FqxeabWm+%02(nCn8s@Apt|@5AY0i`t zD>557OzUf+`jtNC*<8uUizywb)wF&#cZtcg(+1dIGw=fBJ8huN7KTihG0j2t+wci; z4brrs+VJ3w)Vjo04=$?77^AJdTqj|{TKG&e>2bNnv@7frh{_vjz(Sj@9X`x{q2)8| zOqkbTk|%Ap&4%k_e2yEH%DA>Bcg*vQ@hV+RsWBbNJRQjdPi!-zoUdIIJyviaYCLU$ zJq9u5BF=?&8iHo5rgV`#5Yh~mZrWmnw`xV9!5zk)U{!3ZAacM|ip)II=5zIQGp zX*bwsBa(tHXh3#BAE2jz3t^-bG~+c=z(tslo4qKYv|F9B;f@t)cWcg!r5&(ufIFfq z@1U+cE5bcU(w=k5$P-Db*y5U!cssU$lQ!4d%;R*sG-v#NhA!Q&oFWPCf*EOF+qWai z;6mo>S2vwM?J%zJNFIyzjQt1lVMRjJ_{&Kr!b(s3+dhR4)IF!(r2S)a(;66=;z5Uq z053Coujc>)Tal^g5Yl`e6Cg@gswW0D1PFP!Wrd>>)+$!yQ);B^z&TD#8QKv+YADaN zOiy2gNspz~^E?a4c$_BG*AZp>!}Vj+vOSgb&^eCjuo(+ku=yV5%?ci7Gz~r66eF`d zt;ll*5b1>OHLcj#po5m^pg9rUaGL1EVpgyz12^^j3t@sgSw(Fa}=Hp*>!Gi{a~d3e8K@w6)(-{Sq~0jg~T@o}Nz`=(H0EAy2TZg3(lUTcW1q z{FP`FX#+i1;lqk-VSx^- zP|s~})M%Al}GK7R&`E+dJ5H#%V`RgcEGi#_KX@;Z({5 z?P%##%0%sG6}g_)P4dwGHdc_s2ht{cwjhllhXm<`$6*DBvsqo`>F;RI_uN&hy};34z@oj{ zXzzjzY1eqJhEmweyavbnEj6&FCfA;=F0HBQlCd9kn0BM55u&vs=c?`SiXUaD<(@yF zpK>KU{Ed6yeyoMN> z;JF0+>j}uYDm(L&!dZ)f-xM&jL%?I>ks|K&2m!M!dt^2f_u3oLigF@4HlNMt$|E{D zGbcH6E20S0&Pk523Hj}Y$V8?;kYVovM7X6xAX6_Sj5`;OfLWD2Qi_%yFmsaQ5e^s% z)Go{Z8=G&oJ(p3H2O8U4+bwd4IV?0$HDR5YRoNqrX-BcXRr(_j)2GB{wG`?nf`FNm z?4)SsBuDOH5@uEQNW2HDwRTeSle}VD*v}yOAXoeflaNrsM==Lb#}_XZcg%zh$zVMc!8caIWrvSrN59wDpYO&}e1kDQcw{Ju-I93kOY>dR?9Xz}d-TDUE2T-a0NG9vq z%t>~PG;@;mogz@TDtl{$4NhPQ4YkRcS%DFD{Cy^cM)1b9JN%CQ zb#sz$WrUxwm5;UW0*AevVT%@cnO%&6i8O#LFip1yD{_hjF;m;@jc_zyK+jB$W9%*_ z;lVlA{sH<8vh2V-dn)`R%h;Ueo8b3SWq~~asd*z|mZO=O9NEmqX=WxzbmKHLlOr{3 z^k!}L$a@T9W+q2oV)_ZYl2eXzBF|9IOihk(S>?bI$ASn~4+z|#FM`6z9u}RMnH*Wm zhQC}JH$2jxYG!6~1z9GB)&AlX#s)T?D*rz*rzc*UIg5! z$+49T5vLj$wYd2;l-%Is%HfM=v zb`IQaAF7A@U*s1`&D7)w7xfHmviXSSjf|qjwQIBQW1jD^??8l^YXbM$$8qUJdhq(Y zPqP)_0vLh&?av|eMt>|xWb)`nK{YMWvb^S$ML8V9L+NSx6L7)xO(2P$1s3?E-*{3J0)i3BuCz&fwgmz zU!m>q+bs|#GaC5NzL$aZo#Uu(#a5&h^^a+XKeC%eVpd#-9ms#6c2e?uR^M^^Vn$Uz zaMEs*gQ)loH{g7yu^hwAoaD$j7O0$)9573+JJ+O{lN>qDx-xT;BO_>wnUl==#r@w* zN_Hx^c2e^1ygp9b997x?W4wN`7c@ZM$R*bUziPH(V|m&Armw+jZ>*33{;;{MUN3J< z-~HV=$*~W3L7ma%dV?>f3+FF=TU{CV#qMW`{9_lP_qp8{`;rD)o;8SOlP`8R1KOUC z;aBL7arAq@<9P^v<^EV>y1X9V?soWNX{>agcJ1-U`li8^>Ujd1Pxxb3@S08Yyadf!9? z&h=xwK?d?YygydgkG;-V3Ov6d9OopnZL(Z+H-I_G^-*xlAl#^b%sJ+rh`Dn64fgD` z-F35B(|Xr^3N4lPYd7X3vxU=0?Z%vBHXJ7I>a$JyaS0fAa6b#Vk*8}8_I4`1TkX6B zUsP7XzvKukwXgab$@6H!mlF2813-INNf32m&p!djUiv+ZF4JBx3fZ?uluUs^_SKI; z{sYdYHzGZI;Q^pMrrG-_40{ouO3P4yR`WGXBg@B#c#OqquRp_|K3nja5MF#Hd>pzh zv^iNmK7hUpcj=9&I=jA)_SJ)|ln)Zd-IeaI&<5>n9W^FPBdx=X{KML`s&!hOqKKN` zG~h#i8mcWO@e2Y3RS@()y8xc`ySZBDhLJLF;we2n0Ev{3|2`t?K;E0UFY z$i><;2j%B5p2u9Qj|btK&#N8fev9rJsy*(y3!%TFdwYKh4!d?kz;Dr;PMt8_FrRSM zAOkd)T5v7kIuvUx6q?8{OO1jqkll`K&yzB&rQO8(bgg(dJeG*G%8LAHU0Ld~+WKh+ zAG3;U0b2D_ChLdy=tT`#&1G)6PT;^2nSPnOhWdk=&M?eQ?m1Anhj~HSWM2G;M&+fr zIb^qsM=C2Cg#Lp{EJak(bl7t=D_jR={1#=@EvG*xm7|a?|qJhWV&WX9s)>`XeEnd8hGWnn>7Qk>a@-0)BY(rI@<0 zB0aPcRaNi~WJ>@s$WIe|c{a<1N;5keg_q&61s+EBP3$A5-p2{y#$^-Cs%?0i(&~e! z*fwZ!G)MNq7i*w16N6fi_Vmn`sAvwdy5!5};nxeju^AtK<(scicN*L|{P5X)^+m+Q zkDja^`x<+!qtXc8ESherXc^?)fO(eLh=NCB*`of#26Y3RYz}y$CsuB%s8^TYiRbg# zkXcVY3C%z?<_{51ZmKA7C!?7!5EnL8l!kVqbbK9^r>t_6QFtvf%sN3=;;GI3ndfc3 z+b;MY@G-0Y!b_ETyp(|tFKf0S?mXTn!OcxzWxQzMa)(N{=#pUjD=Fen?b41{*T z8xpf)4MK9=vLKiDv7F|R0<=Kmzeso%Vq~^s{xJ%I=u)z8(Qby_x7tHik|uU%CSk$I zR`Nrg@l1?c3U;&VbZw@_GgDmY$7p>!$n0R+=X1Sm$UkS;=d**nG;IYXH58Z(%Ei*H z^V?D0U~YuFDA|jcI`K9a?*R=i;&V~6v%IV{hZOM0cIEZP!?@DPd4=H zO}2Diau>#U7yfZa^TP0uFPqsw`7HepD!0XtIY_!w(bNl0qmnoj4SzdVapyP{2OHQERpMO;lX#-ie;`q$t^jK1IAh%n6kkg=C9$q8L2mYC!o$HVy(~Re!NVxniyzLG&x`o&6?HxA(Ht>9 z6UA_bK7o_f@^>a1BR<>3FINL8xC9SgmefVztX4|zIfhY~jufog7~(`)zt`5rDJESt zILEGy-(_t)j$Gu)sq=S}Q|GOi{PTQN{lok-1Ocr+<*}!jmrb_$hu|)fmk5_lULu%7 z@}8jjWs}zjU%)s2I}V(G$wG1+^L(09RqnQMTebIhZ8MSM>=jvgec;_?SaI;p2D9v)I zIa|&=&5eS^@MdMs5GU@cNWr52FiIglxT~Vxa7y?8Zy-d^%4c*h|BsI~k+m`k{#Ma_ z_P^c;*ams$yE(2L(RW8hy(mWCFh|VTQIRY!GF#!~Ts@n!5Mm`laG2zqqd3F(Lc8#J zh^!O*n-^8n%X-F*G{f*PtN0pc-U~bfy&ODWPqN1O*Q41-KF#M6Bb}hlIy`8l=d9cv z5|^tg;zWE^g{zM2e3O;RyE)=gRYl#z`EW~*O66gQAF3(>iF<7MF(uEpn)X}JrtL=!o=i$S4lrDW_JNgA8 z*^ye`6^+84a@g|}&#+mwr?yg0$x1zjQs;3|G-%d9<7c>w&aj$Zlx~=U3du{L7abh9 z&B4|!$;%E7n#q_Yi^r%0t&xh=ft(qw`7(#;aoVXr4VhULlWU(+kCUgAOVwMcdz>}U zh(?WAsmD4ww;}cC+_+;jW1aE>P^Ip3GW9$t8?BuzWnU+2g4+n}X4M9!BTLm+#@iLD z`CB=m_IL6fjsAbt&)|!9 zJRvy$M(YL4$okp>@0S^g%ST4!W!`!xFZ0?UsMV%7$h1bnT_i92DxI7pU?)gk^lg;c z-a_9=Avfff0HZSh`Y|^-c`}aBTV4rllC_0-q=Z+*=4Kh%QR%X-3${3|>w*~Tx?rnJ z$x-Pml2?$z`6?22RK{DKVY@6r4BD$TJ>KPP&B`7ML7N$=%#b-1>EmO;U++Q<5lb$?ja#|nfkk~Q#z zEQ2{PPhRv|u9NhY6>vo6!W?YfPaUyzhqRO3`KU}I*2?}dc?v&E#T8a@dnC!OakZt+ zg`{;;j4S33wHfOmGuE=e&e#t!W36xjS;V&#%uBM6=0Gc(KUzr-vTFJ#S<|?blNVq= zTc>o0tk{tGt4xBQB3fDdO=j(9xQj8k{#lzwZ{07EDVOoHIbat_UP~GS9HP_5YtzK{ z&&@~?-~Bl)KXf1be#LIW@-z~))CNN!w_EVL1-rv2-Noa**iB>DpE&Ts1&Cj{@e*J< zc8GXbiQQq8%j0TG%mc$y%m`$1g>cv#!!4KcVe4?%VBsblm^31;jyqa$(j^MNp5_%- z>IMA#P#JQrl4r23TcsrxS{^*Ks`VgsvOIX;P-=xBJ!*M8D&Dy0tS^E)mn4cypPZ~C z!u|Io#xvw$sW9v)4o_F#^-M*SDSDos;1dHL&PWmKhbDQ`ImI%^-XXh4t1J&5IH)keA-k-6 zS@*o05}0uwdtk>&v%^u$fNL!AW*p?eWDKw)z<6TZ3bBiAOT2WlqG_fTUx|#55utvr z##gdym8kn%MSjL~_*hvRZpX!HvI2~rF2+1pvD{JL6kk49(KvyZ65K{u2h@Ip=PL%L zOocOooeh(Xnk{pSIPqs;K&*MLV%Yz8@SNx(%mNN9GIW0J9TTdnUZ{A=>DUk}hQC~K zhvNh9mdfXwi`Z8xI^l)!UawTN!Mo^pzEbg*d0d2Ft>|hVsD9-IQB>Y0ihEFgea%cRF> zj~krqaf|L}D(ah;#e_2z-{Xz-L1!y=JC?b{Z)Yoxn=gtZ|EbtLa8(qeU|5Gtz*Ov# z68@T=7|B-rOx__gVacPEK7CD@u3IdAuTFy$)8qd?s&0=%EP1a^y(YHT)!030sLM(l&qEl&I#5 z}{??AhhUjPl!NOemi{-s zCoXl&Nfq7(&-ugy6Q}!xxpQH%81w0l7||uKPjcEoVI{BOdu^N5G9K z$H*30hk7KLZgHu2PC%A6TU@+-dduovzg5h0irwzEsbbykV?Hr;OgG<_ZaY%VmLef( zP{528OS|O++*vY?6Qk0T;(SEx_hWa8zG*W9urJVl-_n41YTVI6(e$|`@uFkYbw06c z&pe;F<*$k=Ty|KQ;&8>9=FWQr6m0XzVzHrdFPE7u3Y(6pCuY>kj2BBXx+aU7$33p< zO@CJ`bcmO74)~DB-Ps2MW+!pp(LZ2%L{^mzdEd zFTnTgr1v__n{3NBQvO8ua4?RYcY0iS48B4*9TzS(_g7zu3%{Be;zYz{7?$EVpWM<4 z%`t#-PDh;0Z01a5^Jj`Vk^ZFd?;3OJq&{_cXUq7xb;S-j{!4{$q~$Qi<2Xj~uQ<}p zz?_zL+E;+ZDlw)sI5Z-ik_M$}|kmx}pd z)0VdtS%u-GG|r}(j14M{am-OXUi2;u-yX+#bE6WKi?fB{9CNPtm4^i)tq6z3qJ0ti zONE%m!*X$VQ8>^$6`|s=Gtx{Pn6?$>F|iwo+re~wVh{&`ci*)$v-AIe2L zG>ecGY|S<9q;VgOM`}D-iniDOO8N%9w(;5#A zwEtMs`bA@|d|=1w*En0_ref)qLxIxnnrN`bH)?#F#tX&SR%-+1K2elAG|=d{=JT4y zpJ@D-C|bHI5SM}>!Ol~T7%vV5(zHDejI*3#2)4jcaG6j>ZjynLjkpqf8U^(s+c%w`sgkV|izc?8 zujYM9<2OZrPg+34bh^!#CKqEE_&YJWU}%n6SA3YUJ`ie#5#5fdqsDzS9;NZE8p}n|RM}GSsKSmX zgUqQDTMpP>`>d&^(~6w0o_(|zy_*aTga%nM8E&|yJ5l2qn$8?ePRp5g`fD_ujhg&! zvYPJqfbB)V9=3EsGT~}E@+BHiTOQK!q9%V$lgkC&l>RwQ&S$E2Jl|>Z-!=IaO&$|K z`u0LsKFrbfDqI1uU9xPlN-S5C)3|^w@1n{3lJV4r+d#0rpcJhW*>O%LGftL&y5=$8 z_JCZj9;YJOPr2g5n*MQe9F(y=2ewx{dR^0bpR5Y-ktV+Y4%r^xYaX=QY3DRL^=e=r zS+%`@Casup^=!K{_ra1SdDfU1c2klN04L$Z?RYx1UKnE;+K zYjU|d9pdCBO?ZZsV?C7=?;@*6_meUFb2|vO*GM_0>ByDmR4u-&$>qXxN-h_kQ*nMy z9VN%w;%hHv26{N^UzJ6Zm2RRY4`}jSjhksYEk*x5hjKzgDN@;%%grfXt;yx`aZ3J* zCjUueX+KkC#fQIz>;*;Q!ATgUxYeUv=}5bp`SK1Ce`IPNEybdHa5dS7B31N(n)f)e zif^{Y($uDs@6+@jA!7jH_Bfb}xO0;W$Em!$L>-mZ>sDB6w0WNn^iggfGO*&WEhQG$)(jxrPI72(zgS2)|C2dJW7jbye6NaaY*A;n*MrC zewQZSWy^79js2R(BenGp<%bELl}xzQ#Q?9-#3Wji1u^ z8;e7-_J5&6)!M&g3=!O%nK)aD{a{-sjjYaALrtEq$(w5O)|$M7ChwgYx*F*)O=+~I zG*#oI1+G;vo$*Q(`YVslA+Ut>#n#V*fz!XhBSCikN$yaK;S<~6B$@gmV2d~OQ#$nCl z*i{eXC5_+IblxMYQl0~|#A{8wphCH-l}lt*;$O*1|6h&M@J!RJ*V3x4R?=bdP>pA5 zT&eLx;&Q)mPRNZXIdt&k9K8+7*e3Yz8{~Q_PEVmcI zNs9lY>3m35rTn^CuU`Q(;RlXiC3p?8v*CKr~qeZX_OkzaZeb&K8OM zA>mBX=)j?*kX))xIK&W$BU>=V?0E zkn`0L(@OK`s&RiyNk%k8lb358(s-4ozn-iTzE9J6l#Jnu+Y|Zd;z`O;qba>g#?I}G zCjUs|?==2Xt<^PIQ zBkrpYrjc}tD^YCK-!2^vq+c&5hlgkCymu( zM}*ha%T!mx{8HM!O6Dg=Ha8WE4%ZFDwbn%4Md^+XfslOUuR;&iyvJ&Mlg77dJYD0t z8ZXe8ugu%ISf}w8i=$W!W4lQBCJ+ei)%^LAyL}B+t?{!OpVas@jn8QOuErl|{DsE+ zN)u^~ka@YJdHkaBKN>suH-Wl%l>b&Jj??4;jq8cE?@S4V8f&5wjhkyMZQQ8n$~1Wo zjeBc6NaJA|^P>Pei_e6`=cIDXb*>$JR}dAzLg zn;O5X@kbhes_}OkU()z@jsMcvoz(4Wjy!nuW#=wl<7AB+YMiZczWA~A!-4iKHBnoQ zJ8Rrk<9-?s68+meoD-U?iKMY0bu%$rlh4zb-wxQ<(d#tcqVaZ(`Tel1f4{~DEw-+R zAJaUf0U~uBUn4%eBb*aQquq8K?~AyF;hfU%HPKHROZ!AB^c78BM-=7z0-e+O|CI7> zs4>5Iu;tA)ZmV&bWU=_}H4Pi_8wgup{+*`cyhW2w5hw0mlM~|C5w_|Yjro;?E#IZF z{L4*6w_lU<`vUvssc~P8hiE*)W|7eI0*oc5zM(KwB7 z(Rhl+{4m6hVzJn_B%C9@-u0|6v_+He)c78a`Q3;e_6d!j(U=BEZJn1imVcRM8ghF} zlfP%NxOexn38mj^9zSXPo5u1#Qx%aZe%$?RPH8UI!jpvE>6?pe(i@1n*O806${9?t9=}C=GX#9dWjnM7o zU!f||4>j+vH2zlOpEUkW%)EJA0IM=rzOyYLR`?tF#%JKMzn!u)t)-%trnMB8YC5en zZl`eFGeeyb**uJIg==W86+_)d#4sAF5F zd2G~}Z^YX9-L3Kc8b745v?-=CcS4iDtg*B&rgYv)L;7|C?`cY(X#Bax{4&VarzLco zrExM9sROrVwp{*!tmJW;oZkt_hYh_@dfo-vPabkLZldwE8n@QCqsCoC!ksvy12oZa zjYn%NZI`JB9J4gJG-IaZi#7S38n4!v-!s`+-(ztfc}5@5JRa7V-#gg>PHOzJ#-}y@ zSj4Re2S$9OiN4qP4~?Y_G?jNJuG{ToqBWNPJ}aFDQZ9}xTi&8kJ58sf#@#gTDXt8e z87Lj2i6&?~Sz~@_WhcK-^j;1deJeE428}msT&3}Djqlg^A&no`xLV^=8oy$()&Kva zdAuV&M7~PTYa)LCWoP>rjsMd4-|Cc=;k^!V?8|yh#LW+HN)?-@I2woxU)`T1#vQ5W z78mx;@rlt7-Rl!`o~%q2^M|xf6$g&g^NB{S4rhpxv$r%5FW+-5R`-ue_KCPf*ZV|T zO14+L)cjV~l9E zJTYEOdeJ{v+zp?t*Di?>FI9x%#anB`dqa!7C=#;IZK@BfZc5_f!0Ougb+WoTyp3;y zs*9`vd=WDf0kJ(tR`W!2K2lJ_@vmgn!R0-@YFsm%c+=W#h-R3jxYadwEA9`zPw^ly*Q#Ya6Ty!uo((>#cro}{GCy`? z6+N#!HiBPKycv8(@lNnNiuZ!gDLx4PRPhP$*NRVrzgPS|_!q_J!G9|L930}i|IF!6 za6~Eo8|+hz&ua{RV@Vw@3z4cg1Kdz?J8)3(4PdS@L;XQuuFy&z18$+1A8vAybI3!+ zEI2wVkCk99NW%d9zqOCzP2fR_cY{YLz7IT3@x$Po6(0n1#W=p{!flaaG=C$k7+u6z z>BIS_(zS4K;Zics-xkHA!8;T$1n*J249vCWsn64KK=A?a@_4jI1Ng^^J&=E) z7-z-!Hl!S^-X9gSN`F_3KT3=%ii^Rtc+W_?fa@sk4o*?r3tUez2c;~X&=HHvXCHY(0_LgF1j>|hyj;8>|mwZ>4 zj&wM_Qyy$AKPfH*|Dm`T{EuRuZx^b7Vavg>irEX|6|V=^Q(Ot=-)Yp}1kO{u9qAif z1eG55fy>D1D((iwKFIqkM*0T-S))!ec(meFF#lPjoK-zdF`_kYSKJ7^NHJ?V3=T0s z5gaR(2TQqLaVeO8tx=~vc!y$M`S80P%6owyR?JhtzuGA0DLAHh1emK_Q$7m(s^T#m z|IaGN&G6v=YgC#F{!lRooX-?I4k!X9dcLq918KM>_A&-5q<|D$*=*o6U}@&({n#f!oGSC8@va9zdxYMX2BQqIpr z`L7B0R1=M=)$I+^E>M$?+Q3*Emn( z=90yK2XAjH1~*DQEH2hv9~7P$D@(+j!_Nid*s-uZ;6t`mYsA%y5 z-0{c6avom+=*=PpZyV*N=;>9d|dFgt15j&|6iKbbI*Xveqp{EhDD{&qmz&RGAOY1Pk+4Q=GR5t*AUaf zx)^)JqnC~(i)ZFHEOM@WEu8C!KP!&FnQ#U(Z!9NJwV7g1%VPoe63iIq zgy%H=kovDEIvvh+PwbAbgv9ut?n@F=Plw~pX|7*SH1TVM3cTI{Osem0!! zf>B2?=I!ufy%%&HaC3aU>@PbzmY@08=j2VWT%BQ<>yvOon-w*A2{-QBeQS2X6Zh=f zyno+P%uF%H1FnMo|Cj1rb6@zy>Q3*3FFO+IwsP4Z#1E>(0mAD%8U_Y|j!L+`bMN6rM8oZRr3UySOTkt&`(^JJ=cZD&7tJcjtXzr8zE z%!qdeQ#Llk@Ge`h%X||p+E;;DQ=HAcCMk3;COYR|=nS<6CixW~3`|y|O*q?nz;*i} zC=5*gh+gfat*`$zFgbzxwt>l&C@Bm~^63xkOLo9bxpOyI*_Y&`uIx)b+z?nebSR>B zZbJ)G1}5)=SQ(h?i>Q==$x0|F1Cv$JK+C}7^(a!Ufyr-T@sP?kFu5XHG~61j+n^HZ z+Xg28#oTNgm~4bBDFc(kQ60`2%+t!ih$|pNAW_TZe(sHA~8pjo9hPkZZQN!^Fdvc-KQFSJsc`IO(#if5dll zgDta_@ehdOpNES>OBm~;QZ;rS!~Y?Zi=`ois}?L5;}j&)f@K+Q5n#bGf+8f*vP?1u zbHmvHrEzC&1E=&umNMO0Tw5-RO98sGiAL0AgmmYST~Q{6e0Q)2Tox1c2x`nSVd;zF zKiakhOTIzq&c!f}wclBLwgt--I32bH%NgR~FT$ylZlZUSgGfFuK5C+S3nEUKe6taC zi(Dhz@K3{Oi<%@IroRY@M@@FuAYzAqGj6YIX)lHW~!tkhz9| zNeG(}SOWdbz)~cZ6=(;|>_9_gC?~*A34;OJJ!}-4m=0$-q? zj>kP_U=X5i5}1g*7Y6wKUQysInm|)5X4nU1u4`G6{5C2Z4KDC4%4q~vqa&JuM-ajh z$cDffcnV3l0!!I+0+&%j*fSc8LySip`zl<2XcttuXK@WxQxVp4_6cAN-M1oEWiTVQ z3{4D%tLT?{qXV|7X!Op{$M>*IMP!Xn`S;!NzkcK}2_3Tk5 zIQ@AI#VZ%W*=8?s@j^JzPS(&jRsmwi;2gj>O@G7?`yQ``6qCf28kpT&CiF#^iFaDy*>#W?n|4W560`9|VS(m$xl_ucHNO zO%8V+pHwmYysPslOaZu%Gx|2u;!ZbuvP@^Ss}G!N_T=&-(+>h~oQi-b=DqMD4;z?fsDv zrbf-6&QFX4_7l-2y+4y1Mr}q_dVe8jM)e^7O3sd2i9X@|jpJ=FY6jYx*S4P+aM$6W%)J=V+$}|3ZOF8Bp|ZXH6>uivD33k-W9`6Vq6jB(pbS zh%51CaBW7z&&TuLOcfQcYrM*SqCXX_*PAWJxfuTe8+FNTs@lBr8HYWew$_V|2CezQ`&g61heqIrI+e^Le|N?4|xatljG+8~*#y&%9mDUqbM4 z`M2`)Up1gu%{a!f0=k>efiqU4AH;imnp}m;%49FeDwDmX!{wK)PuWlOf5zmL{X{F1 z%6_68GrY=vBL2d6MIqMM&8(sUCOIzNJJ@`TNxi~2hDcWVA1WO#EC0i!BgV@9Rr`sP z7~g5O@)722#uwwAWd6$dPGiFKPLVCa@SkKAgp}z-|I2Kv(sUxPG~(IZXPeI>P-?vC zoolv3bp9c1NVlut*YG6FGikBL<^PO*MOjYtbBQzW0&@kNC$?Z<7r4d3rgTy4SXx zm|n`dvMnd3%PwzQPE4<1UD=is(+^?b^lq2cjc3d;93vRJZLy3)z$n`d%ZZ_`blhd~ znm?|Ucc-}>Za?46@G8rR{;{m5-6rQ>m;ZUxkGIxx;&_(%9&-}H#BKB5Yd(&``917; zdnFtGN7)nhnOrf<<*z|A_A1MXey-l(y+0&P9{K!#vBn>egI&D5KJ-2)>oth<;Im&k z8q0~$t1KtViO{PoC;BI{sVd8f{=Gc)%5tK-&hkDYud_=0R~VbJoalG(6(X-PooEd| zFr5eu{HM(rl;uQ!b51LVW!0$ut}G||zhEJb$Wu1kU&4Z4wVcRm_PIEe$MWAh?=f>9 z>&fLkWB$N;k_8K$l_fK*9x6>IBI(%YINZExz6w3`p0`at@V16dWjWERuy;=Q6OIGtS9YZ1@{6rytT0!f^I7Pm400Xyv2Ua^jyneV>@E z5JOy|_iNLH+d4fL^n5GJiT?L_5|rh{gd1-jZ+MmEM5|9;lzlSR-18pY)-`*TECh6)FFYE6TQDnHqx=^FQ!r12Rpjbe_}F! znj@js#g#7SecN(k`VPe6{o5?$ayu*B>9TgN$QgBmJ3X3>@n7>#oTAO{^bxFF!!ZTX z>~^P@F`(%3lQ5>vC|SI~0@tDu*GrbRCXK53@@}IaWjS zXiPedsd}RwJNO02u-Noh%t}adJO$0Y3F+_h zOs6<%kc;Mt>5JGH1CFn7I$I^Cb87U~b8u$tn3&EN+r0H1uOb{RC$ep_Uc4dRM!|IA zx5yq#Xpa+|f>kJ2dxkG&W{m`onS}TR1Z*-MDRI!(rlfc(%z8;0`H4 z>_zsmhK@Ms#W}p0j(_0kU&TtxlI24$I>Yms?f42l?pWXQkvQ2=7a{Yleu8}|>Tgu4 zZ!Ou3nvL1hw~p+H>PPwd8n7$sL9|fc269yNv>CIEd|xFUF|ezS8uD$7MWpWTzHMCZ zEs7(bZ#(^ssN=$WIb1xLD+&5`o`)neY6!h|(K|cp3+VfHQyz?-cvHFI+r#WNj@rpV z;2z3LAfILU?q!}zqqv-pZ!hJ|qP`RBFNaeD-BTdCpUdny|H66oy;Ouale&p#FXJ+q zM8v-h)CqZ)X|K&7;m1_1CsztQetj|BgVfJ3HeIRZE*Pf_oI#ZnwdM{i1%}e zFyA%iUO1BddqRw^xw#*%RDY=n$F(LuQmF6$3=P%S!sNnlnf^Y^a!d1RID-Bq^l4@C z`-MD|pR4xyT;1d^tI+3~CV$t--|h03ACdT6kH}wsIO21?Eq~ARRK%WV>}|}8;H1wH zYcg*-l6ekc>KQH7=XPC!IH`_U`d7GNXco)=@NoHE^r`3KM*}hbkvymMU2J4N|8kx*%eY2ee@nLZ z4A;pJqD@5!m{XsN-&^=x%tq`z)XsEqCA-WAa5BuFPz-C~W3%cSh|C zXee;8oaVsn$%grhoFf?~hts?HtDN3j(#EnnI`yzxF{%2C-xR?ZH@ zHb|Vhf<-~@2Tntd7-dN#SU5su1xF!*L-1HCJ*1hz;2b5}qRBQW*@K$w3S>_q>`6;z zHfK##b}@onWc)>Ve55@3!o$sLZfwC!c)khG6mk1M;bv}PZ*lOS@HL^2fkxgXwuhZm z<*T1&RS50837W<38zFiSyR>%wEp*qQ$g(g-uo>hO?Y2a+XuXu|uqKPYt-ysMRM6!4viIQSOy1Edl7W^5yXQTPga zsL6Mman7-uRi7e?EM8kc$}4emK#^=w8M1G^37w*kSbgw5568dQ*}<}82jh9jImA%e z(w8qv7=_X7vAtv(6X78!a~vgT$(r#VzgP{PTU3hLAd_JFJ%WRY4K!Z^|MjNo8+b%z(9 zi?Pq6pXc7J)am9ap%F17a|)^^WGcLBH5HjE$P8J!K(vuzzRWrgZ&_jKsG>=O@eF# zWOHg|JZCLfbPP=_dhQIUu-&UuY!vpvNDK>C5X%?%%&HbyZP0Ld9{@4O*B9VfT0UW> zVgBgkqen;OfTr@Zs-K*E`sk<}E=SlZ#Ck!rb4JqB_W`e{JX8)hf=v-Qz3XR*8O}&? z=t)jEEo7Q~;04=n+2~Yq`e-35nAD4uEe% zX4Rl@d0iO+NLY9Ul{LfWc?kLFY5~?nR zyX*ZZoEhtC?S?NltCaI|aH9Ae2R>{o%Xp%0Wv}qL9!3Dzf@8Oclb*-n$H^X9zBqh>>m7P(mtdmDfN|{& z^qp;t5<8+I>2CIuJH(T~5W5lcjV@#qrm~+-ml?hl0nDn-jZk^f7{SaLG7HC<@cq2B zv)qo#VWqMc&vXsPnQ>H($SLEbQZ5Vd5wz7snTr=nR~VYl;LO=B4qr&Ls2~#wxtn1~ z>HtUp1iJ%dbs}+@wGl?{1jrgR6HB5afskC*d6Uc~Yu>Dy14V0U*d)`z#Tp;lnVVdE zXlD*IGEFW@UV1%TcX|Eba=p z&8o+8(IJX@vn}>RUfOWh6K?-Rh2|qYc+xw; zW4zexi8Pj#wLs}`UL9#(V+6-Rhn0Jm<>5rawT(QcyOFyb{=E?g>w(uOBdLK=r8j5U zy|OVtLq1zZq?Y&03sXsoi?+~-Q+!}sA37@36$2s_-#a7YHL+kvq{s$cFJFxJ;%bI%xLEnK4G)07Y{MMF*@k;v^$bpeYOR*eVCAkn)mC zw#?vEcySUe7mxZP=@b8_tfS&lz$UV+2#m5eX@b)^-zTLtkn}*|vSgQTV%?$+w3=ZP zhrCoAWS#0FtKb9VspSpoccL^dk{sd*H4r1qg1QZ&XtL#{*UH%NFq-5dOl`xHqsz!d z?i0Y)fJZ04Y>ki4|oC)LftS#na? zCm#ZvL#!#|0eP455rXDy<^=Sh3>xi$TaLv0O}5%xxaD0Xi}tq4yX^b&ioP*YW7E7) z>tkKzKNEtG)^k~WT&)G$L6J=|0Y$N8nEqumXryGUrpb`88FZ+Xu^C_>pAQeV-vPBA zMv&tXJHbRH!@Xv3BV-r=LqW6DRjNnNXbt4EHW$e3B<20l-GpA8}e81P=@#V{P49D`SyR)>ce^LNmiy zY57f+F9m*tQ+9;MLdfZ5l`F(8=cPqRFb>hl^xQ@eElTFTv6Qi!F!z|m z*yUG3xsC1NHVV2x#{O$u!*@K*8M3v)X*`A9ta`l|T|(ZW&XCW&>xA$m z{hY77&^Cgo26?9%jXd(qQPvSM*{zGk#Dqv@2IuT<%KvI~)0EaUu`eN#)r8MWmPjSu z#0MkrrD)StQ6)s2!5zV+dy?D@8zfR^3vPh0}Po^Nx?83VpNo4~L1^PlH6 zU)c?iyX7R`{v`-HOsWg%ApX-}NjscIBxe7awQ4>W|Dz~#)kn10z4IMqw9moa`?#a* zbL5%3_lTqHJbDKAIG5S+`glB1!rtk9#P@y(Ke72`-?=d=WA~M~%3ec0x%+N4%cjGd zdvwFNvICHD_jYr1nu#O#*rHBr;LY8Cv1}T$!QFeOqwFmdg}ZmDqwKRf_|OfzcZs7D z7d_x!XGGaO$bN`F(at($_aYp3Pl~I|^rNKMy^lJ|+M%wvdp9`BwxMRZd)GM1zCfeo z?mg`&y9a|ackgyb8I5Id_rB;Ti$XZ=-pP)Rbup%JFRMoVaQCiol%3$)Undyj3`f~@ zI3wKShq=l^ILF+5uei!SM`dyMKI1669;tBm{cM&U#0lc=?e8cHqomwD!<}XO(f_%7 zXF1Ba#y@xOZH}@VaaOr|%N=FqsB7-N(dW#vg~%3n?_o#TYseXQ-`!@}Z_#*+h~0O_ zEIWbgS?<2C%(7N-7;muq%3NjB(0sZ3Hkf5Cq08Mj##I)8EYP6(wdBZ7hdApiZ!9h> zNv-cf@-4;qyHe^^zZ!@PH4_`)#KF8R4>wC3DAvcc4pjF{i`?%Ny>dr-MfN?%(}e4* zX^A3pi|OK5z4%M6a?~zD&~l94MaZ`tV|EeHx2ZOE7h$mF7`KZs#&V3>g`?b1TB9F! zn8h7|1O0*cl^ZJ67>FG>-5BmnlYZb)lU>edYZ6jY8FOPGGO`^ zuWLJ@lTk}B*(+s>5Mp;!=VWnhVIB2}a7+6d%iYzb>i!DWwo6R4@ zCkqy)h&oLpjm#tB+NO~<=0-82X{2lMsu-I8r7d2|mahFvv%n6I7r!C={bIr>ZUTON zV$W8QY918dHI39apA(+q$T0W!h{7Z4KXFr<2o*=#nw!K^#qd2R-YbqQHeVJ)OOS)T z;^`7Ji}$0%jH<^|#kmWUVns}8B*}bG)Gv)(D_WOC>WFcrk!164F{d;#Ao?Lxj0+Zt z&%RqHNvuwv9xJ}3`abb*X`~pnQ`{_aZ8UR<9E)ccB?Ux9vq%H;ZLzyqq^tRd_^MfC zfO$!@xdvVDphtv09++Z2UVZ7B$fr)R)U~31^?zDMCOTs#PMtGr(%9LziKXk7mQ>%; zHu7<@IQZ4#hGOqCiwmpo=odNV6m?H5ju*${<6}f|0)Eas;ECV5yDCP!v0`Mr$b2Tn zwY6a{pD0P{5+laGDPqLOR4qvz79(~iLbf~GA0rOc&5RLsJab}1zxzEgqUQ8NFAP0-U+^8J}oydYMneM-Rf+B5ofd$mr@5 zgNH;uFFJ`1k&T@njk0rN^ffsC^iuN4V2tZhXNuVKn5UjtQZF;Ldi&7G3Wqp!4>EFF zw>+O1^77(j5kF?SOBAi|`u)j~^`==ODkn7y zR4=Iei}VtW>y2+%dTbN1CmP+17;)mi zeKW-73&rtUAAKNRbnggD#Qj-)=@pj@2@%DE4L>F< zZV~K>#!!5!A)Usp(mmX0CYHT5HA75oHYlbweVCOylnyx&W`fr$x9wl`f80mKf#(`z zbb42bF`^;Zc;mwVQTtoDhe`iwcpsb*S{swf5LcQF3V8Yf6Y;HBnYf&?EhB51(&F`S zBG!9atlYR9fqRxwS-rG8veF?Q|7!6K)#-C0pF5Atk34L~HHW`B6+hToiD`9jt}osX zMSNmfcXWu0{nq*7W?G*7HAjeporeWVXImo7*@k(W#he#Ro-}N@)WM&~66Ft!)_&A; zLqJ@VBWS=v`mZyj%&i z3;b_tD)ISGKj5psQq!%lSVp=EEX*a1lf~s#0jw;xw3#n%wdTJ_G<;}5K&uZCjl^pTK%&|hEG)o!>MEsJ*Zb5meic#itkrw+hi)9t7 zqRJ{>AQr#i515sr;o?Y+Sb6pa9}@g%ZR3EsUNrqAl|CPJ@dsq&adx7J%baG(4=g&G zYSn0doq-Iycy%}+j-_w%i3|OjQ_wJUb0AJ7U&4?}#Lj{v0r^RIPTHi9p7q?c+|3>jo2-C}L)lHW~RynS%gCUBIJGso#3Bb)Sr3c{1 z(bAR=*7#;|u_E$UQwF6fA2=r}W>hVdYN28;`>i3GMk48*`A#XLWJ{Otm#WsziTKpD4Ud)Ljl&x#-HnOfh$PWGuSEJIf#WdZ??SN(-sTg<~}es=B`n4R6LS zL$4AYR-*;15&vBsDNa*eb}l2qNuw4Sm6p8*k*Kb-N_nT^NcJukW8jVRP_ZU*ySY~U zN!L2ja4in2Md!6>BkM)^+DO3&&J4+otkc5SlY3b;N%n5Q54O74ZJmZ>=&&ZqUe)jO zl$^CkM)Ub?EgHrK(P3SrZJsJe7i#sk>X__R!w`yQ&`!?~v1eT*IZqX9n9^n=AbZu| zG)8Gp5@wTK$tdMd>rkLdk-c6fc3Y;frHI;q z3*HT)^M*)Hb5)cAD&u~GMIn2q;Rjns?8$}JElGEq#r6%6;<{(x%%rHFReNNdqmK}4 zyvlSldLwjCkx+?;wyK>Y87X}p#{r60;K<7iMi#HwJ{6;s4m<5lN{7`$_Nq#rrQ|Fu z*~=D>jXjw;U}j}UVgl>|OR#%Yov#5?o{1ybs|MH2l&iqI$@P!;$RW zES}wnX0SngzcJFb$5u;Ao>^3L44m@Jsv48$26BcbdxfRn0f%JB<8dT=D@FOHNEosH zwh37%7wMZZ6R#Y$4cFwGad){^EZ7YBMzM1RgJF&AC46ZlHw zzch}nb5$o<<1CGv)(Urp%vN@rD@z)<7+hTsBv$NM`(PD#^#wW%3 zYx4tmd|a2u7qICEH zoSkHi#-}xw@6ENrzi8aP(ma0A*nv6Dj;N8w*J#{H^EJLR8R^>zY|%XK z)mZ-Lqe^yMlb_c31C1|eEX|47CnDu)TD0se(`EUyYzMel+dK0xEKe3RdfbgIVE(1Qy6vL^pR<9OTx*%knSKJfxum z6_K=Cp!ji3=Si}g9T%?&f|C?Wy9G-BT}}UcatllUXH5<>1Y(D;hbQDrzgiMMSt&~+ z_9}8|YCv&wO<&ro$KN*G${0Po2vhhfA2Hr9OF2{Va6H9xXg^(jKR!c7`Kf3ko!H6OOzCq zP>BvTXHKCqT`X!6MIu5G6*c;lRJ!OQ3eidh@Sj4bS|jL~ zOxG3ML~t9j$wWJS#Jh=TG(8N@5F8V{O7K>)N$hztrf*&^f|CuuE_9BOO~R*)ynq3I z5=#2~ccb*5kn8i`jl7ncc_r2_9UE7rIZE*Lg6|Z(mTdC-6d4mJugzf2%Di?7o!12) zBfEKbPU-( z$E6~`P_jvQs^IxTe=!+DAg>tMJ;i;w&{-{Xb_)5PCP?2sQlx@`F@o^=PAL6KHYNL0 z$ZO&ekSpiG!)}Q)$tIref+q-G;4;g94;{vg50cT@d94Jyhmb!Zbo7btCPU8&`60o_ z$VTUske?Cq^We&*uhpz7;p&3x2yQO87ujTb0J*V~>A_(46!Xi3&eekFRdLi>NJqL8 zcriHH@Uki;OOZ`!%7uJ`kZ%_97X`mAblxJH_)lnd+Mo50@JMZ5rKHbq7;gM|Ei>Ih= z!nMdI(i9=j6r4vkVT%Qi7d%gJoU99m^507b66bY4IN7j1$K90vDe9O^Y^e;4_jiPR zuaLhj_^{CVjBMiniOd%`c_n05c{C85C%BW~L4qd>o-4SN>^49$KD^5CooqN-P7kBB zN$^gxDe;R!euRtB)wB3Z3X6I*f6K3y%pxK1IlH z5PZAfWr7vi#91!n8-#qbBX?F5yM)Ic)vcnWNi%(bxyf)He7gl{F1Wjz`BESJGf{|E z3Em=jpWqW@W24jL){c$NfRhdXA#~{P7ROIEVW|st#@%$`(NYA+74l9(ehC>LUc&`n zD|m_EHDr_UCUP4m>@%&AezI}AAe8<`HkI&!;7^3kDIx!cY~uM#a81Zuc?-c^T&|9c z^r54(`uu2_FKP{?!|4syNN}>@iCW3Y_6)Mg-StAgQ1DX0>xBMBA>SwD`^mXZbyz30 z!%6H{!HLL>o4GcEiv`aTyjbvqf_Dghk8JAZ(XV<=d!8HZf5nNwz zBf-t{Yg9$lQa$u~$%yDE;eVOn$%3Z|o+^I}7cHgvX#|ged@Ku6m2%ar?p5WUZuA^Jw9l~RYn*9E<)LjSOC>dHU zX|)%*Gxtc3m_I*u z^*gGv6Jt{&y@lvf!9&!{HFZ+`B(*Fd%E%-gb{1LCK|ApF~GrCDWf5+>JY=0Fe39cCykgGp~Oh`Hl9q~6JVJvH*V5Pd25dzEo!ajM6v zre^u_!gw>a;m;YVYWgn=^6Wyj_piLv{=KRpGPC&aCz!u2b>$NTPZNBN;2W?}KVGWC z@v8Xh&!3#StM&&3KP-5)VEz!)T|Dm){E`|p;?~p%e;4X{b7NnZkEz;!E zdSNZZ>tVGpJ(?PQN{G1Qxa<9#;Jt$RgA!NgfZ&6I`J+Nt=L^B#2|nwvO8%iw?dS#J z!CxS{folln!+clHt+-w0FBDzQ5!_C2N5T9Np1V{V;IMk&a7n{v6NSf>f@cUu7dVV6 zTcFN&zB9F1T=?)Odv3Ik3SOsX9)BQJ9m^aOOnODWXr5sHOwoPhYXxryPJ%=F<$=#5uw{$h9`k>>%fcW ziMqEOi8Xiqe5#~TLX^Mis0kC*30W53fv#tm?=EK=?h0;YxG%V)VeXf8iDAC;+}|)? zuO4KW?>SE*o9f`aPlj=<>-;bk9e8!Znr%GzVEY!sT&?ow2Gq#{ml$pdzSl7O#VW&C z!&_?%7l5BMTnOH5xEuIc!+lv*dyHc+Jl-%o6#TYf-V>c5n@04NVV2-~!(lMbo1jiQ z_;z=a5b7%{QC?Ie)!Kc`a}^ z!|C8+!)#MS47UJ}GR#awFE@_fa7;E_48GRzNbo$v)4&T2&jj;e5GH&Bm`fY-d@z?b zu}UUtG9L=541t+Wy1{fn&JB3w+yqZy>FPk=&)h7k7I^Afxj?J zi=H;jg8gWC6!_O_sDI{eEF2e%$8>OwM95jGxOgN7nYm6i%#1cPj8`)(Y*VLon4xUL zY?!%*`3QqcDaJDZ+?UKjhBM1R<6r{A4KsnUhS>|QFq{RRYB(Rv9UBS{zA!A?$3DYF z;5Q6Mi{W_NI7Wj{kXc+@Um3;#W}P-nGyY9Z2jH^Nf63ITVHjQCs%x0NBh7FIIKyxY zaEk!P|8(q11P2$0+i(a*hF;46`?F zBXhSkR>AYeV*q%MVGg~o8lD6`V3?&mXm|nmb28?9USAt#8~VYp56pEbb?{|zT}sB9 z!HV)E5dO!L7Z;sm2IiTXWcG+m!z?||*QA_dMk~WCeRnb|6;~g_Y!jCnW}6shm_2KZ z!%_XC(Fw+*9XzfyOmkghxCnf`;ep_}hDU>MGdu~r*f1@`Wh^tqcCeD14ZyY9FspT4 z4b(q9I2>*=9_iq1hS?OJH_Uq7W0>{#s^KE=0mH1acMVShbCJvVXMwrMCEo!4ft&+C z`W9EPbkOYo8OE}}@}Yt#XG5!Dm?LW~!&%@=aw`C?EW`M++8Aco_J%PGSe*^G1Q&s$ z49wxSukq*#9%z_D?{LGHg2x&j0=~lVaPU;aEd30_6Tv+Egz;Yko@e+*@B+iPvix@# z2m9zH>KM7uA_!;n%hMxy-HvA%(huJagYvBKpTLW;tsTuaK z4##`OBL)1i;dJn4hMRy-8Agp*-x|IIeAX~$zh4Z~5`P$GBMo5bU5Aqeu8?6?cQ|Ss z>?#cm*9K=AX2Z-f%<;dCVRkwGa)goQfjb*!^%WT|2KO~Q5In%}VDJPo?hDxdES}~@ z2il%>jbSD>$1r=r?S?s2#0(>dwbXE1aGBv=V4my3IGKq@4YLhBVVKt1n1uAH#KyAK zcw7(OX&4Q}ddYAJc%R`i@EeBNKHf204*t;aTJTZBY%8A|ehU1x;Z1D%-xLhL34hjV_klsqX%vPg8Z-@dqZUqpv@ir$+sQ1Sda&7&iV> zQqKQf@d~N4M@v%Gg%b~CH#2!3iz;^iqcm0U4dk{ef2`d`P5P!&q3?!G7P{$Bw>~qAD^ALcYSy_*JJmPw#C%wZiZGclN>| zzsK68sLk(|hJ172U95We7&_K3q}KdU?p00ucWLU|qXU*{A3KJ47fnRKUzen)p~s6t zz6W;C@s6R0_wquoO1~_UqTU}mJ><*U!g%xj@D4tIYe?NN9^NXg?ZmMpicY_3kKG-p*o?5WN6Y|x2hL+ezpX=a* z4LR~JFHBXFhEK2Uh1Yeeb|Sp?(CdII`?+T7igSps0$wB4WO@a?h;LFW7=Pe^ds5W7 zrgO{8r#cM*I-doiQ$W)=XMm-gJW_8H3ZL9i*T7_!gyWv!|vh^#W zq|i2JoVge6DqAgXo112%BHGkVRcn468%ipIH#;A_bJV`Yozw6rQ-?m8ml;YrCPKGX zc4B?(PSN@muUgl-Zi-rzS1*(l+>YX!2y)fpJ8GxdYgE|_y;9Yp+BoF5c)ObCM7(uQ1%OIUj8ROq}vYN8zN>v`=8RaOguy4FBG)7{gDY3+`p_x{-bjlAt>$fHj?yTzVSLq^<}5 z-p1S$)V|yLr}^q(q{F|iAMc%_9!iSUQWYIh%pLZ5#s)A-4mJI!ibRP*?*aJk{y}_obA_2%U&!O^ND}!qn+5tce>{C)Dmg$HL(7$GgGw?;3*tUGRU&@vnDoa>&#E zbu}-9)Oy##^zX=94NOF?_OsOabrEjhzFR}Sq3}0W$?IGXrO^J1>EEh0;++KlR!;cS z_l^sB&h5wcb13;Tbx-YB3(wFu)bnuquEV-^g*sI`*2FjUUEE@+>UCmGJf1$PO&$2I zD#lYWRd&2S#=JU+^s7HD>!ex?72jH{s1nuMb!eS?;N^KONxjP;8}Ufsf||TPCq*SC z$7*@jgjAzs$k$@k)j%!&w-4s4WJGmCvW-KsZ%js1d#B<-gF64#|IokS<$0n+z04pd zO1MvnbFMangk$V9+P$t@ZpasEW?Q}0+Iloe3jBYB{{l5R1>JgNbK6>gcERCqsam}B znFd}gQMRi?pEqxk)Zk$(LeUTIgXcJ9FB{sx`vjY*T{qUO@|5lKv+s!{bZpmF-PrrS z7WVF4H`a~amFy|4t^Ur6HE1!vmV5Sf&|BIO@f^Zh2o;p`_~TO+!$yg?yA98%p)Sde zT^A0f1rxUMK$YEH9cfd+UPv^KKaXz|f&{%Dv0J4%R%LaG-3j z-_1(Hb9iOGRm<3GNuD|$)#$MiVU<`IE4Mf7T3;CZz++e6bxW7n*VUr2FVQRgOYoE} zP+Eb!TmD`U1mZh^9{*I_7zXYlCs+y3W33gqoA<&#JFqMP7WD@_5a|mHziLJp8|^2LA_YLf&|aC!n~(Nspdp467bN)alO?A7Osdb$-e#5GsQ^5e6P5 zS_vDOgVk*i(B}<2zMLswY_bAR1mI!$ulIr1RRBF!!Yd&-*7LqJvtD51`%DZC)(UJo zgKVZVj=k31`fZW)L7lWtIU0CJ zB>nE&I_ZRmndSE;Au(Ti;G=FB>zqVC7Kt7fiGCsyJt7i4DiZy)D$&4am1*J$^RcBc zO~^`UgbD~8|A>jE1Wv7DqGyqvz!y%UJRUpnCHGVH`kT|>U#*9!6aA<`EATZl9`pxc zrocB9;E?|U#?rvIWE?wsXKgr67b8wzR^UgTt?B2#=K?=P$(DaKo4`4?46nZp3vZ4c z<%5~P&y1vjzm&E43%QYhVi^1@Io&^vI=_+e9~sux@9!Xnrv4?A|8WZPW~fY-Cn1Fm z^ujt|t@Z(rJ(tIUh6`D+1e=LlVV+YT@Y?)WI?l#qY(AUO<%M;0=Gf8j92Tzf*wM?_ zY7_025Y|cz)U;m#gs)**wd{QeY$3OBgzO4@dBeKXno~!kVV*@5s62LbATyn8FJ@GE zfyQ<>H1n{Brb;(ay~C)?v7_OCQItTY%>x$`!`u-x(8Ol7q=$76ZmLsk>ZE8+9S!ee z-p#3_;b;?tn96Q>?LIVCk2YU&#^9ya%QAcfsdG2_iP&+)~ z1u$EnlT%D9kjqN#Y;(haCVddu&_GxFYet~^Za2-azZaswCEDc;-+)dT=x+B!-%kv0 zWkN+ZtFF+of7P+0D;TOHn?z5WTq_vpZD%3HaN}wa_R(yGdEXr9s~z5OBCDk8)X^Uh zEE-r%`xo1Pz|n;NGlImia+NMT&o+M6@H%9zTPBtknN}PfYW1a zoOA3c2vav?2jUgY({L*L>izcjC|ybT7OFj< z!+aItKO_R~0jH6EG}S|PbSEgk7>(T;g8tK*4SODq5XTqkI}Z3C!B6#nIE_P z2vloj;0b#eYB5|wQ?Ao&h1*bLy*&mV-f)oiGAEpd&$GriI0u}D^<4Ut9#%u)OBlu+ zaOw<(=77^^IGx!wC!B_PxNX3ka2o!UZP1)>8Xn7BKBEiJCR|G6ZMB=hym{gKShePa z)9^BsDPRsbbw)aKz-c(h251gA4S&IbV+Txw*~<(q=7iJml`QM?y3Xc=x6n~_!YR!h z^kUku0#`8GFW9|kCvV_=`ySc}Ik5tVjFokjRvvJA8*TofeGSymc|Nw^qW%&dhZ#6* z0%(hUq8*;_2->ppgws-H{;0i*p;H5&+3euX^mI%&V=H_uOLSa262lvq4|Bk&GbU9Y zaLOZ^11IgnjHyoGbku%~QR(_IC!9I~%n7GqzUmh+C!B_OCQ87ZaO(8Qv${_P!tb-L zoD)uKgkNG_%mJrP{r;>=Rnw{8U$i4+1>R2J`17lsjx5x*k^{fn-@$|-o^TrYL$ehr zW4F7Y`(Tkb;$esS%l;E;y}c2=#Q0msR^p4?$3}5c8}=?=M9G1N7wiwqZrWkoPlS0V&r)a4jxYgo_UFpGB!J}hjZ$-#7H44-KSkU z5+nSlaKP`$hUV_X$RPIFYMxGTjSWPyY34+1AcWiB+7ZQY?g6Kf7Bs0j;51rWzvLQ7 z_FM+lb+segS<~(br;)a7f2p2pkbEKjhs@zE&BIB!s7~Z4qiNu|2I2bRgj2Rn+C>iw zIN%hU?OH6MJ4|r4W1(C(XOHYuv_DtCX3gBYZtfMr{A)K(IAsfGCbb(UoU-9CaaW&h z^42PMpewE1NT2aq%M(cVl*2E~$0UKu15Q8T9-DzoPfQgLjWufdX#{IEuAA&NL|)Cf zTCvxB2jlLdGll`eUVBn49~zq#od%_>PUu+n!KV=Uy->>HS()}b-@xZ}I9u{RJpbZP z)+`46;3VWKT zbjG^&n<~xLe3j=zb>Fa9s_z&Av{6qFi{%VEO?)2_{{qN)4Lbh#daDuFNXU=1lpqp508bT>F|1At8>$NtIbS! z=Rk(RiVMh~w*!n6^qzrA?p(B`yl>Hu?DhDAC;#}^<&D$ue`XHzkaEbkhqvXr0j>)8 zw}ocA2a!>@c?U28?)G|%`VI8I)S5#94y$@fd+(+Tr#d~QPjEX8SAie(Zf{KBYPd1- zQosSn-lQY%26ql}W_3W0H>x%x@Dzf0NR1};1fEm3kBHT;I~eFqb4)cGru!Iy#^E*I zSX%UZ51R-tzOsc=(Hijo$84lB9Z*LXl-!6LGg%uU7jC2)U-#oW98dFcxuA6 zfx2lJ6znsO?&x;k(=v|hIJ3|Da{EV}=0&=PcW0~p$y0$?(trhAA{sZ(mM!2-ig8bc zyS+B z>urdK^>&eNUGAZ}+-WFszRt{0otQl;UuR{Q;~MSM>M)%&x5Urq!p|P&;oXp@%!(H1 z{x?GBVgkGhzM!2(>bM_*n;9SJX1qZE17(zlncPX`2{hAa&k(r3qx%J#ag2xS+z>{u zf&`XntTuWs+-)`@^4X~5oCQdp?c2^(dq&050=GlhdNH(@s8ge2$Mc|NNY$kTLDo z)n%h&ZKHqa1lsEahBR^$_`@X7NjL1jeDtwL@c+uz<19c1U<)80@>V!>?WXEZCw>94 zK3b-aKWft!dhGq^oqPt<;W!Fr*YTf%gjXv}kSN$|2;tOn9X|_p9rE68B%4?re+AU; zp)o(AF;jHVH&`}ysZl7`b2>SF98T*j$ap%1E-SdhC8!pAU1cNN0K41e>l!0^U6<=T zQC8-^h%aBax^=qM*(2KNzO+vFkH+ZRP8(bQf7+OFjdt452A#+y(A5KlZZk{i(p|wh z+Gz}`seto{y~)EHnMbOl{GA?V9-sE`Uc^&&MdypiH}YgXfLyk}X2!Laz27qh?)?aC zwH}5Nyaprd5+X$27>1q<+u{aPmyX*xIIU!|8S3(NhncKLD|>`9@J&vrK!~ra!~RYm znXHGl2I$95@4r&3cY&Mbxl;S`CF@SQw@uZ-ad2EG-Q8U0_)g1FEZcQnQJ{@FO^=Iv z8MU_hRS7iuFLY1HVi&qPfnCUtRfN-prYEoqb%Z;I4U>a6{sD7Ytd*X6j;M*3#WF^+ z(fpiFOYl(GRyY*4>n+f^TP_X(OksQ12T@dY_(3yV3>J2%uV>q(=S^OhSFg5 z(Pgpb!A_Z&iS?k9J52e<#jfyiZu(MPGcK0tdmrdg%g4p)``C*z)z)#bG<&dmdmKWp zt_(SRnEGd2td;$#YI%9ARrHNYk2!4Mc^G}IOKw23v+n?5V{lM;*CzNkm`?W&r+f4N z{kk-5S^|zDy)P+rlPm91u77OPo(KC=H4Y%^2+H9nT+ z`y2R-sy`vtHNs}|suPB*jGVuq$!2p_T|Xh#yces`hSi)FgmIJ&2Ht6vGN)BxAcPOK zb1QwU)`gJ$tBy>FWh5PK4rA$R&a~0Ku80ju=eo@vQ}7y6w42*B&{3>wa_Ylftt;M! zRCBM0HTFG&MPN{^x&qlwhBQyT0BN)_kb5<_`MLvvav&QkWDi5eg~n}_GUOG;#L2+y zI9v&?H^J_!RIze)L&hRLA!J7&qg4(VnHn=O7O~$@H%^Q-OiIgki*_Z7_Q=H8r=2NU zjZR(=MSr(v*%@$iPr#OJ$!)Vxeb>@ssm%xep0bHKgCOS^mZ7#ziq&sSLz<#lZD3Hn z@XJ|daxp`lo)l{t?TGT`aB0jg8Aqh7ia9l`oEvC%$R5!$y$)`3D`a{STLNIu+2sU4 z&&gQ@QBOq14Gmm_J_8wtgdZwpjGY6=cs;!Aw#ULu2=rg2g4Oyo0*yo5RMn%C-H!7l zhA2#he6keuj>g{}ebIpJ&!CLw$f$N4m!9Kx%+FxL?>kAv`Fv1YEgGFCUjRTbW<092bkg;o}t0h;)I#+)bPL4Q()H_$k znzmjKCu?Og%F1%gMS?paV_nZRGA@8aut*2hXlg7w%4Z>X4+%RI!tZ?)3qNGLmbJDW{eF{;Y$ZME46Rjv?o-U3_&_(?6A7EASWkV|W=e!M!C zS=~am7)MuiU|Ot!kDHj!Qr}IBwbsMh9k3V;JqMADf+jog29C98{V;Pv+2$zfR~@_>)y0~;PMy6P zZ$ofyx>rS}#~SMO#WSkQbd2}6p)S5smrsx7>-xOl#H9!B2s;S^HCF4V$1-(&c0v_7 zqZjM*X4Gd9l$`pUhQ??Q^&(T&2~@IO{xa6+PJIsba@lb=GTm;uqs5lD3GRG7_Yd_} zz-^Co)|11$^tDGhbv;b`y&b7sPY%=PIw#bJ1?wh4Z-lq6k3Hw&{DOCMEZ(>A)eZj6 z`gxRBuM4QJ*8!t-^a*8u&UY;Cy8oKb`WdZbU(L|^*L!2UT(%skkF#K$d+)J2KcO@X z=X$x|xUJ57(ug_Ux;GyQ4aOvEKj`JZk`v1Qo}cqLJUR6&RDl_>w6L6da(E}hQE;p3 zG6OZnzV^NvPh^e#tQO8djm1$-_0(fCVj0aiv=$;zRXsS1RCYlw5FUW)MD_IyEGaop z+^vGw#+vzAkvs50$i!G!4Z1c~E9z9*qo^-?v#zvF=!$mvOy+pH_CS(;mEo3-6W z(yc3Pvo^$By7g_q7VXb1A)SibqWzzzzwV@4v}L(hJnIGf6>ZfO)13l6g>Un63cs6f zeJiuw%UhXO=w8jq>{;zT4YyPA&;7qDeuu93_NXqWqIa5#{>xOf>;9V+9kqAr{FFf5 zsp;o+O>>_`r=oZ1{MW4Cif{$QR%Z{KHW4QQ!Qu38V=@jw&#ovpR-Lz`h1x7hL-7}A%}0Cvtgfh z^w>i&YUp)BLSPc+_ij*Na}TSBX2r5~YwfQ7H!IduXZIR)W>&13X{Uv>@N)EX{9XlZ z+%A8kqq~|}Zf-N2!DG2z<-0edWxfi8_!>5M+F+Sp=Vzy*PIMc7K>JUDn|=R5?YojL zJcN5t$8^clRMxY|L;4QJgKq2$EGu-C^`Kj~SLI`ST?}{5!xkpYCR~=hdp%6fneA5f z7m&!qrJ&Vy7I=EA!)6(1ehcT|&Xaf2k=P@*% zYmf;vz=YXHAnXm_QE1o;9ieA7WYZyIqfwPIP6=55wJw3rI8}6GEIea`E*5WS?DES{ z)6V0A5&x%HBTTWJQDdaP0>QHpu~TCs{k-iPz^v7Q2k(QEJGp(s${7tA+x8`@;zqn| z#Wn6!ReN@;q#a!bY}RtwA<$RoQ4mFxx?DoLuTgL@lw*FCYuNpHgN9;>XF z-v`x>dt&_<=AV0FMIH6CIcp@pHsO=`7xW!IHkV?8`LwPyYH*jM(`YRR*)h4x3g5}%8$Z8~``0-}pq zystvdX=b5$q2etvDh{T`3!h+qQ%+l;*0r0~<3%|c%~r>A5Zqh+@yE{GU7e1^PSkYH z=$pT5L)%@`zl~*8qoMBqF*Yv4-mA{mDs9pF76eGSgi$#)my+%zw3~7;Bi!$@>Jciv z59eMU3Y9j&ag)D=O1s!wRDSK!OQZ9Q4hyBoh!Z2S<{H-na6M+^m|Zp37_G(DRwKtK zr@6)qM_xgBx|9C@44;J8al^dByy$Rai;jPV2iHr?1Sjc$XIITSrGp!HYY)4+zp3vb zc(CBh1@lRlt3MAv{|KZ;R|?U3!Ose=5d5*=F9iQ2_@dzI=&Ej#VZlutj-oiQtnj!* z@BqQ11z#!n2Ehvj>vK_Zb@Y}J@^yl@*FySk?p_uiZwo#mnB%OgZ=U0rY>@v$g%5{LJ2)O6+epK+Yg84?MoA5!wM+Kh+M_nZk#$}fq2+kJVL2xg@ zV+3C(_*TKCf*-8nsI{reVeJz9n&3l%PYC`&@CCs>4r;kh-E)%zmm3Rir5Uq5uTH`P z|KP6-FhbRycXw)ZrVz~+92fkc;Kv1T6a2E^gM$AS9Ks~(=C`549dsUB3Xej;g9MKg ze6{LPoRJz`EJXJTenjw7f_DmjRq%U)j|u)x@b7{XQgk`g6QRV~(T0x0DTm;Wf_n?T zLa=`5V=8lzkl!mRC!H?KpXxfm%>=g-+(YmX!4m{uEBIEy zalsD>ega%M%4`=Nd=lweg-bz~^`R}MF6XCK$@TdvM*gUf^O>F-_60K5t-SVvlO2v) z2ZYiGWUTsmeIn$ig!~&JKPTih>Q#jekxho`3wgHS4w{|zXLS()^nolU69a^N47s(F zxk*AkgKYG#7jk`0i;>?h!p4P8Sx^LCp&DL`jrm`u$XMz_!QTr0PjD`7YFzz7!94_z z5`2|leY}fF>v2c!SY)qIIwbgKva#%+WZcs5`UjkBII(_}P6pW+p}COf3waO0L-dI! zCcp&YF+~KPDde+-e4&uvK{grUaV#!>Ao#psUz*Wj`Smd>rj$AKz}*Y4TyV1C&XgOS zK4g>W0YW}j@Ku6u6#DaoyaZg?BkvPR4+^EngnXTlZx!+#LjH=7zb54G3Hj$$9JS8V zVM1xjQZS|sFiFS`rsI& zqz{fUTo(_IY@^dia9hEB1?zKTOxVekV?D@g8aUbT4U}sgl>at5OlcNXdf-unkS`bV zM}&M0*+jZSus&$UWP*=%Z7e5veFRQ6{5j?0jnemYm`wacHu8T2CpNCqNg^AaG{M<| z+pDCK<*Cu(BG?$=Jw?c`7V>#ylgIgB=Jz7Bg8XI#suWeu)2BY4) zZeJj3{NEJ1Uyx0azZLSIh5Qd8_oP?phXmIpoA{dwZYMa}Q#b~ZO~S*4e1ecq5%QTr zK3m8a3i%ymQ}E{mA9Xlt@%qJaXs(t~6`+;iUSw06L1fImyoQ034UZQ(SCLI&t`+i_ z;QKO=zN@ra1b9LyJtKIx(BYF{Hxpk8PROj1Hxb;KYzokujJaA5GsSSYN9T+XN)yPY z1XG0kIw8MN$Zr$!MMAzr$nO*KRp6+bz+=K=BN>x2uPtC6^2Teo(0P??GIv18-z8(_ z;`IU8J&xzN(D}YfM_qmWzNF~IDuLx|QWb$dx5q@5A>`f2t|`eF{CO3F-6M8J2%X7- zuOpj`-{{DlMz}zDEEWNl33<8TwL)jJkZ%|AJwm=u$PWtnA$`t|Da|qAaY_U@C%Agk zs?w*BO=%)Ro<%lR87z2~;H@sR{Qq+u;2#BhnpH*AKyaSm9%NI1fna2A zmFElYBlt4G3j{A0yiV|&fr13U5>YS7+g zsnK*H${`!oPJ%BHI-`aBav{G;$gdUhc|xua<}t~aI&!BYEfoP)hyeQZ9uwe6A%9xv zKQH7j3Hg2@e_O~83;Aa)kiKh>Z-mDWWOK{-s|cKs1-UV}KC#DeJ0b5X_*%hp1mEQ{ z%U|v~!0QF;(|Ak*2Zj8MU@N;SLs?{Ftz2?CBE;1WoSd%Fx>*SnkG>jmE__$k4!3O-0S<@=C~#RD%MgOhCd3!!tC zoa5NW`dN7V<9O)6No}-}W^UBxCeTpGGle`~a95$zL&ygT`LH&q8#mHPLP;N$V@h+o zkl!PCrHJTJA%9B9cMI0X=9rp$+tp{=_{?>He-Qk;2>iE@`;jrX3Dh7P^Y#!tQ}BI) zw+j9m9CZW#DLm5isv^}#;+O<_Qw}{|my)sk;WY%z0~~pc6FSq#ro=OZd~TIIYRwlO zcL`owrDQ!RW`Bk}2A)6967V@S-o-5?- zg}evZSfvk`7UHXOgN4o&QK59Z;QIt`6MRVUFM=a&s}k!Zc#_~Hf_EC$<$r|^Q_B5h ztTcJO1$GbZ`&j6lB%3PuTFB1{`ENpQwX4$ikxg2mc9xp>;PSfBW-{DhEyDda!4L;9{c ze-R%4iU0}itISrDY|Ni5jLg*9-E)qI@j9iz0sPGs? zHW`{B_;$f71wTVJCEH2H?F6qE!0y?cuL+$G1piQoMTlF1bHd|qvMHI>sVdSG!QBN< z6TDRLcEO(rK3~Zwf9=jy33L=Zj%-RcTksOWD+E6!c(dT=1n(03GTD9H`Ks`EQ}8>2 zKN5UI@NvPX1b-*^tl(b-M=uD+e}WUbRFys;xTfH`f+K=61UD1hN^qXTPXFsDJh}+( zCAgp9A%aH;zFhD`!B-2uR`5+-kiJ{THw%xb;5!8`6?~syCHN7+PYB*1_!*a3{%2hW z_(j1l3w~Yjn}QDs{#fv*f=>wkTJU$^${XZ!!sA!L7X|ZGGS^y(f`fun1lJRsF1TqG zN3B*>4l7S^q2R89dkO9*c!=N;f-e_5QSjB8o%Uy4D?Dxze6!#Mf)@$COYkzm4+>r> zc#Yt7yLwz!dgbsaUqakp6K{H^J8wlEG|ZoxePEbxMIJHCpPTVrI_mR9#nXoQhUAZi z`BvnghWQesRm;&o3FfX|3~OQeky^{z)ns#N^$ct!+WMW+A=vkFA-_(lcldQiHGH>p zh$rg{HS68d!S+D47f$SuoAe&O)~E^m+O4+W%M<)k{rettx~f6%Lt3I9<<~iNmS59V zw?okJey#331f9+5IGj*z{Qpg7^N$fvdo}lCC>>O<ERuSnKQfRO_RrZESDeCB=XKUFj)ij7bp>%ccXNY60 z+6gDheVkv*l@Yyy6=q@kzFf3 zFMTWD{&m;n+VNtq{e#+6H{Jo8cb=*nUzpf+W>FGe_O4$IFAdK+!w%qos{#1>3Sf$V zF)A~713B#Hn{~k($@TpE&^3ay)x(YA4Wl>x6~r%jr+R`nzl^9dv$5g}-om4aGRHIY zt^A>RW`sCDM(JB<48hx8C0g(bE-3T?eMmbPW$aD3D@$+@G4ordvzUiuS_$0MGkC{% z1o3%;vET9SXP{`Xl&Y3L-w%JY>FAt#V0Y6|zGD--`%MJMnBoblj_B@A%BytBU73kT z7@w1gaz^K5;!&cNa0}88uC@^lDL;NCzWvS7{(?_%o0X{LKa~N;I_hH6&|g#GSl<&$ zP3r|WKEcGab@is9ng6huPcw?lhgr7GAENd$*E7tPxw@Du>w}+}1&xHKX(_X3Xz+zh z==*2F!!7oKA_xgL_Mk%=G83ar8cSU;%?kz{=0{$h8?&Xy%f#2faSJvTg zk~Uqif_bj#)c!s)_Y7s06VAgCeDwvOFC}=Ygh}^iZoY7mu1%AE$=`!`qyF(>IKKK0 ztsv2VE0xSvn#0q<-&7!`kpEZs2EQd^E6pZ|Hh8)nBK2hjfAoeBc@JjoC!*!Qjg@D1 z(tL^S=KR|b*Ym$z1N<}NXyCsY%_sN^Ioim-JROc-=}7l;;12#q&h%$A1OGlBc4+FK z&xrmw1v$6UWPuX++IH~5eZX4ngC2Vl5|8Yu4Vl?VGx7@K^4fo*;iW`$WImg*lV)@v>S!?{3e0T^jh;5SRxsGxPR4*0;c->LKAI6b z@)+!^9p1Ux1qpMv+6oOYOysMrU%MW|PT5+To2vm$S@f zE6qq2vuw7~baH97(u};A0H3O@G@BvTfZpw4xJ|AV3XZZ5F{yEE{-ZUU?2pk7uao_; z+L7pFA3JGsamKAQ`OF_523DjVC2^7_-l5#jPN|>pxNaz5~R@=+3k^yl*py5M6=6ffNKanjIVYoes0hWu!Hms@df-QjIpc-@Xy0 zD~ZJE^MDTXRT_UP5p;LCOuL#5=plP23gNTUbjNo$xlFqSJs}!&cezYE#)7WW=H@P! z94Z*SySp3*g2k>IyIfw+{`Iik9JN!c5cA8+H1w%-2+b~+kvmv3YwXc5omcPb7p&am z@)3?9k7Lh9)PJp&!6)n^utDT!8e*MhE3$^>UvHm)%p3WQ<~O@sMrN=tnO!a;dUi6q zTt-SV;bV5WbjGPoG_ut^qL&3`lgo%+7dV?-Mq5VG*tE?qmyrX^v)Sb`!e5aDx7x45 z5_yqaX3p$#8M%h7-0X7c3_@m?%ZQgP!0d7vd6P5a4s9CK>&+&YkwYxq^Y%VI9GnyR zo2l;7we%pz1DG=C<%k~OD+j?B^qz{fyup|3YM8AeTN!wdW-5M#oCO|X_V(K6@CC*9 z?QT@mL$%os)9KHZ+hHzehx*WtMxcjo_OU&m0rW^~w!?Hx`-wK7Cz8h+tK1H=0SDBh zc7Fy=4Sr_7#=v@xIi}mY6*~-Cf~plK{#%Q$wo}O=CA-@ z=Kn|LuE6-Bd$3iCkal?{%G2svjBEA*B08znx+M)U9-mtDY>DjKZ!+rk^en)iPWT)~ zK3d($fbX<}A2ZjwC;qSiufwm6-stbp8(8gNpTFF(5N9BZ&!~TM;yKZlx`cWQJS#U3 zegzPGk69?I}frV$o@65*)a5C$SySjY2PfgC~dW@EPRiK54yseXo^8^8)T{W z3mR7;2l=ajw$DBaF|Q)0X6S6IZRyjK%rtnlyB{eUReMBxUBYTQpglYnHET^qIvdpK zR`Di27U+NqwT?HiXR6k%QPykb^rRbz*F2(+@GS3K?TJ zoG=v67&#M&cH}{EQHn+glm9RqKwFze=G7S=yPR)>xBVFH$oRYjsS|U1tts;QtojWx z>%1OPX>H>5qcV|vePq`FXGMufF4xhILz)Hnx&J^t1$_%yhs(W4Y>-W#Yz(;_B2C~P zti$z#JD2U^7UZ7$0k9HhJN=<0_HIfXYGwC@_hMbRaZwL8c0lRa7xPQdf$eFP$+y^1&q|wx0ihjt zOt!zX$@cK}+TcGR;qiI#dP9~m4tP|W+H+GPY>myAa@iSJ;9kZXT_uaPqld3906l#5 z2I%2yIKFGB|K-IqJ8xjB+O91;WTd(T&CbsDa4C;X!-8H;LLI9!W0zngargN=ryA$S z`*yxG9cI?yN9pi~q0)8+<{f*Kjv)l>FgpPE813!~clHg4WsZ6*Kc3NYMP>N=bog=b zZ#y9a`uA!5E!3Z`^}mOH>r<8b&wAJ{YM_le={@V=?NT4Oo%D9#`CVb#c%!Zj5Sx?5 z?{yH~A~{KXuY-I6x0TN(V%JDGg)d%<@v+OFRQI=yce0;U2iv0NGt_Tw?oF=v-_M8S8HJLuuGFoEOg1N10@M^Ad_k)}%m$E5A> z$i4&~|7V!Yhk(Q6XlT2`B!^WFlQWELHdgT2Qz866<774jdU(u&k#wzF`HvwDdw7C7 ztjvMjF6X%y_$ll{*gJEaaf7ApfU~h}M|{*`Bis zDofk^DO9$-9=_HSFtNy$EabwaQF5U5SJIm#TF^ zyrBnYfekE(*UM87@ug#q)a+ew>P}_luSajT=TtTvdf4R))Pn_hM!8JAT@Y_>f3JQn zh_{EUMTdCHTJ9X)L2EWslRCuH(kc7|H)>Y?OPJ#9T?wuhi)NQUq#o%I&u&0ro9fO$ z{i5FOYbspa=N#ueokZk#LSCa|JgYK|7j@_g)w5%~e*r_s0x&-MiM0TQ8Qk2dB**wH zRyuqhY6g{&0FLc90R1CHxJVLaEqR$VBJPZ?8zkTo!Fp^+q%?TK2sD;T^5*1J-;9YSihcZ8m@fmZGT zqgX6t$01{Lnyj{Wil-Dj4z#*|iyHv@OLu%g; zuTJr_DAljWB7T;>srQQ~0YnlrO2l1@y;D1LFERZ|jXpU8DJ0nYXKxXB3!yk?X z^GuXCL$(?+c9SJl$z(qTnL89f$I3#FaF$F3_|{`W{z`NOdsXF(ISn3m`Lvc8*R*L? z=?RFpGVNd+pJhL6&r(HQ;%S*2a=GEFGZnAaG4zHzHyu&1aP8E>F7f)=%yMp#kzJ06 zX@s&OUET(!yc`1VP!&*bSTDyNqJ4T6xDrveos1T0`#gu#A6?>&qIx$d_KMFoQLr>1IZo9WqN>IOyg5Nq#>L z7L&a@A?AgegKahhnZu4;98C6ZP;0uzJEh$RQGwq3c$RkxRgo1dy9fScs9(Fr+a%3u zg)qOftwp`FRBpF;V|#-d(kSVWgnq5s@?1sg~E)}^X z-msp(H4Lg3tB1Ypy!PrceO04-yz|(RSfV&n<#Zos(*;l~xCX1j8F~Y&hvDpS zJDPxft&bLe5AIy_PCZf-A}kGi6aHdnE>yB7G0V#C3hxZ{Xm^zHTeZJ?e3YAeX+$rBcX%)nb(OFmKGsd#RC+t9 z{0o_*j#}JUAG!R(_cnBSb!3At@0gEtI{UN_8gvhgMjh1+JuqPPQ>%N#>u1f%bF1`U zAFK2yv;`{*1+xN|qNoD_VZaJ?6575@;EU?N9`VNQh@T@c(`Sdi+-7#|4lV5~xDTh5 z^#OvmVH|j_W_1Q6s$o6jX}-R|*6PNd@${~G&`RXaO#P5geM^gHaBPQTTz3~MKg5D{ z_Vbw-FV3xY`C9c(&v?rQ6!KgR>4S!ge`fcIH%e;U-fcmz_>ZWued1m1h3cU`dI~<+C!U$K z4GK#Ln&5#iRhZHBqn*U>SH)3MrG{K2y|0S1gzdN}tM*Fe_I$lNKNtq_*v#(ufTiFFu8 zA66AEyT}XST=jf0y5T2~JKb;}viemq`o$-zPXBmOQu{*J=TrDh>>nSHw6Rij9-`;_ z$NRUX$cxbd_Y9j*BTUJJ0fJU z+02E&%IA5eb_?CJ;IyXVW0%kA?B=UQBCDhsmUV6M@KmK-8lRE3Wm|25v9Q4F1LLdoG?Atr8x*hCbRqOOeRY5qJ5AZ0x3Q#i&`wst zi(O|7H5=$e=c|fA@kSkZ*O!})*zZBP`ErWe-E#R~o{ne=n;jt^K6L918TMg)N2Lso zr`x}%g2D03sFT@^Y?@E#%r4TI{R+1#o%LPA6Ny|`MT z_^yQ8nSIu4+rCS;F6xuIb)1Ep&mJ~7b&>&JKE}77N*q;TVK-q4^tiJzkptKYxO0)3 z#on>8n_I`OJs`AJqQI{jpLuK(Z2xz|gO>P0*<`Ki^h+q)6fL;LvhC_q5J3%8RxYI0HstJHb#Q1LFQ5Q-s6U3{ITSHZH5?Yd zS>w}c)v)-yHf+uBB9Ly)o46GAC0vI%IAV3TvVH~X#+S$)&Q7at!{g}KRlk3&2@=As>5WM2HWjZX(^PlxJuFMKnxSQBbBIkhok28LUpu} zZASF8r?XJKS!V?c^Q+)Zy{y{-w5XMTGpf>VTKyE5R~9~YxxXiJ_Zj55WII0e zhnxROvq!LzH?Pi$cm;kKC!>5qoj;QmRH(y1%J=UO+bqV$|C+#uUF>&+X#Xvmzuj4D zVh2vd)Kz)66&(^h_d3c?MlOabLY3h(!{+LsYMyLD>+$`P>kHXSXoAX-ab>3O;j{0B#~bS6NK7&>>2%<>u&9J-(t4vbI`=Q>+#f^^ zoc!(8`SZir%-_p8Tr;|^oHfU?U(xQ%;m*b+gMa2bS;O#Z7=1iI(9jtqwNd#|2N&cQW489mFe=o zXLk9$ecbB$1=SU`tl0?bl=v5&k3Z;cjA}4J^U=ng8v9Mx*l@aajs323_9)!6$R9dq zd+3_sy1u4M*WU%54gQuh7mY#Nrz>*O(yhO#5VEdDQHWzPuyny4a>&Yk4IXd6<0kd; z=y*gAkqqOkwYgNZ`(YsC4xx5_0J_%C_}Jw|ecdjYAJAQJxYNGd1=vBI4%t4y4#}T< zGRKbVe{|tg8^`r0T+YI`Ai%b5w;!$NA1ztVEQ3X+54GVR|XW;G3tGDZ7wZYKYUf+gA1A4VTM*sJN zvuq8d%u@0J-Q_mcpva!SEop2#=Arl;9WbU?owSUL6VwZ;$jU8-4_BuX`k|#U9z7>x zvB8Q%f1F_FTiGL_#O}Z|;;0)Dhv%1uaFdAHFmNs9asA!-ILX{~xm615Apdd*AM!*s~LAm)&Iv z!|t+)oO4>TL?tIlk~1P82%>|5Bwh9h1 z`+sv?y?dWir>aiHt`1XU_aBAp^V#;)QLAeAy(eP}3xN+yX>O+EtoH8Fb#*Hp&`X+o zGW3eoeU7wE#}m(HHrOYT-v4uak9q3}ovo=) z;-~uIwidEQJ8{+2AIVU4k*jK9G#L)nM^H_7R7jL%?(4Myb1#qB2w$(s@QFw4aeMlhRpWa1@%8dYu=>Ff>*?#oZ6)N?RbStuRqTfC^78Fe=GV$ptz$*Oqv7PhKsw3tT_Q{7<^)TPGs~&{%=fiUjuF5gZ1NOBKulm#XRgV4Oj6kmW zm%ZuGstd3W@q33>HO3p_8IRx&&!NLD9$8gwir$U)@XVU4%dboopmgRm-Offs!R-WJ zAb5!234#|1zE1E)!FtnEH?KX89`g-8$A!@e!S4$GQt&y!+|J1>Ktga$!Fn@PH{(`9 z-!%*Qdyy{^0iy*^7py01HzB?|<;6`4-Yob&!H)=j#$%TM9ZvwC75s-_?w0LkRzq-^ z;1+_r2)YTa?+X4>@HxRI*YR$~3Bff5 z^B%Eh(2tk{sp0bOYmoce-wOPa2%(06vi2UH64Mc0=?k&O4&x} z^~S4i#zTaDf?&PDs%vwV(61G&pZ2>pt@%?!US=J6n#N*+pDti`4_c!i^=^cb!e)Zt znSvJxzK-n1T|;)4RO`XnWS0LnVYE{iJs|k7;Nyb%i^g6CZVdOeZYgZa$!=!dg?%sA9@jT`xmrZH zSVR~vB2024v_fXHh5aI7f2FWbx%Rl&F>V$52L(T`+3A1AJ0jqW;PZm{J5XMUs|(g! zy}Grcw|d3ulb=4Y@wS5}`c^Q?&mB~~g!B%o zxZB6iJm|fhRj(8_E6Hvt*9!fuLVu^w?-Kflg#IWwg_}8Pq^ z6Z(tEt`k!n8)y8@rhqj)Kiumz+vQb4ueWq{^|uTCHo=DkpCr3ZpC)59&CmN_Z(rFj z^O3)2^oxiPD}dgul`OIwxvAhDf-e+2T=00omy=zGmXWbK*5hwE1U}8@XRR>0UGM{f z50SCx=|*$2&|ED+!{UD6~5=QtcZG}yQ z>^4CT+0CH3uqhHYjf72evg>sB3P$-yR0xJKOYkzmD+O;PyH4Cm#u|YiZdL1TNqdNT z*SW`q{c}S9GTB@Iza;|RCA+oq8QIP3J7M!P+08gyT*);Bw-}GZa z8H)#gxCL#t%d3RVjpRv=&8o>Qj&NKR=DZ z-X^*|sGsEM2MZoScH>SI`e|f0ovVb+>Jqzr@O4#F+l1|I5&opm>z!zEM&;*>u=$mY zQwKkPg1wz(gQb!IQ~OLdIgUo7r{bX->u)$Y=(BZUVdeei@%pKgnG`{G5)i(M%P7-U|>$`-RctLVrx?UlRJ) z$WwGO#yi616Jhf|Ve^~N|6P{@!!1E(y-IE>xSilpf+q=HEO@Qp&4PCdevr&sWceSb zfR^FsNwBw_*Grxe^m-dxw;J^}wr&%ADQtcb%$E+mY7dfK`%IzF1*g1>TQb0PqLbh; zf~S(*gf1haD*3q_obB>*VY8O(I=xZo@2u40tB)e!LBU4_zgQW;I3e_>g`U4F?>YCC z(0@yIo%>a=YCyfy|BM0(ZprGCQI-7gfo!(R?SxGavRkq~LO((1FB7ac?sYrq4MM+B zZ`|u<@PJ6@F*3a6=O{Sa^Dow&OES+2m$3I*$pd)-=T zD)f32U)P}_)Vr)V=ymNEQI8DySqjc}c?I>Z&BlgY9l9mBMFiYKcJ(`je!tKkBD;w` zFKkYbaqx2z|Fd0wpL#drZ^&AY@`oE$1|-Nh_^E>b*)G?j-i_RV?CN_9{QxqbP2)2J zobB>BVKZCsVsgqYSGAmu5d;e{YrKd4Z<;xGstdD}GtW z(613}3*IUCVX~XSJA%IwHb0Y_J5Kz@&5^TR!H25#N){)(PE-;4T0&nW^i2i#7d%?< zRI;1qEKkqzw@3tBNp>B&L+}HFkCELbc$wV7Da~u(Y?uElY(6Ku8GkMG=fEj1KyQxh zCK^CHdin_2)mIl>M{pa#1Icb?!^rNeH$&(zB|DC$j4LVy!xsF6;Ex4=EjWU<_DbJa z@JO=j^dxdir-r71xt%OO^R84q zD9eP=DxqI5^tX}QI2mjPXS=*x*gQmbYxKC_=Y-80&Bgq$cVBi(@Ue)XcVG5uNa*$M z%dXy!&g7Loi|jg7M{rwV)0y0s1wi?`L&(+wUa=8IV=9dBp0D8b!sa$|JGUml{55la zb_<(_$ZkzMCHQ%=cX!~V2zZC=mh4k!RcnQVHZf5ypx3)^j-5iJNfwNt1DQr5E z9fwjz4-qh+GQb!r^y7tovd~{8^w*Nz%x)Gocayt24s8QxySz`^u>SFRl!9ADFA6@P zjU1cPLjQr#e-2h| zzfI`x68b%YpLT6@`CkwL|8WDDwcaS(b?9sAdpZt%3(j`=cM;c*S=4jLBD--5guX=R zo9KP1-4e7C0bR%!IGObTXS+N=*j!9@hLjRTEpM}luWN-fWHOWZqDM>Rsq>{sHfmrf-e{L%iAM=v#(Q{>k*Lca#|SOL3T^C zMd%+F{G70PS?Kll;cip@M!lPU9?qbeS^jcQ0QV-l5%lic{T%1G`*ya=2|g$IU$XafFo*?*+25(^2sqp2BI@1dXhe3ay1CGI68dgJ zf1%J17W%P5KPx4KdBW&Qp&`O!OsZ(Ot25D9?!n2%X<7Z5CL5T4;4IJ z@G`+G1n&|2ir_Z|e?fL@^oMe;|1WZ?{Tu?aT|O_2GCEgQyCS=hYY2Uz(AOakaMEl5 z&UU%Au(_auQ-(2~g4?c>$!>&YJ-D)#K7WH*B(+0D2PdAO5i z18}y>t+fs7AD^xi+>9^K0gisC;PJv{j^L{VUrTl~xS8xaaW{E{ljb&Xw#)lc!st=5 z>%>u^e^Ka92>ofH|3K)!68dk2{&%4dVfoIybop~!f&P^Uu19t~?Id`(;Dv(IWVgh( zl1Dlvz5|@?@=jrMuqWq#H^R#da7%w$@c#s#5t08OyNSkeec*AK;I3ph{odqJjzj&y z*_u)Q5h7rYh;Rk@Vkg2fMsRtRu(^rsI=xNsZejC~&>t51H^|=o|F=ZI$0EWPLjN<_ zbt2ZQk_!d57d%ez<>YBjVV09eJDj>6LbfZUh0z^kw`5y{exKk+h0Rf+e}(L(`MF>p zE5!+seeV5;D`g69ifBKRu7*9u-Kc)j2o1>eS9 zXT2)jEO@)%-GcWD-Y@u3!AAr?Blrcuue+?ve@X@$$F@LwSj;!g2-`E*@WKA7&rM=?FngPLg_ThW!_SW^$Z2RnyHEn~t_Z!AN_JKh) zv+a&Y*R;jvUzZqxSZC{wuOS zcyi5>ieITYdFk@JRSS=;IlS=L4L|j(Q2#i8eYI69qHA%iJG>&ge#$g2=rDpd7ml79 zT<^o9{uz^v;I!Z=PK)Z79J~`hT??k#Z9$k3{15>?)wddinZd6i1k~gV2(z?cDSmY| zI9m%bBg)bdp4#lCi}?X9oozF?Psl3i$*zg0W) z@X}5jR>#bChy8sw^!w9u&!*>r=1p6)vAgc})$u)i?C>2u(rW|ZqHFI7T|2S;;f8(E zE&UnqW>4Jx`^?GP$_Cpr`=@J~L+q9P(~bPy0+-mw`=^@*UcG;x@9?kv)A=#%A9!-{ zwRwjdj!M62=C#G*C&1Dg0drUrd^x&i4P1vbvkMLsRZC6mh%Z?C!m|qy`abT?__DCn zGW=#JMa>qRJbYESD)gJy;si~DBXO4@V8szowFT46XbP-eO5{eQE2yR@H)#)1FDxw~viZ7sghWLDT3;YKGWnpvl{x z2QGVvnv!h%smlfoykr-RNjIy(A4Cnj^ddFkW>xX`WpXGyp{c#~_{BBi&my_NtIbiG z=;qe9K66WTd*7IJHhzZdsWIuAzECUs!!hX^)mt=zRS)w^n(@mJfnE-`w6n&hyT`ec zTVRCw7=vH3CyY(!r1*uRz#NmE#88Ks$y_a%Dg$>d1DBfT>5|I81Kz+qEm-OxI#%E^ zEyUDY=vaaITF6w7p(_OzXd%alax>PzLUR_nZ1iDNeE@slBeiH-)NkNl&Gxym>E0#F z8>3DOoBFZ3nH|Jk-(c-y;P5N(Em%Y}!gK9Q#-;O8v(ZYy(p(fE7UnDI!7_4Ym|wCC z)}gOCs4{R}auk5pC05J@xTR0HXi7JzkxpW5YT{%L}qAeuo1di zCWcsOnjRsBdb2rNVmbw^|J4Id0`-f&}!BP{DXlS+;Fvj?; z<Z{IzoVU@nqd8||5qy9@b6bNTh^1XiKhtpP{jX@DbeNmMYCD!bhR3RvxN}WbL+)WhLzq!+XxDovNk%#CFp|IjoLWej#i?=SwG-U z6_&#Ye4T0u^^U)&jv{6i7N!b^lMx7@TUhtA4+mD$xx=+#kk$JCSXH5jUdQqTj-no| z$9mCfM1>Uz2CST{>7LdI{EsOfT@b1V^>v=Q3QJ%FK89=^8;ie*kTux%5J1(gW2Yyi ztEWztA#9j$19VkG)<_?1^PXWHjq=?HxATri!58aDMwCBIvrc?XT? z?QDqYzO%?A+6Mj5TA))%6k1Dst#SHNmtl6cmipLkhT6e4yi)t>L#ZGv^C|R6OO0k@ zU8Unj)nIg4>uN2;R1=&btQ3Wm5m)CiLapV#3^~9cSmhgtnn|i(FzH*Xbx18$14F@DqlJ965#!pr z!IxsK6&Mjt4;P?pdL)=evRRZ_&OLsuycR zxLwysks6PJSa?3&UA|UfT?cQ!c-%Qa|njZ7T;i`m+)EJeeW`pHHEO* z;p5a|sO_wcojL-XnunrWyL^w(K42a2m7u69gN^Z!HZc?*lvxiu_KLgzS%W@EF^dCKDFbOj=%lh7T9W#5aI!u3XGuw>$ z$NJIDOm~ByoNi!5o3o$(>>G?Y(Of3q$p1CU6J3HbTaEqfIf-gkdw;AQ&P@uqRHV``c_rdvq+Ku|RI{6#u{=}!gR=Ix&gqYf7zc(4f=TCNuZvL;Jt7=4_WefN4 z??yt2nAOYAUqo?I?=4gBaSDEFrwWtm01`0t094e-x}q=xgw>D z-IO-4Yo$i(a+xZHQ@J%(3qB)y6Jw9_Ph{+vHNpQuMeK>vk4df{k8#eLtRq`a6;IJZ z#EA0wk2Tf51qoEGW=;1u!EBJH>uUy6!fd~!HY{fPW3b5U#b%wQi=B6rbun8zo;REs z%+YQb(bnumbNycrw4Vl-u%Iujs0ZaszGa zXMa14==^wKB`Pr*!P(Es2(XP4nN~dTKg3tHbL{lgbhRl1IXp81Y;;TQ;@>PSWGMdn zu2n?~F*S^XBil*Ch-Nj0loQy1gc1p>R$v4=o8m&l%GdUWdV@1=ffjt~xE-5@?(ldC zbVWLis2a!`DAqzu`O6@bXd!My_t361@Do$dwCV(2Wa=Mq>a6RguCuD=rmnN9uZ4g* zUI4QO0Zz^#r?ncoc|4wCvW=Wfoa`HGAz?)M)iA3`U=lJymuMEKg6YG_vALV0PPc_l z*PTdP2AqlXFZR<`fst$!v>7X*b>K~;R5jCT8|Z?R@?K$YY&S#~ByS}P-d<;6L`%_3 zR);`7tfDKLfx84og0rUMPnBztWEB$HoasbQvp2O4E(KR(Yi^6%`6n(eswJQBNjrI!%*(%&=82=Mov#j^I-;a;kb~kX3D{i<#iA;9vxVRF?)2b_Zud2&-o7 z3HJuaL9o;)o*C{7@-&C>b0aJ3{@@}6B_h_oU=$ORlk5XB*#}cH-TgA%15Ua|^nG^Y zhk_@V)JW@4@Yaf?9&wY>XTQTiHd;ts!3p=#AkP93bv;|~F}>96uim4(k82MHsxusc zPXtqRevq1gsMZmk<6w0YMyPdEJ2pg}XZ<{>g`v10#5&eG7Q`tHGRGXQgWl`3SM1Q`o0YJB<~# z-V2UG3Qhv=y9uP4!s3HqJp_cXqCh2B9|l`NO4PPK3Eo8eHHA=q8jJ+(IkVC=Qxh6P z{31AoHhrzHg0Is?kBP6PQ{PCZ&Ui&S!ftprcsC>WvwjFx#|UsD|0pB>BqRUqwvG1V zTndihO%@}1gd^#f;CoCeZ2cbWQ<2mkZc@LaH(Gz{_CwhoVln;-mcp#+Nb8>Rk7}XTG#FT6z;kYuZ3wTT*DBGMX;ly! zLo4nR<*EnSNRJC~NE^2qT2~BVVrT(E0_vKE5GH8>3)j zkqxz!&9pFd3__;r%*MYw#PeM>C&NV{z0RzmdbL5&Vx4_WBl<&gNLPd|Kyp|OT^V|f z{x0X(S{6Ew*oMkNg4R_!lYo=d)jBdR-T9)Ql?vU($T`-vp=vpvQ`b38Wlo;42n%NI zM`p^&dWDW%#Yt+V7P5^fU(2>ug}7T4{J0@B5lK0Itabcwl3J&ea{XAZBZnLhH|QM0 zM)UxutaPXZ2_*8Y8$(;@)QtJFu+F{7t*WsWOl}UnkKU81_?nZoDZ~jr%ZT2_bM!5t zxrkIXY1yG40eSP;acKczK5NPn!+Ic82P(AI7!KG6LoFahKgW#(>*3Ii zU_CDH2UO8RMvpv-@PwHrnp%&CJ_eu?ahh-&mKACp(L!eCuH@(^(jc`87HCW-w{|p8#)W?XfLcMtd~Nih>+C^f1C+`1Yej8 zuK(T$?E|RKptDYDHq=M;A^azF5CH*I2NQ~QD)blxONBWVy%{Ct>A$b)ze!9M@c^fxc;GW+ z7Z0p}`|&_^#E9-=V}20oKps!W&gpI%U7=TI|7roti;OVWEtzvBTwz$z@HrF*!i>4x zvyp;NsaA*^*Fr#D$)-zaA>>?atMD(#!7`#<_%Ace{Trgy*{ZqW$>6N3@yDG;VS!so zn6z|-;@%(Dypb-P2Lnr60(%of8IhG=*w@TYCkKV#c4PyUzA(S*6iL&iKzMu(Sl?R- zS##zsFe3Wi3htXchY2on(K(alD^Bj=HaLexZf86r{Hp!k{B(yhew8Y+g{q?P zzvO#3?Uh(lC(Sn^Tfac;vT%cD_J9THsx8-Hl8o$Nc=PbnNH4OJH{4o=Z^slF*~K(^ z7=gR#+wLEjZ78z$zxM45(#aIRO%mBpi+~XriGPs;dyzok2b=>VN3{MuoB|^+{t0bX z4$e_uzbCDRX)BC!qY4rI zffW%Lk2Z;XMvFi>>*SluXnc(}rY*~ey-RT(i2TUh0yEK2k>6}uZKIXG3J$zm588kC zQOk3xn7$t1O(JYtb?ZJK?s)OZ&*c|nU6t8#nfCZ z9wN=nV~{e{Pqb@c@|PTQ)bpJnv^06kwwhXki8|8CJP9GGKEb>jX>D>xt3ve{tE`Rr z0fZ72!T^i3H9vz;7j^nQ>NFl;v*8j^|81}Tj@EytRv*Uz)^0qoPXA>c#sjR1c)*85 zqEDfoBJIrtIFS+QY+i_KN%bsC-^IPdJqJB1($&4g-I~qO&1B2_)OK4fO4q5khaISw z$uoJ@3`BQ&kZ#H7VJIWPz~xY9ZL-HNO6R8*f+MlOJyac{x$bLvqIFvEEzCucoWLlA zC6bY90ghw!Cg!9_ba?o* z7&AzuAn;iV9#uo>>1jN$N&lrAQGN>~QW$s&9O#Wk%gE@4Bx?`@pSOTP!C=b7c%T>1 zxhonQbPqUp47!7n`vk_InOhI@qA&M`cD(1@1@mGc_c#&_=AJ<1g;Kd=F($*g+~ot4 z#TV!-vC(5IlNg{rq(8SNk`CmqLy?0<;0y*!Z0a7^2U^0b z*u6&)DRfEf{xcX_;s3!jwukeU5nhD`kL@L!!^6)r%Y77l;irng50L%g`WOqb2g!l( z+pWR-$-(fwm~LYau{}fK^_c8q2g%_ucl?VTB3t46?SWTdQCWyHOzcsrqTxDd#@OTJ zSa<>o64TR7BD@jvse{L+%16ne<28TP)Nv_EVF53^)D2BK9*gHLQ6H=HO?B*}Ht3 z>udA_)PE^c|NB=|SfGrK{mVslA{H}EZdR44)9~y5ZsADJEMQ}n$t|{O-iP5e+l*B)Hx#00^BGGlTPI|w zt7}8ZG1;X8>Qxpn*ZeQ)*-}3TAym~uLhXn^sHWrRsJ-HWZqlx2M1&I^x*HK zK7-$}`da9#ve-i!XrZ6ti73{@)Qjr=ssM?`nwgyN2P)pEjWstvhj5#^9rYY*p+h#S z@7R}GnQZ0H)i4a)SZiGiUny=e5No47{YIV3fzZz68T_oejd9wWYao29ifGnB3*V`K zF#=Mtay^0lpuTL2pw1=-!r#fZnB!tybaG?Ng^?ASoFCp*|wGkKbgJy>Tk-9!)I z{$@2hpu;RTW0&iuaaw(mj&G=j9bmuM)3sGSnDaGS7^!yH=CX8Y%>!)CmD$R{!ZDy5j(85O5o`Yti_VFh5rk!Tg*Xime{kZZrbpfmE7V|@-y;)6X zh;6=teshnqQ55`IJxBSy>PGtmL`_X%m2EY-gV27phTUR^`3;1JlTWcpcIsSPnn~XH zjoqtY>$@Oy7jzQ$7^pUXLAnRr~6Y!GuatUfuES?6xPK| z?kd9Iz;DD;>}n?WvjQH`5xbemCQS6OmU@`U8Laq6wRC}*ETL;?%a5$wKHyHh6@?d@`8%ov3u5(Leej+A#K-$r9BXSsMF~`70)0 zbtf(fW2ba}hT_g~u{U+i_>`a7y{(0SD&y?+jut}dW4k<+u0E6-bHv`)$;6Vk1|WQ3 zhBzQX$qt;wJ~XRBdNr9G$@czO7jSldaxr`ACt8}9pS+vZ|C!EzVSe(Iy(fj6Uw?9p z{ZHq1MSijo2h>-(pD)W#9$`QGS`WG9`N^w0K{{iWA)|Zpll%&3?5vKrBR|QjwAlAr z+LfQ2i77DlqaIH8<|nxqZtM@UA>!@LPd?6G{*Sh7Sd{FWDuVd0Hf>y#{E`FWyvd95 zCPm3-=$fG)ZM7~+)@%*Q^nHnDXj_zgohK!q4r^bOOtpvP*HXu#`%ZXRdV`i?>KA&vR!2&x zJk(fxofdH8eGn#w_mhuKpO3AhY0Mz;sVPUu#W;yi_iuxJ))7YH{l6-#y(%B_&p71lu2vJXeuhEr zLQLF7?$d?vA@^;J6kqP$77BT_{(Z3T5m~5zF;_^1|H{23u z(EWYPvaz+SWFKC;Rfiai7RMhgnK=wG40p$1Zsq_sko8YK=y_0FgVTn2!w}s1aCYKy%l~KleXROx^%-7ze$_8h1NON zgsJn4#H~wF;HuUFvb_SF7w&>A61OpZk;Sq>MVb`v`|jMs*vdEi~NxiS0zZFZAy3U^0$Pu$D8+7#9oW%pf* z%#MdUp?@XzF#Tu4XV5_tds!u)hu73bBP8~*Rlf?aMYARz;B))47(VPj@xTrEtGnG9 z_@L{*lM%R>#eR^#FBFIt0uP#)f3mXh$GL&L4ZawGzuO_`P?A9n8N^4xI@|~iOgzC$ zt?-5zIzi$HE6@nPgEL3sD9d4n8>9Cmo@7~lVg7zc;uzTqUkWc0$H|HCt?W8ak#oXV zvg9gx6Pn7R`$u`nSkaiSEb5B-iz;x%Swg!zh0;&rl5zZR2tgB;MW z#UxIWF(7uaWT(y|jlf}yvqb7smN>Ap0Q|May)5q!#Av$+Q0X}$5lhrE??jfW4%5AeFvEQWOoE9*J#kp-UiRzST8N+ktf%Ng8WfphkxU|zC^7NlG%4p2B2lU* zDMP)^Zd|4XQ$KP^)X}F7pW4b%SJz1$&mQ4lqMo@ANks?XM3rc&Lu$43CEA$#&>TwD zhPJJCUjOi}k?3Ty7X=je{YrGvR_9Xc_m+^lng?m8kpI&8R)ioTGc%r|Su+F-gReGWM7;?kP zs&AD2e}Hx!YpFXJIM6(XK&++sBPNMKW>XXq3;*vqUWe%QA(r~>+15kN3lN3{{BdSK z!u$l~nr;<4gIQ_>_BOv4toQoV4s>|J_ol?n#oH$LYi(4LcE5) zt1X0lowk;jb3aNRN1SpIZ?Y zJ;j=wW%@Bs1adLcsD?kmCb9=z!N0JF zqF1Ux?2MuC4fbmYo_PdSqJ}ZpG7J6)Ll{mW!z}2EzNkh}h?xaTQ7ko*=_bsAI+)4S zsIL)%yKMa7X>~D$I%WZ{ht(L)1a-}VMF9w78B)(IC~aX6Sd*?+wQY{lH!=&Nr4Z)PxyEL}PCLB@mmL$(x77k#cQ6ae;}8~(hjmA@pg(Ki@(FOLhgrbi zgHwz67Flon03*#ApligZ|8gnQk&{R-^dq%|^_72xsjhz;VmOVaRx5}`cofbZYUTUj zK=>GUr&g;uG%~|;8Sw^AR5{@pEb?0FTZSKFg!R<74G+ozZ=il;_+g}`Hc~$({4?fi zbtCo5!hc}?P&ZS*JUpiyyovgI!gUz;R_b?zyEF&e(5G<1=*c#@g8?swUqji|os95R z_!0b7cV8F5`69fKnQfu|TzEM%+eZ7}3u>Y=)pqKunFV~Hu6FWydJ;{DQq7n zSI79+eSul<35$4~onRp^g5E{5M9!l6csOkWEnhPX48S;6&&)?#g<|T>d?X*Pi&j!^ zokxL;@bM((W%XY=hCARvy7KNnNF=mSy+5~^eS9qz`_ox(pYcY8rEegq&zbQ&eV$cc zk}op?-(ldXuj?WGz&IxPBfCicX`lMJAKE^AZCmKhu`-PCf++Y8R$o9bYt&!opf1tN z8ud51EIgJq`473Seet?+wyIs^o_UwcX>7gcKg{_nh>8-eNoyyc9{nbzG z!dZHj9jLh6P&s;X9;(ivgIuU`O%`;a;>tx;)y`d^xO7o@T3D(EQK)7Pg4wdalGl9&PmKH0sHu59)X|yrrK?$= z&$6R!*jC;31ow*iQxF4tytl`iHYU7HQn z2OLC;-A=%lXw((DkWJOM^m&OEnjznL5TmPUeWj^Sv18QL=4s~Jmt#Gp851-I^$PPt z1Oya+cQd6{>Qc2;GjUo_t8}mGt!5%ft=9Qor0Ozcjm~PI`U-8SZZP@U(;)RF(_X8E z!OCX!uETGz;>$LQyUwZg=46PQ#l`W+749&on@I#DBali44-L>Kj-Ih!53 zDhsh+cR_STj*tUd2&iDTeIT7~p6bM!d|X>+sRGXIPiUczGi5JBDmsf?BN|o+J!<~R z9Hy(M%-$Ga`q8&~+H_tLxUUQr&uAf2eODjCvsx%rV;VqsUJFfCV|w+17E)dGn+576 zlW!Ib)NdB3mvvo@)X(JAD_Xc%KhVbwTuu^W^rL=tLJMQnLXMKxv@lLx$YQ^)h4K0c zzdET)e2Mylx&B8Bla1&{tc+9U*wwI4tW$59Ic=aA%&zpdZZ|`}bgSOcx5h&1AP3WF zErj($ef3{$W~qg2(GPTv2~}1P!iQQ=YKdKbBhHt67_YuI`94RUx`tKsjjp?D>c5;w z&geT_%hg4N5WdqnT%*R&?0cQVwQ4e^aP@;WTWv(wWkUMNZKwWZ6&30f+N*sX zAQb7BhdZj%ocoG>{hHWIZ%XIawXW)ZJd;t*JL%n2ntdwe^JAXr zu5PhwZ%Wrr@y+Py_iVYf+MPs0b-yphQ`$7nyL&X_VIjxPULW5n$X5?Aoqf92+!^+u z?-0_duWp9t>S3LC1Kh`gb&~g=?u1`({*A^6J>+`|rU^?u>g(U0ms+j3WOeDqmfsrPJ{wf4x-=&~CpUPv+HvG|+fQzP~TKXiOEN6xzb)uifle%k<(b8w}r0&~e{p{PH$CJm{5ytt)q05|$ zC;e=u@!Im2c+%u-aEYJm*I(nwVw5_iCg>9W9Zz1*Rl!7EiOGb1ilQdzi1~@+E}VYV zRDT>bQ7l0kYf;KfuIK4(hM%)s#W_KxF4b8yDo*yuf;dl0jf<0f|6X0Dr6$Em?h3Ew>$+%KoV=N{%K|MmD^9-7 z0ld)92Y)S#lV>@_U9Q907AId}+b_~myW-^Y?0So}Wyj*=8FtGhDSr!iisze=X;^5m z-|G?U#{lerGDkRu+2dVpWH4m*7I$1nxJ@JvEpr0<3+JDBfb&*_a~bPMhlPy@m8=&n z^DcFy3ff;^FL(FUSY3WaH?Q>1L{5o-y2?KlVQK_V!70s5zbYCsdXR0q+&=)}wM$`b z{-l>yXn&&_TG-q?r8Dk0@)0gVcoUtU;s|<~c}_1ZUc`l~QOx^Pl?tPnU*U4)_Zfj- z<8tL6AeRippMnv%jn~<}`u23aPy=v>&i20B(bH-w{}cD)5X$5pgZ9}Q--K{_QoCv^ur zsdM5F$(Q11saqTM?SXfs1F4H>gGwsiK)j3N z>Ox#u&4KP}=-|4EPG9GzOgQ-V*U<7)9f!GjaTj>bSDDSX>G^2;)E(*Ul=l5y`fgra zhCZR4acZDc|01_h=O&cHJaZ0V{5Xky+69SqMqf71FtOKhG~`VQ^9*lFm_r)qbiZ}d zt;e@t&F`2(1fgY^puKGDDR-t-Y9vO3=|dWrvT>N3H+IE5J8|*^YMFjlL~Ejx4Co$W z4k=!e55u5I%ZUhWiq^+h3~^TjisB(SVVP0$R`BHrG)laZjfF;*u7t(8i1oba{|Tu- z93eL#pll-GR;O~&gzVNFgYf|G3O0HeCnU4jgxc7Jzvkx7-R-WM)6G&HJ3=ba{r4@n z(7ZQJJ+5pHFG>_wNWUV~DO;ISwxLa~!&GI~F*(7TBT87RZOFg8o8votC}C;YZAMh+ zoYpG2009pmpy2ZV6VjAD54~zAf*(il20Qbvbk3CLfm^lVXtSkJvd9g6+>JXQb)`Gw zY6ScTwy(JX3oWCBKLpQl^sO+i98D!_5c~mx^Saw>?n;-mX7{Y$-RYtjY&#JAHB{`e z&6o==Qd>mO8YaJ(ie)hVnw!tspWTHEAYGTv)B1@x%@ygobmZ$GH`lf4$mWP*-A~fG zE_WcbSl8x8U7Lp?>-uEfebe2mPq&n4AzgP?4;j$3bh=Y_=%l*tYP-P|wQ~^ySd%Sv zfUe1lUE2%)U)x&|z{Z?Vk%v)oKXk0B753kErwdZ7mb;u_v!zot^`C{wFVL58l456k z+>MXXU-CP2oM+yvNE5LF^B;T`wafXYj6;i)EPFnCaHF6PwacpjJ~CiMf6^1xXt2)T zv+vlFZr)N?`TM&2n!}yW>q;Y>>UJdGjYdgrCNmNf(5?5RbAp?@8pZ*;`aS8!J`9B# z_oVAKHd^k?M#`2x!O?gwGur%SFK^nn{G2G>VPh3Ex3}Dr&Kt$cPHC?soUdXi(oC{Cbi!r($g^E*iJxAr6 zkCd}e)D{9fKqu z;0m?nB{=Jwiz{jr=VH|8nBHEEF4i?VGKdQJ4{E_&;=iDQy#=YK^qC1O6N61&jtHy* zI$9gL9>{iZrLI0l#6akbMjy99Dz~A941;rzx%oQg#YgYZa%TSoc^Qqq!J5N7pv`8& zZ*%kLK8DfiGMr!!YOAQ-dV4y1Pzg^%j%IfVji!g}!`kOxC=V$^_#qu5I}CX+Cqzds zqx>i1Kcd6?P~K|au|3_Q#Td9+Hqxy=mTRG7f%DMF0 zinN`%w0;p1;e=Jj$#EiT!ON-9I-VF0>6~uTIZZ`QP8}W6WitmiUt>SHD_zxU-xQ{g z2KLzR@4{={1xV9;GjJY}_(7@R=2p6?{drSI?wo;&(e3%Rw&W|uMx9FvVS9O(V-m!sEcsv@mm#BiYwV|Xr}M(PM9cQrAMM67{Kptj6?vN*Sg0EispK^PD`YFe zyvE|3&j|stfBtFw8||~uNP6wUrOSURY@Nz4DMbXf%9;NspzLV`T!EQYr<{UNXIVXD zztyXmbx@g`AA;x38h0ye=3e+!HG6YN=jj{|vsMj{Dp>*2@WvghKYEW~`Eq6>q^No!2=W7@xQ0ax#CN~LW zsHYB&wg>Dc_os8)vVEQwIc#*J=o~R0HM*re3VSuq;8?WcFgHJf&QP?*UUq-Fpr;-R z%boHJX?h95tKt|B3#U9c>+(Fq@=Qkno2EAcnK)JkWvqa9BkhmjNQ(Y1cEUmnT>qOQ zoD0FVZXEiL{%+9!ofYY@8gNP}8;20DyXkeuPjUFWL%V)A`~BwUFhHEKzr$^V#`9=_ zeplD{1YQ>XP+Lbi$BYrX_)ab*cG1B2nR2syd-I-jt)l8V(BG>Y`7Q`Uy6jEY zxVSppFXs1L%x`s0{Ptt9?u_5-&X{5%GZ2Aw=7TX3;Se^;xXNXvIjOS3SV1Md@n<{g zy`x=gU%Glp$)}JXggnfNi(2In$5r4DZou5Z_K$nh+0|Li*H#!AC4G@T6WYmy@_pM! z+WGr%_QwzQ!O;9xPrpf|VQ&5tv6`>vdHdS{-)1xim+_4E1R}ddHX8L{q!7>W`UGQc z?li=U6bd?#n(Jx^1=&#M5dMI*@q$bu&;WY9;ft5X@`^MHyfiWsFe;E~oRVq$z*9#% z?S|v~p^7Bhxk+f>Ke9VKfE%a(4n_abSG@NH*xSae=zcX=>fE!M^;X$Qp_l=D72|G{)^^CbopM1O;(Yzb{gagC9e3hHH5 zsX5NaVUL#^@-Z2#$U(M4b(Nfh*4%t-I9i6=S3t``n}dt=h567Rugs^wwIW@xp}Jrz zAv?3@Q2j+}Y@4MEHe44BYYttk5iFKv?1piZs?BX{f4X)P7H#ja|68>BZQ(*<6fX37 z0ICBxH5%yJ@7pK$r>jPIHYkDmZ+r26d@H5~d=*twYL4Y%yxomXoHqZzP_vuSZmSbG z?Ee?2*YWouv?(%};RY{;FNdI`FYR9htQYZ8xVClkEcp;&>`hxM!i|#uxrrTebqkQ# z_t3F~Mu!O)6MxXi+ty9;#=c{DImyPvMAd_jR5Kk9kx%Tiz1I;h~=N zmmk3(<&pTW+4=W;+)T%jJ*xaJ{Ns^0ZkA8L1kFR$4|KU4lQ@s^cKj6y9*J+v^7k=& z^T>S7*ZCK8J04Zel>ZEuc_f}iB1nu!;;?=8Aw0r6gTc!q)AW}Qfr~sc!~XJ*F`My- z7hC1;VUY4rFZs*YVtn$5P4<=lg(~C`yVX~IH^wKA*zLY@{(3Br*llP6jCvliJACE8 z!g(ICJALJ03`-pL^#{|L4QHSdc&IUf&ZQ^|k7%>bQ`%wZ;fQuGzZo^g!#a8R_`&p) zu)RGnILmJRL^>Heg}!1MBc_{%G1DIRM7lKgrPd5_H0dYO?b=-pO~6?A`&C=C5~h^Y z7O3^78~!rHXWZDsRT<-`v&|#vhEs0^n#OScyAy}cxUv!dZ+AGw{~RSS;lE5IWEx|= zoP0*pihR(~jO93}<9|2L{@T{QrrMEgyYcW*QG4SPbutb=aU}g_99#8md^!ESIrs4L zSJJ;lOv}FFt#mCrH*0R@;hk@#3-S_Eu9&f4;rI!YC(j>0amK>K&zwz%0*U!k7F;@e z(S+Gkbbx*L3zOO$KL11dWwYkx^CnMNIA#2lD<(~uw{XU#b0^FmKbr|mnltb4>7UZ4 z!uHbpH)YwU{!F*ZT(EG$!Woms&z~@NvXjpKbMso+9sf#KwQu`*Y*YKM$L$(+=aZ9) z?TvdjEwn#8Icd+~H~vlsO>4sC3#X5tbLnLJ%)U+451;)f{cc{fh24f;IDXi`9$km_ z9N%Nu!2W%@lX{Nq-gDs4J_9c5+JAiiK0}6%?|$LH{^PrM>)O4az2t>W^$vfRyYYI{ zzHI5#JbS=(qZ`}zWnI?j@W*)@GlKT19`m#8PgjnvZtr?+(~b7OckIoyli$ZO?c;eP zEqmXprPkr6Yi(Q?jQ2%dW7aTs;K;MP++8bg0{Wy@oxp#rm^A+v|IyDie=hV~HsG|T z^@X~1(Gwxp24CRnrwKiqGh`1c9$akiual^DI8n0kyJ~2{e>!d~u2%g~#K^%Zo0s~} zkugIB@c#|F(Xfqq?bv%g74Lg^rj5ujWyU>SrsKTRp>6Cn!#4IZr`sooZETTR&Qy>I zOT0nw-DISK8OtC?XX6h(yKqon=yH@N9ef_Z!E}z`|3hThl(-xn4#0<Jem+qn85k z8D|<9Is)brW8C5DBR0;emKun9HZdvlGfnUu!3zX05u6gdLhxF_Hwv}|-{o*hXS`hm z+$Z=!!MxJ<9DPDCzk}=PUl4pk@F~In75q^kuQKu%BH)aD;KiPKso#X^AHn`$WwZ>z zxq_Pt?k;$M;4y+P6?~<`oP!Nxl?b?5@D{;)1wSMBCHu0=Hs*DDPpEzr91B&JBTsNA z!87b@rf$hg-6m8!1s@drqTn|Lerk0la8;2;MFDVZl!een;@ zYvV%0%dD~B4uX5z%`&s{QWJ&hQo(#f%1dI6U|aBB!Q7wOvwvRjn}WX<%xfXoU(5-{ z@Ml&=&J>(4xW3@dg8K`;Sn#Fxw`W%8#knhk=hq>7&hlw__N&JdvD6nruit%Wpgl3p z3w;dhWG^l^VfDC);Esa(3g&g6XFp5uVux{YiqCZ-AZ=$|J1x)LZFl9rWA4FyuUM~0+!Q1Rl$}i2UenhBV68yG3q0RKX>VF7TD7(^&Z2K+* zn~m(QE2iZQ8!JNiqO|AhV!_u7zDe+I!4C_5%AT-tT3(-jg({j;nY6x}>o#Izq3BUvtPVnT5LiM+_3S|>?wG#;PHZI3+BGGUfh*}Zx(!yz4fY% zd8OY7)vtm}#Yw2S-Dv%^ywVGWYLwuV;2Z4fS8r@m`jk+e5d1&Ef7lbQ-dG%ORjtz3 zuJ(;krLGdHHG*#uyiM>4!S4$GLhuiQbE{Wo*;KH8(%HbcNDsm>B4C=}YXz?tyj}2< zf?u}Rr#9kBLa6+>iR3j;HNmBVn+xtNxWC|0f~N{zAb7dM&RKiC2)IM=H-hnSslvHf z%}TB=xJ+;h!CeGjBzPwGk@re`iwJl`@GF8(3;sgzPlC@2j^WzfOTVGuwjSfZ(cKfk zy#)`khh4L=SF_bZwL$PE!FLGWYM;0U{r6d+dfEQ*nvHqY-xjJ51b=1cUc2$L6u(C3 zIm>U@dwf>#dBJ)4l{QTUcMv>A@C?C=1YhT{(-mwHuwC#0!A}Z)Meu3CUkLt5@Oi

    gX#RUW0endC(}G_Y{J!9?1^+78 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

    )12?iJ8^&g0p zi*nlKiH5^;SJ!Y94vT9h%EY`TiG=VewB%*8a`kaFq`hsF7fO9SIn`ROWtt%@&*sf=4x#&Q+E zmzD+|Q+`$X6Xl(WzU_lojmBFq zPBr1MxS=Z3nwAcAQ1PBBeyNHNr=_0QT$Q*-d9(8C%4d~R&}dLmn9jHT^eWMK8^);` z92VD8WiE1d=U*2lFmvjsJeZc1uY_4qNtBtQ%FI+{Zl?2D3%*pYkiJ%zLy{`Vq_q8l(Jos{Bu?Oy-D0`DTGR{vkmEo~C>~osS@< z1vK6zaash2#miKgwW`e1%5N!usmh;$V?N$+a5{@bSp26dl!Eg-=tPv3GA)%aQDp|u zcp1-W2pkp{s4~+Mj(ImG65bM8R@k7tNBOAoIpxx$5*;l|)nw9dm`+ zFd>BoD37*~l_wReY85!?djXQcNX2QT|!EQhs8E=E@yt z%$&OA!+eE;sb@YqCmsj~Wk%A{xiJ!td6*V3AuFs?E>eD9`7h-P1&MX5)5zmghsLXB zPW9oixTPx7wSd?Ed|SrruQKx0%JY?t@-|ieIT|lgIqinS;)ANp`^qP2yCpFGv&9L| z`N=3vu>X(^LS=d)RilE!OAPL1HOxQ!~)jh0=|i;m^n^4=hoFs0(9TGrjC96PBJ{+L9e+R7c3d(zUtWi(!}avBJS z#UoXjiL`WXs)}Fl;`aFS=BtdmXsKwE@*(B#luM6IlrK-`+x~bJX}mDyR0R&cfAj)X zrsY_)AFR+-tuROxnykD?d6n{REI<|Ls&pC*>Z>mnaWZzFc{f@)+f-m8T^f^R7!Iyc?8nR=!Pn zsq)>*tCiO&Z&ZFzbgN!Tw;9U zm?*7WPC2YxS-HA$9p(CBJN~9Bqor~Oh~~r9cvTy2bs4gZp<}jMh;1a(+y(+X{`89KChXGOlGqd)d=c1$jHchKLid}3DI0TZ zZ)2#cYsh|`sd%@F?=vsF_k6U&VHJ8``D5j8mCq^vX3__DikkaYl}R&)AH=rkIk;1r zU&XYUx-qw)RcZ90n(ISbaN$j%?q9OMg4=O;o;nN{!eDb*=o`Be^h}I=Iv=4bJKH@6YJD6FC5Oz z?bSwwIw)VP+*^5|^5x3;=GcJjs6WNLcwd=l?YSyvzVaQ)OU)BCo{!evs6x-sIc`kP zD(^L)g&Rk+?N^3M_D3rFr0G!qfv9P4EITdx2NmbvKKnIYbtTP+Yc@t}msg=0bgs*; zt=zyo{daD(!$m4&zXDW>_F=rXTdkjRK3&Jf$C@dR)r&Tru0r-(K_&YJ6~BYNz^%5_ z9NRQ0>fdi}ymn~RygI8O%~a{JF0I#2Rc4R!OUj3o-&B5A`9t&Vtb%Cl3l;j2uIrlr zRr$Pfs7#_vnsSD6P31bu4V9ZZx3aBuWul&IxQB9ID23;RDO_wY*D$!*eD=%asK3*Ei$#am)LL&TzpwnU@)yddP2QN7qP>1pp+A-F zSC-0{%BEs`4cz!LmF?G;O1!Fx|FbFDw7JS|tK3n!hw>$6ZH338y{=H90_AbaQU+w^qAp?AsHR*~xhdV;RoYUyy>e&e{>p=uhb!khn`PU&mNbK2>sxWv?%5U1 zto3~=rmtdF2iM$cv*NYBxv?S@dR}?I@~g^kDIZn-MEQjB_sTyi|KaRj`kz-B>FJ3+ zmRHW9JG#EtQoc~Rv2vbrcje2J2c~yUR60Us6ewS>rRzzzw1@v z_pA7W%8w}9?|nsgIK9AlXG?Ft@~g@pDaVeh#A)R-%0DXqs>~mt3K~mN&Z4`yPE=B^ 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

    ^)l{z|~AVmxe7 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 CdVZk* delta 2441947 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

    kJ-Zzq7O0k)U&M68oJk9eEN&gj$GE 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%0AS!Q@I|z%x;LS&K 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

    04@f|BB*i&%fC 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%0Ay)<{jfWdRRsKGvtzNN0bhqMA0hyF-ao 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


    L%fSpJ_pBVaiIb|IBr@a%!sxK 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 delta 70547 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 k7{xp7(tKinKP#AFiF>z5oCK diff --git a/tools/sdk/lib/libcoap.a b/tools/sdk/lib/libcoap.a index 73394186edc66ee078e70428f1dc6b7787c0a509..128916defbf5be03c73085142da54f76878cf481 100644 GIT binary patch delta 1480 zcmZuxT}TvB6yAGxW)&q`S#!6fbrk~*TXyc;xib^A4-w%*4?RRb3$bqgQ@WeGhEXKZ zQ}jbP&^0jMqljv=TM|+b{XAtB1csFg1x01A(nEJhSe#7316+V{UOFDHEM2o??$G|URpAm%B#V;{2eer?L6Pfrxwj)!>#Iw0VZ?->gBE*YyWe55)1rt#d z?h07<#`Sd;da@m69M-%@;dHJuFPZ>mV{uSf)`YRIFW;Rufpoqw(A(ebvuW|7?mG0X z0&1a}pwkVYW|PC*O_qiUh(e?=m4FRLohMsUVC@FTM7U4VG^EKRvthP)8w>`WD8^?s z9d=BXG2|l3^Axsg(m&kcP~(%VVY5-;`A(=Q zHU}NqUqWoIgvL_BCa7S`q;p4v8i;HIN`$E?;jd^WZ*LQ}9&}HF5QN=Suxm<$C?1R? z+>yi+$q7ww0TDLQCaA3rb6Yr-w}fw}h6z8JwTqS4UAK8&Yhoqqm{v<8LCoV@?UfSz zyxb?5rn#6HggWB?kJt9jdg{fCWi>pVUu1hv>1iq=3O)Kn2-9e@*aQ_qTbspgEjn_A znDt9)LY%M5k_o%fEEX@XjDgr=IQ~fNtaW_WQh&b_r#3=j{?wAj_~9XADH@~yZh{yc zdIcKT%LTCsaF{JEiit{ZYVwa*p#yAb)K661`7hEt;{dT!%>hAxSf^)q1Y%It+4zn? z+*u5bN7F$=EZ{m delta 1459 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 delta 100 zcmdn9S7Ogzi3w61#^xsGMn+~P8z#KzMGqdJ2w(V(bj7zd%BIfNvMT|hq1jNih d%(7jmi1mgnT=(`*{j4u?;i|Vk`pbGt0RW+p9tQvb diff --git a/tools/sdk/lib/libcore.a b/tools/sdk/lib/libcore.a index 77f94aa253f74139992091017c4746520e959218..92141cabe326a3dff74cfe25745b259cb147fb73 100644 GIT binary patch delta 41 pcmews^(|_G6o-kCg^8KDk- C!4U2M delta 62 zcmeD9$lURfd4d#&vAK!4k&&6{M5Pxnw#j5ZL$S>ojQ8}}p|X<&8O1lN7=AEkJh)jj Hv$!7sN%a!E diff --git a/tools/sdk/lib/libdriver.a b/tools/sdk/lib/libdriver.a index a3769e44cf47ca6074fa0c228e09daddb393285c..e1ff2a41ede6a81675e78c9d3e0aba3ce9f6ea92 100644 GIT binary patch delta 585381 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 i9+pB=zx8RIH#HWHS9~) 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 z z&a!}y3^WH0mk=plp~a~uDRHmSj+3&*mGV3utADPNCLWNZ<1n~fCaxA0gY+`7Q;Zzs zw9H-(?mh&eI)SGRFTm8|rNS4B1NAuQIWkA}seV1ew!dhaRmb4fZtO7Ft=AWFR_%3j z>j{C%Z73A2p@T4cX5uuqoLfIbt8^aN9ENh8fkr0ix1iR6cXP16r=rLh?1W111GDB} z7MMSJJ41;lTxG>wa#HDjupbe_2RmJ|4VM;wC@Sk#D$B}~RfB8fXkd79G^AMZ%%OWY z9sW<3{R10$;a0oxqo(Xm_e~SIL!9(hvhPoqWwFPou0CCL_1KylMEww_!1Krev3iVC zC^ign(yE6ceYF)^BL~zboWPWwPr<*f8s`uB|91X=hKPHIIm6V7@Cu@3pSKxGn|@;C zaHm;hEjqUN5F~3$Q0ZR)%=sX{FzkM>4;kOsH2yz?lHIs%m>cemGF;vmONP4}f`1G5 zbEG1VkLXIdaTWLAASZW`Da9uY-QJ?&FL`FQeI_p_U=?q~iyYi;DmON1h!MkaVxke* zs7cHyWVa<+@eH;5#~hT~nvz(^sn^)9-c4egOrk%MP?LC@oW%UmhML6NWJjJwx&klo z!~wRK^xOoO?r(h$hMMHt)FdCTdVZVidCyv_!{hkKYTquu_)f~e7?#uh4mq57$D|J3 zMfM1%RgL_s>z$Ilg={&h75yY=S!qVEDm{cB25`W&J`)Wiob)nISJc^AJItA96>z%F zhp_mBwWHSvbNIlWD(~e094R+w@$ixEQN=C%&sxG&CHVu_j;CR0S0|nt=?qt+Zi?pZ z7^#|?T<7}Qq9xx;Nt#$y=j1CJo<^jf&ULg&69<|kJSMQvb$aDs8JgkSCVpK~vJ2{z{-~s$c|nN1Yb|_HD&;IF7YN?l1C{iml5+W>lLcIp zAeT#DT11|B`#l}qdbDYH;UCl(UK2*U!|SLVUVowI+T~?RP3{zC0;=J4R1T+=pld(p zY&&|~A>wG$A%cVFM>%+S(Yp>;H^W&n&3KHAqj<6ZCx^{{0Oc@Y6na9QFaU5?Zw(Q8&m*%j2$sQl^&jT(tJmShO}q9387$qx9cedva_{Ysl*2aZYaE z)O=i-sSzJu?b6?2@5oR6o8uoqdu{klWC)W&u6MRIoY#=CC;i>jOq-4nb`&3sb23^F z1XPX3=K;3CMcu4Z4BI<+^qf3YWRJ%;lDjZo>?y3IGHLTE;3ikQwKcLI#$R&Qo#4b@ zgO|E|4Di6Kwgo43yvAhUfW&Q{#wV_~3_D&|B(dgW+U>(j{l#fGKY(Y8@%4T1p_I=S zv+5(m;fGJ>-FlwR=Ar@Jv0k zJ`K6>nOZ$+VI1yog{S{O+^EN)#;1Q_T>WL(PVkv_->4tp^auXhH<)ABe+e@_(?1;b z3#L7v{-JTBp2wbnPk+C-QM|?!pZ@>(M!o6Bmw$LVJ?#2x5fGp88|yDcQha6<*B8J8 zpPBjf=cMCXWIW@4A9W)N#%H`^*Yj4yeIj^Cnp)2rY4DjetNv*W06vq>tgk@Jd?uY- zzYZ$~pIL22Wurs*Y&pTMFNQBZv%jt9Z^QV^{-B;+!Dsv%qt>Cce5N(C>sO=td}dUP z`V~?>{q0wJM|FV%KK;`@qlcqqKI>n?0OK>WT|I9n$tQk;Ua>a^m&f|p_K7vYP^Or< zHz#9#x7;|f?wwGVhYp|YEFKsbHM-Af!$9Y-gC0;8c~s-k>RcCD%&EcV&fU2;`-cdZ`Z0yVfXW8!24@I7G!yA zI+s86)%#9aqPM2JN~9lg?($T35f#VcGQ6)`o;JbbGXsAuyywP`E)MfEgBG_oFmLGQ@+-xnbK?t}k2hGSip}T7 zXEf&>+FY&q;#IH)Uu&>77??Le;YVXT-Fd@ zIJOjX(e>KFz`OyP%kO4j-rLOO^WJ7I=Dp2aJYD?R5Z^6pox!@nz*|IK|Due@qXuiA zf&XjZ4-NdafqyZuhsSE&86g9=G%)}D=<0M7I&ZX&4$?q%R{20q=ua}0cufv+&| zwFcf~;O(utMH_z55IkexcMW{Vz+Z?9&X4aHNx<>PjlG3|GYs6xz&#B-#K5N;c#eUu zH1G`uzD;3O!21lr69#_Kz()-Hn}K~e^12Bm892wlr3S7vaPPcG)OfTZm~7w~#QcYW{`JJ#c9V-EkUc;GTMRxPH}F0KziQw^#HT6!uMPfD zV%>l*KZ?tU^<3;ijNK0(UGwo9>J&}%2jMD>B-YuSZt%}B_;ZQ1?IHuOCDzH@VBlK} zd}ma@t#x0Nu=X2DuNnAViAC=P@qHuB!_kJ*4cwYoXW5AuTPQxNfKxQ?W9SSc)=AbI z{7D9Xs==SF_z~&!JVUV9Fj#8vR~h_918*hP0X<;g#|`{Cv999#2L3#Z_Fcg@hJm*r z>NLZ^`39~c)=qmFc#wfd82YChc(IF_|0b6JzTLo&6YB={8TeHLziH?nHE>*EG=Y$T zi-@()_P`OBs4@iI4TJFpKG(nt4SWr;b}9_K#lW{2`g@}|Vto`PtnZ2Sp!=N|A13(t z3phn%e^FE?nOG0H41*sw_$3Cv+~9YSd^P^8zJ}5;L#f{2pJMQ*82qyh{<#K!p@AduHtP?~QjU1ac=8T=In|2l)ef!M8< zf%#Kym!DkXV&q@dMBwN92A*%=Yl(G*ZX!-q-LVxoMdO`@&V$4_BgV&LhW@h#ewSGM zx+p#+a)dBWssC(Xr*+g#60z1vC)Uk&A=aUFC&pHukKVv38jmAicit(6{+WueCc!L2 zu)r`_WbjuQc!Pm&H}Hc7-b<_--bbthdey*(TBCh8v#%)7S$=OQ{bu0g(x{^f1J@dO zjDgQL@L~h6cQNzd?GnIG82F%pe>E`vA<>jgO9OW`@JM3aH765eN6*Kpz$qHf0FJmy zbE%}ubpf$ESR21%@INEQhLn%P!2B&YAOACS{wCJ`y=6`Q+gdH6gq2M^RvG6L zYe#J)7WZ5dpWC;dSa;Jz1J5GXw(|}CB4X`lnZzO~0zW$qo!tiBN38uEF!*l~Yd;@J zEE?!1zAgAVo+JZ@iM5}$2ET$>`>B;!9H5`m4V_sAUQDe0Tw(B65o0L=v5qr|SnCuitX8TnhCwf4Y!CS82b`ku2t#KAv37c@p?{u%FE#X65#s>K z#~R=ijc;tvl}eX=8%T)>tek!T%mXbShYg({iM7vP4gG`;+Lrm} zkkC$B6XSrvM_b?&jjIfuKE>K!eZAGTKw5sWp~Z+fFv{JYwD57XvqK7q2h`s|~z` zSUcTr@b4kk4Lob$g9iTCz&{(fS;r<@++(M{br_>F+S`9%AihpTU2bSo=I=;I9n)mw{W9NA;_T z&sA;pB`(vmdmxAuEP;H~8%mRib&^vJ{w(5Cm3{-Uw!Khdk#l)`uJ|G`*earRo+Dp( z{Y!@ahX($^z<(InTM_loYjL=3wI$ZcR1sqp;G-5eMdQc-L#d8fCo|UIpJCv0h$ksW zbBVR1MFw6=tdqIHz_%E9r^0H9d7OlH`n;j^3bAhBD`K6^&jz+SMfvFl&NXmX0}n88 zT_7S45j_Vr$|56D+d3d zYXH#)2LG_Z|JLCDX7K+q`2Nn(AX)%N+^Ew)FlzqVA7|*BBCR!WFJhfpKSO^6`4d&p zqYa&D#CjZ@Z|E$J@*~!zhQW1FfpxQCu*2ZrYv@01@Lx0Z-!=G$4E^5?oL9+Y)cCUs zK`?v%i2&a%G-cn{z$ZxqmE}-Fe;oNIEB+~l&TL|x{USqWnZaKfF$``r1ltXR`wjjh zhW?8N{~bgB6N7))(6_rVV-;wD#vzg=AeeoESG>O>zGY+(g?gmc8+e>HqRqr68~g;C zeBJ+N8#;@Kbp=)$I@cNejfVbq#aDguh+*)wVX)sYc*o!$HuQfm_`e$ZNmbDbR2jGy zm<8a!9fnkipH{}FM1}gZB-CZw>x2LqD!M+HeA~?)oAF4>9lvU>1S@tC(Dk_TB8yqLQvegMsH8#upmK z%gEOgVuhh|1F^2eorcbR2LEAKpZULF2o4$s9~=BHT?6RxR>bbtO6) zxX!?1fFmpg|G_bh0-gOi23}y`Ma0@^1lYA*NxrVcYC~rWu@2~NL+9ZrKVm&$7`z%4 zSRWb&UmE;x4gJ3je)F!;Akv9-!#Tt{=q?5xC2^3G96!R4gh;vupGGbt*2b$0d=s%g zX5DV^cM;1~J#5fA`u^%`^;CX8yYkgGXHf_|F;q7Y+U!#8X)Z%X-J)e`e@^W$=G8_`e%`Uk~o$ zboR|aG?mf7tqojd-~k4%Bi4S#8vH2+e>$=5vYEi_zG4r~E6+6yE;bAp{IDLPD4B8bh$r;BO|@rMm@~j`$CsoreBHhW;Ld|GdF}nOOTd08BsfM8QXf(su^_ z*)aHB8}xB7{dz?+2oY?liX9ENV%=66vG!9ztds9fj6Dt?y@69S9%|@}Bi6Z}qWBSMaHb)cWf&|l_=^nw z6$XF3fp0W)wh@n$?yc>_I-vUv{6b%Ghlo$_`yP2Z!Osl*GqLvZe+ECUU({bn;`JNQ zCsl;nO)mr25oL!5hJK3y(Zt#gK>Kc%y$r!115YN7Qvsc2;06OPAlB7dXW&PP^%QuH7+XL- zUI0!ZX8vy&N*@vHIqCb&*1w8MjJ>raK3@t5^JC32EQBd5LeLK5DYa8>J0uw z;?ayB*HI(Z+02kwbia`c4{@B**=XSH#M<@&ga0V8_VbLyqLF^SF?4=1aNJ2zKZ(S; ztu$ioCs$%|41OX54V{q&ox*VTR6FVjaX3Lx1`pj&E%+69PnJJpjLR z4TGfyUPG+)??PJg?=y7XHt-<>|47W95#px!#E5UOCc$ZL;9O#zGq2C&c4mKK zozF;O?1K0h4Vb#JyC*-vg&;{D+|v zHze9{fLI5eN<2#0W({E{XyXD3G_E1m!?%xthZuOYfu|8`r*jPcJYwzhVgq02>Y#nA z(ItSl8Tc*(KS`_`c){SmN~{|=XyES*onH-X4TZi=tQm0A*J3Rx&iObRNxeiXB#>f5YLh-ZLP(I;0oe8DX^|0*2e237Q?n+_1QzLGkDIx zZxL(TLk9l~V(sU9iN#L($ru*(lW*V(V(q7!!S6$?{S1*<1h--pn``JSGVm&5?PtBg zZzR@!9wXL;+eeHo03R;`r)d19p>v3MmeM(@Fb5E>uw*D%!=p-Z#JYhbgP&&b^9_En z!S8I~z6Ks{=#LtX_T2_fH3X*{2Im<3xdwlUfv+-j))@R74gMB`znyp_G9Q5F-6V9m z?gy5o^Wt;?`MO*$8akgF_&bTkk()6j(nmmF53M`{mlLxwJZcSoZ(`lCbvB1276)#_xb)+A<5skVfeVPWZ99YCiCFvTCb1~L z9e&O*bY>g)Vq)#*N`rqjvG%iGVzCB(B2O4P&l~t4vG((c!9Pr_{W#dLy13ZDy$n2= zSoii!Vr)eDI0rc8B)uVBXeeDqtb2R8!C!CSTMc}lfnO%pwyzQE#{MvL;>LiF{U9IB z#$bGPv?Va)2k89IqLr{MCliO*6o^d&x1 z;YmtIt)4STOjm+)lt2;}5>He7OAP)>;xiO~v%$aHz>gXDZ3BO4;BUrp_0$>sXb65W z@LvYzXAf83Z{VPTQw*G8;9LV2xS08uxdd5rgnSrk~@HGa$*1$JJam3mbC9K;FyxqX}8Tdg1KVjgf4g7+E zUor3-20kdU8h_SDhTu~Je{JCJ4E&3M|1dDml)B?1&cHzfCmA>+Vi4H|E-)~!)ap8I zZ{P|8cQtSi1NS%ZAOnxoSmr<45KJ`iWCNdR;Ij>Uo`L5Z_+kSuHSh`pUp>L<+?3h1 zhG4ycZ!+*!iA8?L@R<*FxI6yH0{e)_F7c1VJ^N?!e&uvdwM*5KYMPT|{c zVh7(E#GibdEryojZK1f4Z?}qX@aFOL7v0wrZJGF!Z^OjU_6)CHG`5G% z9pW31xK~}b4tQH4uELwAaPfT4!n8t7mH(65DpSUtHDL1 ze48S^!JEgoT6C|Gj;^W!_po>mZ=T?FqFq;T-w=zsO5KoX@w#;zqp1J^mT4#~_~X<1h5y z<Ib(bwPF)5a02KzfQ!77yUvxwn;V zwM^g*yzQ5Tw;x)1S+wovZ*$!Jx-;S`%WFE7uOFM&`k~GJ{MB6|mkq_OGh~}Sn-^#b zj&6<{8kkW)h+Ao|4dTroUz>zC+i`GU_wsfnp5y_P+y2$y;AY+aWC-qcfYT>a;E8`O z1)Ndv?8#~X$EWW2?Y#lHdRi94E8NEI2IXBTre5ezE38Ko-Y_>N-o1Qj$K$tm3f;87 zfG|5*Y`oB)-R$~iu(kc?Iikfo!K}J>AhW!@(5o+VJK<8mxN+I&xd5T}E(HQL zMD%0mRk&y#+C`tC$H7SqodwOL&{(wFB6J5*Nei&HtCt6$!Ibw^eH-^W#}dtXNR6Zj5(nk;8vl@NH{liGRl+};;qW^Lpvc2hfV^& zKqr`x{~{AChZuL!f|(tf33ndL`vSBQikQACMMBAU)cgZ3P>L34-?qH*$Rwf7n^C2< znTR;l3jtf9iRdyrlm-ZQ6H$ePj=x7WE4owDC*2hyMtHjkL_%dD_`1oexzzbu2KOso z?T`=U@`PI8HR27mMu_P9)@UK2`$B!9gdUZh-xkui&=R!e zgm$4n;zO4sZ+~bWa%vVj45xw67L+t0bOBrhL%DF#Jk%2|LLuHZD=~CA+DZyNjY72u z^@fM!P(D1QgzDilHS`*SOS8Q9qnU&$FGa(OoW6u{T_}q)A0yBXEe8XoPC%OpXHKO- zPQol+oH%#}lbYQChgNVInn*Z@-R=uMhB1{ehvo7I*TF}^x$NX%kXH*#Xkhh|f@@)v za31GbYH%GBnM*&o<)7EfK0W^`G?3^^xF{LDk@POYNm#^+AqBw2gt)<3!omR%tF|v> z+g6MJLE;PEPlHR?l0Vo9HVF~76tukOkyt{f-Z+#p;nIAj$=@R7U@JvtTge+q=1Q`qZ6%)r_rW|Rg}+2!F!OD+ zk#Y)NQWs2}je8+d$i|EQX5*|vFj6cnQiE3Vr*u#vNgz5X%)rD*p%>+#)OFC77d=g8 zNrUaAK~}t#{5$R2OA-Tu_GRN~PbbR0qif%32kl=);UmG$(gHU+O@0=1uu_qT=W*0D z*hP^ZEBP!Iqe_yv-f?mebq`i6QngmW`(dQ8N!40c3Yl*AZ`j&=6h7EP8Z<@Qb2qn< zJ{@j1f)sjD4tgsGslklF5CliD-UaM8OOBvm80M^><$74ZirP^XsJ1%td5XRr_3 zPO=iV1k)$e35RO1FCpdw+N-qY0H^;KWISU%=@7_dj=$g_8EYJR8aL~H=S?+*^R9=u>a=i4~mh81p@{i$^8vl8-y{o8J*25&bV zoJ@$s>FiNFW!_$fF|`&sCVwK9FZH(?wj~X^(`55<8nCF-6^Usu5bJC3OhuwNsyiNQ7kM_?Z@lyW~J4Z~s)ZZ$?i}DBODxE|t`Dc>nD>7syH^Z?h zI8Twyt>jiD=PMGUvV!CSMJAvxNM4}GfR%hQ$%TqUPn|>ZLPh$mz(*V(T)0iZdG{0Ht|!nZMQ9a;$7omTqab zD$*^@&5CqObBiL~(%h;@mIl)~xJ{9nRxlTbjES z>6YdmMY^TASCMXM?o*^&n)?;$mgWIPx|P|jNVhT%s%1-;rtxx=BZc)*L+D{Da|k^a zhl6hNC!BbDl!H7gc{02BaYf>YBg^-MBHi*msYthcPbtzZ-(HewKHII|(@HFd)}AZm z(0ca@cWAw+gznIKNs;c*dRdWf{a#U|TfhG((yiaCigfFDK#^|!UQ?u7zyGQVH4UxT zmDnxd8hzjwIzN`8`)_FZL<`mN^Ndry*iO6`N$RHL)thfQi% zMYtS))TD>0esCq*k&V%@YV2cbSh)RpFpW2a4tC?9>qls1eFm-IX{Q4BwzF>H;Jlct z9Wig%a$ud$yIGgtU;jLc7i=r4+J9qKe52N{oCw?T95KPO6i zPo?(X3&Cm0WYzw+dEQ-Mgg!!x_z(jRcBn0a^@NJS_J*E7L4BdCaKw{0Pc7!f!sQOj zF4-*4;Rk)FiQRfL%soLbmUmn3LwvzoplP>h0N)>MKqPh0aF7g{hf+ zANs={NLYra-MF&JXdrF+f|-+n&aek^UwQ@=TRn{u*q1U$KC1Dw8$WEayOegzz|7$$ z!M>DsV(C@>g2=ZFaCjU7=i_EP?M5E%RglAJcNk1%CwBzhpqtMNhTFrr6}HEOzd*c) zVWX}~na6{)UB`aqz9^TwX1kuGJtnUmWnqAicBP2$CVx-< z($U%s`dRobvL`CnR`DjVw}TyJS!thu$L8h8!HohBin~_%Gb2x;U6sWKW^o_GmQ~xp z?CsGxvjTYAz>>WVS&qCnpd^1Hxs`?4$gtC3ox>fYB6)f9eC{U|iOUG*bGPYIzQP*V zY#!1QS8+xJ(Lf8|2cP}FL!5TCKP?iIM#W*S9O)+WvGW)jK{N7 z_Tf;EN~2T`+o2v+;MQ`m4)rjrh18V;S<&{mHqWs4M@U_tJ-+N-@$1$8!r`p*jI`ro zWeyy6mnybrE)tQ~>Mwi*5{AC?nYg~03a@W$WseQO^+i$FcQm=a zh^}95@_Z3Jf7|4FvEkX?D<-V*m-PE76E_QytnqlXNLoh_aKptojm<&02qIJT8__j#$0cUpBrEo6l;RKMRqn-8dx6oj+M}{_rR3tz|K?rbufg6XX0VVU%^7j|kMmg#v|fNa%LRsg`I?2#;C zulJ{kbFcNMv^oaHYX}DGfnC7?Fw82P2*voJ7H&DZ`C5NwW(pv-K1#(ZTn;HmORjho z(g?d1#?hH*b>#YPuXGoTKcH_nUYU(SDHn{D967wvM7}(}tmN?ps~$h_*(=%8XF-<3 zkAsR_PI3pQ>Qy}PbSFr;vI}^O^P+XG*LXQ@x&E~!bL^WanKL0};)AlutPyqB`vVa! zE|cJbvEvkI;dk_dz!zv<)5=o(3nY3`q^4Tf*}7cVal>rp*6|{&JN6DY=|`bwHy*%P zQAzJ$(l0V;*~vSe5^L7^(+YTmIs_$k7&$SG-Z}q}##+fV(%1$MOk+OMxC;$)F@I9? zqG>#6qybHp1{;@YWLWWxwqq%KW4D{eKAA=Ui;qfUH`C~e1A^+i-Md>;VYKWIYW-Ut z7m51y{;uNCR(~LLT$j8=K|k3UA7QvNi+RX`8U3 zf!)Z9GpeZfGU~NWQSap-(?R!#(!UO(TXX-R`aesiQT=9c;l_P4JTvY>&5Opp9TGEc zxjSI%vii8CD#PvAgM;YhZ5g zTYhlZ0coyWn&d|Zdvq?(g4$om5j8eXu5VxN7W;1SXY_8vlKhX7i5Q)EFQMP;pSglv zNHU#1e|-wl{U8fYNOygKOgD=fR>3g5$a%vd&!z0k0=XS6UJ9DOul=Jy76S+E0**nc zyGQHx6tCUruTt~wkmfBSFI}{4^k*qSEs7xz4oWbi(ce-DHfX^wN^l!2;&{}_5zjXI z!;#OATW99Oz2obO(#7+vv8;L*ZsF`y+buh96N}FdB{*>Ljn*yL|3;U8jy3(LfQz}((Y=!c*<4&_|OzjzC)5E^gC zGDEc3?9Y!7Hp#v7UIl@hYU&-9Tn3nyoJ~P1o^_EgUEbk<8QN5~0|?D-e7UuIydNsd zG#!&m@4Ho@)LKk6J&{sQs7&|POg-k@ss`@xrHncmxHZv;VuWyg2#i(W8&N` z(N73msnxnwHH$}$HLSFCHlB9lg;<)@zGRKumpqI()&6FU+?Tw=xX+;K8V^6U+GENx z__j`dLihvH!oHAlC($3Sn(F5{-zq9b{VJ?N&WT%5t;sQRt9S+^yG7|%f7`M5wsGSa zFYDDj!L8SLU9Z-&@p;%DFSn0VAeEDUFU)lPPAFfv%|DcHZW~#?NK^T)fCom68BzEd z;$iu=XkPTFa0C)}apl~R!-0*<;eZ<;GyX2uaso|j8VTHs+KqR$b2FPJGvn8>r4hNi zn5I)JT?>~m+|9Q!rSj&5(`XO zWLufc75higY`wqs_)XU@WvooklnW7roPk>aI0H{=t0w3n^t)BSnJ2{uwRnRT`>>8! z1z)*he#uPhuar2mNQ#TVmDalpMLYFjusLZ0K;=hkT?8X%x+~O~i#jgpv!)noSwO{1co?kq{i|mQ9 zvY;E`;>3dbRdyG&|A#TQzrCvD#cnNb1z;_*I><`4nZa5VK7beI-5CuWpZ9+tVcv6v zeY?L_XFQaF$c(eBc;?mRD38&FO&OLHtWROx8scII`Q-E{`}l^P1YwK0(W+lX^B~P_ycN8Ez=4A zr6qfsB#&sxh;rKWOnDcy91yl15Syi-Mqs_y&T6#esFvVUfs->3Ode0Y6>3PAV{ZZ0 zGZ+bF;d1*dVz>93?%0Qvdwd=z~)lz8KnX)zL>6W|8rLddz8E&B&KKYj2h%cIQ$ zV$^nhwE0Y2>cUiUAD}$iv`4|zy21}@INJOLOCDlIi9fgd^YPoBoE`q$aTh@?o?jr# z6@`5yyBN18i%`OsE|)pznbl4Gyagq*8?8!rWUrPZ`(m6-R0o*V_(9H^9sX4Lp@nKE zj$Sn!dv*SY!MmojTp)`I`T3W_b9?95;dw129G+i^g**MV<9UYUxbdqeGdU<Ey$hH^Kf`lp6`^Nx452nLs6BaM$YzKGQ<-<(~a*UhiIq|+{-X{xRPOX z6;tl_$7QNMqdVDWyf+ze*LTE{yZos&mDO%M_sV$oqWx023%%D?AEjH%{p!84`9Iz0 zD#gop`CGP-pRym6qH{1Y%ia~g-sR6LlzY`jB>QWyPYn9LD!Jb*<3X9bgBPk~=cs(G zf-O21x%hBNa;nAFyZs#^{4kV{h>zMc ze<8xwGUFFy#?{zL%cY2l%3s-2T&Z5M#fW?SS$*V&{Z;ApZs@j=MK~a7dvux1{WVGL zgY?AQ!!BP@nGMUD%ZZdP_#^^INspi+* z<4&B;bx)kew~$^MEHV9Fe?|+L*nBBm2}#*A;_7?-c_a8$yuDa%p3XqY)j6=Gl5T@i zl*!Yriarf=A=WdiEBd7^!cl!=6`l+pPfm};IDEjLk-|;tWPGBKdm0KNN+7!3=Wp(L zGL>4XV)A|d%&GtB=4Q1?X0;t{sH`>}m(?bnRjJHslZ?++$3wbM^*gZ#>T1=hJ^&HQ zRed%9huPLzxvB(Yh&(Th9qRr5G**IGfb@whQ1VRD{Nhl$NmQX^F-cfo7 zrAoIT9Yl1kFBU|7ErSvj6+{#j1OY*%h=76$78F4#ih}SeDhi6q_y5n#%^re$`#hWb zJ7>+`F6PPNP9Au6`On*!9o0EYn5R{`M;J_KdyytF6fWt?{cBXgM6^5c>sv zTdfsJ^f-^P6^FIb!%<@zWDduyvQ?_{rkHbdaVt*C%3(}hUU+NHhyGGyvw)}8`qHr( zhM;^UYg>C`vtEzQcco*q-WwbJxn;fm+@kxRl`iOhTz*P_bu_lMnSaCHijS?)0gW(& zTT$bJq^tKr$sT;@TGU#fSlykPS3>hIu`j{ZpvgyQ!MC+Ec1$(IUcL=t*Wb5n)u&c= zMf5-#itbP=*5P}R@-i%(&=@tFcmlkyDYP-!3o(BHn2-1c549@3pS9DegQbmgt|A+Hx7LTyN|^U$xB zzGNEdTNvwJUY|>7kV#$l6vNi_!M)VH--n!t`==CG0*RBt5*rPbd^}z zR!v$JU*W=K;;gPNmWlFM@GlsmiqrR0$bK*EM zP0I7?c)E1VcvksJvOC!^8;c@Nk{QUttV*Z7G1I@(JMFDXdJ(r$fAeYnv^guxs>H`p zTyR#1lj868ml&)b9n7M1(WjiJJCvSAW*L72=h6k)R(l)6px2F~c1i?0a(vp==K53v zSC0$LFIu0lAvCWP9U|)!NAiKP6{~Z7;z_*hq7r_&#jChHtj5``bs{#+&kZ5qd0UGFcHkq z#YXAx&-&KVLpLZkis#$6C^o;5HF6==2y<02vTuMH&DbdY-ONCJHnI&nnp_ifKO<9p z>IGEcCiDG%Yj*t+mvdzd8OX9<|UT4*VpBDJD2I0YFj+(rAn|W=)2cbK>JJWm~-2tGL)!tbV!nn`q|5 zYG^qpTB@Hn$5+haBp8Th@T5*;&k`{rd;CRE>rH* zJdKiz=Y*aERTm?9UzL-n6B`9|o{l??pH&}Op|+~?BQnBS9IMe_g@E$B4%m#eY(J5`_JeN0Q!x_V2hqu-T5weZHrGZkNA%LvPGA8{CW=W z*nKTqqUZRIyEm$3f5gFe+!%k$UtQcl;2n25y5*b5lyB^w*>VPse8(-1YOxR}2j7WT zwpfVf`A!@%u;s4^nD4mVF)fF~l<&A%F)i*v<9x?F-r{A1#CKB778z)e@8sGo19A9M zaJ~omTAV@re3$=UiwuOvcg&}2bGOF7)-2WTP8r#`(wRDK%p|>i<=QiU$2X4;ij6Dt zV*@=CZ4GbZ%C$3M1NdI{f87$Xx8%>&()>;I{*Yn$!R7i3q0VKKI^Y}+$2O^vS~sG@Dv6ZHewY;#}vw5TRcn<{Qgnck$RNr6*;$_=AO zP8(UjbQ{PfO^dk4CA>FP$;p`&VBc6x-dDbo25gF%u0~=%P4!rVK&IKuas{d3>1wpl z`(jp#ZcpKz*)}nzW&B^Xsb-UA4V$XAV-jnw?b$9+XGHjMtm?j7 zaLVEJwBRLz*9m@G@K(V)1s@T7Oz=;Fxxk>^cDmt^5j2+NQ6Q z)mXvT37)F%crMVl<|{(ATJUXt&@4f{zRSOK==kDz9!8!Sw_;6Wl2V?Ryn^i-OUDrwYDZ z@I!+6M<<@2R|Ovu{FC5pETh_<`8V(c@Cd;-2);$|{envbe<1jP;Br`oz2NZA45eHX z9QFzdML|o!eFV=G{2#%O3SK36i{L$ik4HG{oQ()h9Ij(tKrID#6MVDadjvlv_#MF? z3qCCPlx8#kob#d}0T(bYh)ltC1?#K4ch(5~V8P=B&lLP0!HV!L8e1TEso*t&-xd6+;BN%uKTPo-b+#LQ zxIytaNpP0n`hr^u?k4yu!Pf}BQSjZRjQmxpfCuOZeqHcZ!M_QP=DnRwfWI#Gm|w(s zTqwAW;GX2LtvpN=@PD(s%5wzYC-@1$%LK0zyj}2K!AAv$PYWT6Ur5-1^p_KsbA-M? zaBIOm1P>KFUoijI(euxL%LJSAZ-Xd!U+_M`#{{1d9E&?u&uK-$H3T;j+)i-s1hnr} z9w7>D5PXZ^`vsQ>eo63p!S4zFLh$zH2?I6#OXooZxue!+XJ16wE)A^z;n`w-9`}-~ka1JEJ0kGfD8xg6|cq1TPl6 zQt;b?cMASO@KMcIq0jO9MHHMD9KuH&FSB&Pxq=%BZXl$DDSJo8Ei-pZAWE}1=kC{iEN{uN46RNSLl}uenZ%7BHQeDl5qy|^$|G5@|P7xM~sfr$Y%e8 zsC-s%EWS@}!+prM;ZbCp%mksoL+~TQ<_V$yT5txw4D;ft zMnFHLYLRZ24$u^lQ$=1;b<|Vn z`;#l{ww%G>6w9N9%|x=zY^u=TEcCYv{R7~z=X9AUSV6WEd^MP-;tKJ~VNkA(e~ zLVr-`e-!+e;5Z~`{e+zm1>0B>n2puO7poPiw_}zasi1$$=IINBzKO7JBlI1GzL(JV z*LpMmoDrg6jHob4=%xKQtf`3Zq=Q-=tUpdl1mf#}tEhg$V?*~Vs=&|fQfdZ`WapDhaR zEG@v-)k6QU&@T}BXUS7dV@t_4pcR6*k!=rsB=`%mccnc{!8-ay7@Z|sr`(R&<4R=f zG+S_O!41jQXM3T)oNRrDhYDe);3vtp+n187n=D@fr&wMiY&MZ+8=H59{$s%hgw0{2 zH|O683R6twQ)Jt~AA%Dx)4hz-1m_6OCtE+wg}yD>`n*E$hzzykjXp1%LUvP@$=c%_HvW{%+-xYjN@Nx1)bER~Cq+lJL z5nK-Isn;v1g0lqYktaI()lBGHldaFbg2RFr=7eEnBVEFRddAT*aEj&C)LWak$u`S( zg#H8a^``E}LVrNm9~Sx_Jx2S^IZpt`REsoFL2x?R22ow;^Mt;k&^HzOwnE>DY!mAV z4tv5F7PuyZiGpVezLjjVd`RdO**aY$c#W{xD0oMN!_FQG*6EQ*fpd&(ot_gMjVq3) zuS~WoTxBK@ElR$F2M_h&0@hX3tlhm-x0h|*c=H9;e_Bb zqC#ekNX8w=b{_O3H!unG1*cdZCTu2E`woW?;{S{=dhXhY3 zwL$(-15fUr4r2mka%yWZOgU3jI!De?aI@lEb#bZ=&Fws1VA9kEaKc8%UK3fazd%~Nd z;A67wu6^Xj#?e<`Zd%CKF=6v7+4k01p^wUo=;O)OXR61{KSvnll5GPW1rHZIn`|B3 zMK03uIQM|PUHcvpHcyjnaEpchHE`)~9^Mj0TZGXr@>tWr9{O#*oz@ZDHe%#lA-J#LA!O_HdZC|6wm#>y{ahFyB3mav3;h{eQHNP4;xLtL1IrSeC%BMoeYO+& za2Eowobnl`X9*F>93mA zrX7*H_$qZ#?3xj*LAEZM2z_(1bN9!b{c&|zRdXi1gtmagZQC9z< zHwv2_g7*mil5BmR5c=@X6l`44g%PeJxTD}Pg6|Ui7}@sC^JF{fuL}L^!hW04n=9j9 zQQ@Gda8y+IUFc(RXXQ1JNVW}EB->=_3+^lU39?=FmNev?Z*9921>XLKtA)`?O-4{uAesZF+yE))7TWb5>D!NY~kc)^ne z&n8=+_kl~lzIuoS*6B-ve-IptTSl+zlF4mNmKDL?_Ji5NrViO#Erh;#L?3qAh=MD~ zR~x52h5pJ&1!p+fHauSNY_gpPcL<&*_))U;|Gd_RO=GW7u#@5~a(koS4EFX1+$C&2 zC)>;p2>tg$e^TgwCyz8f&k228a+647Nt)H}-H~OXm@1o8Te9`hN9YIXYR30S!Bd6J z9Km-9o=>(upBDP?1`4)AwvjuU2HppI`=xy*Yz~oaha469Uj_doY@%@A?D;Q89%1}v zl4sj5?5YW)dZs{IH5B@mLf=m4y9<3Ep&u&rSCegG*9yL^2-Cvr_Ip`ihu~qsC1e}* z%R;}3Y@Kc;&oG(2FZ7=XK2Em&fAN^p@|-7tewEO#6Z&_AeuvR>j^ICoM8OxL!Z$*HOz3|V`m;hG)hv=g zJlSTSBJ^own|nQK6^cL4rq;Z39z; zeiqp_@L$2}1b<4t#q``ka(BbuG)Ma>R`^jE{Xw2>jQ$b&5N_o>N0kNV2`&=chCI~x z=}5M1_3&8r{UT7o`yOHjwRRGOMa>6={xPp6oIWl1bz$?i;O&BUlWjDIg+BZ}1smEa z!LcnP0VN7f6P!aHYEo<{^u=WBv#sEP!e)eFGYKY$f+^&o#_1hGe-GI@eNOOl!CQp= zPQjlF{)#-*`2Vpb*A3h4r&(YdNN5$|N`mW=t$mT;)`Gi`Z3BaaemL3sztLmnzr+*3 zo5{DB=ys8N8r}^~vAkc{d`Gsk^@Py>Avmse#Ah;ji1C>UPVgGYVnI)J>dVN&)R`)q zY%fu7q|lGk)r`N}1V1DAE%GhKW(T>q;ay;Ei_6#N!X|u#f=%jsQQ<8nApD*t3~O zwhcTa^iKGwm)mJFQJBsoTNif={d`>wzVLcM@Jh|3CuHY2Q1BA^;vK`*BLO)IL?SdZ^{FLAq$X7bo>egPSU>jQ_ zco*6B%4dSV7W_T=N)z;1q5p?$ea3Ylt4RkV9o~Q{>$;e1U0g2oJ#{tXdXV6W!e*x6 zTLs@kwmzQ_`tTwOHm>!8-x0h|R5&8|gy7R;+dxc5uuaA#TmLl$*Efta7_SbZLU+Lf z1P>?M1||vp46<$DLBTHy-Yxi);9w`NAhvQ*C$OD*ZOH>oS9b(+CtbdJ37f0PvyFa) z&`%V6qp-O}=nM!M~ENpJ;rtD*f^_ z2*Gp8kDVUZCR?Ws1veMmfoz@j7y7HnHqgpc2_elr6YO*t8bhMR0Gj4e@HB509r{olX`!R~S7g_;JC{ zlC9HKLjMNY`us%j0l~i*dvgk%GlK4^Xnff7GA>894OA8S8f4o*E5U;V-z9j7;EjU! zU(Qp=o;KgJz;^X7WUK#&Y(KlFUlGyQBu_V^n=kZ5WP8ifTnmA`CXvW^>u`*f#4#+mkDkwxTE0if_n=d zBzVZ$SHBC48;RY0D|HF>#IC;McsQxn@^DtgU5>*fHIRqhYAFw=)fpW8p=j0RieL|a zjcB!i#}?7*7>?M5xM^2dolRa$pwSEzB_ zwd1uo_$#<7z6Z2#s)0SAJ*$@Tut=TZVUz0I6NhO^;owh8QpbA2^aa(l7qow=xjal$ zpX1%CuF|VQ;-v{C&YAr-;gdEowhXZOL4}YnpIQSc< zsk429+ps0`#(vO#p%VK;+ag1a=pUScJ&r$z=NB)JZvN&>)D{sihFH+w>V8POHv?QCOU-77Rw=9Q8fL7I~`pN{GAE z+$&-9g8H0?ld9HLILuKqdDx`3^YEamGz2yBiq!ZasL@ZYg^1pW8;ZkOHIRp6YAFwI zsxv&G$zeErp%f1Og7)gzFjSnSnhu9px3ju?IK(09bBNg3y4DC?b0!am)@~mWJRc1Y z+s6d!_~xo##{{d#mR#k-)`}`)Y_OW|plUrfSj%^Z8pp#6>H!@5pOvWWRWYgR!?D36 zfALOrXlyXo*F?pQLs`a0s$d+%yVO94@Epb=rsnI8^Qn4iT(G+D5A_l48t+tX=J--o z!uVhkx-e@zbQOM5UB;vCVs!&VWT|)mHBVE{^;m~894Z2`^Mr~ zzT7vnbW`P~aS;45pQZB)1#7!6q2ZpyM~J1iSYJ!EPgTfzO@GwA~sm4BcKRjB}5%87J;J z*d#^=Dt!fI@*4C+AWeIXPjixYDc`DKL4B>wF4Yc0Yk?dsCdE6+ZQv(RO^g0mY!0i2 zuL`zK`UCwN$T!+5PV!3i3OpsPTxyZ*i4=%kxixA+V=K8cSO2(;-Gg+63T9fQ$G>FO*f zJ89=pnNISE@(?>4v9gnV6x|Z&V#G>La&P5(9Rc;uhPJEL;-CAHm#F%$2U}-_Fr@;0 zwbq~EB+q6y^fMwnZBX-G4;Hjs#2AKYZ8VIw(f@EGqC@-B#Rx6>&>a6IB{0&6sZR0} z>JPX`dI+;3FkWkulHfu$TZ2K+-F$=b1jj=w!)THgqtcz^N|>90$wt(k6zW{lyBxH$ zv^EwY-oQFHYSE8iR$_7nW*ZT88nN^yE&3{=0S?t1Q<~x=KZO|^xY?AJcao@)) zjO+2`8!O+z+59DniJ}QwZXde`8%hhqz!J?PCE?98Ya-3rUr3=~D({Zi@78nuf-NM!%*CP9R0ZX4SBC@@j zvv#2ok!@#=c!?1);Dxv6T?y5MEFZk$^eZ0*~on!lkBH@y*TzdK1c^&&{gK>mz<3FMW-ZUbz+n{3B2Mex!l)d+k(c(0Cmp#ALi0HNtIfdRe zB4#Z2>kDi%BC_njy4#J26KgKh+F?X=>f@~Yo)IxEQj^u9^}%sj!`T;mwAvqZlDo6P zkBx{k_>juofT_E%0<`-~T}0J^Q|e1&gfMDi!3pd)r3hm#C+Ptr>ht?yxXAjOQ|g;i z7e~09d}~A`_M|!jqi}O(Fos)mIZ6F_I$k#kb1gdQBztl?A5;`d`kp7(?d33Il9Kp8 zB!Ne6g-wN||1!VlKSw$lNiUIKu7nQAPU1sb0;>mtYa}h@Jln*lgc- z1>3dJD`~t>tNocys$Pu)MvkxOr0OXaG%{AJ^rM?wgAIIltDn(GxE+^( zhPJellN#b#-^j|TPHHS0ZER)q$KTPAn^?JmliG@lV3C#4AzeBBnp(NMlgbA)1d6Sk z?4&lJ+|0^J&ef@lIkzseibN+hKMitoD5_2}(y)V9sRtiqn00DY{wijx|k`@UAj?0cTw)X&No+bdM+ zmS7eJr3i=Q7!KKBTZ&E|tHwfIn82Qk!9R>U?&HOFD(%UDhVbF49D z*)q<`o2`rv=*I55#mbmvqi7$tGG>|LYI>`c(KFxke7nuc=$UD1!&c1sYt#uGatfIF z-L@1x5zS@f9xJ0Kj;iMG2D93|%PBL@s*!LT264ZYk?oOBojE^YWlWjNh@PH z_@3kQl$CKN|HG@&(^gJ(%BOzHd=^;+I{9vO>oyF*Xtih?I%OQqpSPu$JgwPDORbFa zuvndfb+`e0_C>44=~kOrykupZZduG?xs}nkeVE0|Rz}}uvXfr1GG^IOp1!YI8MCYr z$6|$*(dp;e$t$fK?WpwF_`sMk2&|S`fYo#ars4DNH-gG z1_sVeR?T+=8-?pJmJHsSJ4wH@ciZOSY>rM!$M_qUCcxa~+_(0Fih(i-;g@nYDt zNQ&jz@kaw_zRg&Hd*VQp?@0*9GFz9#=R9@W8K@Kk8=mYJl?&P1L)p~#Ube4MhEU|(1hG?&|&4=!_XwS zHzL49_X|GAC&_JyPYcQJPY9vB%N;;d+!^2s?u&@0qB|3vl(uS<2djtg!qCUNn-D<2eGG#bbQj~N>;8;j`niAOXMZ<<(g9A?8!&a7u%{AR zxXovxBa(iCL$}2kcy*Ha1R}R3IXdY$ns8f@~NJCXB}-e3@&$#s)fVYawk z$OTFBFzejQ$&HiRv+fn-VkatvEqCPu7=mH_fz|Ex46$4 zxczQNshKJ6;61eDLyjGnk8Sa}3ha0Pfww3p>c8xxVap@-qt4NO59W*Geuba-IF4HI zd_AKc7d{X%y{-<*-D7a%bMpd!_a^*|b)xp+;6D69#B#yUw2VXdIc_EV^trWoMmbSi(Xnm`pMbzL za6-7xRAemOp?BP?kpUWR!eL+hSH#`2j&>@DTyJ}a zmWy>~u4QIUR10*P``(KYn-7zD0&uJx_fO1!pZh;_kl*DKDx%y}Op<7~Eygn@?3Tx3 z5$iU@&p5XNW`4XA#ivBMUwjC6i51+hM#5E6He2|5EBrZ0<&lqjur4qHk5M1tgi3OvT5&#nlL0@8A@|ry`dh&B=lCo7?*o#)#G>N<@Cuyxl0M_v zdV=gvdYJl?oIBA;^Etr(;}k)Fr&#;P>)!Oe_^^e1j{5uRR}ZzZRu6 zF(aLwJ@8BYj)1*@|5R0zPXxQ94EG8iu?2^#s@`7(+o``k3I@{;!}2%uZY}PV7<6*q zg3(FnYN)K;!TcCvUt+eJxH}ls^6f@`5^|z$kuk8vud=k`yu0DU$sG#q8EAjUpwjy^ z{N&D9x!0i}swWn0mAxmJRh2f4vZYO-lY2L85@6Fu4c!y0Y?}GZHuG|}Z04wKX4?fW z&4Y~i$?8n0wWe8X zE(&lzwsS>*VFvh9&C-DK*8N+6Y(WPYbmACP_U)JuzPVoKK7&YnCAZb`qMgfV&z43z zm(h0hqm({3`w)CzDn(zd zOQbji+qQZsPJ#pWInJuQClQ%920Y93{9y|^MeO*;OltoWhghHTQoKc{*t)it;!{lV z9COn1=P9N*E(&5C4WHsI)ZG-Zw6}!J%iS`_HI{L#IAnMuH6HYIc+vvPY0PfsY5oYGXR}Bc4lXW*==!a z?pyAq&V6!xB|qkSsV`^hKQTF-`f{dzRkWA-a;82f+G(hBha2YlB#L#e|G>+oa!pas z><_kAyT1+w6ZF;VPMgt0Q}EzXufR+7Jr;D=Q}`=5_LA)JZ%MLcon!?kj=5wPR76_q zyd;OlGRc21PUbdX9g}>US?MI#G0FBZUXtsWf8(j#gagaZuuD$y4t6)&4{{xyt`leMUZ!ki!!)#S%Qs?W3 zUdQ^ptoP}m{i8lESo-EC*2lCnG4t!_v}1kDdlKZjzp%SveYCYVK+z3!n)sOFTzoxz zz1}7AOv2Wy$AVqDK7?w##i;>@95~+M@S@EbTWochp}8MGR}o82AI}cfdI!;5KZ1V@ zXX<1%=U}jM4Dms=kQi0Rab8vHfnnl@WvcQX0axB))L&K|pYO{QJ9)gHk!MM4^m*9C z@wQekfB7E;&+c?EA@Nk!aum~O19yYV4(TYJ-wRdqjp3q?J>1ZL~1G4Xc7 zu;!&E%v%j~M<(__8$2uW%vqr)OW2HR{Z6T9zm|`S3}5Z^sID#a!l|Xhse{%`G_`az zin3m6)VDmpj zy)(B>nU2@XQNDiqSfkQOI|r+-ucUV)FTF-Oy?v$WHPYz~!w{MD8tL>FK-LM3M8%jW zT!{W{+D>YCiG+4Gyi`KDjdVil)X`v!J{Mb}0dX$Q;-w6EMpS0iWgL1zs_4Wqnfx?< z(&%2A<}Er+{)eEMRNZx&A2Tg|Zg$scwhDS_c1N1Eu~QEeI#1TT)WB87UN!s#;!Ubt zZ>gQ$_)=-^Zd@i!{(oa6r@Yx0r>WQ3{0}iOzOkigZRXS}sZr#mHCCr}E7QT^ive z9bspD8KV1{h8IO>0*rD#DAEy@zo?`09y?~QTrE)llJV(@@drM*`(~HMw@3Hje~P{M zX6yLIBOcR(vvqtMDDyKjYQBOR2fTP6Lq!{JN+JsMrM80!*oiG>yxq(xd$(1NEM{+Z zxo!bup0U&6ff4gwip#UNRF>XLu?ao3v3(xn%x}Rta7SqdAET15>)`qu9t%xt_Dh1;{)zl8f@GaYW&3-@g}@WTD@-@;`JI$Z1+$Dr~HDWO+za=99WH;dYC8OW-Qh04f45kmftF;&Iavg2~!Z97ZT!(uH z<>+jLyWB_H#SE99cNRgoRJ5a7T_W1ITj`0fR{S1}&S1!&wbCIQN9Oj*X~LZq&;Jyx zczqu%JOQ-Bq^97fxvN@()E45Lt$tC-4wQV0)1&1@CHqiP53_9GMI}d3G8UsbS>1Lj zSTS7YIv5*$A8N$$>plG$j9Kd*EbqiU2+lu_A@pr5odZX>oRwVJ*6Y-bx>MgR?bMCB zQwy<7)XBxIJ8QzV51(cVri>Yl`CswpV3i#9FMV99e{WR1fA;RTz3bwq)U{Xq2y)@= zOoO((EVffu{1Ob-W1sWia?qo;&-1?impgI2s6VT2`z2VR^BwKHWK#UR_a2R4%?wHL z^WJ+cWIZDuhT)|mj%s&_88NJ#SqdM;Ffh0&aN?bXkN6@hcj;NkR`dv@I&lmw|8-s) zYx=zp4E0dSS2DA`7j#V>H22r2GZUW(VaadCJD^gXgmf+QOZ8d`3Z2DV)Vx#{-P$vY z&Z^gM_C{(Hj73-SY2sxjke)U4sbfyU_d($NO<1RVtx98FkK}zNSK$(8Zlqf2n13jZ zv6Y`O4#3xfIz$@AaDTRcyFV=GP$tICuof}$>?sqYnaSIEN$Fl1QwIF|O4fJuV(PAA zT80?R;CI)9{}*N5kKJ{QJyRe*=SS5Z{*D~9p6NzcSbb&bL2#wP8Z~C(wV5!`GB%c zXQECgyCP(r&J9S%ai&t%+1#MB*#=o>L&ulO=HX5{MtmQqZafiebMY^QlmA(sjU$r?KtS~OF3!>6l&DU9_qr2-YLukJFe*OlgFXd2-mic>@+bCa_4fz58 zR!oOyA?qyY=u%l6>1^iJ?mz6@|J?+szqHvMnN*Y=bJzL}E_J?zr8DYA6kuE1(qI?r zVBcXdI@pCe*uTACXn2WWqMQ|7%0#mj*61>Q4?SH(!*#=aczF+tuy3(W7&_-lynQ7% zU5?gu*Dco3)WL~qqFJn?83S2&&3!N|6HQ(lxWHE(YRZXVC)Mj*Ft!}6^od^8iMvU? z{AVz|ec=^e3oq&x9xiR+Mcu-AuZ6ZS{Pz~@35^E&(nvRu>BP}<{(?B9v9`32XXw>$ zQCF|cwYtqdX^{12m$iDDFQI&ptKVAxcD3wWFi+pdu0XXi5#-t&oyuJ=aY|0_8kxNM z!{t195tDbyCDueXrZY));uvp!3tk96D9z+eJwE%od6|5mGwF_?O(q}cOcp`b<3qz3 zp8o%~CJt7Gf0w;puBNU%Z(4(SyzuOR18)MYgBN?kaYETkeM%+e`zM%Eu2~N+roH}W zRL(!a>Q~&wxwY3n2DZNbb>HPpz+OM?d;=Oz88glCeWCNxk+z2VQoa0ochk$=;Yfe# zxedT?(~^3ai+G*$!Jw~!Dmov`Z^-+Pa{W-qx9&hz|hgJMP+|pK##2T+N~n zT*u)%p?1^1;_*i%c*hU&6>+x{z7zjfv=CF8@5HZ)hGBg8j{UOegCOeR9lNinA7bP? z=5bZHIRo3-9`?0YPd%NT^ZJ+WtmerV?Yz6TcMErTjHmbZ*X`C(^-l1otliSqeY3PM zvM2A_n>)Kz>iV$v?ld>e*HG=A=BDGY==1Vv{-TEJwnwX`tCdsTBIW-Dd-E1H(|h3h ziwad?rHr(wqQYXmd#)Ng&CS%?=0+D4HYrqlIz*?b%#P7jln?&&4!W$Z7~dl<-BRdPm(({d=_UcX`hq+GkOj-E)fyipuPsi|oqm zk_%0J(61-pV_kw>Fd|t4NPX-7p zjP=WLDj7j@b-@h;Hy7Mla9_d01?yc_W^0$uETMlu@T2_QtJgUTMZvRz-w?b}F#m$z ztGiS1$AXUw{z>p}9y9;HJOP}-kBhTS)ain=1lJT?S8#j5dS?~ur>D>l5PUtj^wC&T zMZs*r4+&O+pA!7K;0=N|3*I64V1!#aMKFO7H~1Hwc~~_ECw_lqz(FF1g|AoBJoNg&(I(#SU$N0~xji)Y#AoNGb z){owC#d2I0^fn&;-I|wXmeAKETl*rT#|JLFI*JNCM1_8$!Wf~SChTw4diCwJxW4#T zaX+Yk2}dWkNX8bMYjF%g3!N0wmEGVd{S^sPQ<3B z;8udCk-dw{EfjDY%h&B-Zv)Qzjgi(XvYj&}LeD)-y!p0@JW-oF>&VvUX2GA6ZNi82 zMk!V}E((4T991piv>e&mr;u#}bp>}6JWR0Oa>Uv{=;^}68$YM0w?6+6 zoLB>T(~DszEh0EMg7XD8CtIf-g}y7oE$pfkndTd9rO_ zz2HM++l@bv6OErA!TR@I5dRQ1Q8i&>doiAD>y~dK3Mz>Ly(P$X#%V6~wt)tk)sCo8 z)pi5PF~(+u;K^iLSMU5`ZEmC9`ngxL%8L$F4ZlXVHX8)*B3nOugoHfzmVyZQ}8cQ;I9>Fz!jWB zwodZ}Hxk@JaCfo|dZ5q`CEElhgTtPnSYXHR88W`-+0P{ ztj!o**Z7>MSxus!$3$Jd3f3El*mx?|j>KGr zZ1ZX$xIftr(r_}q=izG z(B{q?WE;d5!C%zoNoIRaZ$4uA2O3%aRd95E#AyQA+EgIh1~LUV5;iRacl4MiSr1PD z4<}DBQBM&18_2eSS%T*a8zoq8L}G(mCiLsc*8f&;*vsI37T5;9793p%dONNOWPJI? zS9x%XcrcrDFp7X9=THiHCDAltyF z3jK{_>*sdO>I?V@zbI^03D&!nSU(>M{inLF>6oMB$%an|{aK-pt_K@CvWaAT#ljai z;!8=l5ALffjB1nZ(AF3FWL6Fi&ahg)Rz?3l26w zW46~TlJQ*yU+G|egTq%1Vbg$YJH4^cw-)*iLf^AN<4A>mqF@+#tZ85r**12aX7ykK zM&J>$?Ug45ze2Wk*9raGWb0?UW_1dF!Y72yX~8iC5kHA!+g25_?G(MA2tLE}l@EQ2 zZ{-R)ns4zz8rwYEAJVsY_ZYSG@@6)UfC8C2?k!{d#3jTm> z>wYfuUy-e!?=-76N$`_U81Yj{a30zEX(;r?Wb3D`X0-@@!V`qe6v20pt)Kga{$aB9 zvsCa~WIF&m$XTWzc7anYe=cl}kY_l*q7gYDjr> z`rpDPwh?S>YnBI(Ymu#=V)A5@Z!4kiD)i&XwtuFO@u8ou8Q_#0`?=&cVKk3y zPltzuzC`Gs5&Gpqzf$NokVl!uHj!<^?+HHGNX<$KrMCN-I-B^Pf?X~@)(5vk@ocJ) zt-l(Y)$SAwN;hHCU+`G6^)pH6XOOKQ{DKCo3MybwmI|8{g1K>t=VzzT?;%@1N62Pj;Z0=Q>30f#lx*wj-Ak;^67@ji>`Lmt6+>y^y~6&W;8UXRpF-~xMPjHRIG=1g zq6xXCiMbg##c~H>(~~^I>8!2#iGty#KODs+ zzb)$S5H=s`y2j_{n$>Rj37;1>@l7K>)5$i5>Oxm_iC($@wz1BFhmvh)jTL;uW#LG{EKzU|**bk#=pQHB2A&nXPS|V~ z{J!8%1nX@==pXGnKZ=6WWZOV|^9a``&o)^$BjfV|UoFAjj^tg0O<(d1V>3wTM+yCS zaIWWc3JZps3Ny*Jfm=1J9aS*rULf0UTq$@9+1A}9^dFP0pZ%IuUIyk|REvloy=92? znMu9%Q%l&?BU?Xh1&<@!PMJc+Ej(Y`D8$?K`Zi%RkL=C4heSb%DbSUl5&Gpqzf$No zkcVhnK~ z^}`KEy!)}eLVrqduyw?~hTv9)ITnsHNEA#F941dT9q~Nbj>bwdZf5y<9h_o$ld#!I zwxh9I==Tf#q1NGu(-WfLoM5+2#8DF222q)OB_hBps}0x&ktetn*^W|Y!M!|2`_5ob z0AEA4PNxa|Y_e_O4#AHLn`Z^TBzU#pcgfcON8r-$6+dHvZQyIcr^z;hzXiv(jp!2v zXOnFM`9fbnw*K3a&9H`@&Z3}Sq`(? zKM&W^QepHO*-nYILcc}mw+sCq@<8KsFWEM5P_r6e14-%~Ol*=#9bjWQhivQC5&A;1 z_0x`Qlk6h&{e^xc*(P}%8COWYCV{cDGS>^oxk(uPhisF)Pv{>L`h`OOywJZS^lOBE zgV1ji`kneWVK%zYSTI1x<9tcBk$$6DEw735NAH1Rd#FN3*jU#4q1d_&guV&c`e~(E zg>upBV};EPf^Q{TKlci~-VVk3d4_u1>r2U2zgp-wk!@Z($+&{?^$|FwmF@K}h0#&6 z?e!mo{x_ljQ|MzlMeKuQ+gL@RuPpR6g+9MiUZg@}7W6mKH6zIZ|u50X{)T~y(PxxI?_d~%4$=1(tq5p|&$ zv7n7QkcVD*gKT?li{MX0<*$VP8?wzz@6=+sTo>qV_Gx4+rF><8Q!LjKHVw(%7c@;p zK|52RD|Z%py=_Zht#$@bZ=DX;tTxp~GIPl`8NE}BQFuWPJK&!OeQvIJQN>OshlkyWs2L> zM{%`)E^ZTusl+XU_ZU?Hu$Rt473zuYkWS#>PpYL_EP(cyx^DrrtJQuU7OOgsP`XuZ;Nd#uE`(8q25QJc6uzlmf`|uApQAQZsJfLv zyIL(Qfp&;G!9zFI{7L$4tmZw5!d+@VMC>zE=P4XMRX6c4NA1MHU!$qYcp5e@sB52w zShrZcNpYTX7s2SHx{8NK)Jr({TU@68S`_*b8J>6s+Ci%Mv(Of|Rr8)jl}TzpL^!JR z9JEOt)tu*`J*9R+#I8nF7UOWMx|W9#Y6B1BmAeFoUFs?v{4M&cUu4+nqtaCKlQ3P-CtFF-p)-NeHpwG#)wGfrhJLm}E+ z2JJevfrnkneNjtS@o-4J#KR(Wj)xJd>q|I%s}}OGK%KzBUocg*SPnPi*WR~0^ivGd zyy-QR-mP}N7OLZGuFkv`sva}%W}mZ2WvvQT_q$4USQX06&wT>VDz0o+1^)C|Y+VkI zNCmgCa@`&35!m}KQyW%=Y9X_4aPVLKy6Sb4FSY!rGS+ElRO8j~K6?!wGQlgYeRmSuLig&Ap5My1R&v~cZqYoxj!2MhJ zydOU*)La{A2Xy?azE7Ul3V8FiiG1e~b4SCcoYlV5}~;#Xju!*)r_Rnopt-F~xS z>$qz%c0M;RfD(5pYwJfPN4xcc_`gplYCs%9N_(A7_M-Ke0o{;Yh#2)N>ck8j0y#Fi zEq?la{zdA+eWA4Whfpc@fla7{M>jtKr?HPrfI%>t>BMi?26p#y&baysT<&o8hntD$ zV%=#_$GHXS#J*6~xUR^|@3vP-Uxq4l-vS|!z6s^g!Bi(P4_*S5wTQp9OWc704^%N? z1t+mGTm~|XnBpW>p>d`W%R7k$uA2O1C?h-qc?7bx+MnPgHpWl{a*T*=jPUqiY_Va) zpp&?fE~^_c-bwt1Vhtn4I*E6)ZcQUbJBj}wnLw@){Z1mE@f4_KLlF{f-Ll z4^>H;kHHPp(`DFmDDiRCbbqKdu1quchYHd^V$%8hG1yK5A5R=8tb%r<6ZWf3`$H9y z=F)GA(zsV!D$!nc@{jOmhGd>nHR)FBYHvHU_>v7Nk;U7m~2EZh$%+&f|zPVFNkSI z^n#eaNzMN{ls{w!C*)1K%#T(FaN^7{rf79ANA6}LqSanF`2)8Y5v~47HW@EQ1`)vMfe$5SPP{q5+*X` z61KWJ;Zyo~lDsbA2z|$<)l#s;Ai^y9OGRV)6cO>*CKTF<~a4Y#a z^6rE<_V{A*rwL1_Uqb#OftvvYo+lqj=s;ddK9q1J`33T~31frJAuOYCEMXZ7UL>DP z_>}w-`BcIo@^bR&1iih}%jB~OAF7uRhg$gFQ$HLIRjJ$`J%wk*BN3mQi1p6z?m&;= zVgB!`tRtb+a-EU8;|9?iKDU!`j}chBNylpBq4i*}RnGsexp z&saAPKjYk$7!o`;y%Xj`@Ur@d%3KG6trvpb`MQB8@e{iPV1dI^=Rd*4FxY-h#Inoh zwEPym{i$jZZ*TDBAQ6k8j91VYqkHa4<1E%jy4O&x?nw>!)ocOIPi z+OxUMY+8YcOoLrj zj;;~=P~;@=_249!M^QidON+c?$(n@ZmY@kfsv{LS1D*S8A??P11%M^x)I+C2?Gm(d zyjA|Lb{`G3H@ekU*IDI!7i#a)t~&2h7t~UFj)scUhM*jyas)rvP{mIHcnJBUYU6kK zqqBbH5tB}D6w||*V$&PN^zNegEBk2_XE$#TYs4cHBl`O5@JGW1!*`sTXK<4FuA%A2 zFs<1GKYZ6xJW8=8jC_+Qo~5`2qg2l~nQ|&hvR(pADD{<%A-k|AUP#nEk*IrO0!rCE ze$wUO`FBbMW!Ldh1vyU*jLdY!x~l3dXW1 zFIl~P4BN{#hob2#P_#|PWYmuus)kJo3Z0xM(ADcvaODLB1y0TjDAtOKUwt?WxCgtGy zUN4SGI*#-TUL5x_jz>5tcz)D|zHHN8%cs%u$xy3sM|jwS-iU`Sdt@rkg6p6=V0#F% zIS1%WM}mj=vBAvsO#ERll4&}U{U|U!@-QR$(2L{*^#2-3G@4nX9y}RpA7&Kq!_JF> zxm^?m9qB0WICnOd`3}#j5-*B-bQH_+(bYsz!YJY~HFSSaZ%??~I8%{DXxDB zqE}$9+bqC#EWFO7>t?g(dG%J?;@+mXVl?KKlfBy(S3j$ZbAsRP>c}slY7KM(Kj|f^pAP>_mD2EWB3yVL465=k7msCC%r)Z8Uqiv5 zUbmiPSX{T-_?}kDr$gzTzRkd+!Sn?(%EuF66yCKSz#Wb+%J(9yxlyTZo!g1o6XK%I zdrVC_?F|)Yuy<|FV5gYOSzTw2=WTzh5`GJ%cRZNsHSOxAdBd8gn|6IC*b`=DrrD*= z#D_93wJ^8o#>{e;a{^ZIc^%A~JYUJRRlSBQ=!Wx=uFjDKWtytqnE9yPzlYj%s`o0^(EfS5uEt!$%NL ze~f=keV5jV;&_O)U*W0Hn6uW`zqY=KX`+PzI2O>{XSmF zECApHXdWv6ExYs1B&- zWDoF)=h))jruh0HEY7(H+V2s{=p3`=wsmqIhbn-D<7T76T5Infp0@>$T~L5~l@%z+ zO2bKhK>_Y=*4u&|YR?~`3SDS(_yU{8PR<9gnS^2dt+c?&IRYJTx)af@X2nGae4JkO zQz&^+)%!D)RkIj{ar`i)7y8`gaTuCvr4y$+vh$T>smXtasG~`XGWxA7HkNjf&wEN1r-H57K~l2prV5E2$n~&J^H99mPhfi z@cw=?bCYB6dH?U{fAiVB-*e{7nKNhR-n%6`m&N&Qb#ZJHi}NqS6EA`_aEPp!fSvry zpo_OB4m#d$b4sJG@DAwgMcY<2C&_kk$h14Kp*uV+xpmhU`3Lbpx08PT zkZO{uJJMbnNnH9SUYoP3_1`(a|%sq6m?w~IB&w~l!`s_2-pemo=VoRWx`PsPN> zZ94IA>zc!HK1NSB{GDlmX~@GN;)L1*Is>@sKw)=)|4IxNPKPv3?oNg9fHA`Ra(ocZ z_q`ob6QJ+RkC4pRb?C`a@3I2TS_N+(>UQNS4GFkvI?jf~f8#lQJDwIosY5Pyx|G5! zoP7~AiKpVJ%eOeoC2f5s3Af@ojJEkm9M^R_&aK-cXg_go*V#xUAE_O>^~GCAKCtRz zw=WP2AE8-p*Rjy?;r+Ag6vV|x!h2o$btxYS?{@tJ{`iO#b#0A8KH}GR?TNq*Z zH`;u}@9nx8RrrWb*jAN#T%o`Az5R!9+!~ZxZb1s=*QO8>c1UQ z!@jXxDDofS^!n_MsWmNCkG**c?voxsZSsxoK6v@;e@UbNt}Gv>{oHdj4Bh?P+DcVDIyFC|qNM7tYZz8ml$NTeKFljfFFmSKS(Q3~l6JaxVnxZyii)GWRF>4= zK00+;@7N&B75_ghhY21nc%I<%1YaijDl(=Ow`;-txR=`<)Q>TIx3GWA*z*{4oTqFB z?40L>(Jr#B{I<~llZ<1E8$b9;v;2*)`I&6%{wDPCIJ^1!B|KOp!e zVe^LIeS-C8!8Vrfg+BHR1)EI=Ck&rkkZnM@g86~5uP-HAr~QO}2-*5PUNFB$_3P?& zbwm1;>^NtMf{V%4>9sF%^PHYDhd5Rh5i#yOowko!S|v9 zzwGcE4)Hbev8LfvvJEJcY#VDW^zDSclh9ZCdL9nlMZo~S0Q#XqKZZQiG(4Vcdp}k1 zIb=IzO9U?$d>z?#;CApCeucYOV4XfBcqiF9-6Qxt!Jm??)1QR?zhvt(7$vJE>l){L zC#tOL3bJ)EQ0R}-)l9#~3Z5fu774yk@a1IdbDhw~>L}Q_?h^%1k!_M+68hJK{Rcw- zwXpw5=>IG1Q}CkD?_^8zP&?-fML`F$4XB^slLenI_$so^9B-=Z2YtKH-zDsy5c*e| zan9Rbz9kCwiwgf1`om;v?>292IFW3F&J$cKcs|)4Bj=HEEIE_#xClZT1#DLeqwC1_ zKvF`#N$~yTA*SxbWa~%Y?A23;ZfKlhpRw2`>Y%9hr_jfxHM&R@oJ+QK+Y2rg+?{Mg zIZo(fr&F*U$87`keMuPc1>iJH4{lcon^oj7M!#0*H;@M#{U)-ld!OJJ$TrYjhIv}S zf9r^X56RZicS6s*Ncc{Z@QH)Z-N?2BwPe_F>k0N(A>%zCe4EkaF~(+Gx;U*)Wx*g* zFq3Q@%@=$*+4kTX!AkH(vi0+z(ASf#&)0lr|G%eTd+-~XZy~T90sBjIB}3=iq?2tA zvW32oJkZo_FZ5-?zM6~&w?5d%eBneE*q%)mJX`RYWZS?cLVqP04{mjWA0pe1Jw?tm zHrv5=jjEXQnlR#jZTUTWPv}1*4=|PgO}37H5FEl=X}<%_1h*7iNVa||wBF1=r#l7f zbcEo=WZQ#_$@qMQ+a+ME#iX~Zg^eQHp{W!4JIVcx{XJw`_mP+oUM1Thcw6uXf zGCn%x))nk8V^k|_`jc%Ah6p|Hsp0E8juQn_$$gE}nPl6*e9h{Rh*wc%&bmg(02>{Rtw;F3!}3I#{^$Vwocaz{Wh|l z$$H^>ezJt^1?bZ(zhP`*x?n#AJ6it~mA?@BZ-o9=!9g5#Zg1_z36X6B%>);dZH7t& z*S13YenCGLSVv=o(Me?M^i;v;3Y(>ZR|vkIY<+GL`n$>WiT0g`eF6NEFnUAqKEVgb z)+ukl<#*r@vQ2vkUlh27CM#hu78%l8CiT{)037qvUMvdA$aXlYg}yJjmvN+*wYN@3 zQg3+%*{1po!RH8GLN>KPTHv93tcMRBk_k{Z)mI2%BVlP2y)FLbi3YbC}X& zOywLFSVwxj`(icfj>Zwv%iG%|jHRiqHiK;SXA0jJk~~0Fy(ZhmYBHM=F5WG+D0kU=Uz0m(bwn@+n<99NRrQ{+|%X*RgarQlE9t!+O zi^#TeH=(Z(`d&icU+6~(o+Nk{d6)@e9@z$QR&K0OxQYd~$7=-NEci~cbyP3(Pm`_F zmj!e$rZCzs_+!Cek*(9;gr4Vg-)FL5ez)QW+QD$l;Z`OJ zdXTNtVM0HeYy+JkSl?g3>Xp!M75s|ePXzz0?-5`tNAZ=C-#~w|owp;%99nFn!D*If zQ*V#R3xxf0!AkJ0NEN(K@By-Q^u5skLbkzm!u7-NKoz;0 zX}CMsUw&vHIOZFTqLJ;*31r**X@bubd;z)EI9)=v4J;SDfowaoMeu`-9CMzaU>&{I zSm5j-Tc_^{);AuoPW6okEC<>)HkLxRK3fZY0onR2Cl5FCs!!v#+je1@)IdVD_F zX6SNqsnIV7`^yil5jGphHoKdI{{9$+8dLdUvUT*7;J3)Om+uSyOz=Un_4B9D$KiVF z`%D#FNQO_9b8l*r|9yeJVS#O^7Y(e#k=B@Do*T zx)UCQ;I9+(f-ri6Y}59((EpQMZ7LrWHb0Q9)890&yRY#aTi6bzwtJn))*!^&&B5#BDpO$(*k3y51ED`8_*cRDP6DQ;jgFV0ZS-L=NFLr0vfBQh{Q{4mYH>i8RN*xjCvqAmNJ$`&S?CaDK_+9NyU#E@? zw7yM!LvfAj@eRcA?P}#W5HC~jLv(*voepBRSY5!~H|jO+rmI%p!ZhnnHSb%PKBAta z*m<)Gf2aMP{2h!At9!T`rhemYyE^U=Y|`&mb%$WHQ+*8)zYp#4JssVvR(_xQGJd@~ z=7-dCVEft+(6)U*wf+&ds1k8?WxcE)af9{r(dQ(ae9K z9j0#LZom2(yMXhII_75-Zc)_w171^W{z&cEAs4y!H`l_#5Pyb%4^yrD$Zp3upuYGc zwb1=krTm#%j82zxw?>`J-HGZ_?p{>)aMw<~&D~-38+ZRwg-25Hd(jqZ*pbwB2}N`8 z?<7%m?vd1jz@YQ>4^x{TM01I@Dejh@uYaSe-aC>Sbstw>qrQ9L+BC1Y^2`hHpB&*v zQ$OIuq`wBds@T(X{7R}on3K!tf505~bLwGIK<`Dj^x?7xgvN|K^wa$4IPHx5HPCV|$<9<9E zoD`|Lpm#}^x))ks*XB^&?cv+-d}(Xzi~bz#Ff3ZxOy9HeZ-bj#{^qd~y6f<`LERJQ z74*5}`2&yEc=rXCVqing$`#sOI>vh~^TVxtUl$(UxTR#{ z9ntN1&RxO#;!Fc=4k!7ZU_i_W_6jp4dUXAziD0~&~6(`>p-(Xq#fLr7~spdc6 zX5vTOlecDdTYF7HvO4rYme&C8G*fPN>eZ{gSHG^wG5sNjVX;UW@h2N%)MX|QP)S`Tg>IuV=}>IKX6 z&vGDGRG$qIFaCOdRDN?V35hQ3v3Jvi1nbSw(mg!m>tC&b@P=Y~e2 zLSE=>G?pJa9?u0%+^yIpbblU3NvmNK*vuRRccN-)t;o%{`3tx4+hWzMf`Oa` z*49jcwk|jZ)@d|$$9R2&=^}8tho|dMcNC0Re=&5NLrl$dt3&5_xpp{a=QikKPC8!( zGd297p3Oo!-=T8c?r6|O^zVPXsVKPFMu}GVV{(LqS8jfS3Nd9K#I?pOkA)9VwwflW*sdOZL}O?y4w>SV9y30+S(W2a+Fgz|VO+3WQU zI`+E6Il9*`!iqNw!R_twaO?OxWHWQSve#qq`0Hqw{tBP|_=%y81vr4(wgRAgUDg)f zd|MuueuDlo);tvKT+w6A-VC!k_PQe~vNJOpbhb0>r9XscRYK4|jc{A=WM}@7vju7DTyrS5Xw(K#x=c$NWf!Q_er&-zGbGpdw|EC{M&pY4IqxCmN zyz*e1KvEoj6(XOXifPr$PEt@^du2klYTn#irY5I(S-4EN!30~ODJKg@TVqM_Fs;_l zAzfgeQ<6{(565+#cdsK4nL0V$E5z)GrF)s`QYtp5d+pNG9XHMmUJ*+Qp%phN75)4H5#Xwxk+8aDWAk*iHs5Qn7W~#ST|JYV)LPxL z2D)#G;-Y`2OX4BJzE0Dwnuzf{kOHc-EYeyXcq6ZU{mTX3r-AF|yqKd}f00|pe>Bt^ zkFS8b_TrX>skv6gLpGoufJ#kh=e5sg=K}h*gf+k}=;Sn<0SfAGZ|7a>;>Bxud#`sh zhSeMy`OsRAslT+nm*%=*)q6-%rn;h|*QWlp4&INh`>1-hlb7p0RR2*Y?^0JS%x}|H zo!Z6Q;%-(cUA^2QW_KkX=}7gx*mID`Oy>=jAF1!um6dY}a@(lQ-MmgQoK>ClJTneF z`H{Kt%tz)3aE$q{x-3s2=i%~XIfV*reEmWj*3&-og-$yJ*ylmV=2JT330n}4^tO)rcd0kLXImraS2bk6a+TFH2=ZSV zgCT=Bu6|LOcU4^KwJwemCJx(Lb)?G6jNK+w_X&PQ@Y`hD=Y3%Rf5Z7hCf^<3^Z5Tx z^Mla;PPVD#A(Lh~1&q2e9ZLpiG!Q=op#aKgSFG$z;qY zZj-@W%YfUQ0NVF^z_&Dh^6=a*VHDo)=H-P=S(%vp??jzeE9uoF12%A^PoaOBQ z>k#}qx$YN6|MrbwbI{swG=HbwHsE58_;(uRLIFN=H75Gxi}cPyua_BM!`S%tso^%I zGlbE3g0B{=e^hEK*Hdq^@-&&pDYoap{y!A%5;p%7HXmCXbSCB;Vu9_=e}s|#!H#w6 z;UK3|9!z;)zcKz=$LE29PZE5(;H83Z)NJOTa}NdEn+M4}ny_sHr&-=EY+fbXpx+ku z`>Z{O>EA;Cr{DmNB>Jp?O?nuD-&m1)U|pNc*l?kmDfk?+jqy@)1|!7(+Y0?k!Pg5` zf^QLgn_&9FQC^?g!z*=TPf)Ul$uojq68wtb_sRCi_(<@-1b-#?C&7mWA2DpkCCHP9 zbs82N6`U!UZw7pOzH#-BhEl05X|>Q{z#1De>wWXDWc%i`X7(+Zg+=Hfx9yy(ua~r@p^&j=}lpEta=;qM#8)(|_ zwboe6kAr8CZ7io-#?Dz}xdoU<&j{XCK$w6@Qxrxo5D#DUbh9OfZw(}4g9X<+2D^X z&jWvMc>(xq%V&YVw|qYM7t0re|FC=sIEYbUyURG+`0|j#N^r#THQ)@(d!{S?0NBi{(7~je5V=tr=!ERfFBw0^#+aTDA95rIBK~BoNc)~IM;GN zaG_<+r%JLt+Im=KTLUb!t>Ih~iAHQ}jO9Eqm#L+`63ovk$i2aHEe{6Ix6HlE{-k|zrc65lFs1EeX zy|#YV5bv<7Hq>Oa^}k6z7q74VGt*^)xk{I>uM@mQ@FRk^3*IGozu?aV#|{bMcflci z5#u+UE;x^zjQ(NkOt#azM(_Z^qXbVBJlil2VaHia!Orz1f>#Q@LGUKQTLnKQcqiFT zdoE1p^8vx%B%*!4;IJr&!-4JVqk_34q<=wZFStT*AF`dg!vv2PJe`b5dj%`h(-*xgZW9OktP z>~vJ0)>zi{Ln=S$s18AiZwudy3udaW!=d}Kqv|uwF;U*o~w2z zq3Rn{ZttWHK*_Q)>n*#_112*z6pAKefsQ3v@o_*eK`_N zKMSe@3*8o~-6)uyTZ(Iq>M;t{Lvcob_r$ztJZ}*@R$T>sd}o|}rm2T%l2@kokMi2Z zuhObdPj?Fg-;}BL$HVJSajGPZJv}8q8h8x16Qy!UyxPe9sCcz?0{Zdc@ytzyIs|2W z9u9`PRIAZwq7N>cyHtN*;FT1$YP8ovT|C;0HcQ2nU5u9*{^qLKd^a;8+!Hr}3aF<> zdj)}|o;olZO-%2tLSvBJcU8AB=xj+JH6CJoJ|^fB>e4Y@VZxz4c<-B_?j7S5#B+&| zXVlwJ2iCVVi}reB5!>FDDsL>jg$RP+SYf3btAIl&W)_Vzg~IV-NTq^v?sc@(St?ySG(1n<)BCHX_m z8+AOp2l2W!%(wMiXHstXE^Gn1fp5IJs#8{ZStmV!^yBNa4$W~E-G#GYpaowQ;G4Cd z(XHUq@Ds@9b>CmX_Y9m)0xkLG8Q-p54I$Vb9NbS$@I9P}<1%=u2;Q&WT;*ki`TMB2 zF6U5lo;tJ&i%9Oqaf5H#HpZ)F?}pP=ht*#5SQ5@l30Zf;3SYhrK@`DW7^%ehY&e(@ z1uoG3hZE1<25m|x@scU93D1F$xPmGt{3F~XUQ5PueCuhurZ;SYTp}lQ;@QAdVvs-D z4UOYhWC?L|@vNR$?G24_k(uO36`oTf{qP))jKFhhWCEVO$V@y(A`9^xja-c9W|0+m zZXQ{O=d?(VFkZw&2IIL!WDK4&BV6(&JF*zhEh9_t+$!=Jp7SDy@SGp{9nS@k5T;~d zgdf7RjpU8Mt|-zO&+Q^LcrK3I2G{MeCNi%1Ne`?B6E;& zH}WY5F_M7HCPa2Yofvsn?Y_>-be~XPUgzb<(lNSDq$38?jcmjPKVV&@=H{S&qz_W% zL>}e^CGs*N3q+oVCK#EB2^1G8L$=}_EQHx=6^x^opk1%EPI4&AiN1uUy*66Jxi`ws zX}laQ#>F|&S%}@sRaah*bJU4y>-Anq?n*S^wbvGIt`mKd?m8GT$B7=Nj$H3`9`_dK*IoG@E(vW5hO2bO*BM^)+H^C%T)x z?`OnTPP8in>u*Gaoy|xF7!hHg&kzP05n=CBXRP(w#8xnbAx4|wMEMP>H`IvfPV_k( ztlqIkOhYL>9%sbnPIMu~VMc7`MEfw8!;OeUe3Aiigb|U5W$2_g(ukfDdgn6hN_gZUn7#3U#BAl}}1Cm0c9JV2eY&TErf&cMeTZM+lZ+5_H6M#RYf zN8Jdc=zY{qG+GzkQ9IUoz1_7PUZr5 zJXt66bffi?d4>`FWX?CDpUeeD^pkm}5&dK?G$NC!zC;6Vo=UjE>umCMt||2Mb)FIZ ze4TGZov$f3`1!iXX#IR$Y($-}IvAOJEj3!5uUBr+`AS-ksiO0Bl_~V|wbF=wzOFW+ zpRa3-=;!NNBQjq&z`a#Q%ygn$#Kl`}#1;@awAUHYPviC524Vum;f0Wylxs|}pU1UE z^z*pRh<+ZG5p^EFLRXN-(2ZW_IeOmRYzqB6-eN>Qj~k50Jo3ogXv9P(+Ke&ZYQzL5 zs;A>^M)cEryAgGIZ@JM=@0~`g)BD7K8boF8n^vjJ4yydEt7V7Q0hF zCCr~xdp*cY!cWs?%4VF}Hir4(wRibl@VhC@cP`%D_u%5cCHxRxUwCiw#B^`C7f*uk z%tGC*;h#CZ{&@~~cen*Cz0WVqf$C5=j*b0`q5TvtAb&wV9DYX4xy2in{SFV7e_w}s zS!-dB3+1;TK#0Do-n<1vu~!|u#T(?lpeiI%i{7C=E5Fn zaT1Qo2$vpqB6q-*8{ubBfr!F|BN&;CSmPp7P%}RAIND5z+yi}Lq#Mjbk@;vcDN>8x zCP&6WlM-1CO*rx!Jfudhg~p3;eUC`Q^YB?jG%^&2PqWB2T+f5EVw8&R@PLF(q z7&0PU5xhm@5Ymtt$-?C^D{?EE%#I|X`IeD$P`6cN4MJ=k`3bJuMAjnlIgwwH^4!R~ z(C0-i!E=6upAr|?{zVJ9ibUl6prbC|=tW|wXge5bh3B})GiW0|!Vj|(A~nz?My8-X z7TCU&sqDhUm?TBJy-X)N5Qh`_2nlc_T(cMpZ2yczM$0!hT2>yS-o-pl)cA~w1Yqab;fR+WAJx*k)ww#7k!BYQM z*1#f^+CT@NK}#+d;Y2>ivl}^p^uTfwszr|*$$vevro(Tb={v|OUf02$8;K!rFy)V| zqsO0z(v;TG6Y;&H6TXY8ar{Kq2~S~{%_TV8jb2Y$19d3OkEEg#=rkPWOR(t4w2y|5 zhbB6aaixb_#n`n;EXZ<#D`<5J7sE)2i%zRyL;NS5=ycN%KMaV@pmR5TBLkSZ0gM3O z!<>oEN`ZZ|*3pHhV&AGQIuKpNSX=GFQ*<%CIVmO4dG`Ur{KzeOI^Z5GH-RQ(r{2D#O0$_(m*^V zb6O{BT29hWT&^OSPq5@kAt8?HloEHq&rpVk!ks&iDknUXJct|@eh$y>U~(w@HDsD>(L{3C>g7UC82%ySoR?rJ{5<7dmMeHhr6O3ci3Y{b5?j6hQ~dgLA4IQi@D^E z=J#EBVdM?}78ZrRZTMWwZFejiYahM_-rN)T(M4y(`a8-KP1uQ0B{I>$mYi)Tat+fq zv6eJX3oL-1+h9E0x{G0&!(l=RqvMu47h~vVXv=)ac_l1wp=EbM-s6}cZf1Zr-IMcA zn|`k2X6dpDR!)e!3PFx3n7cZ}0{px*~&gQF~zvEm}cQe1+P zlp(6e9bW6wyHU_V$8ykRFz)CMk8o5Ex*QpIOot;FIY>Mb+_4=B)76!CcsWBD+vHay>@ZB@oF{z3%kd=kP?4zi`GP%)I~?4jzWNQpB&H zTOh(q)n#{jdCB>}V*WE*XLbLbxGwSLj!&arJ1myDdc4zh5{d$go!wfc7qu?B5UNZh z|FcG2mp7oJtD+C+3XqC;kkt5KTLjq7ooN2A%<0krqidg)2lXnnaLcQg(%N`SUm_i;UDmyH%Gm(*=wJ{ zS@3Vu9{S`I^S>ZFsFW>Ut1122d_r6p{VKVWV?CE&g>jpRhg)|SnlkfpE~mmvXrYjA zgx$FunJ^rca>?z-VP?A81=Cyiw73Q^Qa$*VSE~-)@1@M5P3BurMw~>tEqNI&xeNXF zE<=f1cWbua-a@w51r3zx_7<|l9iv;@479EBa-{QG!Pd~3F{<<~ufG}J+0-$DzUtY# zy!exJt4Da~o$t3gS-08;*A3Il^VurDmM&Ztq8;b>UcZ;4VD|sf%h|Niy~KL!bXzil z=cT27d&_itHTV$Bw6~P)@tf%~-QH4u!eM(!qyN>*uUe}7?Ordn;4Uw&Nnd+UHtpWd zmX`bN@(Uxkjz5Yw?Jj4#C*W*W*p~TN&e7ZkQRkOGk#Ew^B0ZYO@7`9rWp5ZN==r)B zV1_yN2oOivCwQU@odztb%vMW&hjVweAC5^w%Qk*Es~HaOAyuZsSuF;eM*k}fyWkne ziCc=pHa@7jZ1>9kHYG6=!#A98>-`x1i!j}~(i}gA^^BnkqgBXP4(@thpSUi2A-n3X z=S--l$gjeTxSt}%*l};iqSEPa86hJfsP;wCETRC+Mf@x%>PHdM0)H5Q*&q z+T5|a&K(xYXLu#!)6v8oe%zgET$#7VlDS?uM*elz##W=7=s%{(UWUrp4vdure=>*{Z4Gf^&Hbi6IXh}S-Igjekz~GaZlBIs}~<*Xm7(>Bl!QahpW3O z*O8pxBoaMbbgqXBw=G}*B`@;T=|MlTyL4oyxAh}C$jHt>WQB8Ba**%n-tYsx2xdCa z45tfD7=OL2{Zh!`>KD=1y35IhQor`N3ZTw8U z=3wVd5V!D%KH>*)mJWiy@()XX^zelr84a7H1al;0LaS~6H&c3rR@TH0qamm0JU%1NTj0kZ zxZ9xe<6I2Zm&o#6Y`w4{&XFi^>xOpl<1Ey1hA`PX{K|7jq02Hml}7@bM48a^Iu%QZ zW6w-uWB7ifV?$$a=*AXz^c(A_8yktna`@#7EIE8U(r`7^GCzpe4OtH#E86Cdn!4)4g0`V0^Yp#i6837(j)Y4FH&aado4%1@UbR=%Pr*Ncc& zHuQk=!L9Q;`8}xAJ@_6GcKA7jqDq%#HeKn!|A%yKgHQeXp~B-FI>zN2P;T70b(Lo_ ziG3NjgK(iapUt;Ko6xdy4PQ0+?|M%|A-lwD0wzO4mv~L6)GOo;(XP5_S1)yK@HIsH zI!XF^MEL5WeW`s$bwlHS6OO*7(WSmd;0{R)qI?;Ttr-pBou>z45 zN52I5*@V}rXcUT>tuU+`!1p&v@ACX^-5zb`Vc!8z$E5$Gly7feTXfGmWNmwTp?5*Vnq)@ z#Y1e6&^-kmFD8?%ZXv9BAF-m>QNX^QWeV)f_ypP}edU|S@=XZcUBc9J?l{go1mV_w zS?c$HiSB<7Sale{<7tV@PigTHOMPd5Ng{58cqWteT2biTjQYjEfkXz~9$Rb%tE@4G&oO z-Dv#kcPso~P5(N=%WfBpgE>&f12_@zqofzjtVw8oiC=h^EyTw%FZwg*pw(?M6`p+2 zpJr{DNqG8?DG0yhC7Tz#(`~_^N_{MutN?H`VZ_2D=GIW(V`9{$TGriU9pG1Xo+u=WZ1;G_!8nsWZ@s2d-^c}Q$`Mr3%N|foV*4PePdB%zlyj6pp>D!k; zGc~)Upq>t^0>G%p*O;(O)Pw!vGi>o)ws`waFWJ3Ly|xoSKz+;~9QxIRgZtI(2bc4o zXkD)%NF2ThvOQi2=jfok0IRk}Pl_@Botx3T=_;y@#wF8T*HHCQ^wX_7+}$77b^03s zE@z!zI%DBN$Gt(DJ`aT+K3du?()C}u_`KTqia+z2BX&DYeGlC+TY#mg%1Z;za}xte zN9@_|78t&StHiOo)Q$&FgLk7~MQ8pm;euDa^w{JsIQccTc@8#hyJ8*azZRf@VDgb8 zPSL9F~mt1%djkm@}Y#h;0iPPl<#G;4cUI0@*Mq6j7sk^+i9*3crr>$+` zQKhISqa2FMwsE6BRMf+Qg`K0#z~p7`LsaD;HCD4PCa>aA z5Dof=>VIM9*46g$a~}=z?Q~aMOmcqUC`E((=3p0P{k2Xs$owYY+ky@*4i}Wi`0m9X z%k*QS%+p`GA#aNz}-4k&rGd%{X6FwbE8;+>-fG!4bK%eNPj^B$HY)k!uEw&(~w>+n8^NT;Q#S?8Y&V=#p zi;~bc9){=lW`j)+!!{`8DRG0^_@9vim z%ta6T=uR|@SrK0?u(4cS(4?_q{;-i#%n!qV>0`bvDgTit)?N+cx(D5H>u%`lk83YI zuGb@*IrkQPSlK2FzD8hYX(ulNvTfZvl-bWix@Qq@en2{|RmFQjcp zXk|K*JBTm$rUf5?rfW7P{ZSXg-G~H-v#W~nJx2BiaR{#q@?eJKGytc4{s7(k=1cv8 zEw*5x8nxH!pT-kmm(Ois@nIJ7iEbf*CK)vVCgbUWW-1(Ya_|P3lfz|x z4gWGQc@S&VM7h$4Q^Y)RTF0Q>=Vc_+FkhS1t?zin<9RSYH>mLlo)kC-HFy!^Y2af~ zg7LhT!WBIDr@zxl&knE#wuQ=MeiwaZ58_VPW`qwR+&wUlR4v!MGFr8V`xdga>5#Z z-ACXm&@B4}s1mo}smJKyV;%3SWjF+mc?Q)y+*TZiXA7R^zw_%QIz72EkURb(XpG}t z8<8(Q65s2k67hu+9*OVv;;o+e2w&W51l;hEI<8kHrVt;^V;}au9F6di{8L=-eHax! z5_`J6R^pPxN9x>OyU-RNX&riZLbQA&jdy#EN8k8JKiKO@Oin)1|JiFAW(gk|MZM0& zj*rm#UZW8iAECXy7h%Uo@`_-uQ~rbce8lJXx)M4*;){B7WiCFF?+x~T3mxGj+{W#7 zZwUW8hewMEy(YphA1!9|c@*{e=shBc9^#R_JHGdYP+VBw?OpHHo=2~@QGd8aBsWPc zxS=9>kwLy)8h(so80lPy1Giu@0(PqUY!SGa?y7 zo7_pTs-)~FO?i`6t4b=4(o~k!x0@MxWM1}Q92o9;oQ1IQXDvRDQ9r&F853I}RI3E* zn{wG|Hw*nEf}aq)UGNUU9}50V@K=UoIQZ)3+%TTqC%b;DLg9 z67lPvs_(aDdpTPa%olux;FW@}6TDvVy@DST{G#C9KC}NH_yYJ#!9NMs7kwKje`MqL zAWv{-!TLsD)_$1Kj}tr>9P=HWBML4Re63)9F6P_cFPQ%%?CW0?tncb&gGj(7$G2(L z$T4R^qu|UGyioAPf>#J$C-^qO_X~bP@XLbV(ro6Rqwm0FBmGJk@i&-$)LDZ0uOIwT zGq+-}zlaL|C&Rbr#~1EeW7ALQhYS7am?)Sc_&i~>Lg-hKadqUj2ApPjgRr@aY#Y{h z;IjObsJq*;?*GT4@)u-$!o-dL`N5m?a^tV`{GK_uYWoeuldVm*;ErUQ(NeO_RwbC( z!b>yWjSK&aX^lpR3KIp-5xkVVR>$L9LAFkB6nqca`g};}9|g1F8&G{0^=s(|{og~u zR`{}^0H4hW{b8a1L+HbJ!Q=-K1+#%C;5M6j>$5F+EgQpIFJa$>_WZFrKL{!l6?%#a z{X~U9tiT@N_2&d(Gg;VNCRpF43-;XjztsM3sc#n?yIWLvM(`fN`VL&y(YHc>gq&&` z2=U#gWshv_GX=L7HrXIjvf?_wv(-mzDt+ouY^7Uui|~17GxWA9vK%s z&OfIu1pmH+-Goss+4iiL(ChniS^aRK*SF`o$_&Ru>e&Fc8G_Ft+hJM)j`_lJQE(mE zI=WrxpC#KKyh6sgp4;o-G|T&i%_n3V=odo&QzOS5eaEg9#!)c4(P>z40og{~NpOYW zo@DE1gwT&A+u$Y%p091p{BzC~6_yHKLAFkB5_-Nd_cKvX#@UhElVE>|p_hftZnDk9 zKZO3Hm?-#66nsnOdw6U=l5GRO3+8)tKP#Dn^91W#cv(N)h5khHdMuj72BuKJvCM5c zIL-2WYefBdWZQ#_h5jnRYspvA8YdjG^>e#swd$Xd%$Oa;*Qm0*S5*64=)cz0jJux% zC*U7-{kjpsS%UM)Hk2}az zk*&|G4V(FPI|bYOdj)S3{0!MTdQ<5CLAFjm6nse7{3#Xn4cTU; z9~tT9#v5~`Sw3FaoJ_V^nIiP33)VO3y2ALmkb3%=gvaH+0KSQAGqFkVeS#k)TSq&D zUf;FL2KNs2E!Q1roMHOjUDk83O``{Wzb>oKquzGABN<+}bp@wct`#=@$+p`=gnqQp z$Hs|*siI(}&@T}BvxGh-^p^?!HRQ`paMzP`cUXU zBU`5j1?ziy*=&V!bOYLFGr=v%)@LU!wCoS)U>4Z)9#6)D+X>jGS)M|@wV6Y<>76h1 z=L!AALVqQhA30*Xnv93;zrM>C1#DYbV0-YO;3ovXK(>zd3jHCn4er0>JUGPmCpaxn zqmz`|Xv3RI_VRm>B?^iJ>l=7oYAWj+cv(k1X_KdRf6_RIr&48OpF_6QE)e>w$u>qs zE-f|?aJF*R~gxpS>I~CwG%e{roP_pg72%#S@ z^pk{sRz40~cZqR2j|JB0S(;U!&l^YRW~yul?3!IH+mzT zMZr4N_ZPFgfqL76yT~0)5AFk}S$<5|JWsYA*dg?L$QPTs?~rZXj|$MfFZ_oEHtIhG zCl)s9qh#wSU+9a;)@cvHQ^~dibIF}e5c9!lhGQLmZwi=vfxlY*JNw&GUN9Z3D{5<(W<7WrCt6u*Y|7NTOwfoD)gdC>I zcFHYktk;}u^;u*aOTOT8VRMY&fr3YnZ7h?8K6WMr+wlv?B_`k)IL-13VY7y8JHB4% zZx{M4LjMr?0^_ruY<+GwY>v5iDA-#~ub7br1Rly&SZD&6Bnf?FP7r?)et)meBdCsrUl5C?c zBKI155;n(!V}8$06cy$OzCcvCgxtqCy#kzOd9|>qBin4< zD(trje!0;;=Io)+*EszLIL-2bMkD8IvUU20&?n;MguB?(4U=u%48fhqHtiLHdunF> zu??bN9gP!4lgQTTBEeUY?QpCk_cwlS1gBZPL)dI3+YUT0^t)md7MaR>$hPu(f)9~x z4}KLK=+dZ9AzMFO)YG>wAX}d`f~Szt0p0((6b70g=7ZBLpKpy=ayi-dKneY=iHv4A%b#32}?Cd6;aI z`Iyn0Bk5&fv{&$l_Jm2VlAlrt26Wk0hG5ub)6kI5{a|zn_8|Wzt`jf5G zVS-N;Hgg3p7JLzTfeG#!pvtWK{UD(~PUue*`jg8z32a0&MZsKA;cTJ5K(C-uaPlWypvTgWl zFdIG)z(RDw{s_3?avoQX3N{lFvJEI*=yQd>h-@3EB42BIe2mZ!75Y&^KNie@-sf#B zC$YdbJezDAK3(X~75a;W{z{?0nrs8QRq#WCpA@`@oN7)&&U;!gJ@{1cH)K1Oe+YdL zZNDzebY$lh8Y&;zwlb@Q~2|Otub>2+pX4-u664aIxSLvh~?l=wpK^Sf>*NpDuW* z;I)GHk?s8Xggn9w-0{t9n=TOqfE}Xf%Q*}A-+nz z9mszQ`>zH6DmaLDSoq;5$~6$u zC}8U^j7E^Hqf-P=6E>%l=bE|;$=1&Wn$?s)8(;C>PL-Wv_ljyy3;heansK*F@F&9N zYr#JW{)22o@$in`Z!4Bg!Nyf4_&CAS1z#liX2JK9uQ9D++!P9PEkU?950a+dx~A<4q>Il2;k7 z5H`aFPas=AGs$+)&+N(b!~|3MEEJ?!ULuUHBHNjCsfzD*L@_AFiKv&pt&1%hk94gcZRmj!kL9xHeZnUP|f zF7$KA*6AX_%Z1H#f^QPMiEMo4I@?6SlVt1kMa^nKu<;=IMwtGGY~xDk4Ysj|$<{@N z;7-D(LU2#PgUHtBIH8YCqF|j~Ab6wT?SlU;IMAoDZl2)YWII~Nk|#QP8v#zUd=mBk zE2`-f>~uKI6gb=#ldb+dvUPeXc{U8NUD*e0ovs$VnQSw+Rq*42pYIcEbo90;c$aLQ zej@m=u;Hh7egnyZ`7xs(Tw9^A_Q8NL8ML+}!^?ZI-v*9pFbY_oC~`4l+8 zb{{y+@?*m01+vZPPH@A|0NxQs2gtLGqtD6K(YJ!*`ay4lOBLKga4y;UDG~ZAvhf*n zdN&Hr3Bu?U!LtM}AX}$Pg?<^?2D(b{ZNlar!H;NW{;@qx!8(0I7#$$n^nOjAqRpM} zz-gBMD{SKNfvBI}48bkQ)=x*ll`#rajni6in&kn)Xe8N=*;JvQOP*=!E)e<)g#8k- z^|@T|1~P_E{h1hTcw6_NRnp}XWb6Djq2EKc4&M`eNZ9-;IDpSV{dtl?wmw@6eXM|j zb=paAUtx5t;4y+HlC9Izg?Rzj8X+>T}35Ov8mjUnaP(;E{qS37$>1!JSTK z2PWZhwl9EJlI^j*R`4x?H<( z;{}IRw{SEwJ5#7y2`*5RQ9QJZP?ZX<5qyl`0fL7J9;Ke8yOV`#vf!D5=LlXX_-w%! zsoYcqf2B~Z6nwoJiQ?ETLUo(qy9D1Sc$?tI1#cJpqTtsAzbSa1VRO!TUle>Q_zS_` z3jRUxuY&&&92nX-rU`;Q!Oe%ZZZv8s3UV~7?Zxhh`n$bo-8}aLHTZ()$Ut7Ey5WN8 z2zQkF0;0P_RbPnRUbT$7VQL?D8&&Z|FwM$V=UxQURcZ&tP)n6{F~lWm*2TI?J$8Zi ztyCxm?M5{&2C;2xwS{7x`h{Y88#QDJ#Fa`dp>dA-lHx{Hy%b^=?)SA6;ykqvqWhUD zz684^>KyL&svX=dP??uv_oAA`-ELKnUBD?&q06Ep0wo1%Joboi^JOSKq<-OUlp1_F zjG}GT4VS~{m?HHh_UN}8A`XP%qy{* zsAh3@Sk+?}i0h(4%VG0@8n-;U1NUOgT@f9ro>>tMtMgYx2O!30S47VVgez3dRWQ3u zExQVpXRCeOeWQw3Vz*nJ!`*hZgS$;C^J?twRkN@Qlyp~*U5$!cRN^(zE>YvK3-mcg zZMg;!X7yBuv3GZ=!Pn|i#ob2r1$URJ>Q%6<>8q|>1)HsEA4GJucr|u)>KyC>=>ycx z)hHaMGOvRc8RZTc#V(LFNQJIP;S@FQdWfOHY751!>KBOacr|zpcDt0~Zom41yXmTW zE!!NUu3U@wD#oh)*u#DCI$e4WcgQDpfr?2gOQCR!nx&vcLa__PO;Mp6pgmMS?uO{N z#6Wnu+PWdy(JfN%Z-^GgkDu>4->BfmXrcRxD&80^b|szK z?cgp~eaGEmm3b?6n^kY_ep0irOKATz?lF?7*4!E`2=w1;ZoT-%tB)?-D+b8QQKGIH~ZRQrCvgS3m9+(0kt(R zvsD1A3$QiyYF=hU-M6oKIIFUx-08Y-{`9Gfr*>`l@q0C*rn6uLRxvpK{e(J_K8#mJW!^Qcu0xyw$oN3$j~Rm)F4Esf!kMT{L;-Y4aA(SU6+) zh`!nU2UUS0#Cw z*>0K2uL@+L?@PgH4)jF;K_DE(nlF6OA_kFg2l^&R!KR7%RivBv{aWW_k)D=Zq+6D^!w=SmDHB}owi)% ze~4gOA+cH2C8f20XQRg|SY1-C^Wc`~wI#BvOKM90&RP$Bc4qb84Pi-@%^Uz@nT>g1 z<^`9Gc(-|4psH5qFj!Svs}+D6W-l`iP_4fGuz8F6T^}}Y-!`tgq@-G%*|Hgq(_mU8 zP>PDdw2EL=g`-x#+B{9og*IAV(ztj6;xAQwTQ}G zHE*GgP{2Hk#-*JVtSBv4SH`8yiq&v+23ryFG+B88F;mk}UfX0Hh3b-uCN-){nl33( zU4jlY_<+Q<9Q>smVv{Ggtu8@gg+XAcyQK@NkJdCzRv8ZC zCbe|${^IATq?eZ>1B>UMHEs6f1yiR_UN~dwbZ3$JB_XXQSXPQzHx5V9;KZ~@tgLA! z%PX6|;y0YndDAkpEKxI>vI1oPzrF98l<&deR znQ4`Ojji&i*eaW@Zh~t?g*rJYEpJklUcy9ruPSY_%n2?uO~=2gqG>`(tD7vKQjPQE zvi(VEc%*OMpOo=XBQO`r>@A-l@mlR|^RM29@J);ZK zt}Dp8@dUO1y^Q?estHTfZ|`MvNJ>bC-`7*0PF1}>$S7Z*g3I?vUE)rB>yP?>yq|#uZ_ca#=wQazZi{6%Q-YkG+ zLNjPHhSA%t@xab}PaI6i19n+Jd@~n#*K%M&+-G=B3_giq6SDAv2eAguL72gr>V-oY z?Y&JA6tCEc0w*c6rTX)WzY)cPZOSAhtAO8z*HyoF}z1VrwTQB@D5( z5nDMaQ`OZ8AAh^9aQZP8LdzLi7j+8#bGCfKVeSlY{V2NrG_2pV#H)8WgfDh)YXVd zXpqL;j2LoK?qBr2LLgMUqAs(Q{Hh>IiY95mTKM z{z@cilo2shTrVZ*cq3w{CNj^Xcd842$_NenM;i!ZOc@3$NWWu^h=CfwZk}L74Ac+p zA)aW&1SjPsj`=tv;#Sk|sNFyLV{nSm`eQKJi2fK%F`_>PQ;q14!Kp^{$6%Tf{V|ws zM1Krs7||btnLAbNKR9FPjL$Y@%s5UUNv9bRQ~QEAh;xjX=A`I>m}^9TAm$m-ABfY9 z=nuphM)U__z7hR_Sg;c#i;3Wm#F?g;BcZzdoYAJMPWob_^^<;<5&fi}ZA2zror^l| zJ8Ip}es*J~(9iA?Bl_80YD7P~ml)B{?xjZbvwN8l{p?;pT=vA=%;a&5&bl-Hlm-!>x}5n=j)B=&*wG# z{~P2S=N_HiwWiq5?m8p-*;Pi=+3j^$XLsUZKf4=Ep`YDbjp%3hHY57kz1@g@cK;7u z-vJ&~(Y=4~?gnx<2}uZh6IwQ*CX|psLa!l&h@nWY0#c<*5syW5U2epNbuJgJhs`Qs@?dcFB+MS8t?yCS{byhD**Gd!b6uNj_Iq}L2P z6&Y_eQ1i+zMSJbATajKnJf}$6n_u`NR8>tOdllF7_dZ2>{@$-hZwh%qk=_*Yq9WxK zQtfIeJK-FsomUkX&G4n$DMDbj2D?-eO)yXl%Y)P7K0ueLub(yQ$yMS8WptVpl6KPl3y?azwz zYWs^Ky`gqRk={`I&oR;RuTZp_#eP+3o(q0cr00U)6)9aX`7h4}*A+Kx#eXYy{}q}T zkuE4}D|WIapNH&3YudHq<$U94I%LJm={%_E3Rb+F&to*5WW~$Q5Uc6(R=iwV<20RU z#mlv|oTd}3NW5HK<257RikHi4f~L#iiN#!B6Ez)&XZ~`5EwAZVD_*X!Nt%wa;^h)s zLDNAiUQS6NO*>Y+TxMNON5f*d&?aj}Su6gKXm~x;C{YfCRLz$Dy7PKyB1Xd3*F)h% z>6Q$gO1C`Vx?#1gsH?eNvfn zkDHhy>zk{2UVZa49j&X|SktWT1HZbtiD7O&T4^q7n<84+ZaBRa*=;o&20qH&R69+> zz-3~V?dJMo%ZpvMn`O@z=QZj2B-z1-yg%X&t$%6Ww~M7d;U8)f|DiU?R9j26THN|gSL_P# za0G`CXNIDq16KS3ZX9Q7HNO?VSp4C4!}d#}V!+d0@DJ^U|Il7!YR?Tw?MI+JRF-{z zskX>KS{iJzG{9x#2wKtkSg4itiQ;dbOr)EB+8pj&`%8Qu-L4e%|49Rp8KXR9Xrj&XnDr>@8W+g>Ve;pG=`M~qvL-c_C- zl@QLa@psYi8k&Z`ri=F>J@gjlRa>!RP%iJy>||&$_~$jMWojD!sl;sSXqxj6q6P)n>@8SGAq zEl2vgI5+o}EF9yV9*WEE`V7w#Jr!-E%=s?pUYf>y{{y>HZ%v~~zGWNt(KLGM1aWtq z+aUcaZ5p82u%RQHcA%!w>wgiam}F%R;7U8a298OoUis zJ63$QVh6E!wh?>4w(E=U%Au`R3MU>}ekQuagX$+HfJ$#eJ04UjWsuXZOwbz?ZKFx% zi}&J@b4}J_vtr9ZD^e2NJ?W>Yy;DnL_0HoIu}jl10M9o{Kv`WxT%y~?m!2xRB)X|N z8#s%i0W;4B}Q=`x+#9xW-o_5ld zcQxBH<)o%*3diDmn#Mdng$Kb?nnow-B7QFKwuz*(><={?_5Y zqostrM!Tk^yo&#&X|LjcYg#tisE};5dwDq|wuWR4u7OfDi1W)i#rA4YPSaiu;x+Bn zAVJe!4H7l&)u6nlWesLyJA@jPxT*#pyIu_{Ybmb=RW$9@psJ>24eBM!8Wi(#NQ_H% zb0dA(SDW)@>1Z|%{Q(uCFf%%jajKeqwhZpn?$qEk_V6aG8L`fCPI(9U$jbx=;UTOt z<$N@rxuTg^n`7W%*_! zQaClVob|V5KbjHxiDEuU%nrT4q3M^zyif+mWk3>(Li|6Z6D5hoq2)BLj8BZJ=q5#; z=ZYHk?Zuq2HZ+)HG26#m<*g6B%o#05>Xd{WE-Vctu_=^FqLC!Fgl2F> zJV|U1{YIj(BzA`0p-Y=cVozuv=klf`60Q9qKH<}8CX)_?){9^zw-$bfkyFX7n3q6< zI{GZEN2fxs&{hCN*W5C+c)TQVe@Wha#hD>$Qr&F#Kcq4w)zfx)yErFPQhjZA7pXdu8fd#ek*X`HA-4NBsd|zcZoAcCi&I}x zqiy$-2+1r-jj1*zRYfT1je~?N)3Es<>L96Owp)!ml|o4!w_TqPR7XjjKnYAM zlGG{Ny%ki%xk-{|Z1-g*c9PUN+dWO{W=Wm5-Cs!+OX^EB6US3$Nqq}H$@*@Kh9VXcDrQpHdDcyF!B-1LqKi_I!;i<`TYpT{EglbRB`@Te9bXP{LL&XRu^s3 z+&haIx(E(Zx(NUDLr)IsU^>D-zuF*mFddP&p464X(1gnt@|R_Si1tlu!Uf;t3_;LUx^Nr%7@ycv&v64W7Z1nu4w&!;Ps ze@%DqOpqqeDK%Nlu7+ZzZ8|dT**4#>Z9j#iZ8`+)*``C#(zYwrVB1A>ui$-3)w4~9 znPJ;fTCT&)(zbEcm2Eq!d+vO=)Hb^F5k-3L+^9&;ojUsKnY>x0N_S4I;hC(%yq?KA z%qvZPx`yY@r#?N%H-iSJ$JsWblC&M_ch(B1Ef0-DXwSRtEIMK z$Om6jBm#iVqCx&kk?3*K%ZC-|nf$sUrOCI|^1S?};(8_@SET3Vw-hN&K3fZ;;E;%^ z?Y7B!6H8O@BbkVENz6%-=M;(3KP36FB9ZZVF{8Gdo%Id5U*6F9k>po5bpAu~>l-@P z#QW6Ywk!C<4IS<|f-346jdF&QR8h}plru);WcIEva^zv<_OLtoU=Jb(CV~i&)cxm9!C1`-ODnQX{XDu2O2G zU00;naT}HAU5bJ=O7-IFijj2?B}lC+?m>DE?^YDl(LtJ1kF<^s(ws*1Kv0>{+TdoOG{JwXvjo zm#R$`3#m2&JCC3a<N{sJ4Z)4&_m;jd--aTaeQY8=0UNx`S9B(mHfUG2YE4cvorewMB9k4&?Wd ztz&o;TTR-F;lb+_sXR2(=^nokzQ7sdu9Xid6wHgM=nt76dx;8 zyj-D#qOnB9%Oz^PqOnHB4-&l_;QW7_17V|PGo&IOYJfu#A}2Rew;8GHvSnggHUcOP z7olA$(MD`78+(o5ZcQUrRDo;cbDBo1D4X;iO;*3EI}Cd!rR-#Qsb!hYh#90YykTzXuyQGK~?zNKkI%vXu46qD2D3C%_n zK(3tcY8p|1MxuE`w`-1EIzP~Cw2fRl&uAL4ZMk@UsOd6R{F~y%hHe3DT-V4m(Tna$ z6IV3yOuVR-JQIJ=v^4P@ib)gYNef#I&qQ_B3fR)b_*|GMSJ2?H(nN7O*PScBQ3yJ6-yXnS=;P(4B&cabQRJ>9M$_mQ(!a5q_Kc6yG>zwKRZi20 zCd%b1UeoA)vQ`P2jz@%3dOlGzWVOD`^E|JklD1c^6fNd?zM`gOwT3rV)q1M2=Xx*D zC|%#IiRXGRp6FR$U*{rSKa*n8$ZXB_T(6Fj+Vw9q@m#OYgn=72%3~o~%yYdu7~>bUTDjOqBJsWS*rAQmgHS=sN)@;wl&ZdoBC?;)GXU5X*af=p{eq7$n^P>@+ls&kw z7W4erPt(%Ia?O>EJ)3*oLmfOzyN5b^25hf;sN-hnW1P;;GhQ7+19-NC>K@)P z)axGVAR53^I8^sgM^V;FcaJ;FY7J}QxqiB4d);G(rajls)U>SD7cEq^GFy7CU!s$x z>-V?xT)#}SJ?rn+wCozlUnTrV`+vvIwqJ=Z^|X=&sBR?5b| zTX{A4+Gi^XJ_ zIH9Phc9N>u4#Bvo8BqCN7muZ77&lB8G>xU@X6}S8Y8p$+Gu+YqplK{E+qs=EBB`gj zl3&v4h(jLW+Iv~kh(q!wYr&s1onrYAG(HP+(*KSD|BB|L+aIRfe>9D5zd%&VhuA4D zS-)#GdN-rx!9O&O-aT9Nhgf6;Lc&2K(#od*1&v5+O?uaev|c2AU1x(3^ISU8k_Xs; zjSw^MMjW&?jYfQu3#w1kXvDV>`w99rT?Vy!Q(VpWyc^Vf&$}_2_PiUbY0tY}RM+#a z7uChWExqeSbv^HTQC-iwUQ}0k_u2NIcPr>}Jnx1yExmh*V$!=Qn(cYFqNb&H8x(ln z^`gFr0!#0DQC~!XrFT=c8lu3`yJ1ax-c8dqy!#ycSh}V??^e?^y!$V?I>L9Y8CmibWkTzP5=MI$%3>l$~s%&JM+m72hE>G8Q3~pv&`*<;*8e zmS-Vn8F316wDShB{OxM2!-q=+(@$gEBsgP;GeQ^(6`Zfw$1*9O;_x2J!8*iM96m)m zn9~a~Y0ess#)jnAa0XGP(J}be%5dgqfXHP+J?9DHJmPF;BaifriF2Lp;z*%ey;oy; zscSxbUf{H%N4hb&$a##L&Rd9!W!OG=#~<)_HyM%-uG-lMA#NGM5AGV3hX}U}&j;U4 zZGr%|Q%kh&=vHrgQ!KLhh4&O1=iEYk?S0@$p?<_sHh%h!==D$%U++q)FX;~$qRV47!1`wM9IirmY; zZ1dI&Cqn#cBlxj>J)hBQer*x_%jO@q&xA6?@glck#xyqKAYYG8xc6S@vJb=@Uq&&W z%^2c0B*BM$e|5&g9zr=H?k2ZlW@aLIZ~6vyv#j4kH?dzFmvh=RH^>R>ElF6myHs?& z$*qiUsmJ0H>6C%Avi>$b(93L>apGWYe}!J?XSSPA8I+0zSFzo-q*N?8&30cQrDDM~ zZ1*=(Di)k!yU%gxs9114+vU@7f+`lAZM$blsZemP?S2y>sbaxRZFdmIq>2T%wB093 zsaSAZ+dW1~#exeEekG-1!9^;d9aOR4VinL1s#tJ070?c%n!c`BeCRH5KSDxe)yq2R?TpdD19;AISGqjVJtUa8{QK@|#K ztK!)~6$)Oj;@LqJ3NBIc?4XJSZ&LB>U_^z2x2S-2P=$iGsepD+g@U)MfOb%Yf_KV* zwiWCmYq3Ygvx6!WykEt$gDMn!K*h6zDinN3#j}ImrQTr`&kpu*BzX)0Z4oR+cVz53 z*jqABsn~U}kEG71&~>n{q|T|(b+DhL&a2RMu)n0fRH5tO07-qTLf658lDcTS-{bq2 z;28hE(Zw&@?#z0iruegZ;|`NH`h1pnyx6U6ZxC-4yV>C%v7dc@@(_6@;+n3$(eVA`#YHCW^ZtLcdKc>*D4_ z@-en!sw56VISwCA7L!x`R(@m4B`iiRH);usX~Ya-o!78b#mLnr!TFF_t~P23i;=5M ziZhS-v|WjOsyM@m+fg^o39?T4#5J5hQL~u#@`t?{&Qb~$Frl84O`#6N+0JJ23yE`` zr-?ffH+A>`vzQ{{mQLeT;I1c7SX*ZjcDONeO)GF_6U#NN$mxrfGNwD_i=C~+J&3zG zM|t1$n4TnhI`1)|7ja+bCAM5|;(^Xr#C?c|I6o2hB_8hZ2Hr9Kh(|jwprgg~Cm!cm z>{bJaCpj+hK;o%R6XHR{Gn~(f`Rzr-n(YLzABY*ugn3Q^@etxgP8H&z#EYGO6W>O> z%=wyl81YKyXX4?+Yn{J|M-Z=f?(qYUBrb8DWxpFmyvaF4EPwvL#W@ZfiMgE#+nn_n zI5A_0w>xLC>cz~TIJ9#5J5P5@JT%mm^C&M4xE#D|x@nvT)@oeHN&RF6(#J@YMGl1thB(7QhP_{U9i(4)3HEbDT z)o^!i5tnXplXJ4-!IFbI!TB`?SdQol&Sqo~n}NmGO0oQ}V?f4c`ftPkm_~^v-QC&| zAId_DTB%v6xn=pRRDmId`yg21B?(9f-+|Az;p*t7Y2hxw3E{^0j1H&bGZ4nFjVxdI zN0e<_eg~}?mvt|4uNuIn%Zkg1A7)wM9@T)ucVi=Ghu6kYer;J8VEISXvc$*T-P~S# zu|0{)r!an{i=XtwwQmF*aK1*<#}&}_Xy?vo;11}(7~Rv$0pC0p1tmD|VN!`Jrhh6} z{?B21+@RJ__AeGAd${S5_UOWP_y~l2VL#OTVLpvE5Y9m-iNc@KP(pm)N1^S1HwxKx z{Rq0s`b77{aM;}fHMhbgm_h9@AA0EvUxKPXd@t+?gl9R(Cj4>`{}Ky-0k4-0--7dC zba*%RK~6YaF@l*rJdzzU+zAej4R=C+i3_)eCFQ~nMB~Hw8!()@5ekXnF8C6&e7IT- z+(ak*39_ybPJmV@TopOE;e{wBIs7v0$ITwn@Lb(6A6{E2{49Dy}jli zbhN#o@(9%BR@i4R*aT=fozRH(f+v6jR@(FE0Tt|-Oo99P9A01_p>n)@CQ5=TPDDKqXYJ$ zS8;V7pb?9t5ms!#zWY3w)oZ~+_C4$X)#Z((mk`qMh0HbmjuBAV4ivGfF_VB58*R^L zvE`;BX~9+0GL9Lcu-*9dA3}xfby{ZRigZ46xSHDExW^9nOA0 z`o%fz2VO@U?M#5vY(X6BWT36>^&AWd&M><5LE;KdHinwLp&2AooB`-F_CsHz71AvK zp0cRFU9u3`s(0HP-BD=#z37gC@D}ut=x}T7=VL8@cb56sZ!EKhy(1q|&iLwJJwu3} zp0F;@s%&fU(jDxY4^}vpmUYE4swqT5B}2t5*w> z+g2bS{B#1N*M71mt*^#ht2ocHp1WC}woW7Ta{GC9*&^p77;NvQ>x!M{sI`ydc9N6N zVY;6gPjxzB%-b&z&v1Uic!=09l9=s8(=i9wsPml4>`^bX!4^AvI8_|12bq=59CqPX zSnyi(ixi}n2{c4XMMD2o3|adStD~Ly?Es{O=fO2r_;Ds${;oA}xsVTjt*YsOaS@ws z=idWPZQ1wZY>6jLos3kQ&5dGe{pZ59do~9+=01QRT+L51p{yH7ViuL=Q+o9$6OM))7>h_HWaSbBx zq0`$(eExb6sXcDQ1QImJs<(-)QPxj+f88rAKPBL=8%5ia0{;48HcCc-PWDfOa^}|@ z8Fd1)h{u=3RA|?gsi*?IpGBd%lW9?PZ)ebB0jCKrm?95u|GK+OOw4EY0iC)PZipz*mss>vg>ClFj2_k#v7k z*;VX*(jZnGBh|8-1kxap-wIe86y;wF0yfy`PudjlL-gj&Trl2K zwDij&@!=phHR>R`#u#yJkXu*64Wizy8onV0dhn`P=D|ARfCu}FiymAmstnd@FN$Ih zelKQwu#(vB!A{~FV3U8N;9FrGMv)IAAb%39JPn?vtt{53#?$y%1S#o;I4f(aXgvg> zzh!rzb#ZSQs{}x|E@w)%ZW;Qaf`|?1ap$_>) z02f8hLbttWJ=Bef&`eo{pp`}2JEUbp=R5ybkmKuPyzPk6r ze&E_|cW=)&{tb?A&qcuhFh06vqgm`Lo`Yve#q6n;b&FKILdCyOdiRVhkv`0=l*QiE z7U|0GJ(JPKc3JtPhxTz$X0sOL0$c?6af*2NPB$dx4s+{A%AvR@C~`TNipNof#( zXTw9CeyatSLUe)19`3e?aBpMxYBORoHZxVE{&h&@u_3D=lLTf|*$yEm*_cUKmSkf# zBw%9}0u*|pvN1=3BOCK>0QevgA2m_8M#u!~iJjff9_X6}ILOB1hzin>%=xpUOz!VP zh1<3SZ;+-bIRFl^@(aQBRw}xsH>4K8Y}O+Uvsx|7+Kd#{gmQXkFLJ0dH1HL2%I9pnO{^H;+Hs94jN5$JGQ_S;DL4l_QjjgE9{zbD)Qe0%?!B{ zswr_F>7NWg27?vB?h%rivdF&6z$t+=wfkl6g`e$gnZib+xa`@KkhP1&ya!z86#ACk z%J!F^;cX;a8T;>6av!M-Xl2tFSxz+wpQ?tAmnlzKZRJvziTk}gG0M%1FjbaO#mZu~ zwR+Rcma0OxgQ4D=%jb!tb zoSw^#C-UP@7Sa9#(e=vIJB03F8ws61P*g>GHEYu*Kc8Q}ZSZ40)6(;PkYck$5e zZYBGm*n7L15!sC750SD2Z#&n&9OZRB0$vCzonHjVCwK;62|%GITJ$M6o53l%0PqGt z$CChhUf^ta4jEQprfuvautUyr2*ezf~ha0-gR;Wpd{IgUS^67mOucTgM}YN{ zJ$0;`S)JRL@eqLbu#xs}XVrO<`HJP{(}@Sg7zjqV;&V4B+h~SAuQrNY0s0Fn&h-C# z4iuY$_XiF05{e4IDHjb3y8)yV3w0@ZOZJ`A^W%OV${Z2K){%N<1>Xh^pg6L1k40#N9QO0UlV zM|yn&0IL5y^5M=E^O@*4#jO?@M58Z&n}TG!z%LEn!3=3IM`LFie42pv{y;!`dEcr5 zDgQrvQ+zk7hOc+CaV7q@ESnJ00x#Gklb_bf@Tsm`}yTA^)TpBr2G4GkW**w zQqQwkx%tb(*yka~9^~)J)cV}~`M5609dZGZWzQMxAJ1fVv2>>9vzUXT?gZUC-xPx; zxOF4))F>w$P7`v%DQ9JIYH9vpLzFTKT3A={wo68!u8rh`Gs^cUIo(^zQ@8q+TOLYj z#V>tr^(!~KZ$UbQ>Y=i2p{RFA1zfrsjm38^lGjHa7FvP%_?R0)R-JbnAfHaQ{|!i~ z*}9Xlu5^;~t(-b3Kw-6%biT2a+&a;%S()=@hYj$Ez4FH9YX~Z2m%Jz*ndqiP8o=-N zI-9%i*)U)2z7>5Cw46R)yxVK7TWR}e3seB%VOdlTX7xPw)m$VM<841;hv&oZ9AN#C zDEq4f?5`5Azuv{9yCOi30u_4N|8tNHMYej7{WK41?6hA|pL1JTY-VMrtqf4;iON3P z2prjGdvU|7LJ4}1Me!d%Ry)yU3L?mC)~z5{;%z@_FGdAB&joKZvz`nvi&=XTMFN~P z%=$5ag8&_u0vMCR4&)>IbFsaTuAsf|LQdKnht4VOO$R8XXeY`_gPVaR4dyoyn2Q58 zx(YxYSX8tVg>0fu5Znx^yadiG;1pB^rx0t+HL>{)Hw6=J@l-c6cp5USZvO=$GS#gW z^*3qp6p|b{+ahVd=rkEKbO-U*BDbPgF&QU2wq+smD}uDW)!wxb=CUn6MnSSIe6VAUk#2bz z0PQ#&8OgaPQ#ReJAlES8r|e4Ts(8i{alQvEz;QY84ppc@&C@XE;1eUb%8vrz28b%pA^#SA}o9-%gYJppuDr~xn z*v}L+1&2+y9CH6>|J@mhvN6?qdQr@sD%VrAVf}O-8XKd&m{+3Y`IhPhRzU{x?=Tey z6!H61x0+mt?-$`|Qt{?#ZbpCZTL*9Dq;Qw*{}4I!>w|dU966kERvTFtDbL)PF6N?| zcFEp*v3r+6^=E8i{tZx`><@rYT^}b*@zylNBln2Q(_FW9chqX+J<>iq=SI~US?$s9 zR8ZkCfD9_QqWzt2onf!Q7RDb&fNvkSqmXs$4A3<}e~X-o-h#kUl-!=%5gw1N_Cqwv zp9!E3qRJgeWK+mJKfGTcyfp!cTUMXHw-|)hNp)jtKc?B@}#?7w43f$ z2)=`M%Ks9)?qcwC99ihQ4xfc#-vPO`MT#{Otz?&+S*ATgpgf{x)5CHP{x!^Qc@%A9 zpOkbFMuIwwyeBjI?>NUR{#%D2=fg|96WkH0G%^CMJWf~7A{FIW_FMjK5R!eKKLwM0 z{&RprPeS(jtKi5!UmbJJKl}V{CSa^PE`vKC#_o`W54HrU@1l|CoQWfcT09tPFGej*PSvy zUq!=P#hkA6X|mAM{GYSd3}nlp%V}#A@|EssjcQ2u@UNrNJyTg#EvsgPW#CBfJOhAU zG)~q1Fx(#$C9~a>F%RDF4fZ_FUYSU{ zjp^-u!;sRtDKKZRLJ)HHx({Zw?*xvTy(Vdtj}h~KW-qL>)~#?O|LzXAq|R|ODl?ik z^!0iuq0sjg*nG9b+b;P?44vbqM3x}S_Eo^)w=&kyd+H*s`wdY{ToA3a95N2zs~8IH z>5I*G0I-o4PXnk-&NzJ3YLEi?&s5x?8?-Xy67ZQ^0y5cQ>~C!HS#N}Y?aP>&7%%A! zUe*wJB4<20tzGYi0qFsdB?;)-YBj0n<7#pYUTK2}UzU`soQ!?6{L;38kKfwjXn8Y# zj$vo}82z{MXg_Q6Dc7)E-;ot)K-i zXyxw&YpR^2`h$cFn<4_n&ti7Ot=*5yZ5h;_E6-&59RBzSox>Wkmo*$9dsq$7c1bgc z$(H1Ihwa%1_>G~JBOeI9=!Qp!Na0__wTN4-8e_h{LQkzf?PHN9*T1#^T>m~=$vAKR z`14U<(kgxZ7$K zm_9Y%t*=txc$uFE|D6uGczN=tm9Ra@W5BANi zzE9Cl`J&Z!$*`Z`YJ0n{l;f@uyB4_B>$O^gUh88A-X(qV2?mFi^9={%-W$y^NoMl) zx`l3qs;u89P|{xEK$Bi60FYkk631j|Q;L=Kwpg~%tr$1;0Tjdgt=ab@P`Z1e+c=pS zEdpC*)Jn!p*Z5P!^@VPz-IupxOM)EPr1nbx-D@!#u7LMpMKBukd+ARAl9;;5-=6d0 ze|3q=Yh{kD}HWl?;OTdl?t81VrF**jJZ zwdo>btGTMb=XH{!I3cyKj7vTnjUiU2=&AJ_i}3Y#4^E4$4yt_`Nd5 z{t;;z$6qSr_~WX8mXYmM0Y*L-ftGQ6wgZM29w!ypi#&O!NNZaJ-55rCU!BUYSpPtR zY`jMUpHMIscKjpoE`$2ybG+M+1+1KDsQ}xggOzC}0FE%sA^p6hkrva5n2>+v{%G;e=kCQ|eFgVtX+bAnUf>Awvi z*XkDok5K4+(BAN*Q2R>wKwHFG1zmtR@c&pZ`<>Xd*bP?YH&U@M628F+r~L>eZOJX6 zo?bp)?AD2tpMidOE(Nw8ywPs-3;N*()V*^}nL<1S73g%CEqpM*z_;C_Q(Q$!@e4w` zXG0n9J{VxU`#H!;Kb1j}>VN8MmRAGF(E1d~s>#P5mTmqQ8S<-zW73ap(HJt25_3ae zx^4iJWfwRSs0)+i4+OO9{;LOYnMuUkelyU6axVZsCw^MuCaD>*Eoi#znGMoqb(WO{ zqo6N7IJv(C6>oy~|6=#jU+tVl@<9<#wY*+p{B zu(8g|jtf%#bfM(R4cpF3+X7hpJ8h^fC1peQP?ml!E#Q7}xkWheOs z_Q(g2XusBEw8w5GzpwbzSO11!7JsBw;~4VD2T#s@wXIQ`G7;6N*cqIxhT_lr5KbD6 zi9TlDFGC^BEzmq9jj=|hqOZi(y^nI!@G(}78jPIyD}k{WqtJqQmu+Q_tAu5U@3Lpd zHNxhN@3J3`dmEja@1)GJ!!Q%_UEy_m>~om;_^zq8o0l=KHxKuV*V(n~e;;7X#X@ zu(X!3ey+H${lo4uUt(w;5(k3ExFqq ztn7`vF2vimdMv|brG(viS*y6bVD^{7ylzEi5at16kA&TMk*9d82h!zhIaq6DYEOQ3 za9Kew6=g=$`P<^*Ll)|@CP$Z++MOk#ol#PEPwQC#PKCBLke3hf#&3nE;=DZux}ofXm9{?!3f{KOb}}j=l(PTgmMuHSn<;Zx(1< zeOcHg1$ohhF?+8tlzpQ#u&K)y@L4T40?L=LDj~W>7;%!?4cws4iYw{UcsXrB; z7hO(YK(8EVfRe9$_&kNTZS|*p=M}`Kd@-^>FR;CNZH>3*Sgt;dC}c}se?}9Uio3SD zt0FvQvy~y~H8vZGt^J~6AHe09g1RJ&=jwm7Hd#Dwma)|DNIcO$!LJBD^5=!e<8t^m z5mhf!Wd@#qw{)8u8~Ix++g49ckB4kq>hC8Yn{!Yh-td4N7j4Wl>@W3)W3$CFL54Mxfgu{dF z)I;I`6ax>Tzk=cobgl|4_?q`p+_%S>v4Cb=8t96g2x^4`j>zKW0jm|IN*5 zwlBY0@}24U5sN`|fL${9Jwh$+JeM9%9;2=Bh5`=;EVwDIA!1!{4UOwT zv9`v{sJ_N5xP|Z!PaYNF^tZ)O<;ub=xvX%}@Ur|!<20y#qA|1lQe$Sxq3g*9kS{Uo zQdVQi$7xJ?4DVZSD5Nq01#`yD)IyN4`0WxiVqIEj%#7M;%#3a^i?!lYv0*zx{0l0L5A2! zl?Hy)z|R=?MFSr(@JR!IV&Lx${A($WSU&V<&xmpcu4Le*2JUL$UIrd$;86x%Y2XqA zZH*j+Uw>NOHfd?7*c7?@*ZzNZZ ztT7Tw4E&;j&lvbC17A0AG~)iAlaq*}RK1gdlQgbo$kZpEg%c`Y?TmyX;xbCP7#RCu z`5IvG2W!5Il!*p^iou^}@E2)*A>`MRuZp!E8pF})r~)=pNaH6Ap&i8Bq~f)UG8!Kx zf0p7OH{?Gs_~#7%1!Apx37GjL(-3=XX+~v;wNOO^*D-J|v93W2V#GK2Y6G04aWC?< zas3VX@rL{zz!56sKzWXlu-d@ufGN`nGLIVk=L~$*!0!@kvkd5Ug;<0wWWi!!T@A+ zyG&4p-ASyK=NtUHwfrWC-EZ(W81j!2>-?W2F0b<30i2}q{)i#;FJf)oF@t}S80!vS z9}#QiPl1^c4_Oxs{w2+)xBoQw(c_`3E0aVFU1?u32xgQ9h3Yy1(5h|l83~OzK#JW zY5bWXbCFmZ{nHITGPr(&z#rBplnTWY>jJ76xEAq5Raj#~z6G%^xR_X1V4xw7zm(qK zk0p+1h1o{JGDG13gZ~h*mfvph4;b>V8~is7`Ev&Uq9GsokCE`Fp%9B2dNrs*tZQ7; z;MXPA2DLQ!#l(2?)yv=yAlCBZ6kqvwHVM4>x?3ekd>^q^C^7ikiSg#^d4vBFv6eq> z@XrzB&DU23|H4F+?0C?3lWa?^}3OI7)8T{4~i|F@~QzN$#PglBQi4zr`O{^<+kHLSG zSoIET2QlLLeC+~G()fTObA%YXKEB>G`0o>Y`;3o_gs)YCRJdU9e>M2miFINA$*N#_ zIv&{LCux3X@aq`-EX`j6ep~*^)0^lz8A4sO&_fXFPrja@h8cLAf$t#J22BH|C#XBu zkh#~uYdrb-5E5G9E#R$&&<;-s{Jj#36Q|H*XNh%_eLPs0=MFhP6b46*jacf>l=ONMfpsnk`4r5U)8Sl99v;+jgP z7jTlsW69T*oTTKH#xg}n4PgjvHSl&r=5>SrHnA??Brpr3eV-dL7YuyGz<*3d`JVD$ zhH@E91)inx26l;cVYvn_GVrYiUP7$BvXZ#A^2%D^Bx0s*G=!ca)-HP1;J-kOV=P~< z5$lYO05c;F-IE6YQ)0cR`P$%rujOMQ|2J^NE6fjJ&(dVod|VOt&M`Ii(5KQewRM+Dfe5xSP0+;_n4c()d+F<~Xsg zz^4ZP2Lt~_Tt{ch5x|VfBHtunui#3=x`4*STE3%!2OD^-fu|UFrhy+d@X?4tyl3E# z41C_e7Y&>-qtu{g2EN6>V+?$+fj4R_>+`gcu+PA+82GS(&l&g!1OH**Ci>u#^r#{9^bH|=QElK?h%qDbb(mNed<>WcuLb|KA%E78`NP0v?t*Sa4;7b$&NNJ{ z`E`hO0a?H-;6oJ9ntbh{jt1^#;9kU9w;!;ldz&E>8EX)C5@XflD?+T57XnlH9QbPt z`4R&^Zs4bgweB;(p6)(F=8(c_JRLO@-qZ@Y*m0dP6h1a&KGQP%AHw&B%q2s{5AS$J zBoJ$lrV;B(X3j$SUP6wckZ&k-HxvdK{Go>Y1cN`9GYE`6Mw+$DN8ve2y(3rx`!5Dk$JalTRw zT-(6e#9B9(c#bIgB)Lvxupu+rz~iNi%5x6!9SYw=tn*n4OdAfvh7IIv8y++8b_4Gs z*1FFFLwB%LK4=IXHSpVp!bil~mlue&L01gEHK(+I0P!5r?Nd~;F0nQ)*TBuBjH=j8 z#5&LJ#M;o_z^o+y%sG;LozFxA&oJ;DVy!zL7`hRuywng{W8e*j!d7Bk$$iAyphE`# zZA1PfFpXOX<32I?pBwxOb2vn_)mJE_@pWRHtoVwa3#_e<1!kuFyJw2QucG;f!LLWY z&Zn^<(_G8&Kc<~L8BP&B4WYhTi2pPl?Fm6IT0qvDR&A@QV%kUW%`}?f^q!w4pG=P?&GUXgcbs8ucR8dIRCVG89%3>!#UEtPOg~;O{l$Uj(Lcufn)D$k)cbXW%mn z+26HA=M06f451$l{0Fh_6TU^Ix@CY_*ijVblCKL38#u$j^@&+7dq@rlPr11v)ZW0I zJO#*i(ei0N%Nk(F3^8PeYZ?9%dAuPr*^pTQ9Pw&j!UXN!?Zmp4&l~)giM6-hHu#?y z^4}Qz9}M}c20wWBjr=245(!;!Wnx`GJ!0LHn;85egMX{RpGd6pi4g0Nve@7+H{>6Z zd^JL?rwxTYhQc9YEpyhuUlBJ|BkMchB#o~aGS`W9KM34Ynol`m29NPd8et?a&};BHL+EQ_{G@=d3kLsJVqN<`4St!$ zrTogox_~e+3XoB>+T`mAHk()*)M7D!muZ2aT%?tsg%N$p*98wX@JK^`j3Gb8keO}Z zdx`Z(Ur9_uX~!$A-e!hRh`cUnSQ4z<(dGu6cCu++dM#Cm~voLC$5jKSY$@Q)FXR)w83 z_@5AKPk%++TFHF343l7zCayC8&gd;e=3PVPQ$yxULng4IG|!p_ zE;R6{6)4{;c(IZ2n1S~i_^5$DC)Tl^UkrZPm8E$m5^Gnd5Vu#Js{))v%(U7@LbidM z6KmxT#05(ECg3EE2a~ToG~AG%Y~b0%+{xlKpIGZI1&(;cCMM{y{v@&P;kym~O9uZq zvCi~;gMW@#7jTVOSD@@F;6i0Y3~-Xd5i6Yux(2m~wL&)WFr|=3td(0ExErxHx*u_( zlE2O1k2Uynh;^Pzh`ngoS`tM{c|CBF#?O$ijXP-Ie-Ud#-y*(E>7F$B=M8*;Sm*Pn zfvw1DBpW)?BTrd}1xCVsI)TNN z5bI1ICDxhlHSjrN?TK%QJ1Iji04Hhuvmx^b@y$x+uhpFYHIa<3p}mY!iHns`HQ*$T z>l-pniM2~x8~mGyJ1gDJz)2bpGvr6#kcZ`yNeopA(}}ghJOi&L)~Ok0aJ) zi64JYj*fJI&^&UrKbIO3%YkXxCy-fZ@HZOxd1CFJgT&fBM-Bc7gZ~+^w(P=MbOKM| zCnjjqt{OPufzkph66*r08T`5iza_CQpwQqK6YKo@5zDn6zPpXY0aOvMrNr8w4-ns? z_zwanX}radd6rmvZjZtLlvvB#>q_&CCGM{BOaM-bXri(qREt<=+StG?44FcMf3v|K zVerQo{Her)Rlzffb-9r_Ad)~tA?+SRVHL49LKq4M4SdGHpBeZUV%;aM5$h(45~cid z#EEJWvce>^b(tzbnwm$fo1-mpPgR2g;3SQ^8Z!Nfwb6qO{uqNl(cs_3J5YKG5hG!# zp|FNn7bbvNa188t%;4`NzEc_ZlEHsP%m0C-Hx2$7Po9W5rc3h9jc5$nPRX_?0%bGyNx zYv2W1=55FRtb-(`E9;ID>&|k*;D2cFzbDqUxnl6I5^F=_9xTPKfisA8 zSvkas+P%$f{$+#zAA^6Lc%a?{L~kgqO)M~LGXUkK82p;Vx`$^Q{9G-+ z4f1UberH3zr@>={cN1&=a)ZB-SbO40ga0hCZi2TB{E;DZffzOB z>&gv2+B5MXB1CLc$)tRD-Zt?2BJ4{^uK2mZ`r5!hh^|cj-C$iaa6m+m9EpFpw4fvdS2A#_fomDK zj)5B*xUqp-7`TmrJ1VT)e6x|z!@zwEJlMd)3_Qlb6AV1fz%vaz&%lcw4zTv(P;I;M zzSaJemEGi>Wj>F`ZGBp(o2-7TG0y51pGisnI^ZiBV^XqsS7GwE0NV))KMPz|&>;2nyIzXPtT@kQVqjrrf{CK@wH-b!PJ#(DEw>hiDB zoiyg(rMqd|0=SRH?SThrj62Ju^-38dZ=SM2^L8SAlg7J&pU{~9sotS6|3m$p#*Edz zpfN+KuV~DBlf16+8^CXB%>P-xt1#V~WPZeHeSGnwWxw8X8Xn&d_-JzNdSqR8F@i ziKEj~y4s6H@(f(oic!2A7W;7VrOX!5GgG?QLqwmM;2sxSdATTl<7JZQco#0`gy7|h z_=cAuqRA{=7KwXt@kP%QXJ(~z@ukfZ8MBeka4~&0QrC*3yj&K^b8z`xjKam2eYe;@ z2Qu44*}34J5q)s+Mc*T~%?0J7(MaKv(!-e2wyZ8ndU(3a!={%HDv{)?WwdZ1S z23Ocpdp@KNiRrvd6-RklCXyH6fb9}`MT{`cV9{^d$y>3UrKFz zr|61{Z&OWiB7lsR-v_O!Vk3En!Rr!q#V6$L6qhJoLnJRlQt>X)b{Wc_S4*U=O>o8B zWe~X{RxoXJZE-#sS-lOOui!axo`N$pGxdI2@SMoLAI!zI#iTJXbpn|7KoPkg+S_W2 zmE*xXNZx4i4tREo_>Gr~BD@?D6*5IOO}%wFB*uw}TwZ;skkf!Sh|NFVa}& zCrAXc6!A8tQ^co~u9u}sN?i?JOVMC8c-=H_0(nD3guHRktq6+_k~dGhL*81=E4K!` zZ6dq|y!~0?&@fneD|yGnMDot)a?3rKkN~&70-kM&OGARm;%|zjiTJe;%Wfc6vL(B$ zg{^HHC|mC&(X)Y=)D@XN0>Yjlo~88V24ddo6gZK*YvMY1@Jj6mQffyXZ-g5RiyjZ8 zRFArb-=&@xvjFWrVj~jmG2$pM=fovke4qa+PVA0?1J|LL3bRGqb?B?j#i(@56F=>5DMs#kYhK+L@<~A0a)~BTSbF!O? z!FywC`!3pRX4g;M=X)^aShCxumbz;T@AnXMj3p#t+DF)=R(O}u_j^bAU-N_s~L!n8crh0!AB}iQ{a@n2dlAv zKNj{th=Dl&ZqR}B5rkZD1N?uX<-a`%u>LGU-oP%pD|8fe8xJ%@fqh#!e=>$59o+@ z7UMI)S&Pp^XA?flJKOP@fj zsrans)WK(Ur!hWjIQbQEsp)jVXDx>}_N(peN7fmZ{{d0%xfHivJgRItJmcHWH7tZa zCm$a4JCD&z4xfY(@TwKZ_umX12ZzV1lFFc=8)ovv|z@^pC=znol zRca+G@lFb-N)o?!PwWjNc-T%T;8u zl~|rFk*7!(H@n-L5+7NGwuoz@conR~ESA_*kx5qK0FuoVS>8(gju|vpWTKULjb3Y^ z$OJ2K3z|Nz<^SXDy#u4Dy7%#!*-c?~H-&^`v)N>pBtROFPy>R3fP(a^NC_)1y%~SnhprlbF{YgeRNYY#*eRBdUaByC`%Kg`A)E-5NsbfOW0`ca?9SYzi)8Z^>>CLJj$D(nOF z?$9V{iwZl%a7Igt3KM;6jF>k3NMWb%GZID4Yz8k4=8TzSgvL^tbusZC)QwcQff!`kTu{Mmw(s64H;cBIi@)PeXWHNw1U?GT2|yllF0X zkq#Cxl@1oqpaYW7)w}Rl6!$`oqa}idA%lafuBQWfk@icONc$TerTrE76S|Qy5x`K| z-y|tyu)qElXk=y5i*&GzsdRAL8}8Dl!ZGZ`KJZjH@8TJ(io2NTH_?&Wk*<{#{b)No zP_?8O;Op24)=3&RGG@%0YJ~2V6azesLER&1mXR@msp}<0Z(HJ4Y{vvP&+W54d`9Fe zLW%Gn`@!vrI-K1NnsN4CLr%NJ#&{{R+BH4cqJs z=?OE%g&dm4Bt_@WcN^~vmp9wS+2y#DqP!b8wSFULVyclof+Ol%LGiA=^tapvJHri| z{mI-Jg3SE~rZe}S20%Ui)=b#^ENp_9J|?-Z@5D6NgTeeNq&`f8Vp91{P|P;$ng6;3 z#+h_2z5c;OBMWaFH*Y~o_N$zgER#}>)od|1eUj%x81{z@a|?aYQI42Q5=1hc#Os;w z*Lt!4;U(}lFUjV==!LGNmr$*j2Bw3KpFJAmG?XQc!pSO>Y{@Y-FqBNQ88kELiP<|z z<`7z*?SB7ExTw!XOrrwR8k@_RB+7^5O9<=AS1h?IUn8@chP0+(bCX-*>{s2fyTZ-- zFJlF_l=^tlMr7Irm`z(r?rWfeY%Mva1qRv7EP{hfI+Z1DE0XE^bn^rE$gXe;940r| z9c~sE?bS_MTkt+*;!JGSBsa5-Y<_MrbhhNaOe1pP%*oiSNsg^XwwU>QNS=z8MD88U zpO`yCkh%91$;`d4c?YUEGHW8XgF@);*&QxIEMFiNbB>#}C*1Tx;c}>SnI#L<$J`3L zO!}2Bhu69sZ>C{3&VG+gccC;g9V2@Kx26{2^}B+gauL777+x$W2XJ@CYNlmRpU?U@3K$KkDv&Hk=v1 zmL1_%I*J8fV6$v~1CpZP_mn?Od2w{?!ImyYTd$1F%LVt3o_sY8+WeX*W0opIG6C+CLAO_l?ybavxOA{p? zlGg+tL+OHy$Q#Cz))!=S-f_-9IbvLm%iHNLdoG+4e~FIrgu=A^*%Q#y3dQi5mG?aJ zD-{D~Zr*(6P%hNw<=sx3DlsA!X0pPU=B=WGUgig=$Q$w&v++lW zzP2pya3aV^+6**Sc1#yXS`8%c2p;}4Zt)A@!uY#r&6Gll5`yQVOesagi9vSxlt#o!!H0+&6DJ2pAiR_&#Px!QiHnKt z;ERl|gg6kKh2}{qB@T*%y_7QIkm2jjgz`R64J4^&vws#5hs6IHZpKFY37UJ(w3(Kmf}kq?GfEKG{{DLA7hA$oOYudP<%5ih^-#M2GNb$=^kK756z@X( zHP`ft;03(XCQhN08b9M#`8Ks0nN0IlW-;i-k~HZBqcQHwxP~YSKHU9gZ@4UH3M{8$ z#}b9-Hzi6s!U^kTty}q0xJ+oi?vC-`U+!`bHg|V>aFqMK2XA&8zO2liar=AlJ9nW6 z9rqDHv!(mt%i+qxF$hysbI3^Q58N`JB`ZS=##H>wHLa$)m9K;|a(5!Jbp@t4^Fi(kxHu=0i#Oj2g^5%!2eciDu3}CqbgN$p=eE2Q_Oghq*qOj1_)Vu) ziL93O%juQud|g^u3?-5_C{=1t~xF-S%Jfvz?aR zNgtu|j$KIQ2kqNlOXa7TIt{d>E95NDGZ3hHulNK=t4Lu84PeW)Gu-auZDBV2p220 zO4No~!OCc9R4j%b3s`bDz?}fw+`g}d8@HvbVy{Z92qBaK$f*KnPK^yrDgqEX9X!Br zA9FXo8ji&K=0Sr4^f9WIdtN$wpa(!_y6X$D6FOx>0A2!+B{SNeg*nH(4__LD97{9& z%r*S}%xUGU^!r5Le-ZWCp$iAweJ0b)fi1*W?cHv#;Z(u_;ZC(Xx_PN7zUY~EbW`qL94gZ>HNJYNM(mVzHVZ+037`_m?MxfLk+3<>)%c%u*? z{G^!)tIXuTBKbyHBRFM>CPmMA5c=&`x!=DQ&MdjJHp4eWhVQ_k7_*y^Aiv5|hH+}N zbep{%E^kVy7&$pc5>4CBW@WrvTZ*kvHP`$hox0b&jynfLw1>sE<`PV`M#r;Q@Kd5* zFA(Y-pJ#zmQH_{oh2(Vc`5Qw>?hum64r+QPClS^qg=_Iw$RMfvx+m+TKa zoljyv#B^$nb_$~jG0(^mMqe|UeJrJ8UB=DDz>xn@B_FY5^+>mZs#_7}-VftRpGjw8qIBFAA# zv*M=cAVx`Rm2$vKu~b4omGF(1;8O`hRYD>%X0Mv%R|#xNX5x4WvJ)C5^Hf5WN|>3r z%KiF{upOs%e@~dC+}xzJFZL3WWkOlCN?@k5>q()}o>z~}%G&PtmB~t(R^(MmrRdYw zvr?Ypyj*EA?M!r(X0P>vL$f93AiSE8f(O}PorJ+Aa-K0ZI}83Y`6KLgXPRqab_~4J zVRpZ6<`r<*4413k47ZKfFT|#pZ-zIAm^>A3E$?2k1^OIK=&^rAufh_qN+*Gm`wT9^Y2x0mP+{D zOYo}LQ3=A0SH=AHnlT}U4Ic`J6tTHp2pN5!A!SK3@qwP?zk(5?gkSs9kR0E@NZv zyeWZ|2tkuJ*epmvXcz20fJ-sgHZi*HPaKZ(8#$jdmsjwo+m{x08RI7R!9&cJqyH?U zYYdK3nukD=eui3zL%#q__%V&M!+vB`QXdkTQFoqD+~I!zHYVz1M8#k5M}Lo%@WWrd zj%JVNu~)%g^7Cf*S;&gN%tk$4OTZ_T@C)uw=+PGgg1_JGiGz_k5x?Mdz8)3Gn!n^8W{>^|nZM-qX7>w` zAAiZGdTc|a{3V}ecIQWr`D^fD_aba7`D^e~kNuGBule+yaO)!PD>3+XjQ5q8?BBvp zvR(Jt7&kSR+Bj?MtQnJx|M3ADx8W7_vudXJa*l?ZwXFP~pFU~*zkWxhb?a7DH4CCS z74@uERqphM!eRI2Mmdf6m6Gop<(zA^tgPwLIOqK0_$D?=TeK9GM>Wi=rk?y64Zo@3 z4>kO~h7Ht`XPc_wd<{31I4&~ope6Lw@GuQe)bLylU!&n$HGHpzdCk!a=oJmWpHNhn z@THb;O2bKsZl|V^g7}%}6P}a)8Xm3TsT#gg!#8SpjfOXB_$dv)q~U`S%bNN^OZZ8{ z3E1p=!DVW=NW*P4e3pg>Yj~W7XKHv+67u&lSgs{hYxrRe@6_W9WidvFt6r#PE)xzt7@XDhC67ur-p}Vc&>(T z)$rp2%l>B^))JawBK0!srQzWkzF5PTY1q~96B-tK#;O1~Yf|gKGOm$M8t$v%ks6+? z;dvUqUcK z;qNsZz)p}?$gqYRWg>qsp@o)khK74-c&LUi)bLCVFVOIf8oph__j{P-f7~O$do;XX z!yjq*xQ2h#a5DBHy~3QX;qx>+R>M<)Yv=zfw1jIkyi&t!HM~*7H5z_a!>?=j0}X#s zhvUY{I>M8*wI#^Vu%qE}4Y$?snHug+jGY}Wy@0*%$PCnUh7oi7&t)W)u&w4YUQ@b+ z7#kukQ>mlyV#-@e`L&w%Qr2{xr%-XvDWA87K!nn7YVbky(* z5o7A+k`BzTt#D~VxeBhFxUH18)#M$NT$I13rZh~$<28eeHTi5!ez_*UT9aQ#tO9yi z!_R8?)ogA4KfnY`#as>o^BDpz-%_qhbCS5Nlp8pQ=HZZrvx!TkP7`9UCWw{Kj>MwY zQU2bV!MU{wcx#DfFipb?HJ#Ay@IS8cyvGdQdne6Jb&s>zL< zy3(W*D?bg1RY0Yhyh79OtjXj3HG^SV!f4H4x+Y(!>0hVGmudRzH2EW%{!^NKm(-Wz z?+q>Cux9X;CO;t!M8ldm8}5}jomiDPqRC^#s=b?P@{XGRS>nZ^s_HIcg6dq8i8Ev; znhucRlmDv8ah9jnXD-gZc!g{P9LM#3v6O&hDBMa@I-OW$&_$E?*5m^;`3OxuMw4Hn z$*0xH3^gt$ z&S86BRmlSOY9g0d=`_=DXAPgD;RzbPTEjQxY2-m-HDx|V+}s^8D(B4BpKChbY4{gn z6||q1N)R}gWZ(?xhhcx{+HJuNM8%sZjfioIokAur`P3dQ1<>+@!ZpZ43D>d9l!xM>B>&_x>Vu)of zFu%LO<*Hbn&P_4o?`5`9OSp?z1#u6tGTx!#w>A8&hLh0Bo_fd1-SNz;~g#G1I^%bP5!ke|4Ebo zrpc4giM;~UCsx5_Yx06RdE97GM~t?_s+6Yzv&6Td^j#@ewK7oCnWW*XHGG?fAJymSP>S^|fd7eo^cchc}s4bRZO0?!^1ValDJX^ zeH*c=m3xVsOZkJEd@FG?Dc`QiUnFjd_Gi)|E#bI^eHiCn289}KPCQ9EZKcVpG<=4J zyJ)zlhWj?sjyTTK5{7GdtcEYr@Kg=Y)bJG=j%#>{hOeu|=$*XV#4F{k8oo=zcWd|o z_v4FlvU48SMB6m{jGHO1Hd|1PuY4{rrf3M+RH2jB#{g_`-nm(d+ zk|hy1O~aWQ&egD^;l>&+t$BSy&RdmM(Q}YQH;>t3mEP zT%B-Fa<$a$axYeU-IZLeazEwjklXS;taiCqVP$2mcMseLZ?oLO`ysu-oypZ|_gStE zxEULA`r4nY7nf*_`Gz}fUs1k$-3HW~|6cd;4KQ5g`W~RWnt>1GTx43w54t-Z%qcay zxL-V&Q3-yzfro> zE!>pTq~v>ag^Cn8Sozmfa1u_i_<=hqzQvsh^@N7!qWq+6Dy z6j;Hl-9wuZ;BnXYP)?vbMjVfwW*`jq#erDwJ^ASO1RaJ|smad4PU`FJoa9vb*yfoXYYPqt1(-L!a z&2QI5CZ%?}Jr?x$c%#SR9^ZF7A^&yH=&`UC`+6*|#f3fA&HJ&(BRzI|l0AiqkM54e z?vB-LxIMBY!EEd{uZ|RkLXK<){52nPM^#5!g}=h}58os-j+NC9Rcu*Fd}`9S(A`)a zX`6V74IFomRY&?2E(i8E>;@&@R{ZgopGWvAu66kNX=%e}1>NE6BC(uTp=j7;31~b! z3p>e{-HMsm1Km~YB83@curTb`MKX?0k=(uJ<#myUX2x2i`0TqO^V_@uDZ#$p{qyd~ znWpP@z9*8EGDcYPVI({(ndXkaCsJrmb+5fAlHW0aq~y20vG6yzA{l=Vr2Ej5gZY%d z&F`M11#d&alHYj*I(Rm+6GX}H@~`iG_vk&57A^Ulg<=1Nd`-I)0b3|1>cu|021
    VR$;Pptc2VMYGBRI$Hu|855|B<5eC`t=%CLThZ8RVs9d+2Y#;b0Ruw}(+4HGIRF zFzPV#-jBirP8$tDDq(S8)^6rP)4*(+8fm;oGBD>eK!0!%iWZoch(VDYybdk{i`H_p znid>Ra@ATWWd`rW-@xJr@i&~#M~Pn{crTbl3;qiGJo#pBKC{_y>Z)SOtm# zomW9AxC_-5IP-lZ7{Q4c(19+*W^g2m7wAfC1zF{RZtolJ$a^Ej<|FPk_eM^Occ#Js zmLVFPjo}*@L5#e6l3e&HNTxq<^-g5cAc(3CEO`sg8Z5K`uc6ck(K`c9c?`fu^=rSO zIzROjxQ@kYa0eZ!0PQE|VINpMy7NWL%{-oeNs1LI>4U>brnADcl9Ym~D@!bZ` zW)&}XhZ|6H;YiaA9D06{8#=9+gsMYsM2jKDN> z6KOY-c75@SptX2|GLjS9iDY;BhKQ5Mhw5@hySHw@Sh~i2YD1)WPzu^bTE9x`cks)3 z1m>ooKZEA;sdV!IyNYl5j<_RyBZR|nmMd>-it$udK8{Kwg8)k0HV;Ia=kR7R>A5F8 z^RCkfPH`Kp+$$f5m+HsHUArFh_gUR8F>LL#^Ft+VR%vSOlOG z?2Pc+tl0BBi&A0neyxQVx7P>@?w<;i=w~RH`3R^nQm9Wv%QY13@CY+72jq{#pfDe& z+*;nRV3uKS<@oU}-w=0V(CCGn+aQsZF_W=d$$#bI_P7p)(;3NZ*K<_z4BY0|1G4jY z&SI1h4yPX@HUiSIEP@ykmmx_EiGUIPiSgZw6ob3u<{Cb-Amh7N#>a^6ml17?J58a) zEO*pp8EFmKd2o){e9N~X>+lgbYa^b;j-a|^8^!5s1FELsL`+qtNHGUSc%p~rMNl@M z?YG!4RUCZmE0AF z-ZgB*<|zXsv>S*%M0I8uNsO;h+&J`HZR9sVr@HF`g0<@`w$&Nf9`Lg%d}r) zynhRO|{7b*+QP#+UA8R{I!ST-3deTY!&8A*(%@C2J9 z!SX8k6co)hEzu)oqzRVr38m8W5o&_PT7DL^i0=Y26D_vXQSdShC~}&bgJmlu3gZM= zG|pq~CtG|R7tb*?5jSI}h+G>p8AYt#9LchWBE1}r@JPn4&5^MAmiyl3NYnTt#LqI$ z!ru|rrBrZ6;tz+$5Ae*i<%8;mMwQ`Qh-6kzB0Q?K5+aha#16)|a(> zgo9i}Jg-5~Yp!C*u1CT#A;SY6BUrq8e;E;0CTCWq2^QYXhPs~axD3G0Tr&?dwj5vA zGuK`i$`xXxaU+AD3|dslPEI{}Utx1m^EcDY<4BIM=ezEjha*i+?|~=^`7Q{vX>E5{ zjAV07k2J44G!-rSE-V{~$1R##Ov8QDcf016NRIiTo4X}ab_r`E6$xHJJHibcqfnD| zgN%*QR>+2z4HLe%IJ znDWG{utcY5U?efL!lT$On5Sy1avjIZny%QC$&qzRROMC3wp3K*DN&XC(db2DgYb(* z-9$Jk`jd_Fi^W~I=HMdmVMr`VL^GOySs&(LJp?JThzUN9W^Mo*&vUa&bfss8Oo7a332B~BiZqZn7+)8KK75DOyzrH%$|ZD0&Mv%Vql-S zvOcSK@-&<=^l=Jc7e4|yw;mTEt*(Zak1!(tLW&&2tTAs4JIf$uS6NYO5I3By5VA4u zs}&l~F39diU)d#O9K7^_naw$X6z+B$P}*n@hf_S=^3i**2lBOU^!mFd>jW9SW}$ZE zl#m-&Zh1R1AE~GiNpj*D&WXnvshoFJDKj8jq?`}YWH&13d^dw~u6(aX%1DH_MANQT zUgLZhgctKe5XR6R4{5R|A>#v^kvrY*)aB^<@@7U!^1V%V8~d*vxUrS zw^{Ho8Y!%VYc=f&7LGsY_D)SW2Z}7nBXzRK0?71f!a)}{xa0Otosz@rYIOFMCOZo< z#`vcu>jxQQ3}Zm#HWph3uXBw=5`*Lema3SM36L#x=ROh1%i<6eBR*mzodYa37E|4g zPhhurV2+ra-gqLCRm#b!4~DQD*VDu%a|-zp%x&g0F|K*bU&%Xe`qoGmCeh-p5eH{w zx?|Obqbnalh*3WlZd)!z2%PCApooq62(P)^;(Tu{?^JRds>WPlb#?FD8fhMrBeQFX zi3&6yw`K{K6?(waW3iC@huLeWEN4D3})nY4u6EvOY;g_|Tg+#BVd9?8+ z;;pKcp~C#w%}mTS&qokOUbMuk%j=zx|eT@v}>A(s%_jG!J400++?9_a@2e) z>T(n7ay-;ugWW^!C)*-934PHmUUmQ67Ky}JO5U&G<+>D_?DYStlSNiQ_P08Pxu~89 zvi1zU4Q(?`=51)t6f&{r6Je*XbB56%_G8(*M2E&hWCPuePexjpAGser8Oe|G;44-R zqxT3pDG)ga;HVpZD$+1<5Dt=X>~{um$<=6}5^yi7EU59Qk~d8#S)>_c*SOb0y>(-h z%v=-2v4Gq%%Fh!_K>3O$!pg+;V5IT=OJWSP1u5C@e*9D=y7tpmn}B!XJUqL z+=CmnV)JV3Gl}CU^j3pWeN`8MGX%2lP#ixlc+03bPow*aeMe4-4fT|S;DQJm*1?2t z9EDkHB*wiGJ`Lfo5S}9~#4(ri5`^rlBWv9lvDYDEWjaTdn=9%PofDApfca)kwgnxK zp4aQ1cR)zb@ojaQu{{t9*Y5x@!nf-ZouiQPTJE<}X0~EklZy?9&->Apg<4gmiT$ZO zMKaMc^rRASU{(ONB;M68I!uUdA$m-vk<`SE?}+3izLCdvbnn`M-FeP@rPu-$jdOSI zi1afLyQxn{!V}pNC+hMOQ#JbsZ$I#AvxKVPdH zc(;8D%=yCuGwsvRpZUY{HSG#90q~cS(|$EX`~_m>X;I|PU%MXg!Cz|Ic27f%zqFmF z%|-_NwI2_c`~^a0yHqq7f9WOd_{KZ_0zbF=EP|qbhF|^0?f5Ph{u0k?cP=KQbKR6@ zB8`H3+FgoV`3pQzbH+1~gBfEm0b)cB;A$>@e&eJ$U@g(-GJ&gOwFyKA5hERpEOVb#X&r;Qtyd61cnT>0#gOQs}tXI4j`6^^4yYs(@l$hBy_kR(2 zEnrWaGHb@D3nz`aXlBi(tSM)mbD^9#!L3ZlEeo+S(7l98*P#HX$=+n~Ww#pqO?94%7$0G66s8 zaPUkbh7PvG0tYzNVX487^02~z`IO>jKVAW+@iCBR@uL!ERDlDS9k{%NALTKH1LFX& ze1sq6MGAYFeWm2ZSQGPpcP=(dkG$CYJr!QU$?IN4*v=0U!)ZATh`mVJL1|2#txBf? zI>cU}+?>(2739QTpqwQsuY#P|3-lw(MIY)zbb_4N%ZwX5 z%DX~N>}8e$8_K&wo>Fs3%iOm@m8YX~ncRQE(o@6dYIux>C%aQS=Qa;Lpo#Xl8$0LT zf9}$RI#0J~c!P!?(=bo5csU=@@V6TNE5Y4xX6}H&gD|sux??mvOT&Ckp{KJ#!|OD> zS;ITrzFl&&Q@+(iza_e}y5zQxpN{V3x$3Rq5gMML;VU$}M8nI7Q5-I-fW6!6*J?U^ ze}LIp>WC-ky73YfmM58jAD5@G_HMi1OL;dbf0I}lAJpVWh_S8X@;R_~JO1~Y&TquZ zmUEV;pPr2Ty$o`hz@d-D0nSjklyVhBD`MrSy(aHOj4dsfuD}@z_tkWU5-VH2FhKZZ z`6rTaKEW~>*t^S}m-IY?rJezFcooxB)6T8bS9qPKvyoV3wndXarOBTGj(a70jS0%p z5e;Uw%}nH@!(c%3S+sujL1*i_R?4zPFEbCIUgj93NKvQ9s4bkUT05cBu~OK)I4 z@44uy?!eGEL`p;?A=F8EZ9z2Q;O}h$GTb4RD6S zdo-PW#44aSH2n`Wox{YO(Xo66?A=d$g7^A+CHq6eVf1Lvpsj{`YIwAUFDF*bv4A*V zX0{mEyRG$RP3HlnBg+4@X7IYE^d50cI{FYeL*ZkZ&JV<@^gnBIKXzbErQeWP1y@d7 zV2Gt6fbpN9h!I ztOELjxJX9LIU+;hAh4&CO{{`0*5oZUd6gy~KpgiVUJ=((!HOv>-dh$`ksshIo7t7M{MhWk}*;$&-LJi-f>90`wX)OO* zCaBV{*OWFWCC-tXDOVY9*K}Uj@Ru6?UDL;FKn?E^GaERgOa|QmxOVfv*J64>6cMY; z_>N0Y-cplyB<2nsmR_1pe`1xvNa9kdGg;H0Qzv(fMI}+oc zJ*84r+3K&`v=JF&_IFZr#-e2=9kuhMXwADHn%!~CX;7esU7mQueZ zaE8LCYdSrMRiHyPJW|t{$WOC*N>j81z6#NkU#ZEj(eMgQ=WY$(uj%j&gu}uoqmCHa8FfKaYPg$*#dFyRj>}9eMHRRS@w%H6hgtq9Br2l0 z#BCwOG7mUI;j1*A8;Pr=&T{G~yhf8(E4dG9n<-ZXdsNfe4jlI!J*OqSs^O1`Rd8Pt zx04xv1Dv7oDaw_Og@a5lvm|0A7f&^-AhIZzwsE7hju@wFc(7(Xnz+5pcpPws!c!?% z8C*`RGKg#P>oobzntZjuvi}+PXi6J2r9GPbMNR%LaeEoi*BVa1H7!qGpy4(e?y2EX z;sIghXo8k7Ps7VJe6NO|)bJh+zoX&rH0;AMycb+hVNw2$B&r&_6Q3qa)(bd8;qx?| z3y4)!&(QFtn$99kevKwyp~>AS=YN&)y_(V%P3Z|u{+xynYC0bht3bckZ~`ubdGZ_$ zH?74ef9G0)`-L=oqlPzYc(;asCRPRT;jD#sf+>?&O-j7q&eJK>a4B)JGH&L^hvc3X z>aC^scV8TmTNodwi6&@xvWCSoyvoyDO+HVBu^b?4w1j&!e7}Yt z((t1iep16vYxp@0@73_@8h%SW@vKVrzLxNjhCkErml{5y;U6{pn}+|=aH3P!P_~EN zXPe-a(DqD!xaRg@x!cfg3#^Fe0+%Vg1h`V+n}FLYycxKo!cPG6 zC0De42ADTn67L4?tMKcK0PLVUma7x) zV^~?qH@p4^bNiSvci@ANR=M|ZHOoE8)eUZ!jaaRBS8{d0{S+(9zszm52^Qnrt2RNp z%6*Hg{choABpS=zS(}kqGib;^B(t4(h16IjLEOP)Zj+~9sncHC{b6|1H0Ra+q(?fyo# z-tAcfR_s1o1NNMou`RdE!WH!$*MtjD#If6Q`HgR6f z>X7>>SDoCzc4U3^NZdi@w%wjvXeCV+4;j{PhYLmcU%Q++Sv+s(-o8CI&Ai;*2s101 z;vU$JdkfETe*+B-!q-l^Vsg3$MvL8N&P>ityy*&zaPhEV=)@viDo&P1L*v}kF3GtT zK6klhN3Qk-Nj&zKUGwRV-1pklJ@)s>_6FgaLnm|3Ep!XoSYfM0J9pi?^|O7g0N$7t zAgB@&KS0Zs>z;ja<;BnC*DMG}Keo=Qs={-IXASPtWl)d4eekRyj9UH=33b%7h)8eu z&-AL6HTUL5KW$hS(z1@xu)j^)R;}F8TZ4@=s&7W4po!2@Sc>sV|4Hs=9ix?rygM+> zT$x_c7=5$s^k`w@5vuui2vzx~!#`y6Xi*TSG3T9qD)|uBoIeZ>@<{RdJ$L~2@ zcUf&iKVaDSL<%g?ocn45XGF`)VartKr9<9$KN{!Ldf_aQ=d=~NbPT6E{5WH90>6Xk z&wFt|xCI-z>M(9q!jApC2<&okUkmoDI$(FF99zsZ$9;XF*>h#AqMN&ALt0|}}qC#VHQ_aTC(VNZYGp9{7y2XkcjVp;Y zn%O=!uwRcx<6>hb%@{vs+-0$`lg3P(Jbqm4g3FND423n^c3q+k^T$mdGivOFF;hBr ztc=Z@7xQSWW5-wv=nUx+ZSOwXCpo9);V#i`jZDY=*Mw-Z_!y(N_1oc~RnW)S6*Ig? zOBWi(b&Kb{T)iP}!Gg^FOVb~%{>un=GVWM6@3&>!D}vS!)h790>tM5@)L3>$+Ojue z%U+M|4`%H7%6K=L^kKa%Ytr01j~U6Gb}d-Gpn6uYUa)?3$x3%c!XlB=rWqoyIG%b% zW(yWqw@cpAHC^UkiTm|hZWs&sC&@`4U_S;T{FRTFNt<{-Cn*Tx9=rU+YL>MM%~A!#u{iU zJtsxmx@miZO15@Vw9I{OXtJ(yd{VTFTRjaKo-sL!oz3a70(aHqXk&Nlu;hZoU|?y+ zt$W=glcQDU)9$)%zD();ySvOpx8sy(zWI#%$tBUoEXeJ5uBeyhu5N!;iqUp_8@FnB za?Evp%xmE8oe~}A244;q*7ThkEiuiL?(%8T?7Gzh)1oWQKirPfA*@|Zo*tdkVx6zH z(okjRReAOG@8vG+irtPgqJ3JdtM_k=|E=78dImF1t+ktuz1X(3nf_b3JAP(#wb{f? z|0FFNtD9y=3+k8>9-bX-;odO|HC8P3iltsH6MDt2&^vE7^h%^&iPWoQLa&5+{mfFS zQYuwynNTT}u3n!5S7q+P{=O`0U74GBX|zzIo_N@$(Y@&jTNb6Gr(bvNqU4OWs|%0& z-IjBs1@(fbZT6w|KS_26&yBWCX;H{Sk67V?&ghk`+|CCZWF-8rFuW^fboWuWYa0I+ z#ULp0<(+VUnj39y4wkVGma(5JS?y~1WznJL`88i(7On3~o;YRH?3v>+s~(<`A8~#2 zqdl>Qwf12%+st#PV&xvW*a^GMw%`rsx6Y4NxEFrYAnd*{KRVidGnO89Prov{CM&0_ zyhjdy%>slId=neFIqr!oqdD<&u_^LdN&9fzwG5fc2#*rNF&<|2HEyC8z=TB&WttFmSo`|#rKfqXwVK}m}!A$hu z4QbLX^iajD8i?y~{`Mwt`7nyFz-G?h6a_Z??bG2Q{3u|e|2_OoK8io}ZonV-vmU@k z*iKGd6ohSHD`bh+JxgcuFI z1lM^X-s_bga?m(V=sd_{p>I(?4MSH#USRkigHpZr*wIC`eK2)69NJ;glDMXt z%G>ws96`-gBeel(MA8%^ZT8F=hMg;E$VlytTCk&%28~p{(AUnBG+?B#+({Tnq;IFAU3-|(nKS*GwRhYlr+IeZARBclKRmnSl^8# zMJH&9^4pCiwTx801levPDf&PK8qh8Vjbo&ui8B0l79Wny=3V9D1DJLxm03s4^3f!+ zikb@txEPaKgvPQfq`wA6YARaFu9Ou0a{~sk-9pj~BefL0+-@mpeIpg$K{o7GlH%6+ z)N{};?ADT__J2W3+ie8(qe8#PbEjVw&5fUhZeX{QTBy4HtjYG0qUL&{|JkQWikkZc zA=@1!Ma`8l$BvSs=DuLvoGvKzSoo%G0kT;Gvhbal$ijEwgRLxl+_1X}3w99R6=Zi4 zG>EDn#u?%)LE(Y^&Rjx&bSnLI_x$zTL4Ulx!|qk#T6Ok@U=wxU&1c}s;oSsFM->Ua+HDT3l;dFpj}pi^aPu95l-=`=|Z4L_uAPnR^u zNc}iwTx8fYBuBNbr>~iUS{M-m6(gcEHZS&UNl}z-n278-l43+Wig@iyCB=w% zo}+WFq!qL)nNipwq zXO~(aDO#~Q2D(sEbU0qRw--r@!E-IU^Hooy$6<0nBlFFy_F|cg(Q_L|-qn(#&3Chg zmq?0v=Q23#GX2r1^mm8n?=F64BK0KOb*-?#7cx?xWldHKiU??b=Vsc|iL}4l zv%mKM?f0{f-S>C<`=xzr>0tdgbU-iC!2_Oy%@3kOq>f>)ct}{_gR-fYyRR)p*SUPqJ7ISu=E#$Tl*D3eHeQ;VtTXpNy<4g8(qhK zRd7EB%w}f%nxG~+*^@EQ*Cj=TCUPp+FDWYYGIqf?Bt?btRigHrlA>VfP*100;AgW^ zWqlrCBJ1a4@br^Ns&2UfoXp!DF#{%1OG}=>HV`NFvw;W4d%qhOfu}_Or`tp zcpGQxUJK-ew1E59IA4A*DcsM4o&AHPaKDqac2ZL5{@bhRo_WaN|HVXlKgD}EQ&-XZ zFTw!xzz8`J{Hit5} z01iLO@sK2yF#5x9a9}4Zo^OPC^MGAX@jN3ug~hTJj~d~tIMf4@0~)!0JHedKT$q*k zYP1~^$wtI)r3i8J|p~xd*a4uW^@3e z&1Pw2LGpwG3lhUMhuBTgqSL0b{DsmG52c2m=V&WZju6?6Om8GPwxFyZ$9$1)2e|Q@ z&`Rr_(E4ORsHfy|y>+pw}N*Q>RHI^i$c(I!Ml5hS1uXTj_+J zq?6NYoeVP5Fb{^8a1$_?QtTAsa5OAt$8)6@d~H3FNb_pu%6ky)QPRlEG;WWU0_HlK`#571_j0{Ja^}iA zXYH|)t6a}FtC=gambs1>$;@?v`4XhjnX?RgqO|d$D~s*w#gd~c`!n>5%%gNdPtwVx zS|?M@6hs~7orv}{X=P!6h;BDsax^2IOu+~F;N+-#cp17?7Z}KKc4?i}5DwicOmTGHJ2)R-t~fgHd=9HC6vwb?ibC7-6vz40Pz-#&;$b7qS9jZ2k{4sYFWU%D z;?^Lp6tax)A@T)^H$XEsaPM4>6JMXYJC;YCcpJ2xeYHwPd-O+z*h>^oMZ9dlYa~Zg zu++27ktk_4i!Q6~T9M59zrozgN{GWr*q1AgULf{RRwyo`xZdP<1G5>5jAE5YW)!Y@KKinZVzo446w{dNZOTc&2yX;W zv2T}xBoUVT#foTtnaKT4rRe2;m*O(_Tg|!1BKuRfVkKIhw}OWGItF{a(!vD$EL-kg z#l8M>pX93l+-<%}FLWi#ut6lV3>(c$v7Z!v8~xSZROhrYyU*r2r@V*Lp8Sv!pnvh2 zko~aY=wA=Tz_%!l{xy}`>qitv|KfvT_M?iUe~qTY#}r5Z8pBdOt~k2aLs7SKRWu{M z0(#kuUItzxG#L0(W(V{*8TfW(huRQ{k@`!rrI27xt@) zdttw(xEJ>8ihI?)UvV$$H^?~>ys+O?3SQW6Nv^`)Yes>x8N00fw?#55|DgFoZ7JSU zPP|gQueeu=4-{9Wh}(yhz$?awihITQNO7+iA1m$^;}gZbQXE#?E5#AXRVm&z`IePz z7DbdIZXXrtEXG|{0DC9l6z)B)wNN>RKZ^1B0|#)m3nsTUB(lJMnKF<<-%W}5`EY1%(G<4fex5%;&u<7H3|ksa76Uy8K1PknVg44 z^K4CK;0^4P*cbBzNH|cBWBUf4tB3}UH3VM8!`@h62Xe93@F1lq(2+y;9&R;@1Fvvr z>cIoR<$)T^SoTH+QIS4v;uOQ)!9&7U@xVFUgL<3CS5*OiFWWxKV}lL>KF?u)!@ccJ zfrZ3Bao4zOU^g@VgFCX_^PAAtZ*r%!SN{2oI>qG9X21NOIe_!UPT-*YD((ann|#^K zko?!VWvDQ@H#8#u{W$l{tHf^1==@RKYMmkWKE~zq9VvDv(Kr+GJJUmFK_=xt#v-06 z$h7=wrgRZxR{oPDT?Lt&Z^l5n2{JGLHrD%DCfjB~{#A5vwn&NZ%I7_#c6Y&^%jb=t zb`L@J=5J)3og>J;{B(NgDaii(&fMASCCGvNpSjQ0TabhKg`COy2y!TY0!d#%KFR0( zA$C7Oj^^`|6?T799Q_{4U(PxiAd-&f=ds`;#O~9H`~s2-#a_*i`M;baMzjK7r;lv`TZ{Y7O_$En@&6Ka<3B`r)1MvgdS!;U~=0LG@UhZ#=cF= z`e~-aQxEowVk*rv9X?fSzhjCS%5=V9OMNCrden5LatG;i5pm3Pu3%}t5Uj{_J|;UR zSh4AdHw1qvSh?wZ&LVszScU1l5_KcDMm!(RlOWICtFeidw*=`>-j|0dWh)9FU`yI^xo=Nqy= z1e<3%JvgKMDcAzjnJrEM{3YmOM1x7iHpG0g)O2{`x@`(}1IkNg3AW61t|Rjaw#syP ziw0g*$`QUA!LSY!1Y2V|e8rWWC|I>A-d|-W3AWyJhMCw1*vW!!Fr5l^hqnawwrp!-Z`6Z=Pf!S7R?2zdkC(9D-6VoYXYiA2~ z)O6aj2ZaSYW;#2`as)eWI^UDUBZ8hVoj*x)1^dx-9CrDrV5dyyL9#r-en&@UzsMKN zupB>of+LvUa$HWAF~O28=Lpjp3Kq1S0qh9{f~8pw9~rR=d&Q^AeBEiCz!>`!c zjRcEY4nH$zHx?{rIq#D-5v<5^_~kgeSg>Nt;R6nKiD2cHvze?^unNn0k*rLxR+jTA zS-B<7{Z?7dVs@IQBC&(zJVVw@uuhhgCli&!;;VtiW8<9BLa`;s&yRBg3EawigD#0dLPA5+7 z?F5@-IXgKSw-;=ha=yb*u}=q!W20a>29IgZ z5Q&Q|Cq&jsu%(vs4OwTwZm^tgoZ!wBY?*G#Y>nmM zf(m2i1G2Np;>LQ*DIo1G5;s`RyJS5C+hjRW&dcWrw#9NP$a)I)xaD*t>m}GW z%XyZpw_rOgCyV30k6^n{-DG_Qd(Lt?ll2oUzSna2K1I8~p!+O`pF^?-2(}-LX#)j2 zfYOr<66~Pm;G8B7@C7?$InBw=73>qsnO*>Po?u5Ur#sVz2zJbJekL0#*zvgK~k8h4krp$?sGPhT`X9I&)G(HiD0dKPW*XJkdp+h@;Q^)yC)0Q!RMUKDQSve zoqW!lOq(iLSD(WhKkR9Ob%!Rad%9q~e9kIvp=Suz&*!XU+DyR)`J7E;vjiLBbFPYW zAj}qYgwNSSHb=10KIe6^O9dO}bABhAE7$~|^SKFjnP8KAPMQUFxnR?LPIFF4R|q!C z=L}=oJi+Gr96laz&lhZ-&+++?zkQ{k3w#c4YsZW%*kYf9dzWw?L9nGh=W&*4p~~L%Hpw-9SaopY>b1Ut1u`7 zMTACxA2SU!>e(3WZwB~jia=u~Sb-4wb)X5cFEACG-9Rz1KhPB$lRyb^LZDF$xRf|C za0P~Fpo};v5JX!C%88Q$N6`#{ro{CE7bOBW8x3p+=3wI;Xij-3fX9sEMxcTuCE!Q- z1C_+7f#xW0papSS;3Rr_pe1p7AcG}nMO;6SghmLoCeBEoIAgjIXhWPCSV8@^#0>%^ zXyHKBc;ImQgiDP;yNdy%M$-MLf*Ajdjzb_S&N7nv0VnZ>nnXYA)88C>4}tcl0m{2= zf?aNhMrbsu&IqMqkeMNV@zgT>d>c#f>?@FJ$ASY=n!qlM`U(z&EpT-K@E~G;;Ds3Q zVB+M!Pa%{)crHmW&>m$A^2<>ua~o7ra0qc`fZw+diYxu$z-8EH2@az?YWOc>rlamf zrUi%Sq1=3nD{*5`$T=55gyx|UjLFdGR=-G5|`)jGuMPl45Qh<(5z-h_5%mPX3Ln;aSi^` zZ}a^PLC>I>wR}{Cc&~aVGIK!bI;^flzK3O;zM0`fqw+xrukC_LDBlCLN`{r-OGC*; z?7Wu^v0JmSZrU*cj?VF7LJK0MHnlOG!Kh#Z*>0-!Hk97JgwSYOfEqDJa)fcg2!`U@wTdID zXrmlP)2--Z=2$Pj;mqG$v$Pb|xt@{pD`_Y-UM4Ooa6A=ffQk;W8fvmB`Mj!V`EwxB zTi!~(@b3*To)Rc6g!+Rh(HKu19Q~&s{>0fZv!onP2$m0p>x)0;%}g2T^BUl0*28L2PNJr`J>^Nzma{N7nK!S8 zvUzT+6!ER*<*dw;NNklGgLnl;NR6LQreL}^S2C3^=4-VETUYZI(rXey-^L%)CH)sr zlTL{5DY%slEqd%TwY2pn%!AiK0~>zB%rt*0#{&X8AnU#%;lvr`cOqq17tt`{Qxug* z;p`y$=qmtcHx;R7CAv$3PfiY);T}iP%gm9GxD7W&bE@{SF)F8f)~f+%z52hiJ|wI^ z@T_^?A+5js@2tgRHkFNFBqHyntlKyHuOjCII!5J{o;6=4$-J-s@2vS~k5T!8XZ?+` zKJ?#N^PwQ4vJ8JkK|pul#?p=AFbM?+=yr>;IiKA7e5q zvwX_BBLE|hRs2_x^8qNM@;uLafwG?d|6;w?v)-$$_xyL(eDKPsEXFXC{TzUiXH@<- zk*A4Awn`_%=p7i9SGo%y!gZ=6z+Hud;T$L<@IIr`$D1-a{Vep0U@>xGO}eUb;X2UOGObw8F z`Vce%!sRo6M(I4If8yWkOLaaTXq0ZiUxx3)t^u18rP~D&OV_xSJN*%qjz#Gzlapr4 zUZ#rjqsnWRNUbZ1&-VRe&z8?28l^$}WzpCFM}0oCXp|OFKMsQf|IvUCIASvd1D56s z87@o1m%6evc56|*i(@MLlrWElX&>3`Jc)0jpnpI4#(ZU4J|TyCjF6XVfM7@UFuOZke7m!;&hw=CtiQj|2?_#dUr zg9=L-#MT}yoitmHW>w0rNM#TmM5h7a1j&9e&YZ8xA6aC`+v)J?EZj0FS$~BT6qyqo6Juik`l}6@X8e%!-16|Vu z2VGU-NT`v?9k8*eGO@4I771$a991QX+!Xtee~+q(Ug9{0mUue0w6`)i|Nl0CKA)g9 zN~bCP8~>v|pSCqhmn!|I|E3@3k>cMXLI!*^*C?%42H*V6;D6JX0e!FZ^Q!(?;$pqT z@XyD6jZ$7x7UQq?e>8|?(4d?K=tcAYqduP_HcGoH{muV}J`X(*5g$56uTuse{vQTX zUk0>U>4)0=v&1F;C@~*sHcI*abQYjvoj!K`FZqq*_u*>Zp_@)hbGV?x>qua=TS3=?|46b(cz|a+kZ@`8}WKysqul zy6?~Z{au`$$Mw2iuh;eGoO7M)T<5&c`JV=EfyyLhiAW?-Kn$<9tce8n^}O z5bU-ejy~CW#TQV#>pSnYKUnpFnL!0c5?IBF7tC4oPmq{SJN;GQ3>E+0ukEc!)s zg3T&JT#HP89+4JZ?FG+!V*~6roxT?zieu;6Zz_5qPj*AMTa1d}W06S7nSpT&Qh1@e z65Ve9{jCx2>tR~Z?V~c#S6S$ht8f9uk_J3j=wMt;|?|7!-K^zE#`vEPgo>coyHH5^!~ZgD=2w%6ugA41Pc*H{>hl z@%7N*&TXN%e>|yO)Z}0|>4#RAZK9v`f9vxk$hS3Enft`x|8_n$4QlTE$bc)*;-2x& zCOHJ5XT#$|%_bS|Y?5o( zhr-7nOWIWbM0==qsTTb{f6~9y@gE3=0z9D^_)ZF|%W5$w`7Z{I`t{tax@;ExJO8J? zQ=rWEpzj=hJSHR71)PgPcLIv-;_UOWRx>u`fK}XECp!&{i&`{rb}kw;9uwV=GIyD( z&WBhUlm{SpllBn(v3;&+(w?@8J{A`aX#TN%|qRfxhpK@4l~X3Inq6sbcXH> zPk_q5A(3w!w|>JiD6t)qXF6VbaomleB5$em<9nk#H#yc>D8n?Qcs9%*hJ4DfQzC_~ z#=>IY^l6Nybi$MuqJxVoXEDw#>zObJdEv{Yj`H7{TxO-@;SxMb+U=`?1&2dOG+&WkbYL#`NE59P!owpS(|U~XE30b{X`dY$kDl2DtP; z0LLW|Iy*^_)nf~;Up##;fyCVp{nWZaDRkuy)Nf&fLXV%gFXTLe{Kce4HpX3^{+wDA zAKad=8Xq33|4Kg;uJe4<;3V;RV1MWJ@hhFp?Hcy)!4uQ<&IT9BXO!IFX>{Jdh=OThq=OI*)kWiaOw_TjLj zXi_d=9}HW8F*uimw!=PbhmY4_iM}%LJox7lJ~$|EU@&%jEa4-9@+PNZC&Lmx(KGBM z&WBuLKhEQ;g}H=>dWP*pZd~GqZtwZBw=!sUivf`XBhQZyg1fA2D>%F{+ViFr9xK+< z6WRAtDKPFGY6UC1Y^0hfQv3K|6YGf!n;1DM)C23jp;pg$Zg{#&u}@YyM@ zHe+$WVMW^GCfIMh*E*?VEh0g9T^`p)ZTv>kRxJ1e7gu}iAKngbb;qw)MdHO4!}f)@ zi5-VM0f#CzrgF8;Znvkk-=6z7yw~NeSA!!XFeI{qtwo-VeeVj5^V;wK&70U9`zG?r z+L&km^Kahn_Pk@UVPWHVKxW&wf8l9m_xP$sq}_e5cTo6M5aQEgSJ{<&y+4LOgzbpf zL)**$?k(|n?za!_^Ip)r)bW=zNU&wI<875o37IlNg0`oth>g#GDX5^Xy-Epp5=^(%*X?mF8d z+Qy5HLhZn|)IoOb*%ssMjj?f~?)o~Vh27yD@5|9u)ia8#E9R6^LMuMH^})LgSHLA??8f@rw9c%Z)%`;kN5FM}fP3$RqE=?VLd550pu z4{eY9$h(3Y_tuZSYw+fl)K9$KnzeKa5Mhu0#G7WX`q0}a2qpM7H9FZ2TNBpOe&ZAG zlAw=*?26y9!%jWw^?HtPzxt^61y5L2#e&M|CHCOIruN@H=Tq;Lkj{92SE2KouClqa zoHw&skW8kUenQ!=Nba&cir<&2Wb!s6-k3oA>?w=^-6smC zRaBJQMX#nViK;BADydvpGNZ8f%pCiJS5rG|zv+8#A5Z5$_?TWXw`#$h66+7bs*?GI z)2pht?>gn3?};d>t}2{YiI3CG+}`a+@57$hvFD9De{4bF_=1LF9{tHX(TIngH(pA= zz3*vnY>@h_oqgs&>Q#TN1Ik~#sAR_Woj-eD3~r7`^9zeBD~lIzU;L~0Gf!w?;lko_ zJLgd98{2#R8$0%&Y)gu(O16*v-P=7V{tq=k(<~^fymP7VVDp*9P5F zS1xd4Ek90O6`SrJ$(CQ%A@)l_zE1YJ$dqvViy)sL?;UIw?CWa3d2?KpeM<^n)|h#H z+bH|qkfdaLc5L$~dth`*l`S*Ze{CIQFJ<(%zv5{0whM`}-wgH@*?~91 zqPis^mozLzScVHfh&4|27KdZ(fBjgfv&a6l1GfFDHE{{{mR=!Vo){a9dkL?_I>>JO zS!#Rx#SmYCJtou_72Q=5&%@edr-u3ldRpK4SnKvoT@=j&n|ZMx?PHI9DJ*IG*P*^M zo@m6KguBq~_S^n_GvD+eyZmhH@L2YZw_{qu}0IJ(-vg)W4toa;z`GzB|^p#XGI4s{5ah;O^*h zi@V$NTl?beE8={AyJOa#cJ`DLsd;=$tP^l%$961mF7YYgNh8SWKx_!X7>DA1q7%@{ z(7(*elQ;%Dh+k?K|1<95zyuL;0?T8KaZXJXal_%{ZdEaYz#YfqeEiXgI)8$#-d2r7 zd6M&3qZ<=J!B!vZE|Fl6f%H*L();B)dm^P?N8v*2IZ<)r7f8%q1zY_aPK_A4!r}S$ z5C4p77dR+tZZ0F67!9?Ki3Gzx7>#I>KFs<~B%HYPSlpc(Log1Yvl4Y%Wvs>bB{8`1 z@t9B$K?sBxNmv8_5Wm>@J}C{{^o#5tTKS&D9^|jJPkn$l(49*1`ECC%ak-Bi`_S*P zmwo8>+k;};#1&VFAKG$ads&nCtxe+hH;HeP_#W8CVW0SWlk_9D-99BX@GlW_yb))0 zwqkkgBCNv_hi6baNt`kkgO3R@kmIaw79Trh;9PwicD#8K=apBS)ziAEiT#E@#>ZJt zh#=cB=xy=E01OMU#9=o&CUHIz5{J>$**`kK&odl#=MM{&Y=8e{SZeHmCgSt$!tO~) z0p8e%!@k7XMTTN5an?ZVjwb4xB!0|EA8frK@k360sI_0>Sx$VI^{K>p!5+tc7n|E$ zI5W<7Mnr261yyiMTziwJ#;Ockll86|H@pQvcj}G`yd+ zZ!dH;x3~87EJNSZ_}W%>Nq>B8Yv0~Ib98!7zSdP<^4b@jnvOXyiET*h-&duvfAqES zeQNjK*f!q2Z)VGg#Q!`Lu`i}VORsOE3`aOLX>afH`dV-Q%IkZ`6N+Z>OtP1q4omWM zvt!mqCPiQFw3p>)%49qDxIZa+peu5YzbW?Eb&>5oQ|+RY{!6k_^36(Kr{r6de4CO# ztK>VBe5aDvD|uj#O4z3o_AB`TC4X1R4=ec*B|oO*pDXzZB|quP16a9lM>jP-?It+# zGh}Irvr3MR+w#nDRPbY6@LZR}m7LQVMjoT&2}+*qLH@>(S0(tBLAsJ>kSpBGc-zmz zZWDoBhmmKK=ehD6vg|g46z3YYhYn0`7BHp-6pPDIWXWnQSzJyqrpRHUV%{V)Srw7R zb_Q8|mXgI!d82;7n%5YysueFHi=(AvakPvqj#euD8pW#>uOW+{b!73go;ZLAH- zpjPo_#dYNQu0H>IrnrpWx1lfU?jCf33}3Q+Q3qdrKsG=%b%YlwUaEMR;+2YP6t7mi zM)5ku>lFt!s7S5i&5G+3I|sKEbeobtt9Xavor>!f?{T?3R_-X>)ZRI`C4&QwlAYDb zH?qSdN7Ehpu(c%or$)|f=-HaxG40*t%d??twr~zvw(uab>?yfq$u?gxx4)4C|KmpO z+PG2A7Z*;J!cLaLPL{&C%C(cFbJk%d$YzqgrZ6N4Z>Swx6q01$yCE_vM{4b5GH+=i z__28CA0Zu!`TS4@xi6)d8@7)QOiqf+1sXFaw;cNv;aIcE zlt*FRMK}iQZo&yz_jcG`)Wz3>AM9f5v0)-*Bd{r$<)v7&4d~7<94Y$=RjI=)ouZ5Y zAY6wf0nB2p6Q<5%O8%@cix_xbA}r%2WK2&MVSR=0`B={rUW_#t>TJgPUNSOcoyd_g za9|qc$yk#k<(#xrBpywqVcl1;OZ z7r7s6a%3s~AUG8p<#Hre31CyP03%dLmxP9rVxu;c6gsRWx3ejz<8(9xlwnB#8>eKZ zvw&p!>>x}(8N$#HSluN;10MJ^U`ALq7?&xz(~OC#a8P7x>B6Nk4juaIDYh&O*;HVF zBS-uD0gRZY=FUoEX3Bkr1!C)v%}!Jpn2g-^Nk3Fl&5+Fdf|@Og|5jq3|5mTNLjlOW{5e4zP5eNQ6yv zN|;X12-9g4MiQoQNn~VjG1h!W-V`oF*bn^y!t^stn0|PVpSFcqJ1-6}kup(&j>Sjk zjnn1A>5$(cOsD)^6?N$JNny6!3uI*QE7p97-uQV{n49b);Se7G$0b5Xr^#ZRh%0d# zGw^wO zdgJJM;VkI9E=)fMh3SXgD)kxoSiP}L5zdA@&{ZNd?j=m)k-|WWPt_aa%Y|uNE==2M zVcOORvjUuXUho3?T^S?k^r<03Fm^32(xg< zh3A3)A9TIusG!_2H2@_#G+;AXCz`cZs)k*Q6b@FFDeE%1~xgEq>bvoLGZ zL%0Y$UYM1+N*HJv|G8j3XlL?TB^+3agj*!S%G)8)G1w%$401k;XA1YY(&t0% zM*jujmC)a%^j}f>Z#TpCrvYnoND_*`zX`K8sW|MY!_Y}M7tE*sO=i7>Yas6<%*qTD zW@Y&By3xNtcs2Wf{?eWaG#IZ8`0%Ijr zJeo?eZb=Rx(hlGZwS?P>5=XpDqoei0W+?590U_T2xibbV2Otz-VFnLl%}mJKu)dNE z{aRt;C%~aH6Eh3SWJ`Z)l7a=B}3&!^UMIwCt zQ#ckXk)wsL$C`0wb_`C*CbNDb{~U6%$t<68__-MCi-hTiar!v{eR5LnmYjS5>$}NtbPD=pQ=r`3MGm8JMnD*57VaeZ0!cWF1hOeL9neuLj0YwPFTr{i z8ICOM(d5WEV1#Oshd@q_oa@S$QVu`-nc~f&6Am3PUYsGu>m`8~8f0T!OF4{pWBsJ) z#6X8^YhW6Kt!?VDI93;VJ53Fl*-M&|gRmraaB%8c&-CP1DEIoZtlj1YMi)M} zlOyN3&0a-03c+#Y3em}d4%u7<2W}Q64j%6jr9n_48>I(DX9w0#i%u?d$VTU|=&Z#^ z=Of|IvHnyz9P%&7s8~L1$*6#P{QWKo1xO&98b`p02BRP+n;NHzd@ST-Q{#S=qsAOl zju4#*&>@?GUL-mkM@|hx{>)$^l%^`BS)#-rN-iWrX9{%4#?c1R8GymcCebN^4%rm+ z1(DByoNOxgcafI{kidwk!BHll1{_F!CraheA)AbU5gq{!khir86!2v2A2V5XZi=ad{HJB#yrI3?N4Jt&w405umz>So{C&!L=iOx#skWI!L zMF-=>fc1nZ)j)}Cl=#klI^r)M_lnMH=#Y)hNzvh@*^i>L20CO@fe55=^R0uNY$}lC z$g%y`BY_c91AaG)8FRom#8E;TIi6CPNC@VM~!nuXESujM#nY- z#X2O|OyFb>!pk&3A>PFro7+mb$PrsDgwY4N^S+Qn#hELlP87Jk=)_>%Q8)qXOkudi zg9on901XC8#EbP1VH)HM(_o@7^`{E^u`U*-{w!hYvkx)_S}2^3wKIQ=f>IxikMTbu zG^i0JW^k)83v|0M4QyfRKP;Sq^%mhwtX~$!%6d(ht@VyDTk8YiC>G(UM6$3xF3ikM z2s5)Egju*>gtM{!Rhaq~Hle9Zf-v=43+I4+!qjh14oL0U*PG_*B|Hd9eUt$oy)hZE z3pM%|2(v(=mA*68CjR+*3+l7AN`={4fomiJwr&t+bKNG)=DJguwYgU~7tCjJ=#;hL zo^1-pA5@ycJtNG0={cpp)8&A(?GGpeeu0k01u*zP85|Yn<~X7BzY`t>`439}7p0G< z$QlY1Cd>jg=MN`M4O&V9GjN9C(p>2xXLI!z23mQ-Y^@80*;*G1v$ZZ09t-B9L?*8y z;bi1*l_`S?;R%peDuYGF0P@vJf35ID$oaMolfk`8f3wne<`Yq|DbVL|K41)@N6ghXUW5R5$e+mPw--X#)%{Xv{Em|w!j`I;=bHz(S5!jir zgq)dqMb6AR2vgsgyoAmSaCebYKU?Xauk@X30qB=PXPhJF_D5u*GALFCvxLi`Gh3MY z^OQcHwPI~pAZIu)1zMr>of%QcSpi$*Y_0o@K_((kO9IgHV@YV^_R~GcFlLuZHYbl9 z(ZT%*Ya|&u)xt*S64BX#^<-iCnN5a%V39wCy>v`pCO z9HAT)V9)st89FP4jm~Lqe=2bTAy|%AW=u9pv6MrHqZjAK1DL&KN6O)JHT20wzX#>e zVGlV(bk;zJY;;D7&Jm7}8`I%K1hAv*lUwlg09 zKYO6#%m-W!Ko}u9k77Man1}gfzBrT_?}O502#nJiqQqmniVU6o&>VIa_5FL zZXmM(3a})M#UF(8up~e}5o?M9CNho*kc41Oj;zKX1UjJ3Agsg57vm2?J{H4;isuW{ z&k|wUEfbEy`Uc?`9{)Ej#9X|A;X4w+U09cRp$B$NG6; z>c1pR{Wly&`=05H^mQQ_dX&Ar1?f+qjJ|w{bgRZh}t2Y{4$V+yrbH z+Hw-)Sw$pjzbAcXmd|xw)?qc>?S2 zG@}@-Rt9T@S)e-`4CJX7(RZ2@oPl&UF$XRs?y1@CF(&-PtrC@Fn%GpA_g$HAuCqA*`2b_p`^yU&#;zemd zl(Jz=j^qK1uu9}P!sgMNCq#}qSY+eVxwb?hSP|#i5(*QcLylZh4np`%jHd`2r%_T% z)`o1Hwih|g$wnVhD}J!MKXG3mCt%IRGuS@$d`ORIh%yo70#R*;){ZD2Q7#Z25fKZ+ z1){ONTR2+Ph;o4_rf(ZZv>H(^5UpI4)Z=`(-;5|1516423%{1bumuahoyG7J7Q;Kp z(BFwQ7v}KSmQD`uBFe=x_^y6#o+lCG0;Qe#DUMPIT96AwXCPuRyoho!#qg7TFhfWO z#|w8>oJEFhHr8C=?v!LY3Q;Z)6;1FtneqtX0#Rv>TePK!a-reQmOTRSwGL4(rX1_Z z>25hTfaAf;_W{M6k7GHuV9mwYZX=8Bv(y38_w$PD$*|pnb%1}2@jkK`@23)&8NIFe zFd4>2u;yZHkCDapbLxOYu;+cHn1f5tP`6@HvQxHdY=71t=fUGaLw&Ymp=eMZS&G|c+HY9d&F zsra;F3(aT>5v@2~F@FkYbhy75?yGo^Vs>)@qja%Kn5uZT;>C(<6tiPDe*U8PABrQf zFBqMSM#l4%jS(wb@c_lSibp6OrFfj;iHfHxo}qZQ!|wj){A|vYZlO|Is(6Ls8pXFN zUZ?mT#kGnbR=kDx*GHPtihonw0+$`8 zpgzT!iZ4(+NpY#-s}$eB`|HN(oho6o;%5}|mbKA;Tk$c)-z)xIagUHj+aV2%`j2ji z;B=<=O2xdZY%;z{F>eGL`6G&XW7o)eGuQBO#Xpb(`8dcKFy1suco9eg=PKqyd`4%g z;@cG8uXwBCPZWQvIB-@)I94_pv{u|%agO4ViZ4}MqWCVw4=H}uW%u}dMI{_m%tz5o zf%x>9;dY9%6c1I*k9iw?=j~n6(&b8ibu;8|l=#S*;ky;rDdtT-qw}8P&lNjw`;p9o z!W;Et75fdd{=A`Qobo1~VLtd}m^bna^Pw)oOBCOvc)j9B6gzKrm%@Dsc|-sIvr_7W zi)oWVU&ZGsUa0tb#m_0mJEt1_{H!=MqCt-9tHy}M?>Cu@dnq2Kc&y?=#d8&3qjsrYrp zA1eMzachjZOeH%DJN3^|2_qF>s<=dPwc_g(uT}hj;)9AmReXx~H%*Dosf4WP#*z+I zJVx;qif>hXpW-(af1)@Jx2fHHQUA1t2%a!koTqr4;u{s)iXTzDUGd))A5#1!+4TSX zWT0sYyr`yulN5JS%y;1${nd&$D1KYe3{}|iZ>|U zqIjpn?*3=(R|!WHpHzHSaa3YsLA{DI6&EX>uXwrQ+b5{V1B#zg{IcS=6@RMu2gM!j zbC*RW1x8?M(=_I#if1ZbsQ3oOcPV~Y@pFp5QT&_YLCH?OZp#+95sq-J35tspmn&YR zc%|YsiZ>{(Q~a#rdOo>eYJXTIe6IME;!VijnR~*^8vBvzQnyGyU#k~{{RXj@Zq(%-{ zGaDmTmEvWJZ&7@Y;yT68Dc+;_pyFeSzjIiQ?6WE%0+YX{X32^>D$Z7%r+BR5sfx=L zFHu|*P?5V7Z&v)Y;(EnzDn6q4YsF_2hj|+-mLTlZKTRcMDITJDl;X=3mnvSUc%|aC zifa`=;Z-BMohsoq#fKGtq4>1oAYWt6VidPkoT+#~1Ec;04G}y!p?HSkO2x|*->P_n z;>Q&4P`p?1yJR!6JFXH=DgIq?6mD*s9h0A5HJqWiui|{g;}jPu4$M`NrHWT6Ua$CJ z#m_356+P&Q&}{@f5|g6)#eJgW`3mfyRtCsf2Bc zUsSwb@rQ~}DE?V-h`-T)oMOM>0Q&syCITL$_yWZf70*;$t$2mvHHz<7yhZT~;D-Kx zpGtUN@#l(vRLtAtW(RDc*sHjU;vB^z8aZH1XpC6X6wgz9t>V>+?@?T*_&LRU6dzQ4 z%we`a!gng+tm25Y##$yT?x;9hah_tn7~ZtdRK?|rmjqO#M)6&WH!FTxalPU<6(3Rj zwc<01!`i!rbLyWU5w=8{;w;5O6pvDTx#CjA3l*Lvf|zWr}ZAyg~6}igzg9OE&%gyDH(h;!}!$ zR~*%$v6fvG=PMqoc#7gu#Q}a7)9j_o6t7miUh!td+Z69qyif7FijOHi>9TwLolyxP z9UBW2qc}rxw&MAUYZTwAc%9;V6+hv8ayg&-J)Ue+340YERQ!qJuND8SIH*%&1zIX@ zt+2QikE{M`u{a5VUyymieFWHfE>nl!)zZ64ao30jfKBg z#{W{r;awUXMU$mTlgPbYKVGu<=|+~#F{nWY^*>J~T&N7Dko&uirYZRX#VeG~{bVUb z9T`(r3|qkQ!rPV3%j7_=qhsw=2?xl%T={!sF+NU~8vLMiepT|suF#P}_{o^@VMqtZ z3-?euf&Pr-Iy%-6l~6$L>B>iw#ds=N3Nc6NEL8HPO8*um-=Op#a^>#v_qa0HNtR~c zt>o`1KCX0rCrgdPGr^dmVTc093nx)7I_=20j*8VW6ZxBjES1nl84OkOd?g>F)(t#ku3W`s^SdAJ;_ptJS8t6yZ!^##f=ebmQtFhc(LLYWN~_j zlHX01LT^&ML+QM%_%(;!{m*)b5pnvtQu>-KPJdF|ygTGl`#8mI6sMELXCEaWNEV;@ z{MwL-T&|R+D=t^OfGkdLQ1aDeaeAlX$Cb{rigyV+_20{gI6b74J|>IPFBG3uI-%H^ zOiQ#-oJ1C%8A{%rEI#}7VE-?X(Msu3#f6GX$>Maek_X7*r$+JpO6L*9+ZuQZ9(rR$ zoW9nOfHx$N#pwr%zgIeE6w`-ki3oC*U4Ig98x|K`C`z_JKN->^Ai0$*i%KWiJut6U ze7n-QNAZJ-w~({9Yq$ddhj#ew5W=^MqT75|%zg`ovb1g2^UWO3R}@p+1;Dqg7g zHkaLl?h%zxulTUy9~3voDbZx?RXkMjIK}f6FDJ|Kx~A6*M6lr)?p6sKmBBV8e~B#m z`;`1mrGHe(zjO5M+G~7Cd@&9~3*qV%s*@|%o4>wk|* zcuW~QqvX#U1L*Hp{JrAnzKs=VOO`@+CrhFGDfwVq)W-0j`vh1)+lzf%a zzeCCYMwU_40W$72FuV(ncR64kRZ3rza~&P)dnNxD8Rry+-^t>rWk0agGL}(RcShYobb+sthWWobT&38Pq8GtxA8Rl0T{RcPRObO8+g#snp=8GB}|O zzEcM0l)Pn5V}X*%;-@WHYTQG~hbsL7kvsJtqYMg_L4`6{q~zBs{o9m$qtdTa@+Xx3 zOG^G$4o~m0%?_)CPn5y;N`8(k`r)_)Fg0#LmKvujc@MJa=P3D*27T23B9&063`&)J zZi4|18703>>91Gv`<4EaO8%14-$&+)5E4%$;|4X>U@%#_(gHGW`!S3Hn;)25rgWx}a~&0HmXa?di|rC{fX3)ktQuu- zi&DBBOdYJOTBY-l(s_q0h5L|BEnp7yx&1&d&UNKCDY>oq0Wu~=occe^h~G8X zPL>+{U6hz|K*`@%`d=#fFG`<3bTxj$$bL9MNK*1nL)rhM6bxA^p|3I+spOZDMZZYN zXDa=xl>A1ezedULYS0hhO*)K7^X?<#E*QgpaJ=v#rSlKP-;*)B#&DV}`k}dCX~kA# z(P^vX>15vCW4Is}5h=vQ()p2$g~2ndkrT+~hg+#Cp@-sZ zvSe@`8KYf>3zdAT;wzO-C0QzPjnY{TWaq zdV(y4dx<|Yp=4>5II=Wvl9H#BaXrV-U&$vaE>k>5akay2e}qLUA)xp=#j6zG zs`yUDcPp+{yjk(%il5Y(J*N_0Q2esuzbW3Y_<-U=ia%2Pnc^>nr?U3ntAw8v|EBny z;xKF$vuPp}$0<&9*e>enZENS<;wxfB8}5jWRD7x8%M}+ZE>S#3@qEQsE9O=;ci(Ps z+1=2qRKf-_yE=qgEQTLZ{J7#>}?MTJW?=(fupQ9U{DT<5iUuLJY zPq|i!Rw!O&4^2)_3f!ec_b7gpoZ#lXRWW}~Y~(u>zeY}U_1{$dp5hM_A9vZ^u3xAG z{sP|2Qk+#B9MmZ1PyCHetm0ORy^8&cyD09?H>(*(eN+P9pl0O56^~RrMzQm=(`2{y zQ+P2| zv`GrQu0(Gs{y_1^ia%HE{IXQa_@k2ltoYxGJ;9CHN4o6p8ZA`td~8Anr9!ZgKYisvYHe%>mzzgo#xD8|oT8~m?VyumQ*|DcJ0 zA5r|g;$4dODBh>|pyKxxf2{aZ#Xo@?<`#cZ3Fj0ChcwoJZ+14V)k1MA#VLyYiqjQ$ zZRCLE{8(3-k)P@`84OT7O!0Y&M=2hw_%g+l6;D$<(_wf2v*xIT`HB}Q=BuMk;jUAB zqvBf?uT^}v;`mLV&_-L(xM+J`BBAR3On`xMkV~D_!q_J z6!Z1crX?a2w@{p@xV7STiaUhz+EPl|O(pbHoTGSuemX5a$16EsM{V>A z8yNMU*$~0I2o+Z<=0{SD@imH0Z0;>>Q3=l~=6kM9#`TK#DBiF5 zfMUJ}+t?ma{F&mwmn!m|;vW_Ns+jM@HcmtFWS8OQienYGQtVaiciBDuI;n)NihC*U ztC(MKF&Ph2T%edQ-Znbp6fT z;sV8^6i+9&K@AaRHFCh3+ZeGb6|W@wT!R|Lw<+cqVvG*I1Y`J7#ZM{zi{d>FyZfKD zPbIvi_#MS3$Zg#MomA|+1VH4!D7gm@;TZi;#Zii5_|k2ol%}|&;%PW@*oCFhL;qI3=Aez(TU71tX5AFGQ0!COPH~3f%!rANj)tg&JjLfL z9vxL%(>h3%t7RwAu&^>wMxEO_;oReg0>Z20G?&kkrAAXx&^W2U3}IY1Srx+QZmh+^tOG9@ zsGkJBg&+H4qzfYJB!QE>_Y02%KPt@0w{61MU9D$@uK@2Q(8&s(D-KXkHVY5{HhG)yTSb8Oq^^EzO0DMTE+|WjNXwfn<-NmE320<3o%%D z378}I01cKR!l65PEto@ezORF!SeTiW2xHS(i^%kdaIG+P_$3+2sdFb;_K8|y>O3Nh zO%t%TN~ARso)K;jeqOjc_$A>H;J*nMfL|9L3w}#@68Jb-cEE3inel01?h_nL$0eZs znK4JxH0TB9s5wsdSdNs*G;S|Utn-9fh=sx|#ByP7at?N>9|yiu*bC+tX((?8=2vLQmw-9eB?n3o z;ftXdxf1+>@O|KV;RnEbg&zj*7k&(UPdn1LD<7sAkHU73;z?$&*C^W1Gf|A9Abtr-_PD#I1fBncqEvg&!O$b;0s(1 zSl1(Ri6qT^h}e;Hrfsiq6!>jnANV6-Klr$C8kmD%`n&}Eo$y5PX<<%; z{VF_%^G+7}cpC7HcVWVmM+x5!=6QfRJTWB;KL~Cs{1<5<%XMih(d7|Oqn0fKjxYr5e z+!C;EkqD=DY~dR41H$~w?c>5ciTp+QVen32&d%%>=J(a!5aw6MIPhi0d>!A1!k>eW zIgIUp5|J+?fuAHhDa_B?{vzA~?7`TQjs}1ug*my=N_ZSNRhVBA>nzN!JWF^fxUcY9 z@SuQ1HX_2oE;FbD7YMTp9xwa`_zL0U;90`_FxY(IU%^)kN8xb3UYM`)<7?UIKOMYQ zIKWSpt(VA1@cqJL!JCCk!A}Y=06#Cxp6wN3e%$K~;Z5K}!u$a2r@}9QPYCY^e-|PB z|8Yc4OTzcyUxm+rIg((hV{phs3j4sVgnNNgh1tP$7G?+2TbO;yU}5$tBZaGZ{Ew9g zf2?z?x>opo@a<%oW!WH%F2;ITxIK6qnXfG2&H5K4 zVIX*q@M!Rx!V|%Vg{Oj#3(o_e6kZ7aS-1wwXH!^+TY=4lYrz~lQoaKm@Ji$;A{~W) z0A~sR0v;gD({a9V0(gutUuiy3I1@Zgm|v|b7tRMS6utm_jmrV&8+tX8P>qDO!u+b# z24UV4eOUMz@HSz7W90?m1K>Tv?}OhIJ^?-~{2lnXu!R%Y$td>!Xo@gIev$-!KjnAf zEO0o+SJdH$n>a!ymw~;){614hVSX}&Z_=aAYVZJI-Z{({-VEkj^{De0Uq(AoB0Is; zgm;6>gx>{M3!emED;$qKsz#WfLs=`_6}&;1ci$csJ|DbI_#*HN-~dZejL05Im<8rL z{3u@xJ}evn9~HhG{14$r!QTkigMScy75s}ZZ;1U{_#-f{AL;*dzKk}35xMAYEesvY zFO1&V>L|?aAX7LN%y$RUHXfWKOjkpMQ^EPdoxv9fcLk4i7~7wR-=&hkar+cuUI)$+ z9uA%_TmW7wJPv%LFb~mNg)axM6}|%e5Lqs2w+XY7F9amQTD~mI+WcL(75EL|4DdU` zEa(Tq!@!>lGvjZBr+|MJ=F=Y*F3VVm8-NkQf%S+aNaTKSTVampGlV&Y&lKJV9!mBD z5H1jAZ6*lg9Ar%u?gTCs=3`Hl!b8D}TeAQ6yPvgKDG4m~t-{m5>xHYqn}nBuw+OEW zKPS8vyi0g9_+{ap;CIPs0EDB$-2bevBodBUXiVb+qrtEQZ` zDZ=PFtW;rMj&%@D26q+4&TsW32Vl(oqMsy;1P>N21rHbIHalOKHM>ao3GgMtd%=^1 zKLHmD{|ufb9E2Wlj&LYAP$iLOh%6T7Lo@;5PT=c>Ip=koFhAaKxA0K#M&SbRL&E%W z#pA+!Smr6=GVpen1J*)Bc1glD;8%pN2fr$OBls=hHQ@Jz`CQ^h!h9q8r@{|{zZB-g z+qc4xgMSj{vo-&U!S?6&dj*kmlJE{V6uk@ON5GN7pMhhAd5xDO9D**{C(LJM+6%{l zI|;V~GkDH(*W6z`Bk%|LTgcb)aKj^TC-D?GX!*(KyPQG3z~wCRg)ZliN4cC!9_=z+ zc*eLqmVA-R6Uh`H6k!Q?E+)Dk=kTyQLzsufGu}bxQzxDYF7vOc0rzsJ23R|VmI|QJ z8YUz8?0*i!lLfU(tF{G{*Z3+*>`(?PFK8?qNT;Hl@Jc{+ut}zItlw zbRL`x8Q7v`zSDV!zQ}Wxe3WA6{rEBVygO0`CM3EpYMCsÿoPXX;wq63PLklD-# z`e`5M)$t;?&;=WvD8{Z;C z7qLbuTXC*pUeFqyi4NO`XU7zpvhPvJ`k?^*AixQw!zoJR&cd#0I7)G{;&jDXiUWgG zMBk5}pyWl0%N6Te>MNCejbhF$n!@pl)i5U$F|lv=UllcOFwb)c3C$dt!+yn?igOg_ zJ8bV;71bj}hK9>15?)PiYtP&1yUzS3z#9%xnv;Pu6=gVE$#WHtBB#6h6BW-;JWugb z#m;S4v2D9fCDbb3;;>yb-E-afqRaUflP9NG3_CXl}R zr2fB(N-ow6F)-)pj3ti7Vp@jZDAnfA+NrZq%U|n#F{ntxDsd=%g5!|yUNeE^V1_p~Dd6g^_O_d25@)Y~TvssvpYG_1 z73_e8X*`G@YGQw~E2b47H-UN#+^4j^n4c}H9`ZSsUArf}ZP2z%`&3axqW%7!^q4CS zAkp*?ouOnh`?^VH2QqO77wIOL%>L0Nvm@|V1SJ-}tKFu!U7Mg8-RxX%aH2h?xLr)d zAWV3<`Pp^lt=a}vceB?dA@P&)RxuF;jfrQF7`n0>+TU(7r&aqd6OeRR{IVl9<#Yx| zh@0N;ST}oYIrf?=Y+l_6nP=RueX?Bau#NqF(9=6@LU+ugA>9O1&-G3GErY)V7}6g* zdgHI&^*6bpKz!K^KT%?WaroCJ4%ht)Q(JMa!+y%)mrV*dqn}+{5|KEV_h9HNR~+w& z^jQ7~*Pasrra<8UUBOWUaph_sda6zPz~}hY#ssLc4v;pObZcU=4T;B)ZUS91WB|yy zj3DGBdYo_m(cfS!Oyjn89$CiPY@;>kcn`TB+JqFrIJ~fl!>nYF<;4z0heJir*?FL+ z>r^_}&I$=m^p!TTABCCIMX;m&FuQ9>yEb9#QLwH-_NbC}Xm3uy^K=;Vm z344ax2Nrn};~r}wKQh$zrvxX))i;r!8ftI568i5qk%#Bn^AF< zHuZTpW91`30t?Sj4L#cAGJ+7E=CL;57^FW=7#e@qH}UuJ4VYRBb{>kLncEs%uWzDw z$0`hPaBQ34vA@48A}O$WGD;v_#uZ32`8bygMi=XI=(u;NxGDF8P0GD_j>kHQM3%b{ zi}AO!NpZH{=?nnSu}Lrvw>NRProv+#6Nkn2lh3zl6DYh3bDbP8H8FjyiRrxg9xFfI zEz5N1nzDQ(Ws!lob@L;bdQ3Ck+$LmkzG$LX_?pwl*?&n5j*a^si5%LRaL;RY?oymI zJP?|?Fzq0WmKi0iP1@Neg?)CV$Ers<8?F?KDQt@-{>HtI%Iob2U54h+gH2+?9#oCl zIV#fOZ2P6W@HS!BzK0QBvpd(cNQ+*71pP5g<|1{H-Ew$%o6tp{V|-xuc+=M*JiB+V zzS+I9``Z3?!AYULd-lo6vBy4<(y2cmqQGI2%^a-^Ynro-ortryQ@#|-9xOPyS-jI! zj%9-fS16P1)SFu;rJp-@?%!B`!*UcV{&VMkKWDm0-q)erKKQ0DE5S|u41%-g+@929 z*%5E~yc}$YL;MSt?@{eLp6b@B1;=Cz^idOJALtO=_6~oRzXk8*9BW8JIeI1TMAs07 zYmBA5&JdF=&5_il1&>+YvSvsQg5$QmIDz9wrSq|zLW6Q%g{Sh(SoULK_zgu04)-r( zr<2gaUh|gk+B@pIMYW(E!&$8TA;_Vhec1tD8)y3!U~`pIHq_pJz}Max`WgLNq%rKr z`ZN|!d2klPdUlVSl6zb3o=`jCZQt6~>#-SiFb$CqWPiOarfrJ^R-T<9f>Wi$Lbge= zh};DC?=rTmgmqGMM$4hQqrrvIXk1T-!9DX~R&MVVS!oA-r|f?n^!c~XKjiz=W3N5v zD;-!`QB~b-Nan?8L(W#RNHO2%ANID9q>@P2yQ¥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

    ipY2`Du?(qcj-UF*hPp5pV|j=R@AxQ; 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 OySa!vg5s}V@&5thZ+^`H delta 541953 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

    AuMkf5LEvKatZe*e=sYWKlND&ko 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™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

    k+6>HYkl|W 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 delta 352416 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Ν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ÐSl+mSvts{75N_cdqvJd>=R}o-WFy{yerH? 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 F{|l+>?N$H) diff --git a/tools/sdk/lib/libesp_adc_cal.a b/tools/sdk/lib/libesp_adc_cal.a index 2166bd8aff0da7d5076fbfb7bbaf66027427a85b..7d777cb30ceecdd9bf26ba9fa818e7beab0f8dd3 100644 GIT binary patch delta 121 zcmeyco$14NrU_CUCdNi)CPpS^6P2F8*_-(o7dkPTP2S)v!end+rVJrG1Jli)oX>IU qnH!ig#K)(V<|W6+s~DRbnj!Oy4N-Vz43iH!NldJe+$`^R(H8*f3?;7s delta 136 zcmeyco$14NrU_CU#^xsGMn-0)6P2F8*_-(o7dkN-Oy1xu!enF$q9hCr81#zrQxZ!O z_2T2xO7oKA<5i5!EG;*Gaz4kY2V^iHgw279k$6U?$UI{MhRFw=Bqml!ZkG4E=nDW@ Cyeh^3 diff --git a/tools/sdk/lib/libesp_event.a b/tools/sdk/lib/libesp_event.a new file mode 100644 index 0000000000000000000000000000000000000000..62d4faa0ef819855fd2c8486c533f4925c976d2a GIT binary patch literal 88654 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%0A=L>X97H|x#Vt~FMpF&R)>=LDEVJfLSKNH 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 z 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%0D_g6u=$`TZ4Y%kPylvVmxhWlHPwQ{zOJ@o3-X*X0 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 xG@%#9w4m-xG{M^A-e-l_ukOITdNcs%UbYXj|^ zj@llm;Hrz~f}r4yii$U`7p^DDdM)ds>%AWD_uE~a6zo3l^F06m+fb=b{pweDb#--h zbZufsSH_j5$G5hL;q&c!dH&Na3U$QaeC1IImj|$^|U|i)w{Ey7@(K_LJ{=YZw z;Ty#N%B*q=w=$lbkT}Ym`?>HqChEZd3wuwF@ca*qH&h}lbIAq~_2Q3rYfhIrxJ`Kf zKbW{T7YQ0)>fZmEnY>>3Ca;h3&wp#;hqQ_Rt?>`oBmS>u`?tcsJ<30t`B(_QG64}1 zon~N(2#mP;|GkMK(%?DY{?E*tvqVstqkB>n#|Q9W?zv^Md7Gs)>eVVSo5 zBKbdP{EpKmG*3y1vOLL^Dy`||` z&(hwPaPK(Y z_j#Nd`puiYV_ay0OpL5(?O3>Uc}Jva?$Y*-*!F%|JIv$=EdENE-fB2-OtY*t3M z9T#SN=9=BqvMjQ)!}hc?=?FT@?Fi5Yr?;FHX<1^|&N1TVmM-zU_OseL7^}JX_vCD| zKAhq+hlW%7m{)*ek7r+Q^y?R!oO2wnRQ;<4*;lNBIsT&?y=-Z}*u^=IIF~nb`y^M! zjybuj-E!uR4-2DyqoOiac*%2S(j$qJ&3jhM(2jL|_ee;0jPJKU;pkvh!)}FtJ^c6Ih4}sVD0mHcxTq0FhR=er zRJA{YnnZh(ah?z#`NW;c@16E*+~2+LdtP=w=DJr&&-Gt)st|Q?b5{I0umXxAu6j+| z_7!epbhKWyEe}nL3-@?7v&VyZJuWKgG5WY3J&b4TL~!gS{eur(1L(DNd`y1stn_r+Dijto131jbYu&khqu=1cIU^A}VY7Yz|jLR9q^ zuIf2+wpWi1Aw+fc#<|hk)|^)3O+c3HP~L%hC~tqUVQsP=a6SXhsopq#?8rCVRmlro zA0b!Xi@ZXtpMn^kwIf<{!RC{%-BTd0_hr{)&u5;h3I`8*?{LuwA?|fU4>eVE-|&LF zLW`>UZ!S(Q=v@HqUT!Z6E5yGk9i_wA_-{a=EGm{C8N#Ze3~!tWW<2W=!NC`~Q7hBE zsHEx7O8mJ9Q3j{?jmtd}`)zJs-W^g1H(FdImWv>4Xyb6puOJW3G$&u=PK_GUI~iVv z^!0$$Fg)>e8F6#qa=AUNOFD%6YI3&*gf-l8Pg2e2dBUI-_cmPaRL0$REaM)GKb`}& zswan0x#J$Bsyl8XR6XwNq2NVopF$W{;fli5PsSjOJCQyEZGIWP-oZBCNFHMIEr`QA zT)xj#+@IjD?+5&$iC^aYL0OF1NZB9u&XMB~AaFmtyiIZoED>y3(k#4l<-K5cKp=hL zohKiHOu zu|84?7Q$$&|16>=0KYK9}FKSNs1wR9TDy6xOT=PMHF%hA+kji+3WKXMG6--E(a z5pge=03$i46{55jIKzk}y#nxeNHXNfMhE;Y@`BqN%j3u@L#6dQ`|8t&r1bIk}l;<;FVWP7u>*J8@34;=IO+ za~iE1U|1*9ZXs>9J!st_&B=3;!{!I?y1miqC5WRG#t<84(C!T*#dKO@piD7srcd

    4zv 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Ð&D44Lqqn7&3gbh73c^8fKwf*fhwkT5g2Q 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 z z5B5}3#s7fV@jZqj3j2nGGveb0;8EWV z_@C=*h-4c0ra*E-UmQy3`Q+AzzI-T@@7oSJi2@&YmXG`1Kyab&B6M%$8whblzU#qM z>?=hACBE?pE%m(s+}QUll4;_57AiLN^+nufz6OZZJXKQX(oV3X{tcSulg6UHk7P;h z0m1Iu$SUxyKnhM@4rYGwI^)Dr5X}CH{{Cnvu?hvCW@>EKF2R*ZKBqic<5TrYJQZYVZ@RE1@Pt{Z~SN zOo*O^>S+NfI5i;}*non$G$HC-z;tHov{%iR6QX|rr591lxl;Y~MO1R0Og~*_#hecf zTINI3A7{Sr))QP}r#W9{P8R7&NV3x$RZWQck+L}<>iiZ(q9#P0G=D9hc+50h$s z)439&FsDg`IFS8drIybl-t8L0ph%z z)4Z6H>+WS0tL8LKv1(4!6r1R6%GI1a?E;gU`zVT&n(a`2W-;`)ic)i$X6%77vO{ye zj{b!?O-?X+Ij31w7x_9BS=RgzRr9j0<(wwIm;2EvIjLC>IZOBFQqm2!Ht-mlvjN6F z_b^*`%H^Eqe#(`x)tsiEww`r!n$B~q%h9$+O#ZPp4p%0>n$tA(zESFJ)0`U&3}wuFH6$Kk`ACfjwooLZbCTWR|H)cy`xRq3*c z-zkO49ZE5$$yS!Wg!P(`EhGI3%9(F_k#e}7fO|ngR#o~V3|J_OH+?3B-YttReH6=c zkt~(;1oDhIP3Aa#3AMae=0QWe9LKXTWOP)zG@$4ft0-hP3Jvp|dhCZpW4Q zAHpO;4X!zfD-l7>BIMjo{EY0EIiDk*=UINf$;qil`g82bm_+D{{CJ+H4RHvQ2s}SG zM_|D5>|s1COkzB95+P?kR5l$jpj_#Gi zDHP9vT7+m}a}t4MN0f`lJO{fI>slIfL+m;VJ{Oh=!q2<3^4ne1<&X=M+!vv!UPgHh zH9RBg)f{~rc##RcjN_Unvn~Cc~(MV}$M(DJTG2nRj(yM82*KjUW&^r<0 z;ZkdGQalohMiWfdoO`&AyQ|aTxeamXYsmJgU&q4S4`SX#O&?0hpWzp;q7K)SO&^My zVx9_`A^ZB2RN^h9AetkaiBDnTVd&RD%AEqaqIFI*kl2p|^o1WFl&&*=dNqA!w1tdz zAEGs6ed!A~Bm6aZsm>y%^#wf8fTdW#<16$vDN#u&Dvm~KidsWaJe8#(2TgqqMGdxz zgE`Tx`rk7@dul^9THzg%YQe^mrB+^@0Yi zKsP54N`FIGJgk zkA#t4|f4_j~zv5NK#v3!ltw0*>?Kn@W@Avzw9%~@W$4=g;N5i9v; zEcD+^dR#`}qLq};05JmT>H}wcgs*qBVW17^N>B&MFFN+d6F4B=up^Pd^@Dt)4 zyB5+3VkL>IjZ!!RYNoKc+ zUKkebr_U0e;ke8fLx)FS&)C}%uY1T(bNtf9sSWjE3GxC?IPEMg2BdQqHmRlp{PBusdc^c%jK6vK$)1p~%mW1_GWxeB*kjE>9_Ot3m#nJxN{iMpMG zqWt<))n^-w(!hsZffkHG;;)wSOAHU<6SW{ae}g~AwA45|h97_WieJazi&M79AB*I2 zMK4^O|7oge>qXVgZQ`~SWn%4EFvP_EvC-1Md~p#OH)UR(95gQahv)y&#i%t=r#NBj zT#`IHC3@ula`aEaFz1*57rpB4|D`9NS{Ch-{?|l6>Yu!EP4wa=5$m0=NuC|Jn$)}s=?nomTeOc~_YwDP30+AfPBzKn+ z%>Mgx_w=d@s!C>rl3#t0yUT%~hfm~|GzEtV)>cI68aQEFI_V+PT-7zlL{O>|fYr6=MD|B z*?3Q@W6>n;$cwg|_Jb&<^-4 zTCSB^uC29dxms$m8ng{Hi~mpb4eLubZ&;v}Gs#V3%=8RLuQ3HFjW^gvmT#^x1E6Gq zeQo2y!3&+D`fy%udV#&FdY54<=u#!B8aK!;7}(vCbUq&a2Dm^lu6}d9DWJjmr1wbP zaJ#-QIq_KDTYdC>;_`yn-|NlNw97Z68$O7~;BkF1L&2jr#QO!Y%k`NeBOWWorL}n( z&C3k&_jqiu{!;R@czBywbNrmO7O)xiz^cjd$2FG-*6hq{%d2ybg}u@Ifi(v z6h^ez7dj_-{NY&pdi5Y)E5Pq1q=^SciT8=Dr(=cYqJ>V)8#H;3y1>Amh#@ zajuy2UF_y?4BizaD|M??aG|*PT`Ux)#v2(tAOGN}4<$7f&AyM7>E&Yh_u%4N(3|*q zxtt2_7=GkxBbG6^J-nadmkRz$1$V+3@Cfb-Z$oI93NBXK_7vYRn0ar(V3mI!_dwzO zMS~w=p$;s9YZ$DGVKjrG5UcJc#mb@~_HGA&o1y5##B_+zM~Njr#G)BVMI8r@Wb&mS zV*lQsz7Z`U0BO(Y!goWf&B*Sy{@D2xHcIBEIVOF5#J0p;%^;Mltm+*9NqgQ!7bIxnNdeqJVv ztoLx4Ek^UQLhQsv)E+||$NTxcou{KZk5PUD2^!aDVjAiFe5?W!>)!|Sd~t!7jiT~j zxO5U#ylfSxaB&`QpyU2L;4Q?<{oB2M^Az-9ALPTf93hLudWKA%*&ZQ0k$fvcpu>?5 z5cLBzlb)jTZ7{U?Fux7%*wa6R;QnGiE~55Bs22PvzeF5c+y`dXALaY?9b)uH`Ml}x z{3t&pYDki}j&$B6=^uluMwH?rY9D;vAqIVnWHm8|^wVNJFSErVUfPQbxY*vx7m?%n zMdI-ND;=Wi@%%#D@A+a9D7s%%9S5IZyuiyeaSE4=<8fUZg=X_OeuG4Z15Ki6EfpuE zyrI0z#`6;{OT|;>{Xy{%FEwI61AizI=NO1# z?o&`ViMG6aAV%{N6H9n8#7cBlMHFEET1^Ob`Qj*(>JYB1$Um%n`d!qPP}| zL!=)U7jSW&#`_0M%-_B{C=RX7%S7Upr$BCnQKhpOKx@+Zrx58`Q3W#cBv0Kw3{u8v zEXAFy3Sg#~zP~K$JnX|E=jLo->@&pbFDgERu-7uNxq>Nd8p*rG0+Mra$5?7|*Me+& ztED*lS$>g|JL)tv>Hg1=(7{${Br2ghMSl4l9F`51Q6|eMu%K$De-4QyLF_+cnkere z`9ZOtWCIWF??~>|r$NP>^J!3zgL;FQ{>p)%xb?k$ndlFrNp6EN^-WVojmf=}WbUJp zW~O+aWJBm*u+g*^jlV!8{VWF1d#r=F172q>ZXWwgA-liG_d5%()Nwra+h63z*^|JD zTEHbF%D;rH6{7M>R(PeD^ksgL?W=sT5?8&IcmZT=fOv|RY%D7SQ_V`z;tW!_u?BY; zacX_XpxCxKCsVH$3lQvFwVtz+oJtk7XHcf+-xEj4KKwC!DKU+*{a>L>7vq4JA$YE4 z>wQ@4{}(!7r?2wedYb6<6%y0MbX=V6zpQ%_-+@?oQ`rx)?WA3t`wBuAo#FF)<@d|8 zMafy@ayC{dwh|rABA2_x=(CVBL@eP2bIWJ*ORdk4q2$kJ^J@(}b-wUZe#SqnK{?4U zUMyJ0$KiYS6*Rc?IE=^GoaFxh6r5;mem$*8Er|X_)lV6m?Kh-mLJTreojegRmL0pUc zmZEBBPImIk#_?TleRJ}mmhqJ?YJM2Ggl!$n`GL*F2-e` zR&v_FHBT}%l}!8UnDP`;TAlg5a85jemN9xN%gxunP?tG0jX$btwdx;(xN4 z;+xN4z|XcXkysvJV|+mT#YRCb@N3R}+x1_?TchH|2^uwEwKRTu^_LJ-wi#Uo7Kl5M zz%)?HCyt|+b5m9Lm0pX73cXhP^+BaS1*DJX-0IhwslH-os=L6;R9}_qABL|99?dlz zjNA^3jBQl|D=55A`{az#@uzHwSyGD}imBdGp3-8L)Z$NQBDI($Q;mVOOlo2JE9sYd z%(7FDsqi!9+hocs;4}5QUF!8T{j_n@XWN<3hwwKkmdh9CNb$C+ki3_v3mOsn)W?PvKc>;uASEmYp7dj72Gwy$c zt(Z0;URdvt;`#g%PsK^`)P#6$kPC;4kbE{Cc$(?M_0C#FOneBz>4Oo%gsz+;(k909 zB31B1`W(r4y_1;_if!ZXRQcx=eDer=NB!`sFg*={75?wfJOGJbc+uWDiUF zrKo!$s`*_|723_f=b%c(I!x9p&G?$%4R(FFXnJ$JQ2$O0xH%r~`<)c~JVKis#y|as zx=PJqrT-|kpgD`F#ZQv`GPF!Kng2@BH^FC${#oq48AC&!=r|cmNb?+Q*smb8Om07w z=U}Ixd5W1-zVx&G+yELn>fa{EZ%%Y^oMxWjZp2ToUf(8FLS3Xhexxhs6tr$~?t;Jh zUS_PDjQL;sWr=l{{8!;-O}M4ybJ!%gpH{L`!7Xp3r; z^)gvX(Fc~wPB7WAg>C&BGleNKY^6$Js!V~C0nOh}1Jg9A&ujEArhe1KTerk>^}mU; zx5T$xQ!SH2D?@6XvC^niR$aA&Ri_UuyIKZF32s!s*`%r+a=04Q{3Q%h`lF87;N?fP z=GzM4UnkB?i8s<;5gAkC;r6dcO}S#Fxs>&ql=TAqU7w=eKa?K=GNLkUU>SIL;GGIxQ>W( z>AE(Mm(6tnkS|>V|4SspHM}&D3^V7?lQDT_ujQTj7<$UT@YA(xKg7ihy;ccouVIm$ z_5v!yrj@VbwE@dm8^jBTJi9h4v5w$slTOtrg6ykbYa9~2#*_p^|AfbpY=2k0rAyx| zrY%DLc)87E_ZXUPw|hL|w)^7`<#^!HJ$C$ec*6LqLTBTiPuAJsn;iIwqQ=(2}a#4ip=SyI?GJ|J85{*DOAgc(xDxYqk`Db|Vm#kTI;(?@bYc!-2d{0Om8VO^IN#fDxx`bkrWvDic!MB)r6!8=jj}tF7^@bAU()qd$ z$J;xmOQoAde7%Wh6Dyv%#ENG=vEo@oJRSew7UQR@FL`YaF_5XF^EAQgF{1=F~n^fnO0#{ly4R{yAl=P`vj z#4;=;hfOAhzg3uudK@>H0rZ5>9LUrOm~AN)f$OW77~9ThMJGS~DITFP$Z}vMy{kC& zYdjS03DOn#d3kSxyB$9U_r^+J1XIczBq0TM#{hl|?k_44j1Lw=e~ZWQ-f$Ou3AU~4 z!QfRDJeJIe$W4UqC9c%8QQ#r=s&@Ar>EL1iKCCeNv0GIJE77YkyUK8d*}wT?T=sA5 zI)r{(iO-}+03OXd6##CpVqyn>pBOw7KqvN2lPubC#ly;Vu>v5J{hlp>SoV8`IcRW+ z8tJSD-foDO*>NWsLJtyPYbW-mx{0DQy}6_hH4|Q>=FQ`fxy2q1QV+!}V z6Kt9X@jS?#LpjF0qcGe0F@+xl{z&1+fxl3gP4~RQ9EW~V_#eQWM5fH6z}z{XST<{g zIac}7(PSBL3Z9?}I0GC}_#!ZEj>*G*P^54+a8rfzfVuZRd5VEK8BN?2xTC@?fV(Qp zHBDRxL!Lf1G}->jGYSEN6`lY*OyS#s$0*DWH$maMfoWq!LF|CEu_ER>)Lex*qApaJ z{bsSk99=oh9Y`PoJ0>5Y8TnIS9s@wk^~^O2{|@|w!s%$DTNP#}<>NN_IXZL7o0uK< zfWig9v^^)i8}Lzu*{Ks;e8Yfi;Q2&hc3dtWCVe#UIfXgIpI4Zc0zWCt4*I*otARO3 z&bS=z-3r$Nb880D<3S0fozf zdDH>r;PqBpr*L;*zJ-uJ5O|BiW0AhLQ+YTVB^Bmfi02_N!d<}o73Pq0jF^vea33j5 zMY-0Sbi7JvUn-1|K;sr_q~`*kSD04Pb_^?G!i}^13C7NZF90$wT0MmsJE}0VoTqS8 zV6Gwvr~!&+%o0-$R}K(ktkHTaOl7$gob)&_E&Yi3j)N_tFbKd?3ePwd&=h!*!YtEU z6>bO2jgZLS0r*~pS-wjZ?hCw9;X%M_6dn$|LE(kK+Z4VJ>1)p_Pc;JeD7+r{Wrd#v zK0+J=fcuxi%rW0=Np}N(t}sSv?X1E%!2eO0<^GGp9F-kl3?yRarwVTNNI`875GBqB zfXi2yi4`l%#F{Cb4b1I;$j_qgqHqkjkHRe7YZPt@JXGN_;KWGfX#vlT3Ui9-W`(-~ zPgnRV;M*1Eo8Mguj|RS5VczAJD7*mpeua6@dr0Bcz#C1R(AL1SMFp${rj;dgQv>{* z!W)1O5*Gl#y`wOj`-cj%s6SVjMSV_T=8~sUGcMcEPYQPf{+(O9Fkk>YHZ*x+HWs(S zQ-FO6^ZNrg>LCxGK^hUWNy9Z!*a=*rFfP(^lRWG}9TYtV+*9F3NMGxxJbV-4X&sEv z3HSzu*}`vBxHs@Lh5G_?D-!Y#1-?t+QNRln9t->+aUlR4_vs+E1J?j2=wUHFp#nJ6 zZB-bxpzTt)2zal;6~I_xAO*2V-%^;}@~Fa{fIm>U3-BijGXtj;9)yH4-pGDD01t1-* zyTVz(y%lEH>aTDU;IYK&af-W-5L3=ng;}DvDr^AXsc-;zfx;!ge@iG&OL%yQ2?ccp z<{>7;eSjZQn05S!!jph^5K{`=^9nQJy$ZAXXhBOJR^LH|nSpl{PH>1lrabKTA1Taw zJ*n`Oz+Wm%<-S(97clpvWCDGGe^&S!U>=M@`Ve4;-^A=$=?ael_WL>hgXt!Ccw!3i zWMJ+VNzB_~fx@=|mneKEaC3#{1GiH69^iHg-v`XCswn4v;O+`@AnL8~LmdAHD$k<` z7^3iFz#|mi1UydRZNQTh-UU2O;Uw^F3hxD;tMGncZoNV!4gfD!_)XyD#0dl(hUY;Q z@E-75g+BtWQTS8fClo#nyj9_|z`GRw7I?S9-vjd~7$*EP@M{WR1b#zdn~wf>Sb1FV zysxkUd|cry;LjAU5B!zFn1I*5RX7IxgTjq~x#tTLZVb#1gTxiUX$oHsY?!#Ab_F~E z70?MdtZ+Br2FX>o7rvT>dF-J}3j1Lq@+n?w#4otmj=v+Wy05S=mI^#{AE+zDSza*r z{C5PN|EIX`?}d%=$xT|29{hWuAA53t`1itMG3_jNf_E$}EX2%T=~56*hWk3ikmcCD zI`;{i-}coJamUg^7^yBTbcmC`PYMeE*zJDX4@blsB*$Lf>kvOMdX5M$L-bBlRyjm@ z(>d69{lo&UKb%PF2ZONKx^~kFKfV*ZK*HRd>>Tm)GU%~Fc$R}Ot&wnuukJ^({!Q(( z#8A@8mm|$Z%L@x_9~>2%mltwo^#}qmJ^c&A4@aPC;r&Q_g6MTW=vYO<%SQ1KF5>W1 zsB(PJ;-L88e(aq8^>$m%>JXoHi{$g;ycVQyu2pzAH-#v=!J{(ceKQ(%p9y(w$g7q z{JB{BAmVHi`^i-+&XVgZG`Wo?SEnx5`SqY^y9%L8#b{n~#S&hyegPNT@h`*y()@ssIO~l2j<3;$^Ei!b`RIg_qMJ{~=s(%selr#B^Mo zKi@!eUcF%v%JCst=@11GUy%&e|Vj+wm@9%-X^t=Zm=A z6o{%p9kN9Y=oyagx;CLcz8au^Ps7r*`q|>}+CsPO#GT?J@aw&V{xHNXdIArp;(~2v zkQSEc&vkCE7yt(3Yz{Bu#Cl#Ph(o+U0bX{9a5XN|L}hj1|IEiPt}fhl`(I|(lS6`y zcKb1VozyXar~P57#!jZB$*5TxmKkzi3Fd?G7wYKJ)b4WV_3X zT8;lJ!_tR~wqzo1n=M8AGBKz6^PZx~`WML?Uo5(-jjhFHV!)Xe*^Y{GqWY~QYAI<> z&{~!!8~;!=-fL@FE>`|o)FHn`%huY+k>hWjGIr$1LPl!wS8wa&`9F)skF#o!le~3Y z@s*y8H(Yt2*)R~}=c-BWzomG8=fAKy+LX6yZ7y@2|3LDc9mNgp$@9+?XGbeCYcH+) ztiV%~eR08(Ifn7u&TYm?tnReu_BOmN9^2b)^8(!O-5M5S_Woz_TUla9kv&~(Ka}B1 zmY*sfXG_HK!0(Xt=g>3rFn)K861*AH!2+6>9 z5a4uxYd4;+k%Fnd15wYG$7Fl+6tHxdr#&7%QXP`4rVLi9o61O96nuK5#COf4#^xFf8hDi z_6Bj9ktrfy6h{p&ReP&9;<}@v@{8hji5(biY`5q>kTlmHOmK?y=&l__@J!XQ_DgfP zcEsSBCOvM~s~E>@)1}97-AB!4NRQuj(F4y+=?QA?YII85Ed2x|Wch7d^tm?NT)C5m zZL5wIfm&dF0OP7{o8%AZ!ue%!S>iE#Xt3>+yzXiEQegW->f`m>JH3hc8Mof5*(-_g zF7z4xeGKSd0g$QLyWn16@66LfJdPS9kmh$?;UqB|3ol&lon|g$1;}a#>Cs&;;_b}U z(Mfe|uIrKH1pgVPrR;9(&Kj3qBdQX(qm}uFYp-c>g@a)DFq$wk;{=py<6MB zN|Y(oyS3tSn21tjy<1zh(A;Avul~b@DD|;qt^W>$xyOABi1#^!acV;5!LB7jG*UI( z6B%msKpnUzNk(G_>dt*Lr8MuwIE__IYkGoMGd@L2aL?!i>@en{9NaUR2e%PN%XiP( z0&F0$KOw{8pxw3oPgI-xRzmMw_w6*5H^#+4n$38cF$yK+o+HcESc?|mzJn}oqX>23 zzLOa-jGZV{cVg}Z1o(|ov~u@d4Crn2q3n6IH0o<~CQiH#`edUcMJynmX0#*!LMAZF z_yFzBeK#?7a&%k+F5fz&PXV%&ZJLjQvr>MaW?zq<*29T!WM1;A@*=zl!znzG3d^4GgNXKHoQf8>66)| z?59yW={s0s-gNK1G)p$RppAI{&QQ&G4F9~#h;<_$1?F8&Y%>xi7!bVoGoHgZjw4RbE=RZWu5AZw%iwYp@583N zT4?F5COs`<`c%k!q%-QlZOoydM@f$*jO{3I?>a^(FgC`3YZy?NF@Ed}&AXl%DKd_d zzJc^|&>`qCYF}YYL+kTyB)x^fJu$tHbM$Lvw7?C=`vhfn)$D>fe6l+PMFJ?1D9Q4l z=Ehk92rJTUpnDt)O-uJ)sm}#)@enj`Cv~Ub3%IvZ-6`6k3cQ`=kZyB5jmq|RksgPu z9}@9)m7X+LOQ_=QCOvNK15g5A54{kgBQ#-;vL8p=CGa11-^_>8v5|qVGEnMha-_74 zZb8{;?*EY0aB%OC$mzebekmD7p-p&$j>QN|%k}0sxZR7(%Q6T{thri3q&MQ|ivUN$ zRm7}C9fRO=ySS&4H`gJXk83ZQowuQby3}_)&EA*iXb7=6C@W^c>JRnjT_03$d$u{G4(y9AD)lcTDVU!oBm_6 z>F1SzJ-ifM*AeE*DQB3|1!>_0s2x{$0kVbWndyYMJ7jt>$TVu0p4VYKW>Aq~5M*o| z5BZw0C?EeGpAKx(?5)t36UGz&hR>UCJjIDBlX}x(G-E4SFq)Dy z2vCl$4K@4i7$A&oAyB+-W5@hDIXg``OPTU6c{9-LLr{*!Gc?Wg294)mqphZyXwt&G zTQVDX(ASI?c=vG|oWeBrlmTNK<&h{M<3;Wy=*=}==FE*LW1mGvtwqLui;P#K3}Ye& zAmh~-cWVe5{O)ADMmelo0e$W7P|pMZWD~!vk66Z8Vz*I( z!OJ+uzG-A|!x`giwl-ACakL}jn=Huj`i)5}q{eRfq-kVJH9eBe z?~+NR>r5knM+=@}YIyZsOvG>abnX-5l8I!hM3%Do`lTp`OE$?YnFt286)eMmULSFw zVNmCO*Jk8;*2wi$NbhXryzhz*MTpsubSip+UmoVly;K(Y={WW5Ns>fMm9RC8nNuQx}Obc+P#h9scm+Kt;~?+Wm|6l1pREP+H0Ti+bn+yjSM3wOu{8|cRVfTMX3FL0jCaIUP}uWV;FsWshATn@peql~}0D8T|)HzgvzYnwuMi8H*D70TiP9 zX?p&q2a#x`6#t?p(GQ{$@os>d0*lx^f{EX!UjdGWq!0Rku(}7cn3hRdXo)NIN5SNp z$gEY#vesN4-Y`~5&;Li)d4Ok8bZ>t*Jt293BoGoxLVtn?0YVQDiV$k(5L)Pn^Z-&6 z77-A|LJ(O?5bUU6!GemS@QPwVu%IF+Sg@gj4G~5E_dRnqIq&;j-(J@yzd3Ve=FH5Q z+1c{!dJ(ZNQ~y@uKT)xntkOo4hNpKtXNlwQw<@q zV-x>`!AV7A9GlKz{gE`9*ADD*CDh~s^2^LZn>ZPnlN+MsjLZ!%Jt8CX`}!y^BXbax zqcSo-hwafBncb0FOhzW3eTdD-JcYw|Tt+6pUF^kYWb(tw2^pEY5v-Jv`3hVrF(b1X zE0U2}3H=a4-Z(+2oRK*e=2XeZtPhW>nvuz8^OG|&XQKuw8JYa;LTX0lhp0ofjLbjb zGSxFO_oJoLP&`_qMn>k-NS>aN`4iSu85uY}hX&O2P<9f(m=G%D6$B^o82*F?)`Xbt zABS2*E<-g#gIMEAb3;R~FHbSdruYu4pU`l-!dQaH&KLm@M=2r?10209;z7{O<$Uc(+pO2OjG0`%{=ZYaC#)hi<8dp5V`3SF-{|B`jj6K zm3Skqoyv*aN&E}PhtM?kSX5$9mUsDe$S*pPAM*%Jr+qkM^6MgS1+%q9c%hliV1If# zTF*&;6aDO_kA>k8>22Ybk?ET-2}GqgW=83J2nAV;MdHvxmQ$%lXz{&V`ThMLGS&*seCL*Rq^hn5G1&*?{yPdU5w8q@Q21+vP=Fpww zP@*y5E^_6>2T`3+*+i6&g5sl^Gf0y+A~(4-6uFiSu(>WIsS%<3_uzl^FuE!902QlG zW>cASJg3r%(AGhyopt1UtXuv@uf5m2*({M?U=H1PHF_~IYYR(AjKf)HXj{6A@{_HH zJWLNsP2`)eLXU8bTq|kP)M-xWQJ(H*CGx?O(00l%Ppn4|-odlPnYKY5W7jXXt@=27 z>}n_SDCWx06SNxE@45=+Rezu^M9&%P+oPpI&ztg{N{d5JMZo8*`A;kJpHb#NYt0{n zjKuui%qiJg{30z&wHCibi)&bm_fS6GTKqCCo@_0Cg%;11@wb;Im5AgYuVdV5=W>VqovJ2o}f51~V3 zFVWg_nD$gLi|f$4TuP*xb#drD*0F|d+4p^ziT9Olf++MsUt7>eRX9W zj4jl-^;zW?KO4VDME7;Pj>e7>?baNa@ad{v~jBQpE ziBnx(sYr6-eny{$s=23aRyEwIB+tT{T>G>LJJ@-Qu|<+jei{DWr5 zbU!Ljou%!lt6QO-2_)K9sIOb0fmtO>D>T%t&`4S#Zf9eZ*w`&WIWaXtOSv<=$KWL3rXXLHk^xaq-Xqe40Em&`Xe)XH6K^F_9~l5L2`%Qhw= z&YZD^+Pa*TnldNP3E}BDtCWv+zPu9)8-p9Uy|qdG3kwtUGCoJB!7< zVG!zK{2?*64ZSqqwoxqK_!jDF3Wde9;d-HN?nY)?#S2~L)`AyXALuFh7V~(~%Or?P z;W*SOk9$wZAQW{lT~sly=1ss7Y&%)nEf}xK&TymY^N#Hi!z%bQ`1NV|$?R&|Je#Y&#k>&va*v*v1T$ zxLl*wicMkS`EFYz$*Q-kE&>bOUI!tA+yU-nh(7=d#X8pCuorci*$oi&J7rTo* z1UE<4y9aCN&=U7LgkFrSmxP82U1iSW4@cJ9&up%Cc}wMk$a*#C@A!5OH1YF=5a&CV zZG1M`3Gqm1ieC?Bj(0+wduV`(uk3_43(~Zp36bKTX5SL*z!zk3Tiy{_g!pM*- zz=wh`t`q!9dzQP4(G2#EOK64rKH}4NzyK$GJ$ltmAA|uA;iO%KZffARnvS(k;u-jX zn>*bDJBi=m;NiBWJSy={D7kHT@Q6#AKG|{G^46<8kh$&bfs8Y{+uldY8fMyeJNyW) zm3TG!-|a}QV-|#N-WTAk2Ct#J-A)U@QEpmRgA?dzx3dj;)w3`+)8Mr0(dvnAx5sJS zPBgaLo#-S+V!m~I7~>jrNAtRuF;~}(jk5*zWPu6DWe(IErqshyWCBHzhY)VGSVB(2 zw=pF|PBS->zmu40k>>h);{)jah)*LTt7YMy%>*Kk(&33D%Ce_B5ho%hB2yGo6M_VG zTf-|*k;u8GtPT*eEE94XPG-y+Q`S(4F(Ic(HiGVy$d&kaN#9EFe|O494!DF}Fooi# zd=;)c?Is{fTZ?}Qtgx9LHzQ;`!E-Jh2DON@#;VAJkkjz9##|b1iH84T4R4mlw!1%q z>lJQovAboNjqBo~7gF9Zd zF2~I1J`=-1yAV6um&=d%C@vM+OypRZ7Ee#(1`!I+t%skfwc|jT7SH~C0(*P3)^wwX zUlF!E0OxhLnCyC(Bu^trTb{{5y3Nmw30L>%aP<+1f#bN_+`FNX=VUp~zetvM4w1Zk z*P5}N5+ELh5PnsGY2GNtZ>YWAl`(K^$(D@4y zQ~oz%E+S$EJI?a|jkpOBRT1I;PekWO5K#*e+BheHYps?8(7>L1!qhkoYHryNNNsC; zLTcO@6?WM0NRRgubir#C+92sYI2gGHRmw&f={DuT|9?shjjpfL8FnI5^W3`Ym0f|9 z-4!1y=uuk8-@la2WX zNjvcT0b%Cs4xxVyvHmr>kOX*bd=bUU_vdi{w3t$q4sqkBBqKy#rDgEMe+?k-QWeS-N|9 zZ#rCUMC2y2gn^NKFycw1YCm@hS|E~75#Swm%iFUKLu^$`?_b_$XcnAcG}7XD2M>>| z+z4(x1H!M7Hg7y278&IP8hx*XB(n7Q^3KztKge{-XoeB$!yaJ&@HeF>;|{cH-Z98B znL`lK_Y@@deZr>jh5W4uy5DiLB1?n9CnAL@d$+s_shz{&nO^8LppAg$h;hcZ%5AkpTQInL`2Td+m9gS*n0hr zKOAlynSYfaCmxTwqIz`^^$A0;gIV#Y7{o+gpLYU5%CU7`fCN|gNtMF2qg$cH zuJW4$@iXrJmBQ&BJ76^w;3AGYH1aeXjqQIBiA@vy4af;JDw=?A|Fi9n7oKcej*%Hz z@;AF7{{_UXMmby!8u6>kozCwWIq|EIe z>~7hnY>e-<318Ok=YN=-3rHR=ss`q;#K~FEma`@$PB88(w_M|T>J*}{tWw%Cx&ZAUj(Q7 zhlue*&^`W{#BlBOYQRF2#%T(kmcI(AvLIXNH%toG#p9{HlERmGr&EyiH>PC7J43O% zWh((^10&@MfnP^yi?*N^!;28kHOH}TQ617exHzpgFC6M_?mtA9KIe7h zp>#YFu{^ghDiN8QLn$8sGKbRsfYyvPhtkyu!T9m`vl`ZALERoAocxuLl|q(VAshH4 zWDyIU{+D2720b^Qj)`KO{G*8B(PM_yPMq(QIQ3dJSm4yF-`E-S8)C1qF>co&O(CD( z=do%~ZNOHE?ol4y6w;lD9yk+#Qum3*Wz-nOQVUli#yb7mDX8zi=4t}Ua^@n!EsMSs zP54Yb6T?*vAMtFADd-v#1}3hI_{Us&crAS3e8ls0d~;0jj;& z95`k=&o@OH{vg+_WtPFuBhs{b86wAHck4vl4;|C$A0g7TI)7{2nz5$UFGUCw%0~QQ ztD_}jN}Pm$|AniWtm^a1+hWAJEh6|rUXxc}BrVO1i}1R z9>aZvxpK52{$ext2ClVixJ4pj=OcPSEL++~u%I*kxC>)>M=GLp#Nce^b)|`pb|Rfz zUWalQ8M8iyX8s$n?O{~mTQqqWe_hpZGw*2x^T#8l;%$gC|69Bm z;*TM2BVv5OHWHa|jC}=hA1j7EPUo$VorMgUGVHW@8^h797jI6iV9Y{0v+zrUZOzGB zz4#v??wEuyUwQ%6tq8w@a0{$S8kmF^5Ngk-v)qR9qtN}CpB>WXAy#u|t?8x1oe zv~ZTw`DVz1hAjaPN#p%ocR78VTU+dIS(#su8m{YgMn&9`@}=no6SufU;0Ptg5vEo~ z*qptW7)SVn;nfXI%9UA|PSD_R1&j$}tUH|bSZFf698m>keSBs77swp%w#tX&n0jQl zaI#GI+l6`yrx1TmxS*S5l#ey18Yu zTLpF>iKoM?LE+YAj+iC&Lkxe3Y>Dg z+>hd|S8enP5?I#961HCE9yJxe1^TS|C#LE<5Xvp%q-(=b@bBDXEd5wKo$gYGOE^g% zH?6vqVRL%>X*`|q0K(>kZFCg8aDm^VdN{QmeeUL#wh^wR7ntQkPpC8IAss_E^Wf#JcFJ)W!-&YUU^afgS`2moJ z`T4Mmi!LUcT#>AB3}ogYHKZD6y#1VQxqX5ip9g_vw<*N^Z0l+%Xx|4g7~K8m>*DW_ z?q-gDor!o+p}UziBM%%+_peI}*YmofdhXA`)ZWfy$=CeaEPrN}$I6raO1)H$mo_`o zknS1#mW6EDGbf!)M(XFy zRrXp~Mdk9DED3i+xX)dxj(?r_>1X47PpHx1_px2!LY{cSx{_Y8B{|5N1K*4UF_?3svE zwykQJq-6|0UKeR=o9A-gLwI;TJGPE#D5uwCn1ZR#i9*)7e0<9tU}Cax5H6gHh|HmY zWq>9CC+8Z+e?L8(;jw%3gHhieiRqsuiB4zEQo&4sFnamT80307dLoz`|GQ-^+ro0= zai`5M9Tua!RudOarKUZ@ZpBC95Tf_ELp$(#zvSW$>tP$=$7p(FfoXuBqUl$d-b$um zl%FxhT|}n&l~EqM=W}ahu*fNF1UVOe=BU^jmHWpim_b|E0gD|_|1krnT){Y^o?Eu8yjJ#!zc5U)z8YuxYdFIJvbjTOn=Dg`k&UsMa2$Q>=vTxW{F)`hDbI{;ZA^=P+Au9 z&>1r3ABWH_+uS}dKV-~bP;P$6n7_N+{3^!!weMY30Jd;uRtbW>t@ z%{#Jmr&qxH8*Zw}F0%9q&(7V|Vt70A46-vT*uJo4JuPYwlLnK_0yY9|Z5FT{0j(Kp z7O?XXLPyuaA2!h?P)BprGt+4!2-!wmtkB5vAmd7Rf?ut6I4fhRjp7wR+fD;tg#s>e z-Rc+C4p);k#yrT}0{C&z&)0Pb8mhpoNH@R=+s_5D?B}NtwhhzAtWe#dw%7Zb#qtM? zH4W7-Ht1w~j2af}ql|A5Z#w;W7}hsLS<=J#O%Tg!wy%&48VK1izfzrW9sG2&NgW(s z{->L_bJ~bC*8c`wx2yvi!Fp+|vHn82^|8i!-ZZn;$6M=%6_}|j!B`(G2`iP`Zu>Yf zHt1vN11;NPBoS5jm&e8!V%r{Sk5S85bo8Tb-?~aM?~`Rcejoy`Bp?4k0?as zHtcTg*sGyqJmN`28jtuM(3-KvBkEP=wCLn7#Ggty%xv-pXNFrPea)b?Gl`-B4bIEFUuZOHR4Wc*;(X7f#^6PT?=qz+vARk;qwiW%<;SHGkUmUI!5QUyuK!~I~E18d1sqj z_FE_9Y)<))nN$3Y$jF}Z+we0i$#mSOIOWHW;1RZN_nA54_c$@wCOHwswbM#WG}aGK zn&;GSL)f(b6)5u+?CuXy-BGA%{cVUetQtr=@tzY><*XndyN$>|8Fvw2G(;}V*e z1ZIdV5yF8lL5StiDnGw2h8sO|po;+n(RQm=e#Xy55>ga$e3|q9hJd$3DL6B53UeXl z02sszZr@9^Iq5g&{5L>qd+Q&b9CSBl?y$jJ?vHfKp71}a8xDID&;?yP8{6IXPCm?X zC>koF%bfgvBAO9x~vOBoITo_&x!3)D!xewy%=%Qqq!vkJvu|1FPjH9Eucm|=1 zm@#e-p4;<=c+rgwkkuwrPBgUKvQD-f&xmb7PSLSC2p%$8&l;`Y%dI&i*0eV_r`|O; zr*Orp7gCt@!n@GSHP_LOMDV$UD>5;8@&2&;VFZ^(5v61EbD=vEjr$aI(E`!)ow#^h z%qT?AS?uqqAFk~k%tFU+M0geSMm`N-Q?)hK9EW=BL%bUm3AuS)hg;S;A7jC^S5zdc zu?*$5Fy+SJT04FviEts>!C8+C3)z=V>*7z*9E=lpmdWUAgx#`p`Dl30}?lhxH`vib%V z+6pX-;)CFkrB~eO*(xkIvt48s6wEoW7e!BsEM4cd=R<|=iYQ*0i!8kzVVpi+6UCBn z$Fvk4@2)h;1xTFBCk@?eqp}cNf^a_0EX_Ds(9Ith4rjDy2i?}qv7K$ry z3THu?C)I^FF%_nn{O15W(PwA6`42V`2@)z}|J%{Lf(j0s;eQ#P(kn`0}!twG_?!c_d@ zEINQo1*~}Jl>RM^!&N;#d{VR=mpt4W9P7>i(+i201-(!s+WL^~g^Xw(GQQ6W8o8$V zjWZkBc0w()ysuRk!`U=??dYJDE zS*O#~K88cT<4%m`VKfc-+r#K2e_nRDdX>rMoTd}Rh0u38_bZl>vF9b!z51pm;X32^xKR<`a^)T{S#B~}y1jxd z5Byh_Z$|T{PRx>3cq^KExJEW>K1R;l(Y)q24Tk2!O`QWMVvB!ulW;9_jbl$w|L!K? z^bB^%doYA^#{6nd{`FA(0IEOq^xtiQ`$&A2v*;hVygNMxQO>Z6Op+w z?Rg#*QQE_dnt3rScR!=eY*-S*AAMjTJnYp*}$=Uei|eA5hEMr_BU1xb@Jyynclv~MxZI2!mA+|280nT(?;AM6i?MWs3+0Zm z$DA;fJHpFe`PF{w39rb_0P%#q=Eg#~C+st4CpGH_p70-Y20=$Cfup|~%W^v~);Plc zSpIa4j=-uIN9YfrBQ%0XaN@}EW18WT9{r)nZ_o@k6zC7LOe~gHJ)FWsRLI<9;0H43 z7&qC-z%h6UfR1s$h{Z8-Af^XA7i0ww=mQx&;Oz?8pplS$Zo;G7erRQU{Tkgr9a6g0 zdC4@AP3z<@g_vHEh-z|V(koU&CSJiu1B>=T(XA3ked`rl*d}IiQzcGT5S$f~avu=?ZXGfTLMMj*D{6?c?%e~?@V*}dg|MiNZ8g-F#Gh@Rvnp2jI)t8-p zn;9GCAg30b?sDQ7wVqvOyt73!V+hVa%}8%)%)kNA^k=I${;UquT0TaF^8>mu#lP4b zmpFO7p=fd=l+?!*T4oB}S6*lzQ|OZ{bP)>e7ssgg$_wrPUu6#XuQChc_?tVFS%|K% zm!z%$oJZl?k%<`>{@ppa=*B0IiH^wD<7-s0rgBXSGrZ`4nfyPr# zlQ=$#k5`YV9s%*Arf9_2Cv(bvg04M#ebg8d0}t!a6mI2iHxEF$L+rWiVbfJR<3MQVPH((1P+W-D9#*E`X_KT8H1K@KjlhXuN+Wu zV~o$S6(;b>pT>yJ-J6Mw1}1Dpo*fY8EsR0DPu9qpi(ozqH#ZTYP!f$XXJ$FhzyioI z>(}<(R^e)9`IG0@Y!%Mvn1T8Yx5^OVMR4>wVx{_FgI0lIhBzbe?rVCTB87IP5? zBZ~i9?2R5#8QJ#X4Na>(`baeh`tmNU2(IN6(2wqC1!MRcZnytiC@c;_vyH8Tksi9i z-G%Jqqxh)v*vXhLLbteY7|H!ran~=GJ%+vVuj9T#7TiZw{$(6LN6x+SZ{t>`;OLLN z^6%q*gCh6J=f*u1gL8Q7mH!y`HCl>$~W1E#_hw(gL{>_#gPzkk9*H8-j06f9_Ke{8*b|Ls)Yp%_PBf9;;QIi?r}Ta z;@xOk?r{YX#oJH}_o}IG@q=)6?o~70;stO6?n!y>xPPPZuqpPWPm1GEDEFi)Zt+v8 zXbmZSFED}Pqp5#7u^K0B`XBMfKm@wMWLhoJ4aS6b;7w?WOg$G43ecM>(= z9=ChkKIFzd?$2@eL&Cl4E#qpV)woyPQG5jc$2}P>u@Qd5y;5P%sN!O@Aouv%NyRfD z)!mhKMc9q>o6HKojrTkLF)KVUVrR5JGj&XcKWTQjqx-nOWp;Rh`;DJE zC;Wi>v;V@J@YU`KfBf8V*geR9BiwiW=jMj{;k!K1^TKs&-LW*jmg7dAj*buEU;p?7 z{5`NVJ_7$<@Vm_mHw{0(G`iCB`7i2Yv zToxZ0Xak_lzftii`1|D2_$2)M*8gN)c#?ac-?=1wyZg2OQAv0tUT&B(Kin~O!!qWJ z!hVXN4N(!1w=VN1^r@2Wp4oNB{P43b>NId+_-p@(`^H829j*+ob06?uyD~fukHa@y z6uyX$57l2Be$PF!>)hh-;wbmDKWAC^CU>uYaTyxoW`F7OaM#p5OQeu}F;d9OOZ<~} zk4TSrHO9Z@<(XLeEk|1(@Y{RgmF{)^i(a@_>i$KNXm^|>dTo(Ogs*M4SP_2BJ?5WZ zfg1dNmFTUD61{U*S-l%~O}HjJ)Wy&323;3U@z=h%t7`J5Xg40Nk89S^n9VTN9P}Z=zk5x1Ld3-c-@Pu}1-0yY9oql9U3Xp= zPIloWJJyDq;ftfk*M`sg?N>x4`X{eP;>Y~HH-xkOOK-qar*D!=+%x{38=$(;|M7-! zExd9wVIAD+4u8bD@KpCLf6uz`R`(je_{Q*De5~s5jfgw6tM*OdeNq0N10!qfx>y>% zr&40c)Jbz@%_?40GJU}m|Ll*otL^$=b9h5c{KAFPCl}A0K7WD#Zu6#TyKcQd918h| zyR=L5*AHn?dDp?6;n~st3VthUYu|QNeE<7rYxv_CY}RLIoTV)X(-3<{R+U|MJr_=m z@I$?tCHezj98|;4Ny68r&nDo{z!3gyd2MoyU6pr-^Q!sHf5qpi54Tzo=dW)SUBw^2 zXAr(E-4x$f+HyGjW_qpMR_&Z-lP4^g&}`y@;)xUHPbsFI4O+Bp(W=F+)!&CZR_Wai zotW&r_qdotc+%ulUxdlq}L^RDxQgek*>=luIW;mZE3kq@WEV*v{F_wkv~ z9Vh0bd0(605oZV{v|wZEY5x|XvGk4;PT??}$B;UBG<{d9S7eMDu~_h$C49#PfxoA20C z-7iYXZh)T^n?g;Q)vQ8Nnw1&LQ~k$MvYWf|fyDO$`wvYe*-R%$??bmCc-O-Kp$F)bw zIDcpR>|5M~UEMllM@Ha(&phf@_CM>C-3yVdm zkYc`yDKL~?5^yEOX^QJBZmzha;-OJ~%+Tz5o~LB%6#I(rQ_NS~1m*8m{JP@z6`xR? z%)_TNLPN{85n8B-PKrkT7UhyXXjp5nF!;UD?NyWb^ z=D|EDvJwuR0jDXhuQ<=&F(SKu`g|o?r`Y#Dy{vg!!`({6GnydR6N*p!vwAj9^HMNj z2GKke2i#F{f#P9`Co1OU#vtu7#dj!vRq-jyb^u;b5wSSX1sR#IGRugqtK`iTcT_xD z@ifIHikB%~8}BzO%C7F22U&yZQN=&0c$ear6#qx@8;TDp{!sDfihr|g4#W8MUPZ-| z6leLL7iFil7^X!0h+5D_3ly72s-+$q{p?ZM^^=}c(fj?PQQ6IV^J8N{YJOlW;8ewp z74uE0flg1wgZ+0$WxthVem)_Ej_{uuon7BsiBsnw#hr>DQv9OgHxz%U_)EnX6<5MV zoFM-!#k{x!xpk@zDxyH~SjAT;=4Y9LOjjx1p!gxhPb=Q5_#J)`DaeQ~;|=&{#s4U- zgo`MF4qr?Va3jSX74yqSfet@*6!64=S$}@vD2Q0Cc!Og87%tFxMlpXs5y%fKKBf2< z#s4biPhiVu^?C>d88ug&r?|J`$%>aKUZa?w^$GIap?G%%d(PpCfOA~&w~7<7d<-(G zp}2wK9L0Hx3ltAkJl?SNKWCYG@k5GtShl|OqKY`6_yff!75}I>3a4X11riijQCwYdEyeZt`oAD?SVc7V zubGI`x)&#ACw7{uU=&c*QdnFIK!tF@Hr8*!8gD z1OA{X*=Y?=D$x&$qj0w_NLJN9_;B-H>HL*PAX=^Xe*Z`0)bd3oI-vLi#U~a2Si^5K z73Y}^aKjjiq|XNtoRYd zyA)w8FoG1NomK#|1nmwl3t00N4`AqF)8fv~eik$x=#}lCLuQPA(Z254g2s z0^vbQXAD^im`z?{^{-a)YnA@ZWSjtV+W_`bB(Pa2Z6iyj`xU>h_+zr9Jq~6*I9YT) zr(7!VgVO(3$rI{92j{fd@De=)Qf$Df&j=~FHCZysBjbFBTR!!L`zoE`WJx<($!C#8 ze;!#{=o+KX_Q!UE30S^GDc!E*TgZ};`5mkn_afz3Omlk$%wI@zdy8_>IjZ<8vKacE z$ABb=s9(W+&@qtbD(=W$;9`BitpzwmIIjW953K7+C25wvD)BHSA4QhLGnCGiWE?)Z zEd{3t^9i*e|Mg_a|F&{D>d()!1c~1&kH8ZyiZ5wckx@%B4kp~%fK!CKDxH30DU83} z35*z{nE(EiH_9$#Q<)VKxSv=WS@_Wfr@Ec^w=OCE*j7C16Djn}@ z6*#RDoKXobDtT(7icD*Ondy9F8m3$dzEtV7P&#>(&xSI#%dCzaf4xO%AtH(xAsJ0n zJk2IBiDxMNB}%?Q@g~u^3n{iK`F4>%5Ba`EC_iYT*CgUgM7+lYV#G0(_=M8oHwprs zUzE-{(fJ+uBsQ+dzY3VG)z!tFPs*7;>)%i*WhpyYh0EGTTV;_ZrGP`sbKi0zN59nc^Q5|Dp8%R`ND)^eqaRZ8ol3q-$@eMw>rK@Be~b}QzzMRq?71BWrwD(ebbcXA zL;a!T5lt)Pv1G|JS;^Csyt$QI$L*w)x+$gpNy*y=rYJwC&238QZl&}9Sqk2xc%RaLPw5|1d{XIrr{rhJ%#-y`yc7Xxt~4@6E4P~9 z6yZinrv+KMppBAuRq~!nK1j)n6;B42pWMz-5z7@{OBUlcD85(m4yC`7EJhz9^QemL zJ0<_6f;}g)8I*ckrFgO=&LDTU@+>89tGKV?F=R1x8W}sc8Tg+fd?n?ga}7C|IM=9% zQWIelZ&Catd6tzwOUBOabH(SC&Ob_Cxp_sw)yXYw+6+E~lp=wKN~x9N&SdHD?n*vL z@eHN2MDcQ^bG?$^EOImc?obhTlf|IjiVrD1rT7e4n)Dnw*VgO;I7PT-PDKTpC~ls^ ziBpuiF+zB_;%Q_lU>>=REnp!yMfe8FrG(!l=hJ&qt})E zJthB0$-hwYi;5#!R1{p5ECn}F+=}c;M6rsvT=5dJ)L;d8GVKcVDj6vxAV0wdBC*CI=08e6&XKc}gRXsZ(BDS0m? z@2BJ=lza?XT4kZ)TNH0o{CZ1ztR(naMMUF(8pzWXxAse~#zAw663rn?rIwKMY!591 zrwFfAIvdE+L%x#VulO;g^OTamWaY)Cgg2GaM~XjH3BDnBvId<7rwE@@It~V1U{Eyq zD!^fc+xwB2%0GuM++~`<&2eMSAi<0+I@};~6oT@RX82r{w=p@&ihKge(Og1=EPhu;~k>^CQ_B;W@vk1b-=x#;hM? z6c1)b*C3-BluHe2E1gD)J1Fi)mKGX8mes~+a7uUUf6i2;G>ZbcTWJCl2$>e#x0Q-u2~osr~4R%fh|U#{e{lzg$sP5qav zh}GoFY)03EQ-n7voh{@=R_A^te_Y9*R`QpX{8c4C)RrrQMK+@kRK!Gxzgr@5eXBHLH!$B{*+s*=|rOFm5%=PULms=!r>H!8lHEY0`;Sr+mS zgHwc`Ryr?}r82K7`5`6$z{>6T`$8%GsFZ$D@(3Kj10#~iQb00UjA*2|gW};@inm@D_4EoAy3%ituAf=XtVJc#o$d-cS+mDEUz(|4hk$ zQv9dV`A5m)u@npnOD2m!)ye2?GyWPWrRIurMTzz4q~txwlF>-TGZn8^e6!*mil6Po z`Cl@6TSXjEd|L7EWNB&#%O|(cHgyy@ML2_UY2GG^n=Acp<&63dD-YnCkBYBSe6!+v z6hBE8gPtP~vIe~fP7!`x=^Rn~71?^2Oz7J0DEv;jCpxVh5ltoSnW5Ubyt z`ocq%&OD{#Efl3XNV8liT~C%~+^iBjt@tIy?l8nrc)#M~+V>($;?audEB&S95w@`9;1uEO zmCpT2=V@^H`hPbgifrPS!70LTQZBXmSn-!+G45L>Kd(5lTZK*>S@LOJ!T8{UQo5`n z!WpRK!^mRLLdBaDZ&AEW@$=-7wqoCt>svl+blCpbqH&xI3TR9gOPi5LS)G>P6yZ)v zr+_Ri(O=1@D)|g0U!wRrj{(Vaz2Ya8(sSg|)`%CuDZ;NSog<1*lEt7?O8&cI2j>vf zG4-#;fYi99;!dK(qPr=1eSGw@dJvV?ZNq9`sM^9=J1bzprNA|4HPgC5SEP1vekF$Ap0H+9hmno$o zikFh5={&L|*sAzt#qTTrQE?njKmsEwlZ&kpJpD>3w*KeTQA*ilDY%)EcT(J6@fgK3 z6kkb}e6CXRjY@t;FZ6$4-8M#ubx$gOoh(lJnUW_LROmNS+?I^);nqpXhbo>z#&9(C zpP?c=#kVScRPoD-50RyhKO~Q5v3MmvIAy#+=akZMaHbUKR|c2Q|8-PEHaX}5vSd`C zc%;%VCQq=1O#-I~&sI81$dc#s3c2UpR1t7CE8ebnx8m2xlF?gA{*{t{r{w3!Vi3<8 z0!|~3ME`SZtRi}l=Ue$uGInmGl+J9$ixjUVqd;yqEBOP8pI3a)Q-LoO|4OEVVEa?a zlW;N;)Sxz5`n~~qqSX(BQ-oV7odJr+3Y+@RR1u5F(!5ubC8JG>w<`UI$dhcrkAhQ# zpH(`0$&%+`#Yg(W|AQKQsS^CGm@ha93P@F)LzddNB~P|SbOfge_f$HA$YR9!az_29 zD5d#|uTi|7EScV+c!%OQl>TAz6l>52;1uB#O6Ny%aQ){`6%p0H!qRxMBu-XbQ*lGG zv_w<#R9kQkI7PUl(&??(8=(?RQxPTPX*Q!P!70MmD4iS0(xjzIzD4mPO6PGUf5FP_ z_T*plV9qOvzi3C2igSlph2Js)#9yuOdqU zE6LNX5o^FH!lg>5j4Vbxs`yRChXQ@p{}UDQt>PcaQb07$ZUe5PxRc@$if1TZp!g=m zKDd1Tznc+P*qYr7P7&TgxzzqSvefJ&#mAM-H%k74lK-LPe^(rio-JEKSL4 zk;S0qirXn3p?CsW^0}Nm!&Yo2I7N7o(XsyLY)}avAxkZvB};J8%D@~Oal1;eUGW~phZTRI_?Y4oioaI;z2ct-srmnR74f%X2Uk3TmWWkcNpZ5` z>WXVCuB$j)&aLpa_3{ATHK(|p;=ziC`F``*ZHfj`m7a#8Sn}6|YfzgW?T} zHz~eb@x6*4QT&)?J4l~V5zi~$t9ZZSgNol(d{ptLiccy2PVvt}I#zVS?<(S=VqT33 zx+z|9l3!GYUd&RW28u6H++1-R#T^uPReYJ^eu@Vw9$~qT8QY^(#6-nY{iMy=X|v`j z(GtbW6t7l%z2Z{Ew<+GN_#VaE{8AK|{*)5!QoP6Ci)il+B|511h~lG)KUaK8@sEms zR{W>pi;AOhB@dm6`?T2NZNP99#i@#GD$d+BZ%g)!zFyNPWD;$XIm^hgmOmiJTkef` z`E7}_iX5`?Gvun4&Fe=}E#DRcd3DQs$TckgNY1d_0p;Mbq#ZN!;}FQS5s4@?c&v8{ zxxSSTNB}poyt)!NYd|xik&j&nneIvjw*fz9Hjq!>vj>7*jB}x?~J+ZugUiT0TWacXJzqCJ!#k`s5K- z{xsMNE+>}OM8qf?@iuw1<-N7Qa`mTvZLnPBnM{_8EiaLat^Q#Q;^0L5U$UIjo=5iv zCuxnd!1e^pb7nIz*(Uy+JjF79&J~;@m|t+o!h0#@vM~OfJl*QAtOu6G*RNz*59Pyu zf~8AaI5l6M#I2KIw0|T5-6aBk==2t*(-sP&rJN$+Cg91!O~EsS>4WoxTY(n}w+62z z%gDM}nB{KdYoi!JqwW-@-d15awDX`ar^hFR8-V%RD5mA0*eA?EaX|P|Fu$-$og6S< zA(e~~#qE@^M=MTCfCc|7OuavZX~acg8W9I;nGsswsVt0EcB%=p;F`jmof-<$H*Uh4a|2}CCe1+VEQD}P`Klv(Fo2>!gPhLWI4b*Dop*I!qk6OnEG#! zIi9f{5~lu<81z3QAajmM1pVT3Va%e=DPcD6c`_#hZ2t%|qj(G*${}*92-7iZ3e#48 z5u7@-BP?7SoJX3=(F8jS%KUG*+0-HCdScG((s(`aI$3 z;Kg8%1aI(xufh2IDF z68;_B-;=<31V#w|1D+u4MBomOa13~ca2ULtOsB!NR+!GXL71~)nJ^vsL189&LfC77 zzzY({2J_Ws%(NN!P2pVdVd1vm4~6r<$AvEge<3^+{H^e0@K3^Yy5EH7f$_F9%>O8C z4FXQQEtr!-l<;P78o4eN&;`P*Wqo0e?`&Z#`JCp$XnCi#Fe}N|t1+K!a981$od0`C zARiI^g$uw#g!_SuggG;g73KkWhchDq{ZA#%`ST=#X%-1L z1uqk3*IX;y8+?;6ed2audixgP8Q=$md4zmam^18?!Yfg}vr7W&z%L1J1ivQC?s!|c z4E&z(1K^K^9|E5e-U&V{{2cfX;TOO>jbnvh1}B0&23|#guL~f*22K}#7n~{lKDeRq zx8O^J9W-?d;Z!i+vB!Ke!QF-HgZl|L1P>NQx8kc~5@?MGekzQK+k&SFcLdK8?hKwU z%=vtYF#CI%@NDpUGRGJ;ez}6ozAqDI-`{H(?axVLn?!KDJ|@h*e_EJ_)E9(1gI^Ku z0e(%m2>iD21n`H#lfa(~PXT``%%S+JCxK-MToAq%%=bRf>id8(!tC!v;X~kL;UnN0 z!qKRG9btAs17Wsq6X9;)9AS^cri}!~gY$&hq}_yhBrFhK1s))LBY3FrR`4j{XTaly z_kt%29|A8T^WcJQSt93u1lTv%N<v3v(#$7cKz5CEO4Eq3{6kr^4*wFNKGJzvCM&S%VP> zoRNre;NOLLc>POw4wzTIsL$aVExZQIw_PT;0br{m%+_ik%+_im%ofTOZi4ciE)rnv zdkQxL_Y-af9w^L~m_+6}4BK>J7RK-NQC=CmR5%%Yjc^+HI^hiPO<<1+=xDb}L^k*i zVHS3u@DT70;o;!tgeQSt7M=>;FU;0@OL!spUEy269|>jcpMR53Ukr%o$yQG zGr})}e;3{h{!92Hu#0N5GRMKO!k>Zp9#6`@2B!#r4^B6X_WuciOo{jfTwnM+xDA=( z1RLM=N#?<$n{XPqK)5b=fH0kUs4$1(C}FscGhUePGS!nnM+9aH)00bt`+^q>j{+|j z9s^z_d^z|A;hEs|!Yjd>gl`0w373NJ74~jLV4DPP13xBwC-`aMGBCf}#@gQvenogI z_%-4Cz;6q01HUKyEcj#Lec;c8-vobEne#s~J%+&d67f0stnioMbHd+%{}w(Cj=)sO zwCtuh;fvsqFhA>*DqIPiA)Exx60XJ%MmCZ_79yGo*8{f{ZUAm4d?~oIFc+ddgxiDr z2zLSx5WWmNft&}+uuT(=0nZ}y!TLl5=1T+}XNfS!J>P)J#Fv3r3m1ZK5grP@LzoK? zeo2V>Jn%d!JRi)jCsBSSc$Y9IF7G7?_z3(*_zCbE!q0&Z2_FC-6*m1R{5IsLh2H`H zEc_w(cj1r0aaCbNCjhpPWzSqPNtFobIvK)ji7eq9a06iuo3><5{@6MRM}xZybBOj9 z#-hq86vj;M6bZAeNmbGR%qWb&bctZImk6W9oW;T;z{`clfcf%Rrsc8!2H_dt^}=(& zn}kciTZET_`GQ%dy&B~^k4j)U_(|av;N8Mo!LJG53qC0PF!+7p?ck%rkAqJL?+2d} zJ_$Z8?7}gB279!Er&@nV1V_O|VXoEVa0H=FGjOtSD==SUOF2C}Q@8-kFV9lWpPODH zJRaOam{(ic3SZ9kKi_-H1hWv)UAP3?TX+SyP?(oq_}*LU^U@2y#74dsJVW??@EqYs zz$?l5s5-W_!aQ2uY#8ld1A&bakp;d}xCMBtaC`8B!kntN3)7i*3g?5L6D|Pn5$*$i zRk$DcO<@k>!=41_TptQ^93K}R4gNxS9Qa$|@!+3?xk&j&j^nPN1&AC9sq1{!Zau(%-Jnfm@{dHaAR<@HF98;90_)!slD|OzoFQM1Mqh!UMspg(rd633IwF z73RXy7rqL-S-2E@pYTTTL&9|47s$N;*j`CR|1-dvy(SU(=e#Xk2mFyRj}e~Mp9D`7-VNs4s40IHyoB5vfXx$T zEAs1!l;fYXPPi_3lWY>f9%RTtqx9Ob2;fm{adF!kljTnMoEv|JW-$1pK=2 zRPaIJnP9#KoBE5vM}?Pz`AY2M-e`Y1%PEOqvwSB^XZf4VafmIVx@FcfP8i+mgoNoU z>B97tEMfXeBVqbVQ(?{lEjwyl)vt;2op=c}L_}rb#^7qg^w^rh?6bPUoG}{;cLuj3_XA+-EF2H+A&l~! zLSfE~!^s{JaB3VQ5&7VW!km3C7p5P~6J{ST6}|#|t?*3n^}-9lw+OQI30Xmn2XYXgmb}s^*Z%=%{W1LIGA6lrkvM_Q-v3R8Sb@`v_-&2MUM5!-X#aj}dMUo@f~DZ-$vfaG1> WLAUp=V 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 z%0D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%0A#?t1YBJbFt`t8kp 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