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