Expand Up
@@ -46,6 +46,11 @@ typedef int socklen_t;
typedef int socket_t ;
#endif
#if USE_BLUETOOTH
#include < bluetooth/bluetooth.h>
#include < bluetooth/rfcomm.h>
#endif
#include " constants.h"
#include " debug.h"
#include " settings.h"
Expand All
@@ -59,6 +64,7 @@ typedef int socket_t;
#include < iomanip>
#include " util/string.h"
#include " util/numeric.h"
#include " config.h"
// Set to true to enable verbose debug output
bool socket_enable_debug_output = false ;
Expand Down
Expand Up
@@ -110,13 +116,22 @@ Address::Address(u8 a, u8 b, u8 c, u8 d, u16 port)
setPort (port);
}
Address::Address (const IPv6AddressBytes * ipv6_bytes, u16 port)
Address::Address (const IPv6AddressBytes *ipv6_bytes, u16 port)
{
memset (&m_address, 0 , sizeof (m_address));
setAddress (ipv6_bytes);
setPort (port);
}
#if USE_BLUETOOTH
Address::Address (const BluetoothAddressBytes *bt_bytes, u16 port)
{
memset (&m_address, 0 , sizeof (m_address));
setAddress (bt_bytes);
setPort (port);
}
#endif
// Equality (address family, address and port must be equal)
bool Address::operator ==(Address &address)
{
Expand All
@@ -132,6 +147,13 @@ bool Address::operator==(Address &address)
return memcmp (m_address.ipv6 .sin6_addr .s6_addr ,
address.m_address .ipv6 .sin6_addr .s6_addr , 16 ) == 0 ;
}
#if USE_BLUETOOTH
else if (m_addr_family == AF_BLUETOOTH)
{
return memcmp (m_address.bluetooth .rc_bdaddr ,
address.bluetooth .rc_bdaddr , 6 ) == 0 ;
}
#endif
else
return false ;
}
Expand All
@@ -143,6 +165,11 @@ bool Address::operator!=(Address &address)
void Address::Resolve (const char *name)
{
#if USE_BLUETOOTH
if (m_addr_family == AF_BLUETOOTH) {
throw ResolveError (" Bluetooth does not support name resolving" );
}
#endif
if (!name || name[0 ] == 0 ) {
if (m_addr_family == AF_INET) {
setAddress ((u32) 0 );
Expand Down
Expand Up
@@ -225,14 +252,34 @@ std::string Address::serializeString() const
}
return os.str ();
}
#if USE_BLUETOOTH
else if (m_addr_family == AF_BLUETOOTH)
{
char dest[18 ];
ba2str (&m_address.bluetooth .rc_bdaddr , dest);
return std::string (dest);
}
#endif
else
return std::string (" " );
#else
char str[INET6_ADDRSTRLEN];
if (inet_ntop (m_addr_family, (m_addr_family == AF_INET) ? (void *)&(m_address.ipv4 .sin_addr ) : (void *)&(m_address.ipv6 .sin6_addr ), str, INET6_ADDRSTRLEN) == NULL ) {
return std::string (" " );
if (m_addr_family == AF_INET || m_addr_family == AF_INET6) {
char str[INET6_ADDRSTRLEN];
if (inet_ntop (m_addr_family, (m_addr_family == AF_INET) ? (void *)&(m_address.ipv4 .sin_addr ) : (void *)&(m_address.ipv6 .sin6_addr ), str, INET6_ADDRSTRLEN) == NULL ) {
return std::string (" " );
}
return std::string (str);
}
#if USE_BLUETOOTH
else if (m_addr_family == AF_BLUETOOTH)
{
char dest[18 ];
ba2str (&m_address.bluetooth .rc_bdaddr , dest);
return std::string (dest);
}
return std::string (str);
#endif
else
return std::string (" " );
#endif
}
Expand All
@@ -246,6 +293,13 @@ struct sockaddr_in6 Address::getAddress6() const
return m_address.ipv6 ; // NOTE: NO PORT INCLUDED, use getPort()
}
#if USE_BLUETOOTH
struct sockaddr_rc Address::getAddressBt () const
{
return m_address.bluetooth ;
}
#endif
u16 Address::getPort () const
{
return m_port;
Expand All
@@ -270,6 +324,13 @@ bool Address::isZero() const
return memcmp (m_address.ipv6 .sin6_addr .s6_addr ,
zero, 16 ) == 0 ;
}
#if USE_BLUETOOTH
else if (m_addr_family == AF_BLUETOOTH) {
static const char zero[6 ] = {0 };
return memcmp (m_address.bluetooth .rc_bdaddr ,
zero, 6 ) == 0 ;
}
#endif
return false ;
}
Expand All
@@ -288,7 +349,7 @@ void Address::setAddress(u8 a, u8 b, u8 c, u8 d)
m_address.ipv4 .sin_addr .s_addr = addr;
}
void Address::setAddress (const IPv6AddressBytes * ipv6_bytes)
void Address::setAddress (const IPv6AddressBytes *ipv6_bytes)
{
m_addr_family = AF_INET6;
m_address.ipv6 .sin6_family = AF_INET6;
Expand All
@@ -298,9 +359,29 @@ void Address::setAddress(const IPv6AddressBytes * ipv6_bytes)
memset (m_address.ipv6 .sin6_addr .s6_addr , 0 , 16 );
}
#if USE_BLUETOOTH
void Address::setAddress (const BluetoothAddressBytes *bt_bytes)
{
m_addr_family = AF_BLUETOOTH;
m_address.bluetooth .rc_family = AF_BLUETOOTH;
m_address.bluetooth .rc_channel = 1 ;
if (bt_bytes)
memcpy (m_address.bluetooth .rc_bdaddr , bt_bytes->bytes , 6 );
else
memset (m_address.bluetooth .rc_bdaddr , 0 , 6 );
}
#endif
void Address::setPort (u16 port)
{
m_port = port;
if (m_addr_family == AF_INET || m_addr_family == AF_INET6)
m_port = port;
#if USE_BLUETOOTH
else if (m_addr_family == AF_BLUETOOTH) {
m_port = port % 0xff ;
m_address.bluetooth .rc_channel = port % 0xff ;
}
#endif
}
void Address::print (std::ostream *s) const
Expand All
@@ -309,30 +390,43 @@ void Address::print(std::ostream *s) const
{
(*s) << " [" << serializeString () << " ]:" << m_port;
}
else
else if (m_addr_family == AF_INET)
{
(*s) << serializeString () << " :" << m_port;
}
#if USE_BLUETOOTH
else if (m_addr_family == AF_BLUETOOTH)
{
(*s) << " [" << serializeString () << " ]:" << m_port;
}
#endif
}
/*
UDPSocket
*/
UDPSocket::UDPSocket (bool ipv6 )
UDPSocket::UDPSocket (int addr_family )
{
if (g_sockets_initialized == false )
throw SocketException (" Sockets not initialized" );
// Use IPv6 if specified
m_addr_family = ipv6 ? AF_INET6 : AF_INET;
m_handle = socket (m_addr_family, SOCK_DGRAM, IPPROTO_UDP);
m_addr_family = addr_family;
if (m_addr_family == AF_INET || m_addr_family == AF_INET6)
m_handle = socket (m_addr_family, SOCK_DGRAM, IPPROTO_UDP);
#if USE_BLUETOOTH
else if (m_addr_family == AF_BLUETOOTH)
m_handle = socket (m_addr_family, SOCK_STREAM, BTPROTO_RFCOMM);
#endif
else
throw SocketException (" Unknown address family" );
if (socket_enable_debug_output)
{
dstream << " UDPSocket(" << (int ) m_handle
<< " )::UDPSocket(): ipv6 = "
<< (ipv6 ? " true " : " false " )
<< " )::UDPSocket(): addr_family = "
<< m_addr_family
<< std::endl;
}
Expand All
@@ -342,6 +436,9 @@ UDPSocket::UDPSocket(bool ipv6)
}
setTimeoutMs (0 );
#if USE_BLUETOOTH
bt_init_done = false ;
#endif
}
UDPSocket::~UDPSocket ()
Expand All
@@ -363,9 +460,9 @@ void UDPSocket::Bind(Address addr)
{
if (socket_enable_debug_output)
{
dstream << " UDPSocket(" << (int ) m_handle << " )::Bind(): "
<< addr.serializeString () << " : "
<< addr. getPort () << std::endl;
dstream << " UDPSocket(" << (int ) m_handle << " )::Bind(): " ;
addr.print (dstream);
dstream << std::endl;
}
if (addr.getFamily () != m_addr_family)
Expand All
@@ -392,7 +489,7 @@ void UDPSocket::Bind(Address addr)
throw SocketException (" Failed to bind socket" );
}
}
else
else if (m_addr_family == AF_INET)
{
struct sockaddr_in address;
memset (&address, 0 , sizeof (address));
Expand All
@@ -409,10 +506,39 @@ void UDPSocket::Bind(Address addr)
throw SocketException (" Failed to bind socket" );
}
}
#if USE_BLUETOOTH
else if (m_addr_family == AF_BLUETOOTH)
{
btaddr = addr.getAddressBt ();
// We do not do anything here yet
// because we do not yet know whether this is
// a server socket or client socket
}
#endif
else
throw SocketException (" Unknown address family" );
}
#if USE_BLUETOOTH
void UDPSocket::bt_do_clientinit ()
{
// This method is called if the Send or Recv method is called first
if (connect (m_handle, (const struct sockaddr *) &btaddr, sizeof (btaddr)) < 0 ) {
dstream << (int ) m_handle << " : Connect failed: "
<< strerror (errno) << std::endl;
throw SocketException (" Failed to bind socket" );
}
bt_init_done = true ;
}
#endif
void UDPSocket::Send (const Address & destination, const void * data, int size)
{
#if USE_BLUETOOTH
if (m_addr_family == AF_BLUETOOTH && !bt_init_done)
bt_do_clientinit ();
#endif
bool dumping_packet = false ; // for INTERNET_SIMULATOR
if (INTERNET_SIMULATOR)
Expand Down
Expand Up
@@ -465,7 +591,7 @@ void UDPSocket::Send(const Address & destination, const void * data, int size)
sent = sendto (m_handle, (const char *) data, size,
0 , (struct sockaddr *) &address, sizeof (struct sockaddr_in6 ));
}
else
else if (m_addr_family == AF_INET6)
{
struct sockaddr_in address = destination.getAddress ();
address.sin_port = htons (destination.getPort ());
Expand All
@@ -481,6 +607,10 @@ void UDPSocket::Send(const Address & destination, const void * data, int size)
int UDPSocket::Receive (Address & sender, void * data, int size)
{
#if USE_BLUETOOTH
if (m_addr_family == AF_BLUETOOTH && !bt_init_done)
bt_do_clientinit ();
#endif
// Return on timeout
if (WaitData (m_timeout_ms) == false )
{
Expand Down
Expand Up
@@ -562,6 +692,16 @@ void UDPSocket::setTimeoutMs(int timeout_ms)
bool UDPSocket::WaitData (int timeout_ms)
{
#if USE_BLUETOOTH
if (m_addr_family == AF_BLUETOOTH && !bt_init_done) {
// Server socket
// Bind it to the address and put it into listen mode
bind (m_handle, (const struct sockaddr *) &btaddr, sizeof (btaddr));
listen (m_handle, 1 );
// TODO: need to make a seperate thread to listen to the socket, accept connections
// TODO: then need to make this functions select() all sockets
}
#endif
fd_set readset;
int result;
Expand Down