Merge pull request #473 from Montellese/onplaybackspeedchanged
[vuplus_xbmc] / xbmc / network / TCPServer.cpp
1 /*
2  *      Copyright (C) 2005-2011 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 #include "TCPServer.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <memory.h>
26 #include <netinet/in.h>
27 #include <arpa/inet.h>
28
29 #include "settings/AdvancedSettings.h"
30 #include "interfaces/json-rpc/JSONRPC.h"
31 #include "interfaces/AnnouncementManager.h"
32 #include "utils/log.h"
33 #include "utils/Variant.h"
34 #include "threads/SingleLock.h"
35
36 static const char     bt_service_name[] = "XBMC JSON-RPC";
37 static const char     bt_service_desc[] = "Interface for XBMC remote control over bluetooth";
38 static const char     bt_service_prov[] = "XBMC JSON-RPC Provider";
39 static const uint32_t bt_service_guid[] = {0x65AE4CC0, 0x775D11E0, 0xBE16CE28, 0x4824019B};
40
41 #ifdef HAVE_LIBBLUETOOTH
42 #include <bluetooth/bluetooth.h>
43 #include <bluetooth/rfcomm.h>
44 #include <bluetooth/sdp.h>
45 #include <bluetooth/sdp_lib.h>
46
47  /* The defines BDADDR_ANY and BDADDR_LOCAL are broken so use our own structs */
48 static const bdaddr_t bt_bdaddr_any   = {{0, 0, 0, 0, 0, 0}};
49 static const bdaddr_t bt_bdaddr_local = {{0, 0, 0, 0xff, 0xff, 0xff}};
50
51 #endif
52
53 using namespace JSONRPC;
54 using namespace ANNOUNCEMENT;
55 //using namespace std; On VS2010, bind conflicts with std::bind
56
57 #define RECEIVEBUFFER 1024
58
59 CTCPServer *CTCPServer::ServerInstance = NULL;
60
61 bool CTCPServer::StartServer(int port, bool nonlocal)
62 {
63   StopServer(true);
64
65   ServerInstance = new CTCPServer(port, nonlocal);
66   if (ServerInstance->Initialize())
67   {
68     ServerInstance->Create();
69     return true;
70   }
71   else
72     return false;
73 }
74
75 void CTCPServer::StopServer(bool bWait)
76 {
77   if (ServerInstance)
78   {
79     ServerInstance->StopThread(bWait);
80     if (bWait)
81     {
82       delete ServerInstance;
83       ServerInstance = NULL;
84     }
85   }
86 }
87
88 CTCPServer::CTCPServer(int port, bool nonlocal)
89 {
90   m_port = port;
91   m_nonlocal = nonlocal;
92   m_sdpd = NULL;
93 }
94
95 void CTCPServer::Process()
96 {
97   m_bStop = false;
98
99   while (!m_bStop)
100   {
101     SOCKET          max_fd = 0;
102     fd_set          rfds;
103     struct timeval  to     = {1, 0};
104     FD_ZERO(&rfds);
105
106     for (std::vector<SOCKET>::iterator it = m_servers.begin(); it != m_servers.end(); it++)
107     {
108       FD_SET(*it, &rfds);
109       if ((intptr_t)*it > (intptr_t)max_fd)
110         max_fd = *it;
111     }
112
113     for (unsigned int i = 0; i < m_connections.size(); i++)
114     {
115       FD_SET(m_connections[i].m_socket, &rfds);
116       if ((intptr_t)m_connections[i].m_socket > (intptr_t)max_fd)
117         max_fd = m_connections[i].m_socket;
118     }
119
120     int res = select((intptr_t)max_fd+1, &rfds, NULL, NULL, &to);
121     if (res < 0)
122     {
123       CLog::Log(LOGERROR, "JSONRPC Server: Select failed");
124       Sleep(1000);
125       Initialize();
126     }
127     else if (res > 0)
128     {
129       for (int i = m_connections.size() - 1; i >= 0; i--)
130       {
131         int socket = m_connections[i].m_socket;
132         if (FD_ISSET(socket, &rfds))
133         {
134           char buffer[RECEIVEBUFFER] = {};
135           int  nread = 0;
136           nread = recv(socket, (char*)&buffer, RECEIVEBUFFER, 0);
137           if (nread > 0)
138           {
139             m_connections[i].PushBuffer(this, buffer, nread);
140           }
141           if (nread <= 0)
142           {
143             CLog::Log(LOGINFO, "JSONRPC Server: Disconnection detected");
144             m_connections[i].Disconnect();
145             m_connections.erase(m_connections.begin() + i);
146           }
147         }
148       }
149
150       for (std::vector<SOCKET>::iterator it = m_servers.begin(); it != m_servers.end(); it++)
151       {
152         if (FD_ISSET(*it, &rfds))
153         {
154           CLog::Log(LOGDEBUG, "JSONRPC Server: New connection detected");
155           CTCPClient newconnection;
156           newconnection.m_socket = accept(*it, (sockaddr*)&newconnection.m_cliaddr, &newconnection.m_addrlen);
157
158           if (newconnection.m_socket == INVALID_SOCKET)
159             CLog::Log(LOGERROR, "JSONRPC Server: Accept of new connection failed");
160           else
161           {
162             CLog::Log(LOGINFO, "JSONRPC Server: New connection added");
163             m_connections.push_back(newconnection);
164           }
165         }
166       }
167     }
168   }
169
170   Deinitialize();
171 }
172
173 bool CTCPServer::Download(const char *path, CVariant &result)
174 {
175   return false;
176 }
177
178 int CTCPServer::GetCapabilities()
179 {
180   return Response | Announcing;
181 }
182
183 void CTCPServer::Announce(EAnnouncementFlag flag, const char *sender, const char *message, const CVariant &data)
184 {
185   std::string str = AnnouncementToJSON(flag, sender, message, data, g_advancedSettings.m_jsonOutputCompact);
186
187   for (unsigned int i = 0; i < m_connections.size(); i++)
188   {
189     {
190       CSingleLock lock (m_connections[i].m_critSection);
191       if ((m_connections[i].GetAnnouncementFlags() & flag) == 0)
192         continue;
193     }
194
195     unsigned int sent = 0;
196     do
197     {
198       CSingleLock lock (m_connections[i].m_critSection);
199       sent += send(m_connections[i].m_socket, str.c_str(), str.size() - sent, sent);
200     } while (sent < str.size());
201   }
202 }
203
204 bool CTCPServer::Initialize()
205 {
206   Deinitialize();
207
208   bool started = false;
209
210   started |= InitializeBlue();
211   started |= InitializeTCP();
212
213   if(started)
214   {
215     CAnnouncementManager::AddAnnouncer(this);
216     CLog::Log(LOGINFO, "JSONRPC Server: Successfully initialized");
217     return true;
218   }
219   return false;
220 }
221
222 bool CTCPServer::InitializeBlue()
223 {
224   if(!m_nonlocal)
225     return false;
226
227 #ifdef _WIN32
228
229   SOCKET fd = socket (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
230   if(fd == INVALID_SOCKET)
231   {
232     CLog::Log(LOGINFO, "JSONRPC Server: Unable to get bluetooth socket");
233     return false;
234   }
235   SOCKADDR_BTH sa  = {};
236   sa.addressFamily = AF_BTH;
237   sa.port          = BT_PORT_ANY;
238
239   if(bind(fd, (SOCKADDR*)&sa, sizeof(sa)) < 0)
240   {
241     CLog::Log(LOGINFO, "JSONRPC Server: Unable to bind to bluetooth socket");
242     closesocket(fd);
243     return false;
244   }
245
246   ULONG optval = TRUE;
247   if(setsockopt(fd, SOL_RFCOMM, SO_BTH_AUTHENTICATE, (const char*)&optval, sizeof(optval)) == SOCKET_ERROR)
248   {
249     CLog::Log(LOGERROR, "JSONRPC Server: Failed to force authentication for bluetooth socket");
250     closesocket(fd);
251     return false;
252   }
253
254   int len = sizeof(sa);
255   if(getsockname(fd, (SOCKADDR*)&sa, &len) < 0)
256     CLog::Log(LOGERROR, "JSONRPC Server: Failed to get bluetooth port");
257
258   if (listen(fd, 10) < 0)
259   {
260     CLog::Log(LOGERROR, "JSONRPC Server: Failed to listen to bluetooth port");
261     closesocket(fd);
262     return false;
263   }
264
265   m_servers.push_back(fd);
266
267   CSADDR_INFO addrinfo;
268   addrinfo.iProtocol   = BTHPROTO_RFCOMM;
269   addrinfo.iSocketType = SOCK_STREAM;
270   addrinfo.LocalAddr.lpSockaddr       = (SOCKADDR*)&sa;
271   addrinfo.LocalAddr.iSockaddrLength  = sizeof(sa);
272   addrinfo.RemoteAddr.lpSockaddr      = (SOCKADDR*)&sa;
273   addrinfo.RemoteAddr.iSockaddrLength = sizeof(sa);
274
275   WSAQUERYSET service = {};
276   service.dwSize = sizeof(service);
277   service.lpszServiceInstanceName = (LPSTR)bt_service_name;
278   service.lpServiceClassId        = (LPGUID)&bt_service_guid;
279   service.lpszComment             = (LPSTR)bt_service_desc;
280   service.dwNameSpace             = NS_BTH;
281   service.lpNSProviderId          = NULL; /* RFCOMM? */
282   service.lpcsaBuffer             = &addrinfo;
283   service.dwNumberOfCsAddrs       = 1;
284
285   if(WSASetService(&service, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR)
286     CLog::Log(LOGERROR, "JSONRPC Server: failed to register bluetooth service error %d",  WSAGetLastError());
287
288   return true;
289 #endif
290
291 #ifdef HAVE_LIBBLUETOOTH
292
293   SOCKET fd = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
294   if(fd == INVALID_SOCKET)
295   {
296     CLog::Log(LOGINFO, "JSONRPC Server: Unable to get bluetooth socket");
297     return false;
298   }
299   struct sockaddr_rc sa  = {0};
300   sa.rc_family  = AF_BLUETOOTH;
301   sa.rc_bdaddr  = bt_bdaddr_any;
302   sa.rc_channel = 0;
303
304   if(bind(fd, (struct sockaddr*)&sa, sizeof(sa)) < 0)
305   {
306     CLog::Log(LOGINFO, "JSONRPC Server: Unable to bind to bluetooth socket");
307     closesocket(fd);
308     return false;
309   }
310
311   socklen_t len = sizeof(sa);
312   if(getsockname(fd, (struct sockaddr*)&sa, &len) < 0)
313     CLog::Log(LOGERROR, "JSONRPC Server: Failed to get bluetooth port");
314
315   if (listen(fd, 10) < 0)
316   {
317     CLog::Log(LOGERROR, "JSONRPC Server: Failed to listen to bluetooth port %d", sa.rc_channel);
318     closesocket(fd);
319     return false;
320   }
321
322   uint8_t rfcomm_channel = sa.rc_channel;
323
324   uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_uuid;
325   sdp_list_t *l2cap_list = 0,
326              *rfcomm_list = 0,
327              *root_list = 0,
328              *proto_list = 0,
329              *access_proto_list = 0,
330              *service_class = 0;
331
332   sdp_data_t *channel = 0;
333
334   sdp_record_t *record = sdp_record_alloc();
335
336   // set the general service ID
337   sdp_uuid128_create( &svc_uuid, &bt_service_guid );
338   sdp_set_service_id( record, svc_uuid );
339
340   // make the service record publicly browsable
341   sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
342   root_list = sdp_list_append(0, &root_uuid);
343   sdp_set_browse_groups( record, root_list );
344
345   // set l2cap information
346   sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
347   l2cap_list = sdp_list_append( 0, &l2cap_uuid );
348   proto_list = sdp_list_append( 0, l2cap_list );
349
350   // set rfcomm information
351   sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
352   channel = sdp_data_alloc(SDP_UINT8, &rfcomm_channel);
353   rfcomm_list = sdp_list_append( 0, &rfcomm_uuid );
354   sdp_list_append( rfcomm_list, channel );
355   sdp_list_append( proto_list, rfcomm_list );
356
357   // attach protocol information to service record
358   access_proto_list = sdp_list_append( 0, proto_list );
359   sdp_set_access_protos( record, access_proto_list );
360
361   // set the name, provider, and description
362   sdp_set_info_attr(record, bt_service_name, bt_service_prov, bt_service_desc);
363
364   // set the Service class ID
365   service_class = sdp_list_append(0, &svc_uuid);
366   sdp_set_service_classes( record, service_class);
367
368   // cleanup
369   sdp_data_free( channel );
370   sdp_list_free( l2cap_list, 0 );
371   sdp_list_free( rfcomm_list, 0 );
372   sdp_list_free( root_list, 0 );
373   sdp_list_free( access_proto_list, 0 );
374   sdp_list_free( service_class, 0 );
375
376   // connect to the local SDP server, register the service record
377   sdp_session_t *session = sdp_connect( &bt_bdaddr_any, &bt_bdaddr_local, SDP_RETRY_IF_BUSY );
378   if(session == NULL)
379   {
380     CLog::Log(LOGERROR, "JSONRPC Server: Failed to connect to sdpd");
381     closesocket(fd);
382     sdp_record_free(record);
383     return false;
384   }
385
386   if(sdp_record_register(session, record, 0) < 0)
387   {
388     CLog::Log(LOGERROR, "JSONRPC Server: Failed to register record with error %d", errno);
389     closesocket(fd);
390     sdp_close(session);
391     sdp_record_free(record);
392     return false;
393   }
394
395   m_sdpd = session;
396   m_servers.push_back(fd);
397
398   return true;
399 #endif
400   return false;
401 }
402
403 bool CTCPServer::InitializeTCP()
404 {
405
406   struct sockaddr_in myaddr;
407   memset(&myaddr, 0, sizeof(myaddr));
408
409   myaddr.sin_family = AF_INET;
410   myaddr.sin_port = htons(m_port);
411
412   if (m_nonlocal)
413     myaddr.sin_addr.s_addr = INADDR_ANY;
414   else
415     inet_pton(AF_INET, "127.0.0.1", &myaddr.sin_addr.s_addr);
416
417   SOCKET fd = socket(PF_INET, SOCK_STREAM, 0);
418
419   if (fd == INVALID_SOCKET)
420   {
421     CLog::Log(LOGERROR, "JSONRPC Server: Failed to create serversocket");
422     return false;
423   }
424
425   if (bind(fd, (struct sockaddr*)&myaddr, sizeof myaddr) < 0)
426   {
427     CLog::Log(LOGERROR, "JSONRPC Server: Failed to bind serversocket");
428     closesocket(fd);
429     return false;
430   }
431
432   if (listen(fd, 10) < 0)
433   {
434     CLog::Log(LOGERROR, "JSONRPC Server: Failed to set listen");
435     closesocket(fd);
436     return false;
437   }
438   m_servers.push_back(fd);
439   return true;
440 }
441
442 void CTCPServer::Deinitialize()
443 {
444   for (unsigned int i = 0; i < m_connections.size(); i++)
445     m_connections[i].Disconnect();
446
447   m_connections.clear();
448
449   for (unsigned int i = 0; i < m_servers.size(); i++)
450     closesocket(m_servers[i]);
451
452   m_servers.clear();
453
454 #ifdef HAVE_LIBBLUETOOTH
455   if(m_sdpd)
456     sdp_close( (sdp_session_t*)m_sdpd );
457   m_sdpd = NULL;
458 #endif
459
460   CAnnouncementManager::RemoveAnnouncer(this);
461 }
462
463 CTCPServer::CTCPClient::CTCPClient()
464 {
465   m_announcementflags = ANNOUNCE_ALL;
466   m_socket = INVALID_SOCKET;
467   m_beginBrackets = 0;
468   m_endBrackets = 0;
469   m_beginChar = 0;
470   m_endChar = 0;
471
472   m_addrlen = sizeof(m_cliaddr);
473 }
474
475 CTCPServer::CTCPClient::CTCPClient(const CTCPClient& client)
476 {
477   Copy(client);
478 }
479
480 CTCPServer::CTCPClient& CTCPServer::CTCPClient::operator=(const CTCPClient& client)
481 {
482   Copy(client);
483   return *this;
484 }
485
486 int CTCPServer::CTCPClient::GetPermissionFlags()
487 {
488   return OPERATION_PERMISSION_ALL;
489 }
490
491 int CTCPServer::CTCPClient::GetAnnouncementFlags()
492 {
493   return m_announcementflags;
494 }
495
496 bool CTCPServer::CTCPClient::SetAnnouncementFlags(int flags)
497 {
498   m_announcementflags = flags;
499   return true;
500 }
501
502 void CTCPServer::CTCPClient::PushBuffer(CTCPServer *host, const char *buffer, int length)
503 {
504   for (int i = 0; i < length; i++)
505   {
506     char c = buffer[i];
507
508     if (m_beginChar == 0 && c == '{')
509     {
510       m_beginChar = '{';
511       m_endChar = '}';
512     }
513     else if (m_beginChar == 0 && c == '[')
514     {
515       m_beginChar = '[';
516       m_endChar = ']';
517     }
518
519     if (m_beginChar != 0)
520     {
521       m_buffer.push_back(c);
522       if (c == m_beginChar)
523         m_beginBrackets++;
524       else if (c == m_endChar)
525         m_endBrackets++;
526       if (m_beginBrackets > 0 && m_endBrackets > 0 && m_beginBrackets == m_endBrackets)
527       {
528         std::string line = CJSONRPC::MethodCall(m_buffer, host, this);
529         CSingleLock lock (m_critSection);
530         send(m_socket, line.c_str(), line.size(), 0);
531         m_beginChar = m_beginBrackets = m_endBrackets = 0;
532         m_buffer.clear();
533       }
534     }
535   }
536 }
537
538 void CTCPServer::CTCPClient::Disconnect()
539 {
540   if (m_socket > 0)
541   {
542     CSingleLock lock (m_critSection);
543     shutdown(m_socket, SHUT_RDWR);
544     closesocket(m_socket);
545     m_socket = INVALID_SOCKET;
546   }
547 }
548
549 void CTCPServer::CTCPClient::Copy(const CTCPClient& client)
550 {
551   m_socket            = client.m_socket;
552   m_cliaddr           = client.m_cliaddr;
553   m_addrlen           = client.m_addrlen;
554   m_announcementflags = client.m_announcementflags;
555   m_beginBrackets     = client.m_beginBrackets;
556   m_endBrackets       = client.m_endBrackets;
557   m_beginChar         = client.m_beginChar;
558   m_endChar           = client.m_endChar;
559   m_buffer            = client.m_buffer;
560 }
561