| 1 | #include<config.h>
 | 
|---|
| 2 | 
 | 
|---|
| 3 | #ifdef HAVE_LIBBLUETOOTH
 | 
|---|
| 4 | 
 | 
|---|
| 5 | #ifndef BOOST_ASIO_BLUETOOTH_BLUETOOTH_ENDPOINT_HPP__
 | 
|---|
| 6 | #define BOOST_ASIO_BLUETOOTH_BLUETOOTH_ENDPOINT_HPP__
 | 
|---|
| 7 | 
 | 
|---|
| 8 | #include <bluetooth/bluetooth.h>
 | 
|---|
| 9 | #include <bluetooth/rfcomm.h>
 | 
|---|
| 10 | 
 | 
|---|
| 11 | #include <boost/asio/basic_stream_socket.hpp>
 | 
|---|
| 12 | 
 | 
|---|
| 13 | namespace boost {
 | 
|---|
| 14 | namespace asio {
 | 
|---|
| 15 | namespace bluetooth {
 | 
|---|
| 16 | 
 | 
|---|
| 17 | /**
 | 
|---|
| 18 |  * Describes an endpoint for a RFCOMM Bluetooth socket.
 | 
|---|
| 19 |  *
 | 
|---|
| 20 |  * @author Martin Florian <mflorian@lafka.net>
 | 
|---|
| 21 |  */
 | 
|---|
| 22 | template<typename BluetoothProtocol>
 | 
|---|
| 23 | class bluetooth_endpoint {
 | 
|---|
| 24 | private:
 | 
|---|
| 25 |         static bdaddr_t addr_any;
 | 
|---|
| 26 | 
 | 
|---|
| 27 | public:
 | 
|---|
| 28 |         /// The protocol type associated with the endpoint.
 | 
|---|
| 29 |         typedef BluetoothProtocol protocol_type;
 | 
|---|
| 30 | 
 | 
|---|
| 31 |         /// The type of the endpoint structure. This type is dependent on the
 | 
|---|
| 32 |         /// underlying implementation of the socket layer.
 | 
|---|
| 33 |         typedef boost::asio::detail::socket_addr_type data_type; // <-- Do I need this?
 | 
|---|
| 34 |         //typedef sockaddr_rc data_type;
 | 
|---|
| 35 | 
 | 
|---|
| 36 |         /// Default constructor.
 | 
|---|
| 37 |         bluetooth_endpoint() :
 | 
|---|
| 38 |                 data_() {
 | 
|---|
| 39 |                 data_.rc_family = AF_BLUETOOTH;
 | 
|---|
| 40 |                 data_.rc_bdaddr = addr_any;
 | 
|---|
| 41 |                 data_.rc_channel = (uint8_t) 0;
 | 
|---|
| 42 |         }
 | 
|---|
| 43 | 
 | 
|---|
| 44 |         bluetooth_endpoint(const BluetoothProtocol& protocol,
 | 
|---|
| 45 |                         unsigned short channel) :
 | 
|---|
| 46 |                 data_() {
 | 
|---|
| 47 |                 data_.rc_family = AF_BLUETOOTH;
 | 
|---|
| 48 |                 data_.rc_bdaddr = addr_any;
 | 
|---|
| 49 |                 data_.rc_channel = channel;
 | 
|---|
| 50 |         }
 | 
|---|
| 51 | 
 | 
|---|
| 52 |         /// Construct an endpoint using a port number, specified in the host's byte
 | 
|---|
| 53 |         /// order. The IP address will be the any address (i.e. INADDR_ANY or
 | 
|---|
| 54 |         /// in6addr_any). This constructor would typically be used for accepting new
 | 
|---|
| 55 |         /// connections.
 | 
|---|
| 56 |         bluetooth_endpoint(unsigned short channel) :
 | 
|---|
| 57 |                 data_() {
 | 
|---|
| 58 |                 data_.rc_family = AF_BLUETOOTH;
 | 
|---|
| 59 |                 data_.rc_bdaddr = *BDADDR_ANY;
 | 
|---|
| 60 |                 data_.rc_channel = channel;
 | 
|---|
| 61 |         }
 | 
|---|
| 62 | 
 | 
|---|
| 63 |         /// Construct an endpoint using a port number and an BT address.
 | 
|---|
| 64 |         /// The address is in human readable form as a string.
 | 
|---|
| 65 |         bluetooth_endpoint(const char *addr, unsigned short channel) :
 | 
|---|
| 66 |                 data_() {
 | 
|---|
| 67 |                 data_.rc_family = AF_BLUETOOTH;
 | 
|---|
| 68 |                 data_.rc_channel = channel;
 | 
|---|
| 69 |                 str2ba(addr, &data_.rc_bdaddr);
 | 
|---|
| 70 |         }
 | 
|---|
| 71 | 
 | 
|---|
| 72 |         /// Construct an endpoint using a port number and an BT address.
 | 
|---|
| 73 |         /// The address is given in the bluetooth-internal format.
 | 
|---|
| 74 |         bluetooth_endpoint(bdaddr_t addr, unsigned short channel) :
 | 
|---|
| 75 |                 data_() {
 | 
|---|
| 76 |                 data_.rc_family = AF_BLUETOOTH;
 | 
|---|
| 77 |                 data_.rc_channel = channel;
 | 
|---|
| 78 |                 data_.rc_bdaddr = addr;
 | 
|---|
| 79 |         }
 | 
|---|
| 80 | 
 | 
|---|
| 81 |         /// Copy constructor.
 | 
|---|
| 82 |         bluetooth_endpoint(const bluetooth_endpoint& other) :
 | 
|---|
| 83 |                 data_(other.data_) {
 | 
|---|
| 84 |         }
 | 
|---|
| 85 | 
 | 
|---|
| 86 |         /// Assign from another endpoint.
 | 
|---|
| 87 |         bluetooth_endpoint& operator=(const bluetooth_endpoint& other) {
 | 
|---|
| 88 |                 data_ = other.data_;
 | 
|---|
| 89 |                 return *this;
 | 
|---|
| 90 |         }
 | 
|---|
| 91 | 
 | 
|---|
| 92 |         /// The protocol associated with the endpoint.
 | 
|---|
| 93 |         protocol_type protocol() const {
 | 
|---|
| 94 |                 return protocol_type::get();
 | 
|---|
| 95 |         }
 | 
|---|
| 96 | 
 | 
|---|
| 97 |         /// Get the underlying endpoint in the native type.
 | 
|---|
| 98 |         /// TODO: make this nice and generic -> union like in tcp
 | 
|---|
| 99 |         data_type* data() {
 | 
|---|
| 100 |                 return (boost::asio::detail::socket_addr_type*) &data_;
 | 
|---|
| 101 |         }
 | 
|---|
| 102 | 
 | 
|---|
| 103 |         /// Get the underlying endpoint in the native type.
 | 
|---|
| 104 |         const data_type* data() const {
 | 
|---|
| 105 |                 return (boost::asio::detail::socket_addr_type*) &data_;
 | 
|---|
| 106 |         }
 | 
|---|
| 107 | 
 | 
|---|
| 108 |         /// Get the underlying size of the endpoint in the native type.
 | 
|---|
| 109 |         std::size_t size() const {
 | 
|---|
| 110 |                 return sizeof(data_type);
 | 
|---|
| 111 |         }
 | 
|---|
| 112 | 
 | 
|---|
| 113 |         /// Set the underlying size of the endpoint in the native type.
 | 
|---|
| 114 |         void resize(std::size_t size) {
 | 
|---|
| 115 |                 if (size > sizeof(data_type)) {
 | 
|---|
| 116 |                         boost::system::system_error e(boost::asio::error::invalid_argument);
 | 
|---|
| 117 |                         boost::throw_exception(e);
 | 
|---|
| 118 |                 }
 | 
|---|
| 119 |         }
 | 
|---|
| 120 | 
 | 
|---|
| 121 |         /// Get the capacity of the endpoint in the native type.
 | 
|---|
| 122 |         std::size_t capacity() const {
 | 
|---|
| 123 |                 return sizeof(data_type);
 | 
|---|
| 124 |         }
 | 
|---|
| 125 | 
 | 
|---|
| 126 |         /// Get the channel associated with the endpoint. The port number is always in
 | 
|---|
| 127 |         /// the host's byte order.
 | 
|---|
| 128 |         unsigned short channel() const {
 | 
|---|
| 129 |                 return data_.rc_channel;
 | 
|---|
| 130 |         }
 | 
|---|
| 131 | 
 | 
|---|
| 132 |         /// Set the channel associated with the endpoint. The port number is always in
 | 
|---|
| 133 |         /// the host's byte order.
 | 
|---|
| 134 |         void channel(unsigned short channel_num) {
 | 
|---|
| 135 |                 data_.rc_channel = channel_num;
 | 
|---|
| 136 |         }
 | 
|---|
| 137 | 
 | 
|---|
| 138 |         /// Get the Bluetooth address associated with the endpoint.
 | 
|---|
| 139 |         bdaddr_t address() const {
 | 
|---|
| 140 |                 return data_.rc_bdaddr;
 | 
|---|
| 141 |         }
 | 
|---|
| 142 | 
 | 
|---|
| 143 |         /// Set the Bluetooth address associated with the endpoint.
 | 
|---|
| 144 |         void address(const boost::asio::ip::address& addr) {
 | 
|---|
| 145 |                 bluetooth_endpoint<BluetoothProtocol> tmp_endpoint(addr, channel());
 | 
|---|
| 146 |                 data_ = tmp_endpoint.data_;
 | 
|---|
| 147 |         }
 | 
|---|
| 148 | 
 | 
|---|
| 149 |         /// Get the Bluetooth address in human readable form and write it to buf.
 | 
|---|
| 150 |         void address_hr(char &buf) {
 | 
|---|
| 151 |                 ba2str(&data_.rc_bdaddr, buf);
 | 
|---|
| 152 |         }
 | 
|---|
| 153 | 
 | 
|---|
| 154 |         /// Compare two endpoints for equality.
 | 
|---|
| 155 |         friend bool operator==(const bluetooth_endpoint& e1,
 | 
|---|
| 156 |                         const bluetooth_endpoint& e2) {
 | 
|---|
| 157 |                 return e1.address() == e2.address() && e1.channel() == e2.channel();
 | 
|---|
| 158 |         }
 | 
|---|
| 159 | 
 | 
|---|
| 160 |         /// Compare two endpoints for inequality.
 | 
|---|
| 161 |         friend bool operator!=(const bluetooth_endpoint& e1,
 | 
|---|
| 162 |                         const bluetooth_endpoint& e2) {
 | 
|---|
| 163 |                 return e1.address() != e2.address() || e1.channel() != e2.channel();
 | 
|---|
| 164 |         }
 | 
|---|
| 165 | 
 | 
|---|
| 166 |         /// Compare endpoints for ordering.
 | 
|---|
| 167 |         friend bool operator<(const bluetooth_endpoint<BluetoothProtocol>& e1,
 | 
|---|
| 168 |                         const bluetooth_endpoint<BluetoothProtocol>& e2) {
 | 
|---|
| 169 |                 if (e1.address() < e2.address()) return true;
 | 
|---|
| 170 |                 if (e1.address() != e2.address()) return false;
 | 
|---|
| 171 |                 return e1.channel() < e2.channel();
 | 
|---|
| 172 |         }
 | 
|---|
| 173 | 
 | 
|---|
| 174 | private:
 | 
|---|
| 175 |         // The underlying rfcomm socket address structure thingy.
 | 
|---|
| 176 |         //struct data_type data_;
 | 
|---|
| 177 |         struct sockaddr_rc data_;
 | 
|---|
| 178 | };
 | 
|---|
| 179 | 
 | 
|---|
| 180 | template<typename X>
 | 
|---|
| 181 | bdaddr_t bluetooth_endpoint<X>::addr_any = { {0u, 0u, 0u, 0u, 0u, 0u} };
 | 
|---|
| 182 | 
 | 
|---|
| 183 | }}} // namespace boost::asio::bluetooth
 | 
|---|
| 184 | 
 | 
|---|
| 185 | #endif
 | 
|---|
| 186 | #endif
 | 
|---|