bool CIrssMessage::FromBytes(char* from, int size, CIrssMessage& message) { if (!from) return false; if (size < 8) return false; //IRSS_MessageType type = (MessageType)BitConverter.ToInt32(from, 0); //IRSS_MessageFlags flags = (MessageFlags)BitConverter.ToInt32(from, 4); uint32_t type; memcpy(&type, from, 4); uint32_t flags; memcpy(&flags, from + 4, 4); message.SetType((IRSS_MessageType)type); message.SetFlags(flags); if (size > 8) { message.SetDataAsBytes(from + 8, size - 8); } return true; }
bool CRemoteControl::SendPacket(CIrssMessage& message) { int iSize = 0; char* bytes = message.ToBytes(iSize); char buffer[4]; uint32_t len = htonl(iSize); memcpy(&buffer[0], &len, 4); bool bResult = WriteN(&buffer[0], 4); if (bResult) { bResult = WriteN(bytes, iSize); } delete[] bytes; if (!bResult) { Close(); return false; } return true; }
bool CRemoteControl::HandleRemoteEvent(CIrssMessage& message) { try { //flag should be notify, maybe check it? char* data = message.GetData(); uint32_t datalen = message.GetDataSize(); char* deviceName; char* keycode; uint32_t devicenamelength; uint32_t keycodelength; if (datalen == 0) { CLog::Log(LOGERROR, "IRServerSuite: no data in remote message."); return false; } if (datalen <= 8) { //seems to be version 1.0.4.1, only keycode is sent, use Microsoft MCE mapping?? devicenamelength = 13; deviceName = new char[devicenamelength + 1]; sprintf(deviceName, "Microsoft MCE"); keycodelength = datalen; keycode = new char[keycodelength + 1]; memcpy(keycode, data, keycodelength); } else { //first 4 bytes is devicename length memcpy(&devicenamelength, data, 4); //devicename itself if (datalen < 4 + devicenamelength) { CLog::Log(LOGERROR, "IRServerSuite: invalid data in remote message (size: %u).", datalen); return false; } deviceName = new char[devicenamelength + 1]; memcpy(deviceName, data + 4, devicenamelength); if (datalen < 8 + devicenamelength) { CLog::Log(LOGERROR, "IRServerSuite: invalid data in remote message (size: %u).", datalen); delete[] deviceName; return false; } //next 4 bytes is keycode length memcpy(&keycodelength, data + 4 + devicenamelength, 4); //keycode itself if (datalen < 8 + devicenamelength + keycodelength) { CLog::Log(LOGERROR, "IRServerSuite: invalid data in remote message (size: %u).", datalen); delete[] deviceName; return false; } keycode = new char[keycodelength + 1]; memcpy(keycode, data + 8 + devicenamelength, keycodelength); } deviceName[devicenamelength] = '\0'; keycode[keycodelength] = '\0'; //translate to a buttoncode xbmc understands m_button = CButtonTranslator::GetInstance().TranslateLircRemoteString(deviceName, keycode); if (g_advancedSettings.m_logLevel == LOG_LEVEL_DEBUG_FREEMEM) { CLog::Log(LOGINFO, "IRServerSuite, RemoteEvent: %s %s", deviceName, keycode); } delete[] deviceName; delete[] keycode; return true; } catch(...) { CLog::Log(LOGERROR, "IRServerSuite: exception while processing RemoteEvent."); return false; } }
void CRemoteControl::Update() { if ((!m_bInitialized && !m_isConnecting) || (m_socket == INVALID_SOCKET)) { return; } CIrssMessage mess; if (!ReadPacket(mess)) { return; } switch (mess.GetType()) { case IRSSMT_RegisterClient: m_isConnecting = false; if ((mess.GetFlags() & IRSSMF_Success) != IRSSMF_Success) { //uh oh, it failed to register Close(); CLog::Log(LOGERROR, "IRServerSuite: failed to register XBMC as a client."); } else { m_bInitialized = true; //request info about receivers CIrssMessage mess(IRSSMT_DetectedReceivers, IRSSMF_Request); if (!SendPacket(mess)) { CLog::Log(LOGERROR, "IRServerSuite: failed to send AvailableReceivers packet."); } mess.SetType(IRSSMT_AvailableReceivers); if (!SendPacket(mess)) { CLog::Log(LOGERROR, "IRServerSuite: failed to send AvailableReceivers packet."); } mess.SetType(IRSSMT_ActiveReceivers); if (!SendPacket(mess)) { CLog::Log(LOGERROR, "IRServerSuite: failed to send AvailableReceivers packet."); } } break; case IRSSMT_RemoteEvent: HandleRemoteEvent(mess); break; case IRSSMT_Error: //I suppose the errormessage is in the packet somewhere... CLog::Log(LOGERROR, "IRServerSuite: we got an error message."); break; case IRSSMT_ServerShutdown: Close(); break; case IRSSMT_ServerSuspend: //should we do something? break; case IRSSMT_ServerResume: //should we do something? break; case IRSSMT_AvailableReceivers: { uint32_t size = mess.GetDataSize(); if (size > 0) { char* data = mess.GetData(); char* availablereceivers = new char[size + 1]; memcpy(availablereceivers, data, size); availablereceivers[size] = '\0'; CLog::Log(LOGINFO, "IRServerSuite: Available receivers: %s", availablereceivers); delete[] availablereceivers; } } break; case IRSSMT_DetectedReceivers: { uint32_t size = mess.GetDataSize(); if (size > 0) { char* data = mess.GetData(); char* detectedreceivers = new char[size + 1]; memcpy(detectedreceivers, data, size); detectedreceivers[size] = '\0'; CLog::Log(LOGINFO, "IRServerSuite: Detected receivers: %s", detectedreceivers); delete[] detectedreceivers; } } break; case IRSSMT_ActiveReceivers: { uint32_t size = mess.GetDataSize(); if (size > 0) { char* data = mess.GetData(); char* activereceivers = new char[size + 1]; memcpy(activereceivers, data, size); activereceivers[size] = '\0'; CLog::Log(LOGINFO, "IRServerSuite: Active receivers: %s", activereceivers); delete[] activereceivers; } } break; } }