aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoakim <elupus@ecce.se>2011-05-08 04:32:01 +0200
committerelupus <elupus@xbmc.org>2011-05-10 19:17:29 +0200
commit010f74a3b75a40dc4832e86bd8e22e3ca1f208d7 (patch)
tree2778145f44c2a5820b83427d2749e191f551cb3d
parent25cecfcdb5e494b011ea32967e3915f89087f147 (diff)
added: provide JSON-RPC server over bluetooth on linux aswell
-rw-r--r--configure.in1
-rw-r--r--xbmc/network/TCPServer.cpp116
-rw-r--r--xbmc/network/TCPServer.h1
3 files changed, 118 insertions, 0 deletions
diff --git a/configure.in b/configure.in
index 13804799f6..989e25e227 100644
--- a/configure.in
+++ b/configure.in
@@ -587,6 +587,7 @@ AC_CHECK_LIB([crypto], [main],, AC_MSG_ERROR($missing_library))
AC_CHECK_LIB([mysqlclient], [main],, AC_MSG_ERROR($missing_library))
AC_CHECK_LIB([ssh], [sftp_tell64],, AC_MSG_RESULT([Could not find suitable version of libssh]))
AC_CHECK_LIB([smbclient], [main],, AC_MSG_ERROR($missing_library))
+AC_CHECK_LIB([bluetooth], [hci_devid],, AC_MSG_RESULT([Could not find suitable version of libbluetooth]))
PKG_CHECK_MODULES([FONTCONFIG], [fontconfig],
[INCLUDES="$INCLUDES $FONTCONFIG_CFLAGS"; LIBS="$LIBS $FONTCONFIG_LIBS"],
AC_MSG_ERROR($missing_library))
diff --git a/xbmc/network/TCPServer.cpp b/xbmc/network/TCPServer.cpp
index 1091872c28..2a31f7b3f4 100644
--- a/xbmc/network/TCPServer.cpp
+++ b/xbmc/network/TCPServer.cpp
@@ -17,6 +17,12 @@ static const char bt_service_desc[] = "Interface for XBMC remote control ove
static const char bt_service_prov[] = "XBMC JSON-RPC Provider";
static const uint32_t bt_service_guid[] = {0x65AE4CC0, 0x775D11E0, 0xBE16CE28, 0x4824019B};
+#ifdef HAVE_LIBBLUETOOTH
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/rfcomm.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+#endif
using namespace JSONRPC;
using namespace ANNOUNCEMENT;
@@ -58,6 +64,7 @@ CTCPServer::CTCPServer(int port, bool nonlocal)
{
m_port = port;
m_nonlocal = nonlocal;
+ m_sdpd = NULL;
}
void CTCPServer::Process()
@@ -250,6 +257,108 @@ bool CTCPServer::InitializeBlue()
return true;
#endif
+
+#ifdef HAVE_LIBBLUETOOTH
+
+ SOCKET fd = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+ if(fd == INVALID_SOCKET)
+ {
+ CLog::Log(LOGINFO, "JSONRPC Server: Unable to get bluetooth socket");
+ return false;
+ }
+ struct sockaddr_rc sa = {0};
+ sa.rc_family = AF_BLUETOOTH;
+ sa.rc_bdaddr = *BDADDR_ANY;
+ sa.rc_channel = 0;
+
+ if(bind(fd, (struct sockaddr*)&sa, sizeof(sa)) < 0)
+ {
+ CLog::Log(LOGINFO, "JSONRPC Server: Unable to bind to bluetooth socket");
+ closesocket(fd);
+ return false;
+ }
+
+ socklen_t len = sizeof(sa);
+ if(getsockname(fd, (struct sockaddr*)&sa, &len) < 0)
+ CLog::Log(LOGERROR, "JSONRPC Server: Failed to get bluetooth port");
+
+ if (listen(fd, 10) < 0)
+ {
+ CLog::Log(LOGERROR, "JSONRPC Server: Failed to listen to bluetooth port %d", sa.rc_channel);
+ closesocket(fd);
+ return false;
+ }
+
+ m_servers.push_back(fd);
+
+ uint8_t rfcomm_channel = sa.rc_channel;
+
+ uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_uuid;
+ sdp_list_t *l2cap_list = 0,
+ *rfcomm_list = 0,
+ *root_list = 0,
+ *proto_list = 0,
+ *access_proto_list = 0,
+ *service_class = 0;
+
+ sdp_data_t *channel = 0;
+
+ sdp_record_t *record = sdp_record_alloc();
+
+ // set the general service ID
+ sdp_uuid128_create( &svc_uuid, &GUID_XBMC_RFCOMM );
+ sdp_set_service_id( record, svc_uuid );
+
+ // make the service record publicly browsable
+ sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
+ root_list = sdp_list_append(0, &root_uuid);
+ sdp_set_browse_groups( record, root_list );
+
+ // set l2cap information
+ sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
+ l2cap_list = sdp_list_append( 0, &l2cap_uuid );
+ proto_list = sdp_list_append( 0, l2cap_list );
+
+ // set rfcomm information
+ sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
+ channel = sdp_data_alloc(SDP_UINT8, &rfcomm_channel);
+ rfcomm_list = sdp_list_append( 0, &rfcomm_uuid );
+ sdp_list_append( rfcomm_list, channel );
+ sdp_list_append( proto_list, rfcomm_list );
+
+ // attach protocol information to service record
+ access_proto_list = sdp_list_append( 0, proto_list );
+ sdp_set_access_protos( record, access_proto_list );
+
+ // set the name, provider, and description
+ sdp_set_info_attr(record, bt_service_name, bt_service_prov, bt_service_desc);
+
+ // set the Service class ID
+ service_class = sdp_list_append(0, &svc_uuid);
+ sdp_set_service_classes( record, service_class);
+
+ // cleanup
+ sdp_data_free( channel );
+ sdp_list_free( l2cap_list, 0 );
+ sdp_list_free( rfcomm_list, 0 );
+ sdp_list_free( root_list, 0 );
+ sdp_list_free( access_proto_list, 0 );
+ sdp_list_free( service_class, 0 );
+
+ // connect to the local SDP server, register the service record
+ sdp_session_t *session = sdp_connect( BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY );
+ if(session == NULL)
+ CLog::Log(LOGERROR, "JSONRPC Server: Failed to connect to sdpd");
+ else
+ {
+ if(sdp_record_register(session, record, 0) < 0)
+ CLog::Log(LOGERROR, "JSONRPC Server: Failed to register record with error %d", errno);
+ sdp_record_free(record);
+ }
+ m_sdpd = session;
+
+ return true;
+#endif
return false;
}
@@ -303,6 +412,13 @@ void CTCPServer::Deinitialize()
closesocket(m_servers[i]);
m_servers.clear();
+
+#ifdef HAVE_LIBBLUETOOTH
+ if(m_sdpd)
+ sdp_close( (sdp_session_t*)m_sdpd );
+ m_sdpd = NULL;
+#endif
+
CAnnouncementManager::RemoveAnnouncer(this);
}
diff --git a/xbmc/network/TCPServer.h b/xbmc/network/TCPServer.h
index cb617f9b93..d58157767c 100644
--- a/xbmc/network/TCPServer.h
+++ b/xbmc/network/TCPServer.h
@@ -60,6 +60,7 @@ namespace JSONRPC
std::vector<SOCKET> m_servers;
int m_port;
bool m_nonlocal;
+ void* m_sdpd;
static CTCPServer *ServerInstance;
};