PageRenderTime 50ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/addons/pvr.nextpvr/src/Socket.cpp

https://github.com/jzeaherra/xbmc-pvr-addons
C++ | 772 lines | 608 code | 130 blank | 34 comment | 81 complexity | 80b8441ddb0175adb1b3c557805796f0 MD5 | raw file
Possible License(s): GPL-3.0, AGPL-1.0, GPL-2.0, LGPL-2.1
  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 of the License, or
  8. * (at your option) 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 this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. #include "libXBMC_addon.h"
  20. #include <string>
  21. #include "platform/os.h"
  22. #include "client.h"
  23. #include "Socket.h"
  24. using namespace std;
  25. using namespace ADDON;
  26. using namespace NextPVR;
  27. namespace NextPVR
  28. {
  29. /* Master defines for client control */
  30. #define RECEIVE_TIMEOUT 6 //sec
  31. Socket::Socket(const enum SocketFamily family, const enum SocketDomain domain, const enum SocketType type, const enum SocketProtocol protocol)
  32. {
  33. _sd = INVALID_SOCKET;
  34. _family = family;
  35. _domain = domain;
  36. _type = type;
  37. _protocol = protocol;
  38. memset (&_sockaddr, 0, sizeof( _sockaddr ) );
  39. }
  40. Socket::Socket()
  41. {
  42. // Default constructor, default settings
  43. _sd = INVALID_SOCKET;
  44. _family = af_inet;
  45. _domain = pf_inet;
  46. _type = sock_stream;
  47. _protocol = tcp;
  48. memset (&_sockaddr, 0, sizeof( _sockaddr ) );
  49. }
  50. Socket::~Socket()
  51. {
  52. close();
  53. }
  54. bool Socket::setHostname ( const std::string& host )
  55. {
  56. if (isalpha(host.c_str()[0]))
  57. {
  58. // host address is a name
  59. struct hostent *he = NULL;
  60. if ((he = gethostbyname( host.c_str() )) == 0)
  61. {
  62. errormessage( getLastError(), "Socket::setHostname");
  63. return false;
  64. }
  65. _sockaddr.sin_addr = *((in_addr *) he->h_addr);
  66. }
  67. else
  68. {
  69. _sockaddr.sin_addr.s_addr = inet_addr(host.c_str());
  70. }
  71. return true;
  72. }
  73. bool Socket::read_ready()
  74. {
  75. fd_set fdset;
  76. FD_ZERO(&fdset);
  77. FD_SET(_sd, &fdset);
  78. struct timeval tv;
  79. tv.tv_sec = 1;
  80. int retVal = select(_sd+1, &fdset, NULL, NULL, &tv);
  81. if (retVal > 0)
  82. return true;
  83. return false;
  84. }
  85. bool Socket::close()
  86. {
  87. if (is_valid())
  88. {
  89. if (_sd != SOCKET_ERROR)
  90. #ifdef TARGET_WINDOWS
  91. closesocket(_sd);
  92. #else
  93. ::close(_sd);
  94. #endif
  95. _sd = INVALID_SOCKET;
  96. osCleanup();
  97. return true;
  98. }
  99. return false;
  100. }
  101. bool Socket::create()
  102. {
  103. if( is_valid() )
  104. {
  105. close();
  106. }
  107. if(!osInit())
  108. {
  109. return false;
  110. }
  111. _sd = socket(_family, _type, _protocol );
  112. //0 indicates that the default protocol for the type selected is to be used.
  113. //For example, IPPROTO_TCP is chosen for the protocol if the type was set to
  114. //SOCK_STREAM and the address family is AF_INET.
  115. if (_sd == INVALID_SOCKET)
  116. {
  117. errormessage( getLastError(), "Socket::create" );
  118. return false;
  119. }
  120. return true;
  121. }
  122. bool Socket::bind ( const unsigned short port )
  123. {
  124. if (!is_valid())
  125. {
  126. return false;
  127. }
  128. _sockaddr.sin_family = _family;
  129. _sockaddr.sin_addr.s_addr = INADDR_ANY; //listen to all
  130. _sockaddr.sin_port = htons( port );
  131. int bind_return = ::bind(_sd, (sockaddr*)(&_sockaddr), sizeof(_sockaddr));
  132. if ( bind_return == -1 )
  133. {
  134. errormessage( getLastError(), "Socket::bind" );
  135. return false;
  136. }
  137. return true;
  138. }
  139. bool Socket::listen() const
  140. {
  141. if (!is_valid())
  142. {
  143. return false;
  144. }
  145. int listen_return = ::listen (_sd, SOMAXCONN);
  146. //This is defined as 5 in winsock.h, and 0x7FFFFFFF in winsock2.h.
  147. //linux 128//MAXCONNECTIONS =1
  148. if (listen_return == -1)
  149. {
  150. errormessage( getLastError(), "Socket::listen" );
  151. return false;
  152. }
  153. return true;
  154. }
  155. bool Socket::accept ( Socket& new_socket ) const
  156. {
  157. if (!is_valid())
  158. {
  159. return false;
  160. }
  161. socklen_t addr_length = sizeof( _sockaddr );
  162. new_socket._sd = ::accept(_sd, const_cast<sockaddr*>( (const sockaddr*) &_sockaddr), &addr_length );
  163. if (new_socket._sd <= 0)
  164. {
  165. errormessage( getLastError(), "Socket::accept" );
  166. return false;
  167. }
  168. return true;
  169. }
  170. int Socket::send ( const std::string& data )
  171. {
  172. if (!is_valid())
  173. {
  174. return 0;
  175. }
  176. int status = Socket::send( (const char*) data.c_str(), (const unsigned int) data.size());
  177. return status;
  178. }
  179. int Socket::send ( const char* data, const unsigned int len )
  180. {
  181. fd_set set_w, set_e;
  182. struct timeval tv;
  183. int result;
  184. if (!is_valid())
  185. {
  186. return 0;
  187. }
  188. // fill with new data
  189. tv.tv_sec = 0;
  190. tv.tv_usec = 0;
  191. FD_ZERO(&set_w);
  192. FD_ZERO(&set_e);
  193. FD_SET(_sd, &set_w);
  194. FD_SET(_sd, &set_e);
  195. result = select(FD_SETSIZE, &set_w, NULL, &set_e, &tv);
  196. if (result < 0)
  197. {
  198. XBMC->Log(LOG_ERROR, "Socket::send - select failed");
  199. _sd = INVALID_SOCKET;
  200. return 0;
  201. }
  202. int status = ::send(_sd, data, len, 0 );
  203. if (status == -1)
  204. {
  205. errormessage( getLastError(), "Socket::send");
  206. XBMC->Log(LOG_ERROR, "Socket::send - failed to send data");
  207. _sd = INVALID_SOCKET;
  208. }
  209. return status;
  210. }
  211. int Socket::sendto ( const char* data, unsigned int size, bool sendcompletebuffer)
  212. {
  213. int sentbytes = 0;
  214. int i;
  215. do
  216. {
  217. i = ::sendto(_sd, data, size, 0, (const struct sockaddr*) &_sockaddr, sizeof( _sockaddr ) );
  218. if (i <= 0)
  219. {
  220. errormessage( getLastError(), "Socket::sendto");
  221. osCleanup();
  222. return i;
  223. }
  224. sentbytes += i;
  225. } while ( (sentbytes < (int) size) && (sendcompletebuffer == true));
  226. return i;
  227. }
  228. int Socket::receive ( std::string& data, unsigned int minpacketsize ) const
  229. {
  230. char * buf = NULL;
  231. int status = 0;
  232. if (!is_valid())
  233. {
  234. return 0;
  235. }
  236. buf = new char [ minpacketsize + 1 ];
  237. memset ( buf, 0, minpacketsize + 1 );
  238. status = receive( buf, minpacketsize, minpacketsize );
  239. data = buf;
  240. delete[] buf;
  241. return status;
  242. }
  243. //Receive until error or \n
  244. bool Socket::ReadResponse (int &code, vector<string> &lines)
  245. {
  246. fd_set set_r, set_e;
  247. timeval timeout;
  248. int result;
  249. int retries = 6;
  250. char buffer[2048];
  251. char cont = 0;
  252. string line;
  253. size_t pos1 = 0, pos2 = 0, pos3 = 0;
  254. code = 0;
  255. while (true)
  256. {
  257. while ((pos1 = line.find("\r\n", pos3)) != std::string::npos)
  258. {
  259. pos2 = line.find(cont);
  260. lines.push_back(line.substr(pos2+1, pos1-pos2-1));
  261. line.erase(0, pos1 + 2);
  262. pos3 = 0;
  263. return true;
  264. }
  265. // we only need to recheck 1 byte
  266. if (line.size() > 0)
  267. {
  268. pos3 = line.size() - 1;
  269. }
  270. else
  271. {
  272. pos3 = 0;
  273. }
  274. if (cont == ' ')
  275. {
  276. break;
  277. }
  278. timeout.tv_sec = RECEIVE_TIMEOUT;
  279. timeout.tv_usec = 0;
  280. // fill with new data
  281. FD_ZERO(&set_r);
  282. FD_ZERO(&set_e);
  283. FD_SET(_sd, &set_r);
  284. FD_SET(_sd, &set_e);
  285. result = select(FD_SETSIZE, &set_r, NULL, &set_e, &timeout);
  286. if (result < 0)
  287. {
  288. XBMC->Log(LOG_DEBUG, "CVTPTransceiver::ReadResponse - select failed");
  289. lines.push_back("ERROR: Select failed");
  290. code = 1; //error
  291. _sd = INVALID_SOCKET;
  292. return false;
  293. }
  294. if (result == 0)
  295. {
  296. if (retries != 0)
  297. {
  298. XBMC->Log(LOG_DEBUG, "CVTPTransceiver::ReadResponse - timeout waiting for response, retrying... (%i)", retries);
  299. retries--;
  300. continue;
  301. } else {
  302. XBMC->Log(LOG_DEBUG, "CVTPTransceiver::ReadResponse - timeout waiting for response. Failed after 10 retries.");
  303. lines.push_back("ERROR: Failed after 10 retries");
  304. code = 1; //error
  305. _sd = INVALID_SOCKET;
  306. return false;
  307. }
  308. }
  309. result = recv(_sd, buffer, sizeof(buffer) - 1, 0);
  310. if (result < 0)
  311. {
  312. XBMC->Log(LOG_DEBUG, "CVTPTransceiver::ReadResponse - recv failed");
  313. lines.push_back("ERROR: Recv failed");
  314. code = 1; //error
  315. _sd = INVALID_SOCKET;
  316. return false;
  317. }
  318. buffer[result] = 0;
  319. line.append(buffer);
  320. }
  321. return true;
  322. }
  323. int Socket::receive ( std::string& data) const
  324. {
  325. char buf[MAXRECV + 1];
  326. int status = 0;
  327. if ( !is_valid() )
  328. {
  329. return 0;
  330. }
  331. memset ( buf, 0, MAXRECV + 1 );
  332. status = receive( buf, MAXRECV, 0 );
  333. data = buf;
  334. return status;
  335. }
  336. int Socket::receive ( char* data, const unsigned int buffersize, const unsigned int minpacketsize ) const
  337. {
  338. unsigned int receivedsize = 0;
  339. int status = 0;
  340. if ( !is_valid() )
  341. {
  342. return 0;
  343. }
  344. while ( (receivedsize <= minpacketsize) && (receivedsize < buffersize) )
  345. {
  346. status = ::recv(_sd, data+receivedsize, (buffersize - receivedsize), 0 );
  347. if ( status == SOCKET_ERROR )
  348. {
  349. int lasterror = getLastError();
  350. #if defined(TARGET_WINDOWS)
  351. if ( lasterror != WSAEWOULDBLOCK)
  352. errormessage( lasterror, "Socket::receive" );
  353. #else
  354. if ( lasterror != EAGAIN && lasterror != EWOULDBLOCK )
  355. errormessage( lasterror, "Socket::receive" );
  356. #endif
  357. return status;
  358. }
  359. receivedsize += status;
  360. if (receivedsize >= minpacketsize)
  361. break;
  362. }
  363. return receivedsize;
  364. }
  365. int Socket::recvfrom ( char* data, const int buffersize, const int minpacketsize, struct sockaddr* from, socklen_t* fromlen) const
  366. {
  367. int status = ::recvfrom(_sd, data, buffersize, 0, from, fromlen);
  368. return status;
  369. }
  370. bool Socket::connect ( const std::string& host, const unsigned short port )
  371. {
  372. if ( !is_valid() )
  373. {
  374. return false;
  375. }
  376. _sockaddr.sin_family = _family;
  377. _sockaddr.sin_port = htons ( port );
  378. if ( !setHostname( host ) )
  379. {
  380. XBMC->Log(LOG_ERROR, "Socket::setHostname(%s) failed.\n", host.c_str());
  381. return false;
  382. }
  383. int status = ::connect ( _sd, reinterpret_cast<sockaddr*>(&_sockaddr), sizeof ( _sockaddr ) );
  384. if ( status == SOCKET_ERROR )
  385. {
  386. XBMC->Log(LOG_ERROR, "Socket::connect %s:%u\n", host.c_str(), port);
  387. errormessage( getLastError(), "Socket::connect" );
  388. return false;
  389. }
  390. return true;
  391. }
  392. bool Socket::reconnect()
  393. {
  394. if ( _sd != INVALID_SOCKET )
  395. {
  396. return true;
  397. }
  398. if( !create() )
  399. return false;
  400. int status = ::connect ( _sd, reinterpret_cast<sockaddr*>(&_sockaddr), sizeof ( _sockaddr ) );
  401. if ( status == SOCKET_ERROR )
  402. {
  403. errormessage( getLastError(), "Socket::connect" );
  404. return false;
  405. }
  406. return true;
  407. }
  408. bool Socket::is_valid() const
  409. {
  410. return (_sd != INVALID_SOCKET);
  411. }
  412. #if defined(TARGET_WINDOWS)
  413. bool Socket::set_non_blocking ( const bool b )
  414. {
  415. u_long iMode;
  416. if ( b )
  417. iMode = 1; // enable non_blocking
  418. else
  419. iMode = 0; // disable non_blocking
  420. if (ioctlsocket(_sd, FIONBIO, &iMode) == -1)
  421. {
  422. XBMC->Log(LOG_ERROR, "Socket::set_non_blocking - Can't set socket condition to: %i", iMode);
  423. return false;
  424. }
  425. return true;
  426. }
  427. void Socket::errormessage( int errnum, const char* functionname) const
  428. {
  429. const char* errmsg = NULL;
  430. switch (errnum)
  431. {
  432. case WSANOTINITIALISED:
  433. errmsg = "A successful WSAStartup call must occur before using this function.";
  434. break;
  435. case WSAENETDOWN:
  436. errmsg = "The network subsystem or the associated service provider has failed";
  437. break;
  438. case WSA_NOT_ENOUGH_MEMORY:
  439. errmsg = "Insufficient memory available";
  440. break;
  441. case WSA_INVALID_PARAMETER:
  442. errmsg = "One or more parameters are invalid";
  443. break;
  444. case WSA_OPERATION_ABORTED:
  445. errmsg = "Overlapped operation aborted";
  446. break;
  447. case WSAEINTR:
  448. errmsg = "Interrupted function call";
  449. break;
  450. case WSAEBADF:
  451. errmsg = "File handle is not valid";
  452. break;
  453. case WSAEACCES:
  454. errmsg = "Permission denied";
  455. break;
  456. case WSAEFAULT:
  457. errmsg = "Bad address";
  458. break;
  459. case WSAEINVAL:
  460. errmsg = "Invalid argument";
  461. break;
  462. case WSAENOTSOCK:
  463. errmsg = "Socket operation on nonsocket";
  464. break;
  465. case WSAEDESTADDRREQ:
  466. errmsg = "Destination address required";
  467. break;
  468. case WSAEMSGSIZE:
  469. errmsg = "Message too long";
  470. break;
  471. case WSAEPROTOTYPE:
  472. errmsg = "Protocol wrong type for socket";
  473. break;
  474. case WSAENOPROTOOPT:
  475. errmsg = "Bad protocol option";
  476. break;
  477. case WSAEPFNOSUPPORT:
  478. errmsg = "Protocol family not supported";
  479. break;
  480. case WSAEAFNOSUPPORT:
  481. errmsg = "Address family not supported by protocol family";
  482. break;
  483. case WSAEADDRINUSE:
  484. errmsg = "Address already in use";
  485. break;
  486. case WSAECONNRESET:
  487. errmsg = "Connection reset by peer";
  488. break;
  489. case WSAHOST_NOT_FOUND:
  490. errmsg = "Authoritative answer host not found";
  491. break;
  492. case WSATRY_AGAIN:
  493. errmsg = "Nonauthoritative host not found, or server failure";
  494. break;
  495. case WSAEISCONN:
  496. errmsg = "Socket is already connected";
  497. break;
  498. case WSAETIMEDOUT:
  499. errmsg = "Connection timed out";
  500. break;
  501. case WSAECONNREFUSED:
  502. errmsg = "Connection refused";
  503. break;
  504. case WSANO_DATA:
  505. errmsg = "Valid name, no data record of requested type";
  506. break;
  507. default:
  508. errmsg = "WSA Error";
  509. }
  510. XBMC->Log(LOG_ERROR, "%s: (Winsock error=%i) %s\n", functionname, errnum, errmsg);
  511. }
  512. int Socket::getLastError() const
  513. {
  514. return WSAGetLastError();
  515. }
  516. int Socket::win_usage_count = 0; //Declared static in Socket class
  517. bool Socket::osInit()
  518. {
  519. win_usage_count++;
  520. // initialize winsock:
  521. if (WSAStartup(MAKEWORD(2,2),&_wsaData) != 0)
  522. {
  523. return false;
  524. }
  525. WORD wVersionRequested = MAKEWORD(2,2);
  526. // check version
  527. if (_wsaData.wVersion != wVersionRequested)
  528. {
  529. return false;
  530. }
  531. return true;
  532. }
  533. void Socket::osCleanup()
  534. {
  535. win_usage_count--;
  536. if(win_usage_count == 0)
  537. {
  538. WSACleanup();
  539. }
  540. }
  541. #elif defined TARGET_LINUX || defined TARGET_DARWIN
  542. bool Socket::set_non_blocking ( const bool b )
  543. {
  544. int opts;
  545. opts = fcntl(_sd, F_GETFL);
  546. if ( opts < 0 )
  547. {
  548. return false;
  549. }
  550. if ( b )
  551. opts = ( opts | O_NONBLOCK );
  552. else
  553. opts = ( opts & ~O_NONBLOCK );
  554. if(fcntl (_sd , F_SETFL, opts) == -1)
  555. {
  556. XBMC->Log(LOG_ERROR, "Socket::set_non_blocking - Can't set socket flags to: %i", opts);
  557. return false;
  558. }
  559. return true;
  560. }
  561. void Socket::errormessage( int errnum, const char* functionname) const
  562. {
  563. const char* errmsg = NULL;
  564. switch ( errnum )
  565. {
  566. case EAGAIN: //same as EWOULDBLOCK
  567. errmsg = "EAGAIN: The socket is marked non-blocking and the requested operation would block";
  568. break;
  569. case EBADF:
  570. errmsg = "EBADF: An invalid descriptor was specified";
  571. break;
  572. case ECONNRESET:
  573. errmsg = "ECONNRESET: Connection reset by peer";
  574. break;
  575. case EDESTADDRREQ:
  576. errmsg = "EDESTADDRREQ: The socket is not in connection mode and no peer address is set";
  577. break;
  578. case EFAULT:
  579. errmsg = "EFAULT: An invalid userspace address was specified for a parameter";
  580. break;
  581. case EINTR:
  582. errmsg = "EINTR: A signal occurred before data was transmitted";
  583. break;
  584. case EINVAL:
  585. errmsg = "EINVAL: Invalid argument passed";
  586. break;
  587. case ENOTSOCK:
  588. errmsg = "ENOTSOCK: The argument is not a valid socket";
  589. break;
  590. case EMSGSIZE:
  591. errmsg = "EMSGSIZE: The socket requires that message be sent atomically, and the size of the message to be sent made this impossible";
  592. break;
  593. case ENOBUFS:
  594. errmsg = "ENOBUFS: The output queue for a network interface was full";
  595. break;
  596. case ENOMEM:
  597. errmsg = "ENOMEM: No memory available";
  598. break;
  599. case EPIPE:
  600. errmsg = "EPIPE: The local end has been shut down on a connection oriented socket";
  601. break;
  602. case EPROTONOSUPPORT:
  603. errmsg = "EPROTONOSUPPORT: The protocol type or the specified protocol is not supported within this domain";
  604. break;
  605. case EAFNOSUPPORT:
  606. errmsg = "EAFNOSUPPORT: The implementation does not support the specified address family";
  607. break;
  608. case ENFILE:
  609. errmsg = "ENFILE: Not enough kernel memory to allocate a new socket structure";
  610. break;
  611. case EMFILE:
  612. errmsg = "EMFILE: Process file table overflow";
  613. break;
  614. case EACCES:
  615. errmsg = "EACCES: Permission to create a socket of the specified type and/or protocol is denied";
  616. break;
  617. case ECONNREFUSED:
  618. errmsg = "ECONNREFUSED: A remote host refused to allow the network connection (typically because it is not running the requested service)";
  619. break;
  620. case ENOTCONN:
  621. errmsg = "ENOTCONN: The socket is associated with a connection-oriented protocol and has not been connected";
  622. break;
  623. default:
  624. break;
  625. }
  626. XBMC->Log(LOG_ERROR, "%s: (errno=%i) %s\n", functionname, errnum, errmsg);
  627. }
  628. int Socket::getLastError() const
  629. {
  630. return errno;
  631. }
  632. bool Socket::osInit()
  633. {
  634. // Not needed for Linux
  635. return true;
  636. }
  637. void Socket::osCleanup()
  638. {
  639. // Not needed for Linux
  640. }
  641. #endif //TARGET_WINDOWS || TARGET_LINUX || TARGET_DARWIN
  642. } //namespace NextPVR