From a5d626f818e53513e9b68855b68e90a1e8d084e4 Mon Sep 17 00:00:00 2001 From: huangqinjin Date: Wed, 25 Dec 2019 01:41:53 +0800 Subject: [PATCH 1/2] Add basic bluetooth support --- include/boost/asio/bluetooth/address.hpp | 165 ++++++++++++++ .../boost/asio/bluetooth/basic_endpoint.hpp | 212 ++++++++++++++++++ .../boost/asio/bluetooth/detail/endpoint.hpp | 143 ++++++++++++ .../asio/bluetooth/detail/impl/address.ipp | 121 ++++++++++ .../asio/bluetooth/detail/impl/endpoint.ipp | 115 ++++++++++ .../boost/asio/bluetooth/stream_protocol.hpp | 92 ++++++++ include/boost/asio/detail/config.hpp | 7 + include/boost/asio/impl/src.hpp | 2 + 8 files changed, 857 insertions(+) create mode 100644 include/boost/asio/bluetooth/address.hpp create mode 100644 include/boost/asio/bluetooth/basic_endpoint.hpp create mode 100644 include/boost/asio/bluetooth/detail/endpoint.hpp create mode 100644 include/boost/asio/bluetooth/detail/impl/address.ipp create mode 100644 include/boost/asio/bluetooth/detail/impl/endpoint.ipp create mode 100644 include/boost/asio/bluetooth/stream_protocol.hpp diff --git a/include/boost/asio/bluetooth/address.hpp b/include/boost/asio/bluetooth/address.hpp new file mode 100644 index 0000000000..989ed38b3b --- /dev/null +++ b/include/boost/asio/bluetooth/address.hpp @@ -0,0 +1,165 @@ +// +// bluetooth/address.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2019 Huang Qinjin (huangqinjin 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 BOOST_ASIO_BLUETOOTH_ADDRESS_HPP +#define BOOST_ASIO_BLUETOOTH_ADDRESS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include + +#if !defined(BOOST_ASIO_NO_IOSTREAM) +# include +#endif // !defined(BOOST_ASIO_NO_IOSTREAM) + +#include + +namespace boost { +namespace asio { +namespace bluetooth { + +/** + * Implements Bluetooth addresses. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class address +{ +public: + /// Get the address as a string. + BOOST_ASIO_DECL std::string to_string() const; + + /// Compare two addresses for equality. + BOOST_ASIO_DECL friend bool operator==(const address& a1, + const address& a2) BOOST_ASIO_NOEXCEPT; + + /// Compare two addresses for inequality. + friend bool operator!=(const address& a1, + const address& a2) BOOST_ASIO_NOEXCEPT + { + return !(a1 == a2); + } + + /// Compare addresses for ordering. + BOOST_ASIO_DECL friend bool operator<(const address& a1, + const address& a2) BOOST_ASIO_NOEXCEPT; + + /// Compare addresses for ordering. + friend bool operator>(const address& a1, + const address& a2) BOOST_ASIO_NOEXCEPT + { + return a2 < a1; + } + + /// Compare addresses for ordering. + friend bool operator<=(const address& a1, + const address& a2) BOOST_ASIO_NOEXCEPT + { + return !(a2 < a1); + } + + /// Compare addresses for ordering. + friend bool operator>=(const address& a1, + const address& a2) BOOST_ASIO_NOEXCEPT + { + return !(a1 < a2); + } + +public: + unsigned char data[6]; +}; + +/// Create an address from an Bluetooth address string in colon-separated or hyphen-separated form. +/** + * @relates address + */ +BOOST_ASIO_DECL address make_address(const char* str); + +/// Create an address from an Bluetooth address string in colon-separated or hyphen-separated form. +/** + * @relates address + */ +BOOST_ASIO_DECL address make_address(const char* str, + boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT; + +/// Create an address from an Bluetooth address string in colon-separated or hyphen-separated form. +/** + * @relates address + */ +BOOST_ASIO_DECL address make_address(const std::string& str); + +/// Create an address from an Bluetooth address string in colon-separated or hyphen-separated form. +/** + * @relates address + */ +BOOST_ASIO_DECL address make_address(const std::string& str, + boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT; + +#if defined(BOOST_ASIO_HAS_STRING_VIEW) \ + || defined(GENERATING_DOCUMENTATION) + +/// Create an address from an Bluetooth address string in colon-separated or hyphen-separated form. +/** + * @relates address + */ +BOOST_ASIO_DECL address make_address(string_view str); + +/// Create an address from an Bluetooth address string in colon-separated or hyphen-separated form. +/** + * @relates address + */ +BOOST_ASIO_DECL address make_address(string_view str, + boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT; + +#endif // defined(BOOST_ASIO_HAS_STRING_VIEW) + // || defined(GENERATING_DOCUMENTATION) + +#if !defined(BOOST_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 boost::asio::bluetooth::address + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const address& addr) +{ + os << addr.to_string(); + return os; +} + +#endif // !defined(BOOST_ASIO_NO_IOSTREAM) + +} // namespace bluetooth +} // namespace asio +} // namespace boost + +#include + +#if defined(BOOST_ASIO_HEADER_ONLY) +# include +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // BOOST_ASIO_BLUETOOTH_ADDRESS_HPP diff --git a/include/boost/asio/bluetooth/basic_endpoint.hpp b/include/boost/asio/bluetooth/basic_endpoint.hpp new file mode 100644 index 0000000000..05603c4e1d --- /dev/null +++ b/include/boost/asio/bluetooth/basic_endpoint.hpp @@ -0,0 +1,212 @@ +// +// bluetooth/basic_endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2019 Huang Qinjin (huangqinjin 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 BOOST_ASIO_BLUETOOTH_BASIC_ENDPOINT_HPP +#define BOOST_ASIO_BLUETOOTH_BASIC_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#if defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) \ + || defined(GENERATING_DOCUMENTATION) + +#include + +#if !defined(BOOST_ASIO_NO_IOSTREAM) +# include +#endif // !defined(BOOST_ASIO_NO_IOSTREAM) + +#include + +namespace boost { +namespace asio { +namespace bluetooth { + +/// Describes an endpoint for a Bluetooth socket. +/** + * The boost::asio::bluetooth::basic_endpoint class template describes an endpoint + * that may be associated with a particular Bluetooth 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 boost::asio::detail::socket_addr_type data_type; +#endif + + /// Default constructor. + basic_endpoint() BOOST_ASIO_NOEXCEPT + : impl_() + { + } + + // Construct an endpoint using an address and channel number. + basic_endpoint(const boost::asio::bluetooth::address& addr, + unsigned short channel_num) BOOST_ASIO_NOEXCEPT + : impl_(addr, channel_num) + { + } + + /// The protocol associated with the endpoint. + protocol_type protocol() const BOOST_ASIO_NOEXCEPT + { + return protocol_type(); + } + + /// Get the underlying endpoint in the native type. + data_type* data() BOOST_ASIO_NOEXCEPT + { + return impl_.data(); + } + + /// Get the underlying endpoint in the native type. + const data_type* data() const BOOST_ASIO_NOEXCEPT + { + return impl_.data(); + } + + /// Get the underlying size of the endpoint in the native type. + std::size_t size() const BOOST_ASIO_NOEXCEPT + { + 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 BOOST_ASIO_NOEXCEPT + { + return impl_.capacity(); + } + + // Get the channel associated with the endpoint. + unsigned short channel() const BOOST_ASIO_NOEXCEPT + { + return impl_.channel(); + } + + // Set the channel associated with the endpoint. + void channel(unsigned short channel_num) BOOST_ASIO_NOEXCEPT + { + return impl_.channel(channel_num); + } + + // Get the Bluetooth address associated with the endpoint. + boost::asio::bluetooth::address address() const BOOST_ASIO_NOEXCEPT + { + return impl_.address(); + } + + // Set the Bluetooth address associated with the endpoint. + void address(const boost::asio::bluetooth::address& addr) BOOST_ASIO_NOEXCEPT + { + return 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.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 Bluetooth endpoint. + boost::asio::bluetooth::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 boost::asio::bluetooth::basic_endpoint + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const basic_endpoint& endpoint) +{ + os << boost::asio::bluetooth::detail::endpoint(endpoint.address(), endpoint.channel()).to_string(); + return os; +} + +} // namespace bluetooth +} // namespace asio +} // namespace boost + +#include + +#endif // defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) + // || defined(GENERATING_DOCUMENTATION) + +#endif // BOOST_ASIO_BLUETOOTH_BASIC_ENDPOINT_HPP diff --git a/include/boost/asio/bluetooth/detail/endpoint.hpp b/include/boost/asio/bluetooth/detail/endpoint.hpp new file mode 100644 index 0000000000..994cd55a32 --- /dev/null +++ b/include/boost/asio/bluetooth/detail/endpoint.hpp @@ -0,0 +1,143 @@ +// +// bluetooth/detail/endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2019 Huang Qinjin (huangqinjin 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 BOOST_ASIO_BLUETOOTH_DETAIL_ENDPOINT_HPP +#define BOOST_ASIO_BLUETOOTH_DETAIL_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#if defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) + +#include +#include +#include +#include +#include + +#include + +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) +# include +#endif + +namespace boost { +namespace asio { +namespace detail { +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) +typedef SOCKADDR_BTH sockaddr_rc_type; +# define BOOST_ASIO_OS_DEF_AF_BLUETOOTH AF_BTH +# define BOOST_ASIO_OS_DEF_BTPROTO_RFCOMM BTHPROTO_RFCOMM +#else +struct sockaddr_rc_type { + sa_family_t addressFamily; + unsigned char btAddr[6]; + unsigned char port; +}; +# define BOOST_ASIO_OS_DEF_AF_BLUETOOTH AF_BLUETOOTH +# ifdef BTPROTO_RFCOMM +# define BOOST_ASIO_OS_DEF_BTPROTO_RFCOMM BTPROTO_RFCOMM +# else +# define BOOST_ASIO_OS_DEF_BTPROTO_RFCOMM 3 +# endif +#endif +} +namespace bluetooth { +namespace detail { + +// Helper class for implementing a Bluetooth endpoint. +class endpoint +{ +public: + // Default constructor. + BOOST_ASIO_DECL endpoint() BOOST_ASIO_NOEXCEPT; + + // Construct an endpoint using an address and channel number. + BOOST_ASIO_DECL endpoint(const boost::asio::bluetooth::address& addr, + unsigned short channel_num) BOOST_ASIO_NOEXCEPT; + + // Get the underlying endpoint in the native type. + boost::asio::detail::socket_addr_type* data() BOOST_ASIO_NOEXCEPT + { + return &data_.base; + } + + // Get the underlying endpoint in the native type. + const boost::asio::detail::socket_addr_type* data() const BOOST_ASIO_NOEXCEPT + { + return &data_.base; + } + + // Get the underlying size of the endpoint in the native type. + std::size_t size() const BOOST_ASIO_NOEXCEPT + { + return sizeof(boost::asio::detail::sockaddr_rc_type); + } + + // Set the underlying size of the endpoint in the native type. + BOOST_ASIO_DECL void resize(std::size_t size); + + // Get the capacity of the endpoint in the native type. + std::size_t capacity() const BOOST_ASIO_NOEXCEPT + { + return sizeof(data_); + } + + // Get the channel associated with the endpoint. + BOOST_ASIO_DECL unsigned short channel() const BOOST_ASIO_NOEXCEPT; + + // Set the channel associated with the endpoint. + BOOST_ASIO_DECL void channel(unsigned short channel_num) BOOST_ASIO_NOEXCEPT; + + // Get the Bluetooth address associated with the endpoint. + BOOST_ASIO_DECL boost::asio::bluetooth::address address() const BOOST_ASIO_NOEXCEPT; + + // Set the Bluetooth address associated with the endpoint. + BOOST_ASIO_DECL void address(const boost::asio::bluetooth::address& addr) BOOST_ASIO_NOEXCEPT; + + // Compare two endpoints for equality. + BOOST_ASIO_DECL friend bool operator==( + const endpoint& e1, const endpoint& e2) BOOST_ASIO_NOEXCEPT; + + // Compare endpoints for ordering. + BOOST_ASIO_DECL friend bool operator<( + const endpoint& e1, const endpoint& e2) BOOST_ASIO_NOEXCEPT; + + #if !defined(BOOST_ASIO_NO_IOSTREAM) + // Convert to a string. + BOOST_ASIO_DECL std::string to_string() const; + #endif // !defined(BOOST_ASIO_NO_IOSTREAM) + +private: + // The underlying Bluetooth socket address. + union data_union + { + boost::asio::detail::socket_addr_type base; + boost::asio::detail::sockaddr_rc_type bt; + } data_; +}; + +} // namespace detail +} // namespace bluetooth +} // namespace asio +} // namespace boost + +#include + +#if defined(BOOST_ASIO_HEADER_ONLY) +# include +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) + +#endif // BOOST_ASIO_BLUETOOTH_DETAIL_ENDPOINT_HPP diff --git a/include/boost/asio/bluetooth/detail/impl/address.ipp b/include/boost/asio/bluetooth/detail/impl/address.ipp new file mode 100644 index 0000000000..746af7a00f --- /dev/null +++ b/include/boost/asio/bluetooth/detail/impl/address.ipp @@ -0,0 +1,121 @@ +// +// bluetooth/impl/address.ipp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2019 Huang Qinjin (huangqinjin 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 BOOST_ASIO_BLUETOOTH_DETAIL_IMPL_ADDRESS_IPP +#define BOOST_ASIO_BLUETOOTH_DETAIL_IMPL_ADDRESS_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace bluetooth { + +address make_address(const char* str) +{ + boost::system::error_code ec; + address addr = make_address(str, ec); + boost::asio::detail::throw_error(ec); + return addr; +} + +address make_address(const char* str, + boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT +{ + unsigned d[6]; + int r = sscanf(str, "%02X%*[:-]%02X%*[:-]%02X%*[:-]%02X%*[:-]%02X%*[:-]%02X", + &d[5], &d[4], &d[3], &d[2], &d[1], &d[0]); + + address addr; + if (r == 6) + { + while (--r >= 0) + { + if (d[r] > 0xffu) + break; + addr.data[r] = d[r]; + } + } + else + { + r = 0; + } + + if (r == -1) + { + ec = boost::system::error_code(); + return addr; + } + + ec = boost::asio::error::invalid_argument; + return address(); +} + +address make_address(const std::string& str) +{ + return make_address(str.c_str()); +} + +address make_address(const std::string& str, + boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT +{ + return make_address(str.c_str(), ec); +} + +#if defined(BOOST_ASIO_HAS_STRING_VIEW) + +address make_address(string_view str) +{ + return make_address(static_cast(str)); +} + +address make_address(string_view str, + boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT +{ + return make_address(static_cast(str), ec); +} + +#endif // defined(BOOST_ASIO_HAS_STRING_VIEW) + +std::string address::to_string() const +{ + std::string s(17, '\0'); + sprintf((char*)s.c_str(), "%02X:%02X:%02X:%02X:%02X:%02X", + data[5], data[4], data[3], data[2], data[1], data[0]); + return s; +} + +bool operator==(const address& a1, const address& a2) BOOST_ASIO_NOEXCEPT +{ + return memcmp(&a1.data, &a2.data, sizeof(a1.data)) == 0; +} + +bool operator<(const address& a1, const address& a2) BOOST_ASIO_NOEXCEPT +{ + return memcmp(&a1.data, &a2.data, sizeof(a1.data)) < 0; +} + +} // namespace bluetooth +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BLUETOOTH_DETAIL_IMPL_ADDRESS_IPP diff --git a/include/boost/asio/bluetooth/detail/impl/endpoint.ipp b/include/boost/asio/bluetooth/detail/impl/endpoint.ipp new file mode 100644 index 0000000000..ff6ae7b650 --- /dev/null +++ b/include/boost/asio/bluetooth/detail/impl/endpoint.ipp @@ -0,0 +1,115 @@ +// +// bluetooth/detail/impl/endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2019 Huang Qinjin (huangqinjin 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 BOOST_ASIO_BLUETOOTH_DETAIL_IMPL_ENDPOINT_IPP +#define BOOST_ASIO_BLUETOOTH_DETAIL_IMPL_ENDPOINT_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#if defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) + +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace bluetooth { +namespace detail { + +endpoint::endpoint() BOOST_ASIO_NOEXCEPT + : data_() +{ + data_.bt.addressFamily = BOOST_ASIO_OS_DEF(AF_BLUETOOTH); +} + +endpoint::endpoint(const boost::asio::bluetooth::address& addr, + unsigned short channel_num) BOOST_ASIO_NOEXCEPT + : data_() +{ + data_.bt.addressFamily = BOOST_ASIO_OS_DEF(AF_BLUETOOTH); + address(addr); + channel(channel_num); +} + +void endpoint::resize(std::size_t new_size) +{ + if (new_size > sizeof(data_)) + { + boost::system::error_code ec(boost::asio::error::invalid_argument); + boost::asio::detail::throw_error(ec); + } +} + +unsigned short endpoint::channel() const BOOST_ASIO_NOEXCEPT +{ + return data_.bt.port; +} + +void endpoint::channel(unsigned short channel_num) BOOST_ASIO_NOEXCEPT +{ + data_.bt.port = channel_num; +} + +boost::asio::bluetooth::address endpoint::address() const BOOST_ASIO_NOEXCEPT +{ + boost::asio::bluetooth::address addr; + memcpy(&addr.data, &data_.bt.btAddr, sizeof(addr.data)); + return addr; +} + +void endpoint::address(const boost::asio::bluetooth::address& addr) BOOST_ASIO_NOEXCEPT +{ + memcpy(&data_.bt.btAddr, &addr.data, sizeof(addr.data)); +} + +bool operator==(const endpoint& e1, const endpoint& e2) BOOST_ASIO_NOEXCEPT +{ + return e1.address() == e2.address() && e1.channel() == e2.channel(); +} + +bool operator<(const endpoint& e1, const endpoint& e2) BOOST_ASIO_NOEXCEPT +{ + if (e1.address() < e2.address()) + return true; + if (e1.address() != e2.address()) + return false; + return (e1.channel() < e2.channel()); +} + +#if !defined(BOOST_ASIO_NO_IOSTREAM) +std::string endpoint::to_string() const +{ + std::ostringstream tmp_os; + tmp_os.imbue(std::locale::classic()); + tmp_os << '[' << address() << ']' << ':' << channel(); + + return tmp_os.str(); +} +#endif // !defined(BOOST_ASIO_NO_IOSTREAM) + +} // namespace detail +} // namespace bluetooth +} // namespace asio +} // namespace boost + +#include + +#endif // defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) + +#endif // BOOST_ASIO_BLUETOOTH_DETAIL_IMPL_ENDPOINT_IPP diff --git a/include/boost/asio/bluetooth/stream_protocol.hpp b/include/boost/asio/bluetooth/stream_protocol.hpp new file mode 100644 index 0000000000..20e6bcdac6 --- /dev/null +++ b/include/boost/asio/bluetooth/stream_protocol.hpp @@ -0,0 +1,92 @@ +// +// bluetooth/stream_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2019 Huang Qinjin (huangqinjin 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 BOOST_ASIO_BLUETOOTH_STREAM_PROTOCOL_HPP +#define BOOST_ASIO_BLUETOOTH_STREAM_PROTOCOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#if defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace bluetooth { + +/// Encapsulates the flags needed for stream-oriented Bluetooth sockets. +/** + * The boost::asio::bluetooth::stream_protocol class contains flags necessary for + * stream-oriented Bluetooth 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 BOOST_ASIO_OS_DEF(BTPROTO_RFCOMM); + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return BOOST_ASIO_OS_DEF(AF_BLUETOOTH); + } + + /// The type of a Bluetooth endpoint. + typedef basic_endpoint endpoint; + + /// The Bluetooth socket type. + typedef basic_stream_socket socket; + + /// The Bluetooth acceptor type. + typedef basic_socket_acceptor acceptor; + +#if !defined(BOOST_ASIO_NO_IOSTREAM) + /// The Bluetooth iostream type. + typedef basic_socket_iostream iostream; +#endif // !defined(BOOST_ASIO_NO_IOSTREAM) +}; + +} // namespace bluetooth +} // namespace asio +} // namespace boost + +#include + +#endif // defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) + // || defined(GENERATING_DOCUMENTATION) + +#endif // BOOST_ASIO_BLUETOOTH_STREAM_PROTOCOL_HPP diff --git a/include/boost/asio/detail/config.hpp b/include/boost/asio/detail/config.hpp index 215c8da614..1d4427573e 100644 --- a/include/boost/asio/detail/config.hpp +++ b/include/boost/asio/detail/config.hpp @@ -1188,6 +1188,13 @@ # endif // !defined(BOOST_ASIO_DISABLE_LOCAL_SOCKETS) #endif // !defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) +// Bluetooth sockets. +#if !defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) +# if !defined(BOOST_ASIO_DISABLE_BLUETOOTH_SOCKETS) +# define BOOST_ASIO_HAS_BLUETOOTH_SOCKETS 1 +# endif // !defined(BOOST_ASIO_DISABLE_BLUETOOTH_SOCKETS) +#endif // !defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) + // Can use sigaction() instead of signal(). #if !defined(BOOST_ASIO_HAS_SIGACTION) # if !defined(BOOST_ASIO_DISABLE_SIGACTION) diff --git a/include/boost/asio/impl/src.hpp b/include/boost/asio/impl/src.hpp index 7f155ad25c..9274a0d6b6 100644 --- a/include/boost/asio/impl/src.hpp +++ b/include/boost/asio/impl/src.hpp @@ -77,5 +77,7 @@ #include #include #include +#include +#include #endif // BOOST_ASIO_IMPL_SRC_HPP From 13fa7e0308a0a7b1d92356a365e15034531f4457 Mon Sep 17 00:00:00 2001 From: huangqinjin Date: Wed, 25 Dec 2019 02:26:48 +0800 Subject: [PATCH 2/2] Add bluetooth example --- example/cpp03/bluetooth/Jamfile.v2 | 45 ++++++++++++++ example/cpp03/bluetooth/bluetooth_client.cpp | 59 ++++++++++++++++++ example/cpp03/bluetooth/bluetooth_server.cpp | 63 ++++++++++++++++++++ 3 files changed, 167 insertions(+) create mode 100644 example/cpp03/bluetooth/Jamfile.v2 create mode 100644 example/cpp03/bluetooth/bluetooth_client.cpp create mode 100644 example/cpp03/bluetooth/bluetooth_server.cpp diff --git a/example/cpp03/bluetooth/Jamfile.v2 b/example/cpp03/bluetooth/Jamfile.v2 new file mode 100644 index 0000000000..b7cfa37348 --- /dev/null +++ b/example/cpp03/bluetooth/Jamfile.v2 @@ -0,0 +1,45 @@ +# +# Copyright (c) 2019 Huang Qinjin (huangqinjin 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) +# + +lib socket ; # SOLARIS +lib nsl ; # SOLARIS +lib ws2_32 ; # NT +lib mswsock ; # NT +lib ipv6 ; # HPUX +lib network ; # HAIKU + +exe bluetooth_client + : bluetooth_client.cpp + /boost/system//boost_system + : BOOST_ALL_NO_LIB=1 + multi + solaris:socket + solaris:nsl + windows:_WIN32_WINNT=0x0501 + windows,gcc:ws2_32 + windows,gcc:mswsock + windows,gcc-cygwin:__USE_W32_SOCKETS + hpux,gcc:_XOPEN_SOURCE_EXTENDED + hpux:ipv6 + haiku:network + ; + +exe bluetooth_server + : bluetooth_server.cpp + /boost/system//boost_system + : BOOST_ALL_NO_LIB=1 + multi + solaris:socket + solaris:nsl + windows:_WIN32_WINNT=0x0501 + windows,gcc:ws2_32 + windows,gcc:mswsock + windows,gcc-cygwin:__USE_W32_SOCKETS + hpux,gcc:_XOPEN_SOURCE_EXTENDED + hpux:ipv6 + haiku:network + ; diff --git a/example/cpp03/bluetooth/bluetooth_client.cpp b/example/cpp03/bluetooth/bluetooth_client.cpp new file mode 100644 index 0000000000..2646eb2708 --- /dev/null +++ b/example/cpp03/bluetooth/bluetooth_client.cpp @@ -0,0 +1,59 @@ +// +// bluetooth_client.cpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2019 Huang Qinjin (huangqinjin 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) +// + +#include +#include +#include +#include +#include +#include + + +#if defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) + +using boost::asio::bluetooth::stream_protocol; + +int main(int argc, char* argv[]) +{ + try + { + if (argc != 3) + { + std::cerr << "Usage: bluetooth_client \n"; + return 1; + } + + boost::asio::io_context io_context; + + stream_protocol::endpoint ep(boost::asio::bluetooth::make_address(argv[1]), atoi(argv[2])); + stream_protocol::socket s(io_context); + s.connect(ep); + std::cout << "connect to " << s.remote_endpoint() << std::endl; + + char buf[6] = "hello"; + boost::asio::write(s, boost::asio::buffer(buf, 5)); + + int n = boost::asio::read(s, boost::asio::buffer(buf, 5)); + buf[n] = '\0'; + std::cout << "receive [" << buf << "]" << std::endl; + + io_context.run(); + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} + +#else // defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) +# error Bluetooth sockets not available on this platform. +#endif // defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) diff --git a/example/cpp03/bluetooth/bluetooth_server.cpp b/example/cpp03/bluetooth/bluetooth_server.cpp new file mode 100644 index 0000000000..b7f441371a --- /dev/null +++ b/example/cpp03/bluetooth/bluetooth_server.cpp @@ -0,0 +1,63 @@ +// +// bluetooth_server.cpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2019 Huang Qinjin (huangqinjin 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) +// + +#include +#include +#include +#include +#include +#include + + +#if defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) + +using boost::asio::bluetooth::stream_protocol; + +int main(int argc, char* argv[]) +{ + try + { + if (argc != 2) + { + std::cerr << "Usage: bluetooth_server \n"; + return 1; + } + + boost::asio::io_context io_context; + + stream_protocol::endpoint ep(boost::asio::bluetooth::address(), atoi(argv[1])); + stream_protocol::socket s(io_context); + stream_protocol::acceptor acceptor(io_context); + acceptor.open(ep.protocol()); + acceptor.bind(ep); + acceptor.listen(); + acceptor.accept(s); + std::cout << "connect to " << s.remote_endpoint() << std::endl; + + char buf[6]; + int n = boost::asio::read(s, boost::asio::buffer(buf, 5)); + buf[n] = 0; + + std::cout << "receive [" << buf << "]" << std::endl; + boost::asio::write(s, boost::asio::buffer(buf, n)); + + io_context.run(); + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} + +#else // defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS) +# error Bluetooth sockets not available on this platform. +#endif // defined(BOOST_ASIO_HAS_BLUETOOTH_SOCKETS)