An Overlay-based
Virtual Network Substrate
SpoVNet

source: source/ariba/utility/transport/rfcomm/bluetooth_endpoint.hpp @ 10653

Last change on this file since 10653 was 10653, checked in by Michael Tänzer, 7 years ago

Merge the ASIO branch back into trunk

File size: 5.3 KB
Line 
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
14namespace boost {
15namespace asio {
16namespace bluetooth {
17
18/**
19 * Describes an endpoint for a RFCOMM Bluetooth socket.
20 *
21 * @author Martin Florian <mflorian@lafka.net>
22 */
23template<typename BluetoothProtocol>
24class bluetooth_endpoint {
25private:
26        static const bdaddr_t addr_any;
27
28public:
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
183private:
184        // The underlying rfcomm socket address structure thingy.
185        //struct data_type data_;
186        struct sockaddr_rc data_;
187};
188
189template<typename X>
190const bdaddr_t bluetooth_endpoint<X>::addr_any = { {0u, 0u, 0u, 0u, 0u, 0u} };
191
192}}} // namespace boost::asio::bluetooth
193
194#endif /* HAVE_LIBBLUETOOTH */
195#endif /* BOOST_ASIO_BLUETOOTH_BLUETOOTH_ENDPOINT_HPP__ */
Note: See TracBrowser for help on using the repository browser.