示例#1
0
文件: connection.c 项目: rdaoc/xbmc
cConnection::~cConnection()
{
  isyslog("VNSI: cConnection::~cConnection()");
  StopChannelStreaming();
  m_socket.close(); // force closing connection
  isyslog("VNSI: stopping cConnection thread ...");
  Cancel(10);
  isyslog("VNSI: done");
}
示例#2
0
void cConnection::Action(void)
{
  uint32_t kaTimeStamp;
  uint32_t logStringLen;
  uint32_t channelID;
  uint32_t requestID;
  uint32_t opcode;
  uint32_t dataLength;
  uint8_t* data;

  while (Running())
  {
    if (!m_socket.read((uint8_t*)&channelID, sizeof(uint32_t))) break;
    channelID = ntohl(channelID);

    if (channelID == 1)
    {
      if (!m_socket.read((uint8_t*)&requestID, sizeof(uint32_t), 10000)) break;
      requestID = ntohl(requestID);

      if (!m_socket.read((uint8_t*)&opcode, sizeof(uint32_t), 10000)) break;
      opcode = ntohl(opcode);

      if (!m_socket.read((uint8_t*)&dataLength, sizeof(uint32_t), 10000)) break;
      dataLength = ntohl(dataLength);
      if (dataLength > 200000) // a random sanity limit
      {
        esyslog("VNSI-Error: dataLength > 200000!");
        break;
      }

      if (dataLength)
      {
        data = (uint8_t*)malloc(dataLength);
        if (!data)
        {
          esyslog("VNSI-Error: Extra data buffer malloc error");
          break;
        }

        if (!m_socket.read(data, dataLength, 10000))
        {
          esyslog("VNSI-Error: Could not read data");
          free(data);
          break;
        }
      }
      else
      {
        data = NULL;
      }

      //LOGCONSOLE("Received chan=%lu, ser=%lu, op=%lu, edl=%lu", channelID, requestID, opcode, dataLength);

      if (!m_loggedIn && (opcode != 1))
      {
        esyslog("VNSI-Error: Not logged in and opcode != 1");
        if (data) free(data);
        break;
      }

      /* Handle channel open and close inside this thread */
      if (opcode == VDR_CHANNELSTREAM_OPEN)
      {
        cResponsePacket *resp = new cResponsePacket();
        if (!resp->init(requestID))
        {
          esyslog("VNSI-Error: response packet init fail");
          delete resp;
          continue;
        }

        uint32_t number = ntohl(*(uint32_t*)&data[0]);
        free(data);

        if (m_isStreaming)
          StopChannelStreaming();

        const cChannel *channel = Channels.GetByNumber(number);
        if (channel != NULL)
        {
          if (StartChannelStreaming(channel, resp))
          {
            isyslog("VNSI: Started streaming of channel %i - %s", number, channel->Name());
            continue;
          }
          else
          {
            LOGCONSOLE("Can't stream channel %i - %s", number, channel->Name());
            resp->add_U32(VDR_RET_DATALOCKED);
          }
        }
        else
        {
          esyslog("VNSI-Error: Can't find channel %i", number);
          resp->add_U32(VDR_RET_DATAINVALID);
        }

        resp->finalise();
        m_socket.write(resp->getPtr(), resp->getLen());
      }
      else if (opcode == VDR_CHANNELSTREAM_CLOSE)
      {
        if (m_isStreaming)
          StopChannelStreaming();
      }
      else
      {
        cRequestPacket* req = new cRequestPacket(requestID, opcode, data, dataLength, this);
	m_cmdcontrol.recvRequest(req);
      }
    }
    else if (channelID == 3)
    {
      if (!m_socket.read((uint8_t*)&kaTimeStamp, sizeof(uint32_t), 1000)) break;
      kaTimeStamp = ntohl(kaTimeStamp);

      //LOGCONSOLE("Received chan=%lu kats=%lu", channelID, kaTimeStamp);

      uint8_t buffer[8];
      *(uint32_t*)&buffer[0] = htonl(3); // KA CHANNEL
      *(uint32_t*)&buffer[4] = htonl(kaTimeStamp);
      if (!m_socket.write(buffer, 8))
      {
        esyslog("VNSI-Error: Could not send back KA reply");
        break;
      }
    }
    else if (channelID == 4)
    {
      if (!m_socket.read((uint8_t*)&logStringLen, sizeof(uint32_t), 1000)) break;
      logStringLen = ntohl(logStringLen);

      LOGCONSOLE("Received chan=%lu loglen=%lu", channelID, logStringLen);

      uint8_t buffer[logStringLen + 1];
      if (!m_socket.read((uint8_t*)&buffer, logStringLen, 1000)) break;
      buffer[logStringLen] = '\0';

      LOGCONSOLE("Client said: '%s'", buffer);
      if (m_NetLogFile)
      {
        if (fputs((const char*)buffer, m_NetLogFile) == EOF)
        {
          fclose(m_NetLogFile);
          m_NetLogFile = NULL;
        }
        fflush(NULL);
      }
    }
    else
    {
      esyslog("VNSI-Error: Incoming channel number unknown");
      break;
    }
  }

  /* If thread is ended due to closed connection delete a
     possible running stream here */
  StopChannelStreaming();
}