5 #include <netinet/in.h>
8 #include "settings/AdvancedSettings.h"
9 #include "interfaces/json-rpc/JSONRPC.h"
10 #include "interfaces/AnnouncementManager.h"
11 #include "utils/log.h"
12 #include "utils/Variant.h"
13 #include "threads/SingleLock.h"
15 static const char bt_service_name[] = "XBMC JSON-RPC";
16 static const char bt_service_desc[] = "Interface for XBMC remote control over bluetooth";
17 static const char bt_service_prov[] = "XBMC JSON-RPC Provider";
18 static const uint32_t bt_service_guid[] = {0x65AE4CC0, 0x775D11E0, 0xBE16CE28, 0x4824019B};
20 #ifdef HAVE_LIBBLUETOOTH
21 #include <bluetooth/bluetooth.h>
22 #include <bluetooth/rfcomm.h>
23 #include <bluetooth/sdp.h>
24 #include <bluetooth/sdp_lib.h>
26 /* The defines BDADDR_ANY and BDADDR_LOCAL are broken so use our own structs */
27 static const bdaddr_t bt_bdaddr_any = {{0, 0, 0, 0, 0, 0}};
28 static const bdaddr_t bt_bdaddr_local = {{0, 0, 0, 0xff, 0xff, 0xff}};
32 using namespace JSONRPC;
33 using namespace ANNOUNCEMENT;
34 //using namespace std; On VS2010, bind conflicts with std::bind
36 #define RECEIVEBUFFER 1024
38 CTCPServer *CTCPServer::ServerInstance = NULL;
40 bool CTCPServer::StartServer(int port, bool nonlocal)
44 ServerInstance = new CTCPServer(port, nonlocal);
45 if (ServerInstance->Initialize())
47 ServerInstance->Create();
54 void CTCPServer::StopServer(bool bWait)
58 ServerInstance->StopThread(bWait);
61 delete ServerInstance;
62 ServerInstance = NULL;
67 CTCPServer::CTCPServer(int port, bool nonlocal)
70 m_nonlocal = nonlocal;
74 void CTCPServer::Process()
82 struct timeval to = {1, 0};
85 for (std::vector<SOCKET>::iterator it = m_servers.begin(); it != m_servers.end(); it++)
88 if ((intptr_t)*it > (intptr_t)max_fd)
92 for (unsigned int i = 0; i < m_connections.size(); i++)
94 FD_SET(m_connections[i].m_socket, &rfds);
95 if ((intptr_t)m_connections[i].m_socket > (intptr_t)max_fd)
96 max_fd = m_connections[i].m_socket;
99 int res = select((intptr_t)max_fd+1, &rfds, NULL, NULL, &to);
102 CLog::Log(LOGERROR, "JSONRPC Server: Select failed");
108 for (int i = m_connections.size() - 1; i >= 0; i--)
110 int socket = m_connections[i].m_socket;
111 if (FD_ISSET(socket, &rfds))
113 char buffer[RECEIVEBUFFER] = {};
115 nread = recv(socket, (char*)&buffer, RECEIVEBUFFER, 0);
118 m_connections[i].PushBuffer(this, buffer, nread);
122 CLog::Log(LOGINFO, "JSONRPC Server: Disconnection detected");
123 m_connections[i].Disconnect();
124 m_connections.erase(m_connections.begin() + i);
129 for (std::vector<SOCKET>::iterator it = m_servers.begin(); it != m_servers.end(); it++)
131 if (FD_ISSET(*it, &rfds))
133 CLog::Log(LOGDEBUG, "JSONRPC Server: New connection detected");
134 CTCPClient newconnection;
135 newconnection.m_socket = accept(*it, (sockaddr*)&newconnection.m_cliaddr, &newconnection.m_addrlen);
137 if (newconnection.m_socket == INVALID_SOCKET)
138 CLog::Log(LOGERROR, "JSONRPC Server: Accept of new connection failed");
141 CLog::Log(LOGINFO, "JSONRPC Server: New connection added");
142 m_connections.push_back(newconnection);
152 bool CTCPServer::Download(const char *path, CVariant &result)
157 int CTCPServer::GetCapabilities()
159 return Response | Announcing;
162 void CTCPServer::Announce(EAnnouncementFlag flag, const char *sender, const char *message, const CVariant &data)
164 std::string str = AnnouncementToJSON(flag, sender, message, data, g_advancedSettings.m_jsonOutputCompact);
166 for (unsigned int i = 0; i < m_connections.size(); i++)
169 CSingleLock lock (m_connections[i].m_critSection);
170 if ((m_connections[i].GetAnnouncementFlags() & flag) == 0)
174 unsigned int sent = 0;
177 CSingleLock lock (m_connections[i].m_critSection);
178 sent += send(m_connections[i].m_socket, str.c_str(), str.size() - sent, sent);
179 } while (sent < str.size());
183 bool CTCPServer::Initialize()
187 bool started = false;
189 started |= InitializeBlue();
190 started |= InitializeTCP();
194 CAnnouncementManager::AddAnnouncer(this);
195 CLog::Log(LOGINFO, "JSONRPC Server: Successfully initialized");
201 bool CTCPServer::InitializeBlue()
208 SOCKET fd = socket (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
209 if(fd == INVALID_SOCKET)
211 CLog::Log(LOGINFO, "JSONRPC Server: Unable to get bluetooth socket");
214 SOCKADDR_BTH sa = {};
215 sa.addressFamily = AF_BTH;
216 sa.port = BT_PORT_ANY;
218 if(bind(fd, (SOCKADDR*)&sa, sizeof(sa)) < 0)
220 CLog::Log(LOGINFO, "JSONRPC Server: Unable to bind to bluetooth socket");
226 if(setsockopt(fd, SOL_RFCOMM, SO_BTH_AUTHENTICATE, (const char*)&optval, sizeof(optval)) == SOCKET_ERROR)
228 CLog::Log(LOGERROR, "JSONRPC Server: Failed to force authentication for bluetooth socket");
233 int len = sizeof(sa);
234 if(getsockname(fd, (SOCKADDR*)&sa, &len) < 0)
235 CLog::Log(LOGERROR, "JSONRPC Server: Failed to get bluetooth port");
237 if (listen(fd, 10) < 0)
239 CLog::Log(LOGERROR, "JSONRPC Server: Failed to listen to bluetooth port");
244 m_servers.push_back(fd);
246 CSADDR_INFO addrinfo;
247 addrinfo.iProtocol = BTHPROTO_RFCOMM;
248 addrinfo.iSocketType = SOCK_STREAM;
249 addrinfo.LocalAddr.lpSockaddr = (SOCKADDR*)&sa;
250 addrinfo.LocalAddr.iSockaddrLength = sizeof(sa);
251 addrinfo.RemoteAddr.lpSockaddr = (SOCKADDR*)&sa;
252 addrinfo.RemoteAddr.iSockaddrLength = sizeof(sa);
254 WSAQUERYSET service = {};
255 service.dwSize = sizeof(service);
256 service.lpszServiceInstanceName = (LPSTR)bt_service_name;
257 service.lpServiceClassId = (LPGUID)&bt_service_guid;
258 service.lpszComment = (LPSTR)bt_service_desc;
259 service.dwNameSpace = NS_BTH;
260 service.lpNSProviderId = NULL; /* RFCOMM? */
261 service.lpcsaBuffer = &addrinfo;
262 service.dwNumberOfCsAddrs = 1;
264 if(WSASetService(&service, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR)
265 CLog::Log(LOGERROR, "JSONRPC Server: failed to register bluetooth service error %d", WSAGetLastError());
270 #ifdef HAVE_LIBBLUETOOTH
272 SOCKET fd = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
273 if(fd == INVALID_SOCKET)
275 CLog::Log(LOGINFO, "JSONRPC Server: Unable to get bluetooth socket");
278 struct sockaddr_rc sa = {0};
279 sa.rc_family = AF_BLUETOOTH;
280 sa.rc_bdaddr = bt_bdaddr_any;
283 if(bind(fd, (struct sockaddr*)&sa, sizeof(sa)) < 0)
285 CLog::Log(LOGINFO, "JSONRPC Server: Unable to bind to bluetooth socket");
290 socklen_t len = sizeof(sa);
291 if(getsockname(fd, (struct sockaddr*)&sa, &len) < 0)
292 CLog::Log(LOGERROR, "JSONRPC Server: Failed to get bluetooth port");
294 if (listen(fd, 10) < 0)
296 CLog::Log(LOGERROR, "JSONRPC Server: Failed to listen to bluetooth port %d", sa.rc_channel);
301 uint8_t rfcomm_channel = sa.rc_channel;
303 uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_uuid;
304 sdp_list_t *l2cap_list = 0,
308 *access_proto_list = 0,
311 sdp_data_t *channel = 0;
313 sdp_record_t *record = sdp_record_alloc();
315 // set the general service ID
316 sdp_uuid128_create( &svc_uuid, &bt_service_guid );
317 sdp_set_service_id( record, svc_uuid );
319 // make the service record publicly browsable
320 sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
321 root_list = sdp_list_append(0, &root_uuid);
322 sdp_set_browse_groups( record, root_list );
324 // set l2cap information
325 sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
326 l2cap_list = sdp_list_append( 0, &l2cap_uuid );
327 proto_list = sdp_list_append( 0, l2cap_list );
329 // set rfcomm information
330 sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
331 channel = sdp_data_alloc(SDP_UINT8, &rfcomm_channel);
332 rfcomm_list = sdp_list_append( 0, &rfcomm_uuid );
333 sdp_list_append( rfcomm_list, channel );
334 sdp_list_append( proto_list, rfcomm_list );
336 // attach protocol information to service record
337 access_proto_list = sdp_list_append( 0, proto_list );
338 sdp_set_access_protos( record, access_proto_list );
340 // set the name, provider, and description
341 sdp_set_info_attr(record, bt_service_name, bt_service_prov, bt_service_desc);
343 // set the Service class ID
344 service_class = sdp_list_append(0, &svc_uuid);
345 sdp_set_service_classes( record, service_class);
348 sdp_data_free( channel );
349 sdp_list_free( l2cap_list, 0 );
350 sdp_list_free( rfcomm_list, 0 );
351 sdp_list_free( root_list, 0 );
352 sdp_list_free( access_proto_list, 0 );
353 sdp_list_free( service_class, 0 );
355 // connect to the local SDP server, register the service record
356 sdp_session_t *session = sdp_connect( &bt_bdaddr_any, &bt_bdaddr_local, SDP_RETRY_IF_BUSY );
359 CLog::Log(LOGERROR, "JSONRPC Server: Failed to connect to sdpd");
361 sdp_record_free(record);
365 if(sdp_record_register(session, record, 0) < 0)
367 CLog::Log(LOGERROR, "JSONRPC Server: Failed to register record with error %d", errno);
370 sdp_record_free(record);
375 m_servers.push_back(fd);
382 bool CTCPServer::InitializeTCP()
385 struct sockaddr_in myaddr;
386 memset(&myaddr, 0, sizeof(myaddr));
388 myaddr.sin_family = AF_INET;
389 myaddr.sin_port = htons(m_port);
392 myaddr.sin_addr.s_addr = INADDR_ANY;
394 inet_pton(AF_INET, "127.0.0.1", &myaddr.sin_addr.s_addr);
396 SOCKET fd = socket(PF_INET, SOCK_STREAM, 0);
398 if (fd == INVALID_SOCKET)
400 CLog::Log(LOGERROR, "JSONRPC Server: Failed to create serversocket");
404 if (bind(fd, (struct sockaddr*)&myaddr, sizeof myaddr) < 0)
406 CLog::Log(LOGERROR, "JSONRPC Server: Failed to bind serversocket");
411 if (listen(fd, 10) < 0)
413 CLog::Log(LOGERROR, "JSONRPC Server: Failed to set listen");
417 m_servers.push_back(fd);
421 void CTCPServer::Deinitialize()
423 for (unsigned int i = 0; i < m_connections.size(); i++)
424 m_connections[i].Disconnect();
426 m_connections.clear();
428 for (unsigned int i = 0; i < m_servers.size(); i++)
429 closesocket(m_servers[i]);
433 #ifdef HAVE_LIBBLUETOOTH
435 sdp_close( (sdp_session_t*)m_sdpd );
439 CAnnouncementManager::RemoveAnnouncer(this);
442 CTCPServer::CTCPClient::CTCPClient()
444 m_announcementflags = ANNOUNCE_ALL;
445 m_socket = INVALID_SOCKET;
451 m_addrlen = sizeof(m_cliaddr);
454 CTCPServer::CTCPClient::CTCPClient(const CTCPClient& client)
459 CTCPServer::CTCPClient& CTCPServer::CTCPClient::operator=(const CTCPClient& client)
465 int CTCPServer::CTCPClient::GetPermissionFlags()
467 return OPERATION_PERMISSION_ALL;
470 int CTCPServer::CTCPClient::GetAnnouncementFlags()
472 return m_announcementflags;
475 bool CTCPServer::CTCPClient::SetAnnouncementFlags(int flags)
477 m_announcementflags = flags;
481 void CTCPServer::CTCPClient::PushBuffer(CTCPServer *host, const char *buffer, int length)
483 for (int i = 0; i < length; i++)
487 if (m_beginChar == 0 && c == '{')
492 else if (m_beginChar == 0 && c == '[')
498 if (m_beginChar != 0)
500 m_buffer.push_back(c);
501 if (c == m_beginChar)
503 else if (c == m_endChar)
505 if (m_beginBrackets > 0 && m_endBrackets > 0 && m_beginBrackets == m_endBrackets)
507 std::string line = CJSONRPC::MethodCall(m_buffer, host, this);
508 CSingleLock lock (m_critSection);
509 send(m_socket, line.c_str(), line.size(), 0);
510 m_beginChar = m_beginBrackets = m_endBrackets = 0;
517 void CTCPServer::CTCPClient::Disconnect()
521 CSingleLock lock (m_critSection);
522 shutdown(m_socket, SHUT_RDWR);
523 closesocket(m_socket);
524 m_socket = INVALID_SOCKET;
528 void CTCPServer::CTCPClient::Copy(const CTCPClient& client)
530 m_socket = client.m_socket;
531 m_cliaddr = client.m_cliaddr;
532 m_addrlen = client.m_addrlen;
533 m_announcementflags = client.m_announcementflags;
534 m_beginBrackets = client.m_beginBrackets;
535 m_endBrackets = client.m_endBrackets;
536 m_beginChar = client.m_beginChar;
537 m_endChar = client.m_endChar;
538 m_buffer = client.m_buffer;