public void UploadFileByBlocking(BacnetClient comm, BacnetAddress adr, BacnetObjectId object_id, string filename, Action <int> progress_action) { Cancel = false; //open file System.IO.FileStream fs = null; try { fs = System.IO.File.OpenRead(filename); } catch (Exception ex) { throw new System.IO.IOException("Couldn't open file", ex); } try { int position = 0; int count = comm.GetFileBufferMaxSize(); byte[] buffer = new byte[count]; while (count > 0 && !Cancel) { //read from disk count = fs.Read(buffer, 0, count); if (count < 0) { throw new System.IO.IOException("Couldn't read file"); } else if (count == 0) { continue; } //write to device if (!comm.WriteFileRequest(adr, object_id, ref position, count, buffer)) { throw new System.IO.IOException("Couldn't write file"); } //progress if (count > 0) { position += count; if (progress_action != null) { progress_action(position); } } } } finally { fs.Close(); } }
public void DownloadFileByBlocking(BacnetClient comm, BacnetAddress adr, BacnetObjectId object_id, string filename, Action <int> progress_action) { Cancel = false; //open file System.IO.FileStream fs = null; try { fs = System.IO.File.OpenWrite(filename); } catch (Exception ex) { throw new System.IO.IOException("Couldn't open file", ex); } int position = 0; uint count = (uint)comm.GetFileBufferMaxSize(); bool end_of_file = false; byte[] buffer; int buffer_offset; try { while (!end_of_file && !Cancel) { //read from device if (!comm.ReadFileRequest(adr, object_id, ref position, ref count, out end_of_file, out buffer, out buffer_offset)) { throw new System.IO.IOException("Couldn't read file"); } position += (int)count; //write to file if (count > 0) { fs.Write(buffer, buffer_offset, (int)count); if (progress_action != null) { progress_action(position); } } } } finally { fs.Close(); } }
private static void OnAtomicReadFileRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, bool is_stream, BacnetObjectId object_id, int position, uint count, BacnetMaxSegments max_segments) { lock (m_lockObject) { try { if (object_id.Type != BacnetObjectTypes.OBJECT_FILE) { throw new Exception("File Reading on non file objects ... bah!"); } else if (object_id.Instance != 0) { throw new Exception("Don't know this file"); } //this is a test file for performance measuring int filesize = m_storage.ReadPropertyValue(object_id, BacnetPropertyIds.PROP_FILE_SIZE); //test file is ~10mb bool end_of_file = (position + count) >= filesize; count = (uint)Math.Min(count, filesize - position); int max_filebuffer_size = sender.GetFileBufferMaxSize(); if (count > max_filebuffer_size && max_segments > 0) { //create segmented message!!! } else { count = (uint)Math.Min(count, max_filebuffer_size); //trim } //fill file with bogus content byte[] file_buffer = new byte[count]; byte[] bogus = new byte[] { (byte)'F', (byte)'I', (byte)'L', (byte)'L' }; for (int i = 0; i < count; i += bogus.Length) { Array.Copy(bogus, 0, file_buffer, i, Math.Min(bogus.Length, count - i)); } //send HandleSegmentationResponse(sender, adr, invoke_id, max_segments, (seg) => { sender.ReadFileResponse(adr, invoke_id, seg, position, count, end_of_file, file_buffer); }); } catch (Exception) { sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_ATOMIC_READ_FILE, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER); } } }
private static void handler_OnAtomicReadFileRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, bool is_stream, BacnetObjectId object_id, int position, uint count, BacnetMaxSegments max_segments) { lock (device) { BaCSharpObject File = device.FindBacnetObject(object_id); if (File is BacnetFile) { try { BacnetFile f = (BacnetFile)File; int filesize = (int)f.PROP_FILE_SIZE; bool end_of_file = (position + count) >= filesize; count = (uint)Math.Min(count, filesize - position); int max_filebuffer_size = sender.GetFileBufferMaxSize(); if (count > max_filebuffer_size && max_segments > 0) { //create segmented message!!! } else { count = (uint)Math.Min(count, max_filebuffer_size); //trim } byte[] file_buffer = f.ReadFileBlock(position, (int)count); sender.ReadFileResponse(adr, invoke_id, sender.GetSegmentBuffer(max_segments), position, count, end_of_file, file_buffer); } catch (Exception) { sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_ATOMIC_READ_FILE, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER); } } else { sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_ATOMIC_READ_FILE, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER); } } }
/// <summary> /// This method is based upon increasing the MaxInfoFrames in the MSTP. /// In Bacnet/IP this will have bad effect due to the retries /// </summary> public void DownloadFileByAsync(BacnetClient comm, BacnetAddress adr, BacnetObjectId object_id, string filename, Action <int> progress_action) { Cancel = false; //open file System.IO.FileStream fs = null; try { fs = System.IO.File.OpenWrite(filename); } catch (Exception ex) { throw new System.IO.IOException("Couldn't open file", ex); } uint max_count = (uint)comm.GetFileBufferMaxSize(); BacnetAsyncResult[] transfers = new BacnetAsyncResult[50]; byte old_max_info_frames = comm.Transport.MaxInfoFrames; comm.Transport.MaxInfoFrames = 50; //increase max_info_frames so that we can occupy line more. This might be against 'standard' try { int position = 0; bool eof = false; while (!eof && !Cancel) { //start many async transfers for (int i = 0; i < transfers.Length; i++) { transfers[i] = (BacnetAsyncResult)comm.BeginReadFileRequest(adr, object_id, position + i * (int)max_count, max_count, false); } //wait for all transfers to finish int current = 0; int retries = comm.Retries; while (current < transfers.Length) { if (!transfers[current].WaitForDone(comm.Timeout)) { if (--retries > 0) { transfers[current].Resend(); continue; } else { throw new System.IO.IOException("Couldn't read file"); } } retries = comm.Retries; uint count; byte[] file_buffer; int file_buffer_offset; Exception ex; comm.EndReadFileRequest(transfers[current], out count, out position, out eof, out file_buffer, out file_buffer_offset, out ex); transfers[current] = null; if (ex != null) { throw ex; } if (count > 0) { //write to file fs.Position = position; fs.Write(file_buffer, file_buffer_offset, (int)count); position += (int)count; if (progress_action != null) { progress_action(position); } } current++; } } } finally { fs.Close(); comm.Transport.MaxInfoFrames = old_max_info_frames; } }