sBool sMiniFTPClient::GetFile(const sChar *filename,sFile *writeTo) { sSize currentPos = 0; if(State == CS_NOTARGET) return sFALSE; for(;;) { if(State != CS_CONNECTED && !TryReconnect(RetryCount)) break; sU8 sizeBuf[8]; if(SendCommand(sMFC_GET,filename,currentPos) && ReadAll(sizeBuf,8)) { sSize totalSize; sUnalignedLittleEndianLoad64(sizeBuf,(sU64&) totalSize); if(!Progress(filename,currentPos,totalSize,ProgressUser)) return MaybeNextTime(); sFixedArray<sU8> ioBuf(FileIOBufferSize); while(currentPos < totalSize) { sDInt size = (sDInt) sMin<sS64>(totalSize-currentPos,ioBuf.GetSize()); sDInt read; if(!Socket.Read(&ioBuf[0],size,read) || !read) { MaybeNextTime(); break; } if(!writeTo->Write(&ioBuf[0],read)) return sFALSE; currentPos += read; if(!Progress(filename,currentPos,totalSize,ProgressUser)) return MaybeNextTime(); } if(currentPos == totalSize) return sTRUE; } else if(Error == sMFE_OK) MaybeNextTime(); else break; } return sFALSE; }
sBool sMiniFTPClient::PutFile(const sChar *filename,sFile *readFrom) { sSize currentPos = 0; sSize totalSize = readFrom->GetSize(); if(State == CS_NOTARGET) return sFALSE; for(;;) { if(State != CS_CONNECTED && !TryReconnect(RetryCount)) break; if(!ContinueUploads) currentPos = 0; if(SendCommand(sMFC_PUT,filename,currentPos)) { sU8 sizeBuf[8]; sUnalignedLittleEndianStore64(sizeBuf,totalSize); if(!WriteAll(sizeBuf,8)) continue; if(!Progress(filename,currentPos,totalSize,ProgressUser)) return MaybeNextTime(); sFixedArray<sU8> ioBuf(FileIOBufferSize); while(currentPos < totalSize) { sInt size = (sInt) sMin<sS64>(totalSize-currentPos,ioBuf.GetSize()); if(!readFrom->Read(&ioBuf[0],size)) return MaybeNextTime(); if(!WriteAll(&ioBuf[0],size)) break; currentPos += size; if(!Progress(filename,currentPos,totalSize,ProgressUser)) return sFALSE; } if(currentPos == totalSize) return sTRUE; } else if(Error == sMFE_OK) MaybeNextTime(); else break; } return sFALSE; }
sBool sMiniFTPClient::Connect(const sChar *host,sIPPort port) { Disconnect(); sCopyString(TargetHost,host); TargetPort = port; if(!sResolveNameAndPort(host,TargetAddress,TargetPort)) { sLogF(L"MiniFTP",L"Could not resolve host '%s'.\n",host); return sFALSE; } State = CS_NOTCONNECTED; return TryReconnect(1); }
void cXVDRData::Action() { uint32_t lastPing = 0; cResponsePacket* vresp; SetPriority(19); while (Running()) { // try to reconnect if(ConnectionLost() && !TryReconnect()) { SleepMs(1000); continue; } // read message vresp = cXVDRSession::ReadMessage(); // check if the connection is still up if (vresp == NULL) { if(time(NULL) - lastPing > 5) { lastPing = time(NULL); if(!SendPing()) SignalConnectionLost(); } continue; } // CHANNEL_REQUEST_RESPONSE if (vresp->getChannelID() == XVDR_CHANNEL_REQUEST_RESPONSE) { CMD_LOCK; SMessages::iterator it = m_queue.find(vresp->getRequestID()); if (it != m_queue.end()) { it->second.pkt = vresp; it->second.event->Signal(); } else { delete vresp; } } // CHANNEL_STATUS else if (vresp->getChannelID() == XVDR_CHANNEL_STATUS) { if (vresp->getRequestID() == XVDR_STATUS_MESSAGE) { uint32_t type = vresp->extract_U32(); char* msgstr = vresp->extract_String(); std::string text = msgstr; if (g_bCharsetConv) XBMC->UnknownToUTF8(text); if (type == 2) XBMC->QueueNotification(QUEUE_ERROR, text.c_str()); if (type == 1) XBMC->QueueNotification(QUEUE_WARNING, text.c_str()); else XBMC->QueueNotification(QUEUE_INFO, text.c_str()); delete[] msgstr; } else if (vresp->getRequestID() == XVDR_STATUS_RECORDING) { vresp->extract_U32(); // device currently unused uint32_t on = vresp->extract_U32(); char* str1 = vresp->extract_String(); char* str2 = vresp->extract_String(); PVR->Recording(str1, str2, on); PVR->TriggerTimerUpdate(); delete[] str1; delete[] str2; } else if (vresp->getRequestID() == XVDR_STATUS_TIMERCHANGE) { XBMC->Log(LOG_DEBUG, "Server requested timer update"); PVR->TriggerTimerUpdate(); } else if (vresp->getRequestID() == XVDR_STATUS_CHANNELCHANGE) { XBMC->Log(LOG_DEBUG, "Server requested channel update"); PVR->TriggerChannelUpdate(); } else if (vresp->getRequestID() == XVDR_STATUS_RECORDINGSCHANGE) { XBMC->Log(LOG_DEBUG, "Server requested recordings update"); PVR->TriggerRecordingUpdate(); } delete vresp; } // UNKOWN CHANNELID else if (!OnResponsePacket(vresp)) { XBMC->Log(LOG_ERROR, "%s - Rxd a response packet on channel %lu !!", __FUNCTION__, vresp->getChannelID()); delete vresp; } } }
DemuxPacket* cXVDRDemux::Read() { if(ConnectionLost() && !TryReconnect()) { SleepMs(100); return PVR->AllocateDemuxPacket(0); } cResponsePacket *resp = ReadMessage(); if(resp == NULL) return PVR->AllocateDemuxPacket(0); if (resp->getChannelID() != XVDR_CHANNEL_STREAM) { delete resp; return PVR->AllocateDemuxPacket(0); } DemuxPacket* pkt = NULL; int iStreamId = -1; switch (resp->getOpCodeID()) { case XVDR_STREAM_CHANGE: StreamChange(resp); pkt = PVR->AllocateDemuxPacket(0); pkt->iStreamId = DMX_SPECIALID_STREAMCHANGE; delete resp; return pkt; case XVDR_STREAM_STATUS: StreamStatus(resp); break; case XVDR_STREAM_SIGNALINFO: StreamSignalInfo(resp); break; case XVDR_STREAM_CONTENTINFO: // send stream updates only if there are changes if(!StreamContentInfo(resp)) break; pkt = PVR->AllocateDemuxPacket(sizeof(PVR_STREAM_PROPERTIES)); memcpy(pkt->pData, &m_Streams, sizeof(PVR_STREAM_PROPERTIES)); pkt->iStreamId = DMX_SPECIALID_STREAMINFO; pkt->iSize = sizeof(PVR_STREAM_PROPERTIES); delete resp; return pkt; case XVDR_STREAM_MUXPKT: // figure out the stream id for this packet for(unsigned int i = 0; i < m_Streams.iStreamCount; i++) { if(m_Streams.stream[i].iPhysicalId == (unsigned int)resp->getStreamID()) { iStreamId = i; break; } } // stream found ? if(iStreamId != -1) { pkt = (DemuxPacket*)resp->getUserData(); pkt->iSize = resp->getUserDataLength(); pkt->duration = (double)resp->getDuration() * DVD_TIME_BASE / 1000000; pkt->dts = (double)resp->getDTS() * DVD_TIME_BASE / 1000000; pkt->pts = (double)resp->getPTS() * DVD_TIME_BASE / 1000000; pkt->iStreamId = iStreamId; delete resp; return pkt; } else { XBMC->Log(LOG_DEBUG, "stream id %i not found", resp->getStreamID()); } break; } delete resp; return PVR->AllocateDemuxPacket(0); }
sBool sMiniFTPClient::ListFiles(const sChar *basepath,sArray<sChar> &listing) { listing.Clear(); if(State == CS_NOTARGET) return sFALSE; for(;;) { if(State != CS_CONNECTED && !TryReconnect(RetryCount)) break; sU8 sizeBuf[8]; if(SendCommand(sMFC_LIST,basepath,0) && ReadAll(sizeBuf,8)) { sSize totalSize; sUnalignedLittleEndianLoad64(sizeBuf,(sU64&) totalSize); if((totalSize & 1) // we expect 16bit chars || totalSize > 16*1024*1024) // 16MB limit for directory listings (for now) return sFALSE; if(!Progress(basepath,0,totalSize,ProgressUser)) return MaybeNextTime(); sFixedArray<sU8> ioBuf((sInt) totalSize); sSize currentPos = 0; while(currentPos < totalSize) { sDInt size = (sDInt) (totalSize-currentPos); sDInt read; if(!Socket.Read(&ioBuf[(sInt) currentPos],size,read) || !read) { MaybeNextTime(); break; } currentPos += read; if(!Progress(basepath,currentPos,totalSize,ProgressUser)) return MaybeNextTime(); } if(currentPos == totalSize) { listing.HintSize(sU32(totalSize/2)); listing.AddMany(sU32(totalSize/2)); for(sInt i=0;i<totalSize/2;i++) { sU16 v; sUnalignedLittleEndianLoad16(&ioBuf[i*2],v); listing[i] = v; } return sTRUE; } } else if(Error == sMFE_OK) MaybeNextTime(); else break; } return sFALSE; }