public String GetReceiverInfo() {
   Lock();
   String lcName = "";
   String lcLang = "";
   write(Header.PT_GETSYSINFO);
   try {
     byte[] laFlags = new byte[5];
     readbyte(laFlags);
     byte[] laLang = new byte[3];
     readbyte(laLang);
     lcName = readstring();
     ack();
   } catch (IOException e) {
     e.printStackTrace();
   } finally {
     Unlock();
   }
   return lcName;
 }
 /**
  * @param DvrFile poFile
  * @param OutputStream poWrite Lese Datenströme im Single File Streaming Format mit statischer
  *     Chunk größe
  * @throws InterruptedException
  */
 private void readstream_singlepart(BufferedOutputStream poWrite)
     throws IOException, InterruptedException {
   int lnChunkSize = 0, lnBytes = 0;
   byte[] laBuffer = null;
   byte lbRead = 0;
   int lnUnknown = readint();
   int lnFileSize = readint();
   int lnReadSize = 0;
   lnChunkSize = readint();
   laBuffer = new byte[lnChunkSize];
   do {
     lbRead = readbyte();
     if (lbRead >= 0) {
       readskip(3);
       lnReadSize = lnFileSize - lnBytes > lnChunkSize ? lnChunkSize : lnFileSize - lnBytes;
       readbyte(laBuffer, 0, lnReadSize);
       poWrite.write(laBuffer, 0, lnReadSize);
       lnBytes += lnChunkSize;
     } else resumeread(lbRead);
   } while (lnBytes < lnFileSize);
   readbyte(laBuffer, 0, lnChunkSize - lnReadSize);
   poWrite.close();
 }
  private String readstring() throws IOException {
    byte lnFieldLen = readbyte();
    if (lnFieldLen > 0) {
      byte[] laField = new byte[lnFieldLen & 0xff];
      int lnStartPos = 0;
      readbyte(laField);
      switch (laField[0]) {
        case 0x05:
        case 0x0b:
          lnStartPos = 1;
          break;
      }
      return new String(laField, lnStartPos, laField.length - lnStartPos, "CP1252");

    } else return "";
  }
 private void readbyte(byte[] paData) throws IOException {
   readbyte(paData, 0, paData.length);
 }
  /*
   * Download a File from the Reciever to the
   * Destination File specified in pcDstFile
   */
  public boolean Download(DvrFile poFile, String pcDstFile) {
    /*
     * Parameter Checks
     */
    if (pcDstFile.endsWith("/")) {
      pcDstFile = pcDstFile + poFile.getUniqueFileName();
    }
    String lcPostCopyAction = Props.Get("POSTCOPYSCRIPT");
    int lnPostCopyThreads = Integer.parseInt(Props.Get("POSTCOPYTHREADCOUNT"));
    boolean lbStartDownload = false;
    boolean lbPostCopyAction = false;
    boolean lbReturn = false;

    if (lcPostCopyAction.equals("")) {
      Lock();
    } else {
      lbPostCopyAction = true;
      do {
        Lock();
        if (m_nActivePostCopyThreads < lnPostCopyThreads) {
          m_nActivePostCopyThreads++;
          lbStartDownload = true;
        } else {
          Unlock();
          try {
            Thread.sleep(1000);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      } while (!lbStartDownload);
    }
    /*
     * Socket Streams
     */
    ByteArrayOutputStream loSocketWriteLow = new ByteArrayOutputStream();
    DataOutputStream loSocketWrite = new DataOutputStream(loSocketWriteLow);
    String laDstFiles[];
    try {
      Logfile.Write("Copy File " + poFile.getFileName() + " to " + pcDstFile);

      if (poFile.m_nType == 1) {
        write(new byte[] {Header.PT_GETFILE_BYNAME, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0});
        readbyte();
        write(poFile.m_oParent.m_cRemoteName.getBytes("CP1252"));
        readbyte();
        ping();
        write(poFile.getFileName().getBytes("CP1252"));
        readbyte();
        laDstFiles = new String[] {pcDstFile};
        readstream_singlepart(createdstfile(pcDstFile));
      } else {
        loSocketWrite.writeByte(Header.PT_GETFILE_BYRECNO); // Download Command;
        loSocketWrite.writeShort(poFile.getIndex()); // File Index	
        loSocketWrite.writeLong(0); // Start Position (maybe!!)
        write(loSocketWriteLow.toByteArray()); // Send Message to DVR

        byte lbResponse = readbyte();
        long lnFileSize = readlong();
        byte lbFileCount = readbyte();
        BufferedOutputStream[] laWrite = new BufferedOutputStream[lbFileCount];
        laDstFiles = new String[lbFileCount];
        for (int i = 0; i < laWrite.length; i++) {
          byte lbFileNo = readbyte();
          laDstFiles[i] = pcDstFile + "." + readstring().toLowerCase();
          laWrite[lbFileNo] = createdstfile(laDstFiles[i]);
        }
        write(Header.PT_ACK);
        readstream_multipart(laWrite);
      }
      Logfile.Write("Transfer Complete");
      if (lbPostCopyAction) {
        PostCopy loPostCopy = new PostCopy(lcPostCopyAction, poFile, laDstFiles[0], this);
        loPostCopy.start();
      }
      lbReturn = true;
    } catch (IOException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      Unlock();
    }
    return lbReturn;
  }
  public void OpenDir(DvrDirectory poDir) {
    if (poDir.m_bIsOpen) return;

    Lock();
    try {
      Calendar loCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
      byte[] laGetDir = new byte[] // Command
          {Header.PT_GETDIR, 0, (byte) (poDir.m_oParent == null ? 0 : 1)};
      write(laGetDir); // Send
      readack();

      if (poDir.m_oParent != null) {
        write(poDir.m_cRemoteName);
        readbyte();
        ping();
      }

      short lnAnzElements = readshort();
      short lnIndex = 0;
      String lcFileName = "";
      long lnSize = 0;
      int lnTimeStamp = 0;
      while (lnAnzElements > 0) {
        loCalendar.set(1999, 12, 01, 00, 00, 00);
        byte lbType = readbyte();
        byte lbIsDir = 0;
        switch (lbType) {
          case 0: // Directory
            lbIsDir = readbyte();
            lcFileName = readstring();
            poDir.m_oDirectorys.add(new DvrDirectory(poDir, lcFileName, lcFileName, null));
            break;
          case 1: // Binary
            lcFileName = readstring();
            lnSize = readlong();
            lnTimeStamp = readint();
            loCalendar.add(Calendar.SECOND, lnTimeStamp);
            poDir.m_oFiles.add(
                new DvrFile(poDir, lcFileName, lnSize, (short) -1, lbType, loCalendar.getTime()));
            break;
          case 3: // TS Radio
          case 4: // TS File Record SD Quality
          case 7: // TS File Record HD Quality
            lbIsDir = readbyte();
            lnIndex = readbyte();
            lcFileName = readstring();
            lnSize = readlong();
            lnTimeStamp = readint();
            loCalendar.add(Calendar.SECOND, lnTimeStamp);
            poDir.m_oFiles.add(
                new DvrFile(poDir, lcFileName, lnSize, lnIndex, lbType, loCalendar.getTime()));
            break;
          case 9: // USB Memory Stick
            lbIsDir = readbyte();
            String lcDescription = readstring();
            String lcName = readstring();
            poDir.m_oDirectorys.add(
                new DvrDirectory(poDir, lcName, lcName.substring(1), lcDescription));
            break;
          default:
            throw new IOException("Unknown RecordType " + lbType);
        }
        lnAnzElements--;
      }
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      Unlock();
    }
    poDir.m_bIsOpen = true;
  }
 private void readskip(int i) throws IOException {
   byte[] laSkip = new byte[i];
   readbyte(laSkip);
 }