This commit is contained in:
Kurt Moraw
2020-11-15 01:32:47 +01:00
parent f0fc9622a4
commit e335d4efbf
24 changed files with 1215 additions and 551 deletions
+5 -3
View File
@@ -1,5 +1,4 @@
using System;
using System.Runtime.InteropServices;
using System.Threading;
// Input: Byte Array
@@ -79,8 +78,10 @@ namespace oscardata
long filesize = data.Length;// statics.GetFileSize(filename);
Byte[] fnarr = statics.StringToByteArray(realname);
// CRC16 over complete file contents is the file ID
Crc c = new Crc();
UInt16 fncrc = c.crc16_messagecalc(fnarr, fnarr.Length);
UInt16 fncrc = c.crc16_messagecalc(data, data.Length);
// create the file header
// 50 bytes ... Filename (or first 50 chars of the filename)
@@ -151,13 +152,14 @@ namespace oscardata
if (txlen <= statics.PayloadLen)
{
// we just need to send one frame
txudp(txdata, txtype, statics.LastFrame);
txudp(txdata, txtype, statics.SingleFrame);
setSending(false); // transmission complete
}
else
{
// additional frame follow
// from txdata send one chunk of length statics.PayloadLen
// frame is repeated for preamble by hsmodem.cpp
Array.Copy(txdata, 0, txarr, 0, statics.PayloadLen);
txudp(txarr, txtype, statics.FirstFrame);
txpos = statics.PayloadLen;
+80 -21
View File
@@ -77,6 +77,7 @@
this.tb_shutdown = new System.Windows.Forms.TextBox();
this.bt_resetmodem = new System.Windows.Forms.Button();
this.textBox2 = new System.Windows.Forms.TextBox();
this.textBox3 = new System.Windows.Forms.TextBox();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.label6 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
@@ -100,7 +101,10 @@
this.timer_searchmodem = new System.Windows.Forms.Timer(this.components);
this.progressBar_fifo = new System.Windows.Forms.ProgressBar();
this.label_fifo = new System.Windows.Forms.Label();
this.textBox3 = new System.Windows.Forms.TextBox();
this.trackBar_maxlevel = new System.Windows.Forms.TrackBar();
this.tb_info = new System.Windows.Forms.TextBox();
this.label7 = new System.Windows.Forms.Label();
this.cb_stampinfo = new System.Windows.Forms.CheckBox();
this.statusStrip1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tabPage2.SuspendLayout();
@@ -115,6 +119,7 @@
((System.ComponentModel.ISupportInitialize)(this.tb_CAPvol)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.tb_PBvol)).BeginInit();
this.groupBox2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.trackBar_maxlevel)).BeginInit();
this.SuspendLayout();
//
// timer_udpTX
@@ -608,6 +613,18 @@
this.textBox2.Text = "in case the RX has sync\r\nproblems, it can be\r\nre-initialized here.";
this.textBox2.Visible = false;
//
// textBox3
//
this.textBox3.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.textBox3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBox3.ForeColor = System.Drawing.Color.Black;
this.textBox3.Location = new System.Drawing.Point(15, 46);
this.textBox3.Multiline = true;
this.textBox3.Name = "textBox3";
this.textBox3.Size = new System.Drawing.Size(151, 50);
this.textBox3.TabIndex = 12;
this.textBox3.Text = "only uncheck if modem runs on a separate PC";
//
// groupBox3
//
this.groupBox3.Controls.Add(this.label6);
@@ -709,6 +726,9 @@
//
// groupBox2
//
this.groupBox2.Controls.Add(this.cb_stampinfo);
this.groupBox2.Controls.Add(this.tb_info);
this.groupBox2.Controls.Add(this.label7);
this.groupBox2.Controls.Add(this.textBox5);
this.groupBox2.Controls.Add(this.cb_announcement);
this.groupBox2.Controls.Add(this.textBox4);
@@ -786,7 +806,7 @@
this.tb_callsign.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
this.tb_callsign.Location = new System.Drawing.Point(71, 28);
this.tb_callsign.Name = "tb_callsign";
this.tb_callsign.Size = new System.Drawing.Size(151, 20);
this.tb_callsign.Size = new System.Drawing.Size(104, 20);
this.tb_callsign.TabIndex = 1;
//
// label1
@@ -803,7 +823,7 @@
this.cb_stampcall.AutoSize = true;
this.cb_stampcall.Checked = true;
this.cb_stampcall.CheckState = System.Windows.Forms.CheckState.Checked;
this.cb_stampcall.Location = new System.Drawing.Point(71, 67);
this.cb_stampcall.Location = new System.Drawing.Point(71, 64);
this.cb_stampcall.Name = "cb_stampcall";
this.cb_stampcall.Size = new System.Drawing.Size(146, 17);
this.cb_stampcall.TabIndex = 2;
@@ -815,7 +835,7 @@
this.cb_savegoodfiles.AutoSize = true;
this.cb_savegoodfiles.Checked = true;
this.cb_savegoodfiles.CheckState = System.Windows.Forms.CheckState.Checked;
this.cb_savegoodfiles.Location = new System.Drawing.Point(71, 90);
this.cb_savegoodfiles.Location = new System.Drawing.Point(71, 102);
this.cb_savegoodfiles.Name = "cb_savegoodfiles";
this.cb_savegoodfiles.Size = new System.Drawing.Size(159, 17);
this.cb_savegoodfiles.TabIndex = 3;
@@ -833,10 +853,14 @@
"5500 8APSK BW: 2300 Hz",
"6000 8APSK BW: 2500 Hz (QO-100)",
"6600 8APSK BW: 2600 Hz",
"7200 8APSK BW: 2700 Hz"});
this.cb_speed.Location = new System.Drawing.Point(636, 593);
"7200 8APSK BW: 2700 Hz",
"5500 8PSK BW: 2300 Hz",
"6000 8PSK BW: 2500 Hz (QO-100)",
"6600 8PSK BW: 2600 Hz",
"7200 8PSK BW: 2700 Hz"});
this.cb_speed.Location = new System.Drawing.Point(658, 591);
this.cb_speed.Name = "cb_speed";
this.cb_speed.Size = new System.Drawing.Size(324, 21);
this.cb_speed.Size = new System.Drawing.Size(304, 21);
this.cb_speed.TabIndex = 11;
this.cb_speed.Text = "4410 QPSK BW: 2500 Hz (QO-100)";
this.cb_speed.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
@@ -844,7 +868,7 @@
// label_speed
//
this.label_speed.AutoSize = true;
this.label_speed.Location = new System.Drawing.Point(545, 596);
this.label_speed.Location = new System.Drawing.Point(567, 594);
this.label_speed.Name = "label_speed";
this.label_speed.Size = new System.Drawing.Size(71, 13);
this.label_speed.TabIndex = 12;
@@ -857,10 +881,10 @@
//
// progressBar_fifo
//
this.progressBar_fifo.Location = new System.Drawing.Point(636, 620);
this.progressBar_fifo.Location = new System.Drawing.Point(658, 618);
this.progressBar_fifo.Maximum = 20;
this.progressBar_fifo.Name = "progressBar_fifo";
this.progressBar_fifo.Size = new System.Drawing.Size(324, 23);
this.progressBar_fifo.Size = new System.Drawing.Size(304, 23);
this.progressBar_fifo.Step = 11;
this.progressBar_fifo.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
this.progressBar_fifo.TabIndex = 13;
@@ -868,29 +892,59 @@
// label_fifo
//
this.label_fifo.AutoSize = true;
this.label_fifo.Location = new System.Drawing.Point(545, 625);
this.label_fifo.Location = new System.Drawing.Point(567, 623);
this.label_fifo.Name = "label_fifo";
this.label_fifo.Size = new System.Drawing.Size(55, 13);
this.label_fifo.TabIndex = 14;
this.label_fifo.Text = "TX Buffer:";
//
// textBox3
// trackBar_maxlevel
//
this.textBox3.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.textBox3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBox3.ForeColor = System.Drawing.Color.Black;
this.textBox3.Location = new System.Drawing.Point(15, 46);
this.textBox3.Multiline = true;
this.textBox3.Name = "textBox3";
this.textBox3.Size = new System.Drawing.Size(151, 50);
this.textBox3.TabIndex = 12;
this.textBox3.Text = "only uncheck if modem runs on a separate PC";
this.trackBar_maxlevel.Location = new System.Drawing.Point(535, 591);
this.trackBar_maxlevel.Maximum = 100;
this.trackBar_maxlevel.Name = "trackBar_maxlevel";
this.trackBar_maxlevel.Orientation = System.Windows.Forms.Orientation.Vertical;
this.trackBar_maxlevel.Size = new System.Drawing.Size(45, 75);
this.trackBar_maxlevel.TabIndex = 15;
this.trackBar_maxlevel.TickFrequency = 10;
this.trackBar_maxlevel.TickStyle = System.Windows.Forms.TickStyle.TopLeft;
this.trackBar_maxlevel.Value = 50;
//
// tb_info
//
this.tb_info.Location = new System.Drawing.Point(243, 28);
this.tb_info.Name = "tb_info";
this.tb_info.Size = new System.Drawing.Size(413, 20);
this.tb_info.TabIndex = 22;
this.tb_info.Text = "tnx fer QSO, vy 73";
//
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(204, 31);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(28, 13);
this.label7.TabIndex = 21;
this.label7.Text = "Info:";
//
// cb_stampinfo
//
this.cb_stampinfo.AutoSize = true;
this.cb_stampinfo.Checked = true;
this.cb_stampinfo.CheckState = System.Windows.Forms.CheckState.Checked;
this.cb_stampinfo.Location = new System.Drawing.Point(71, 82);
this.cb_stampinfo.Name = "cb_stampinfo";
this.cb_stampinfo.Size = new System.Drawing.Size(128, 17);
this.cb_stampinfo.TabIndex = 23;
this.cb_stampinfo.Text = "Insert Info into picture";
this.cb_stampinfo.UseVisualStyleBackColor = true;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1293, 691);
this.Controls.Add(this.trackBar_maxlevel);
this.Controls.Add(this.label_fifo);
this.Controls.Add(this.progressBar_fifo);
this.Controls.Add(this.cb_speed);
@@ -925,6 +979,7 @@
((System.ComponentModel.ISupportInitialize)(this.tb_PBvol)).EndInit();
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.trackBar_maxlevel)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
@@ -1003,6 +1058,10 @@
private System.Windows.Forms.TextBox textBox4;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.TextBox textBox3;
private System.Windows.Forms.TrackBar trackBar_maxlevel;
private System.Windows.Forms.CheckBox cb_stampinfo;
private System.Windows.Forms.TextBox tb_info;
private System.Windows.Forms.Label label7;
}
}
+176 -462
View File
@@ -39,9 +39,9 @@ namespace oscardata
Byte frameinfo = (Byte)statics.FirstFrame;
String TXfilename;
int rxbytecounter = 0;
DateTime starttime;
String old_tsip = "";
bool modemrunning = false;
receivefile recfile = new receivefile();
public Form1()
{
@@ -240,9 +240,7 @@ namespace oscardata
// RX timer
int rxstat = 0;
int speed;
int tmpnum = 0;
int file_lostframes = 0;
int last_fileid = 0;
int maxlevel = 0;
private void timer_udprx_Tick(object sender, EventArgs e)
{
while (true)
@@ -260,383 +258,92 @@ namespace oscardata
speed = rxd[5];
speed <<= 8;
speed += rxd[6];
int dummy3 = rxd[7];
maxlevel = rxd[7];
int dummy4 = rxd[8];
int dummy5 = rxd[9];
if (rxstat == 4)
{
framelost++;
file_lostframes++;
}
calcBer(rxfrmnum);
rxbytecounter += statics.UdpBlocklen;
if (minfo == statics.FirstFrame)
file_lostframes = 0;
trackBar_maxlevel.Value = maxlevel;
int v1 = 255;
int v2 = 220;
if (maxlevel < 20 || maxlevel > 70) trackBar_maxlevel.BackColor = Color.FromArgb(v1,v2,v2);
else if (maxlevel < 30 || maxlevel > 60) trackBar_maxlevel.BackColor = Color.FromArgb(v1, v1, v2);
else trackBar_maxlevel.BackColor = Color.FromArgb(v2, v1, v2);
Byte[] rxdata = new byte[rxd.Length - 10];
Byte[] rxdata = new byte[rxd.Length - 10];
Array.Copy(rxd, 10, rxdata, 0, rxd.Length - 10);
//Console.WriteLine("minfo:" + minfo + " data:" + rxdata[0].ToString("X2") + " " + rxdata[1].ToString("X2"));
if (minfo == statics.FirstFrame)
{
rxbytecounter = rxdata.Length;
starttime = DateTime.UtcNow;
}
else
{
rxbytecounter += rxdata.Length;
}
TimeSpan ts = DateTime.UtcNow - starttime;
ts += new TimeSpan(0, 0, 0, 1);
// ===== ASCII RX ================================================
if (rxtype == statics.AsciiFile)
{
// if this is the first frame of a file transfer
// then read and remove the file info header
if (minfo == statics.FirstFrame || minfo == statics.SingleFrame)
{
//Console.WriteLine("first, single");
rxdata = ArraySend.GetAndRemoveHeader(rxdata);
if (rxdata == null) return;
if (last_fileid == ArraySend.FileID) return; // got first frame for this ID already
last_fileid = ArraySend.FileID;
}
else
last_fileid = 0;
// collect all received data into zip_RXtempfilename
Byte[] ba = null;
Byte[] nba;
try
{
ba = File.ReadAllBytes(statics.zip_RXtempfilename);
}
catch { }
if (ba != null)
{
//Console.WriteLine("write next");
nba = new Byte[ba.Length + rxdata.Length];
Array.Copy(ba, nba, ba.Length);
Array.Copy(rxdata, 0, nba, ba.Length, rxdata.Length);
}
else
{
//Console.WriteLine("write first");
nba = new Byte[rxdata.Length];
Array.Copy(rxdata, nba, rxdata.Length);
}
File.WriteAllBytes(statics.zip_RXtempfilename, nba);
long filesize = 0;
// check if transmission is finished
if (minfo == statics.LastFrame || minfo == statics.SingleFrame)
{
// statics.zip_RXtempfilename has the received data, but maybee too long (multiple of payload length)
// reduce for the real file length
Byte[] fc = File.ReadAllBytes(statics.zip_RXtempfilename);
Byte[] fdst = new byte[ArraySend.FileSize];
if(fc.Length < ArraySend.FileSize)
{
Console.WriteLine("len=" + fc.Length + " fz=" + ArraySend.FileSize);
return;
}
Array.Copy(fc, 0, fdst, 0, ArraySend.FileSize);
File.WriteAllBytes(statics.zip_RXtempfilename, fdst);
//Console.WriteLine("size:"+ ArraySend.FileSize.ToString());
//Console.WriteLine("last");
// unzip received data and store result in file: unzipped_RXtempfilename
rtb_RXfile.Text = "";
ZipStorer zs = new ZipStorer();
String fl = zs.unzipFile(statics.zip_RXtempfilename);
if (fl != null)
{
// save file
int idx = fl.LastIndexOf('/');
if (idx == -1) idx = fl.LastIndexOf('\\');
String fdest = fl.Substring(idx + 1);
fdest = statics.getHomePath("", fdest);
try { File.Delete(fdest); } catch { }
File.Move(fl, fdest);
filesize = statics.GetFileSize(fdest);
String serg = File.ReadAllText(fdest);
printText(rtb_RXfile, serg);
}
else
printText(rtb_RXfile, "unzip failed");
File.Delete(statics.zip_RXtempfilename);
}
int rest = ArraySend.FileSize - rxbytecounter;
if (rest < 0) rest = 0;
if (rest > 0)
label_rxfile.Text = "RX file: " + ArraySend.rxFilename + " " + rest.ToString() + " bytes";
else
label_rxfile.Text = "RX file: " + ArraySend.rxFilename + " " + filesize + " bytes";
if (minfo == statics.LastFrame)
ShowStatus((int)filesize, (int)ts.TotalSeconds);
else
ShowStatus(rxbytecounter, (int)ts.TotalSeconds);
}
// ===== HTML File RX ================================================
if (rxtype == statics.HTMLFile)
{
// if this is the first frame of a file transfer
// then read and remove the file info header
if (minfo == statics.FirstFrame)
{
rxdata = ArraySend.GetAndRemoveHeader(rxdata);
if (last_fileid == ArraySend.FileID) return; // got first frame for this ID already
last_fileid = ArraySend.FileID;
}
else
last_fileid = 0;
Byte[] ba = null;
Byte[] nba;
try
{
ba = File.ReadAllBytes(statics.zip_RXtempfilename);
}
catch { }
if (ba != null)
{
nba = new Byte[ba.Length + rxdata.Length];
Array.Copy(ba, nba, ba.Length);
Array.Copy(rxdata, 0, nba, ba.Length, rxdata.Length);
}
else
{
nba = new Byte[rxdata.Length];
Array.Copy(rxdata, nba, rxdata.Length);
}
File.WriteAllBytes(statics.zip_RXtempfilename, nba);
long filesize = 0;
if (minfo == statics.LastFrame)
{
// unzip received data
rtb_RXfile.Text = "";
ZipStorer zs = new ZipStorer();
// unzip returns filename+path of unzipped file
String fl = zs.unzipFile(statics.zip_RXtempfilename);
if (fl != null)
{
// save file
int idx = fl.LastIndexOf('/');
if (idx == -1) idx = fl.LastIndexOf('\\');
String fdest = fl.Substring(idx + 1);
fdest = statics.getHomePath("", fdest);
try { File.Delete(fdest); } catch { }
File.Move(fl, fdest);
filesize = statics.GetFileSize(fdest);
rxbytecounter = (int)statics.GetFileSize(fdest);
String serg = File.ReadAllText(fdest);
printText(rtb_RXfile, serg);
try
{
OpenUrl(fdest);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
else
printText(rtb_RXfile, "unzip failed");
}
int rest = ArraySend.FileSize - rxbytecounter;
if (rest < 0) rest = 0;
if (rest > 0)
label_rxfile.Text = "RX file: " + ArraySend.rxFilename + " " + rest.ToString() + " bytes";
else
label_rxfile.Text = "RX file: " + ArraySend.rxFilename + " " + filesize + " bytes";
if (minfo == statics.LastFrame)
ShowStatus(ArraySend.FileSize, (int)ts.TotalSeconds);
else
ShowStatus(rxbytecounter, (int)ts.TotalSeconds);
}
// ===== Binary File RX ================================================
if (rxtype == statics.BinaryFile)
{
// if this is the first frame of a file transfer
// then read and remove the file info header
if (minfo == statics.FirstFrame || minfo == statics.SingleFrame)
{
//Console.WriteLine("first, single");
rxdata = ArraySend.GetAndRemoveHeader(rxdata);
if (last_fileid == ArraySend.FileID) return; // got first frame for this ID already
last_fileid = ArraySend.FileID;
}
else
last_fileid = 0;
// collect all received data into zip_RXtempfilename
Byte[] ba = null;
Byte[] nba;
try
{
ba = File.ReadAllBytes(statics.zip_RXtempfilename);
}
catch { }
if (ba != null)
{
//Console.WriteLine("write next");
nba = new Byte[ba.Length + rxdata.Length];
Array.Copy(ba, nba, ba.Length);
Array.Copy(rxdata, 0, nba, ba.Length, rxdata.Length);
}
else
{
//Console.WriteLine("write first");
nba = new Byte[rxdata.Length];
Array.Copy(rxdata, nba, rxdata.Length);
}
File.WriteAllBytes(statics.zip_RXtempfilename, nba);
long filesize = 0;
// check if transmission is finished
if (minfo == statics.LastFrame || minfo == statics.SingleFrame)
{
// statics.zip_RXtempfilename has the received data, but maybee too long (multiple of payload length)
// reduce for the real file length
Byte[] fc = File.ReadAllBytes(statics.zip_RXtempfilename);
Byte[] fdst = new byte[ArraySend.FileSize];
if (fc.Length < ArraySend.FileSize)
{
Console.WriteLine("len=" + fc.Length + " fz=" + ArraySend.FileSize);
return;
}
Console.WriteLine("copy final binary file");
Array.Copy(fc, 0, fdst, 0, ArraySend.FileSize);
File.WriteAllBytes(statics.zip_RXtempfilename, fdst);
//Console.WriteLine("last");
// unzip received data and store result in file: unzipped_RXtempfilename
rtb_RXfile.Text = "";
ZipStorer zs = new ZipStorer();
String fl = zs.unzipFile(statics.zip_RXtempfilename);
if (fl != null)
{
int idx = fl.LastIndexOf('/');
if(idx == -1) idx = fl.LastIndexOf('\\');
String fdest = fl.Substring(idx + 1);
fdest = statics.getHomePath("", fdest);
try { File.Delete(fdest); } catch { }
File.Move(fl, fdest);
filesize = statics.GetFileSize(fdest);
//File.WriteAllBytes(fl, nba);
printText(rtb_RXfile, "binary file received\r\n");
printText(rtb_RXfile, "--------------------\r\n\r\n");
printText(rtb_RXfile, "file size : " + filesize + " byte\r\n\r\n");
printText(rtb_RXfile, "stored in : " + fdest + "\r\n\r\n");
printText(rtb_RXfile, "transmission time : " + ((int)ts.TotalSeconds).ToString() + " seconds" + "\r\n\r\n");
printText(rtb_RXfile, "transmission speed: " + ((int)(filesize*8/ts.TotalSeconds)).ToString() + " bit/s" + "\r\n\r\n");
}
else
printText(rtb_RXfile, "unzip failed");
File.Delete(statics.zip_RXtempfilename);
}
int rest = ArraySend.FileSize - rxbytecounter;
if (rest < 0) rest = 0;
if (rest > 0)
label_rxfile.Text = "RX file: " + ArraySend.rxFilename + " " + rest.ToString() + " bytes";
else
label_rxfile.Text = "RX file: " + ArraySend.rxFilename + " " + filesize + " bytes";
if (minfo == statics.LastFrame)
ShowStatus((int)filesize, (int)ts.TotalSeconds);
else
ShowStatus(rxbytecounter, (int)ts.TotalSeconds);
}
// ===== IMAGE RX ================================================
// ========= receive file ==========
// handle file receive
if (rxtype == statics.Image)
{
// if this is the first frame of a file transfer
// then read and remove the file info header
if (minfo == statics.FirstFrame)
if (recfile.receive(rxd))
{
rxdata = ArraySend.GetAndRemoveHeader(rxdata);
if (rxdata == null) return;
}
ih.receive_image(rxdata, minfo);
// show currect contents of rxtemp.jpg in RX picturebox
try
{
String fn = statics.addTmpPath("temp" + tmpnum.ToString() + ".jpg");
try
if (recfile.filename != null && recfile.filename.Length > 0 && minfo != statics.FirstFrame)
{
File.Delete(fn);
// reception complete, show stored file
Console.WriteLine("load " + recfile.filename);
pictureBox_rximage.BackgroundImage = Image.FromFile(recfile.filename);
pictureBox_rximage.Invalidate();
}
catch { }
tmpnum++;
fn = statics.addTmpPath("temp" + tmpnum.ToString() + ".jpg");
File.Copy(statics.jpg_tempfilename, fn);
try
if (recfile.pbmp != null)
{
if(statics.GetFileSize(fn) > 1200)
pictureBox_rximage.BackgroundImage = Image.FromFile(fn);
}
catch {
}
if (minfo == statics.LastFrame)
{
// file is complete, save in RX storage
// remove possible path from filename
String fname = ArraySend.rxFilename;
int idx = fname.IndexOfAny(new char[] {'\\','/' });
if (idx != -1)
// in case we can display portions of an image return this portion
try
{
try
{
fname = fname.Substring(idx + 1);
} catch{ }
}
if (!cb_savegoodfiles.Checked || (file_lostframes == 0 && cb_savegoodfiles.Checked))
{
// add home path and RXstorage path
String fnx = statics.getHomePath(statics.RXimageStorage, fname);
File.Copy(fn, fnx);
pictureBox_rximage.BackgroundImage = recfile.pbmp;
}
catch { }
}
}
catch { }
}
int rest = ArraySend.FileSize - rxbytecounter;
if (rest < 0) rest = 0;
if(rest > 0)
label_rximage.Text = "RX image: " + ArraySend.rxFilename + " remaining: " + rest.ToString() + " bytes";
else
label_rximage.Text = "RX image: " + ArraySend.rxFilename;
ShowStatus(rxbytecounter, (int)ts.TotalSeconds);
if (rxtype == statics.AsciiFile)
{
if(recfile.receive(rxd))
{
// ASCII file received, show in window
String serg = File.ReadAllText(recfile.filename);
printText(rtb_RXfile, serg);
}
}
if (rxtype == statics.HTMLFile)
{
if (recfile.receive(rxd))
{
// HTML file received, show in window
String serg = File.ReadAllText(recfile.filename);
printText(rtb_RXfile, serg);
// and show in browser
OpenUrl(recfile.filename);
}
}
if (rxtype == statics.BinaryFile)
{
if (recfile.receive(rxd))
{
// Binary file received, show statistics in window
printText(rtb_RXfile, "binary file received\r\n");
printText(rtb_RXfile, "--------------------\r\n\r\n");
printText(rtb_RXfile, "transmission time : " + ((int)recfile.runtime.TotalSeconds).ToString() + " seconds" + "\r\n\r\n");
printText(rtb_RXfile, "transmission speed: " + ((int)(recfile.filesize * 8 / recfile.runtime.TotalSeconds)).ToString() + " bit/s" + "\r\n\r\n");
printText(rtb_RXfile, "file size : " + recfile.filesize + " byte\r\n\r\n");
printText(rtb_RXfile, "file name : " + recfile.filename + "\r\n\r\n");
}
}
// ===== BER Test ================================================
if (rxtype == statics.BERtest)
{
RXstatus.Text = "BER: " + ber.ToString("E3") + " " + rxframecounter.ToString() + " frames received OK";
BERcheck(rxdata);
BERcheck(rxdata, rxfrmnum,minfo);
}
ShowStatus(rxtype, minfo);
}
}
@@ -894,18 +601,21 @@ namespace oscardata
Image img = new Bitmap(fullfn);
String cs = tb_callsign.Text;
if (cb_stampcall.Checked == false) cs = "";
String inf = tb_info.Text;
if (cb_stampinfo.Checked == false) inf = "";
if (!checkBox_big.Checked)
{
img = ih.ResizeImage(img, 320, 240, cs);
img = ih.ResizeImage(img, 320, 240, cs, inf);
// set quality by reducing the file size and save under default name
ih.SaveJpgAtFileSize(img, TXimagefilename, max_size / 2);
}
else
{
img = ih.ResizeImage(img, 640, 480, cs);
img = ih.ResizeImage(img, 640, 480, cs, inf);
// set quality by reducing the file size and save under default name
ih.SaveJpgAtFileSize(img, TXimagefilename, max_size);
}
pictureBox_tximage.Load(TXimagefilename);
TXRealFileSize = statics.GetFileSize(TXimagefilename);
ShowTXstatus();
@@ -977,11 +687,8 @@ namespace oscardata
private void button_startBERtest_Click(object sender, EventArgs e)
{
ber = 0;
framelost = 0;
totallostframes = 0;
last_rxfrmnum = -1;
rtb.Text = "";
missBlocks = 0;
frameinfo = (Byte)statics.FirstFrame;
txcommand = statics.BERtest;
}
@@ -991,36 +698,23 @@ namespace oscardata
txcommand = statics.noTX;
}
DateTime dt = DateTime.Now;
int rxframecounter = 0;
int framelost = 0;
int last_rxfrmnum = -1;
double ber = 0;
int totallostframes = 0;
void calcBer(int rxfrmnum)
int lastfrmnum = 0;
int missBlocks = 0;
private void BERcheck(Byte[] rxdata, int frmnum, int minfo)
{
if (last_rxfrmnum == -1)
{
last_rxfrmnum = rxfrmnum;
return;
}
if (minfo == statics.FirstFrame)
rxframecounter = 0;
// calc gap
int gap = ((rxfrmnum+1024) - last_rxfrmnum) % 1024;
rxframecounter += gap;
totallostframes += (gap - 1);
if (lastfrmnum == frmnum) return;
lastfrmnum = frmnum;
int totalbits = rxframecounter * 258 * 8;
int errorbits = totallostframes * 258 * 8;
ber = (double)totallostframes / (double)rxframecounter;
rxframecounter++;
last_rxfrmnum = rxfrmnum;
}
private void BERcheck(Byte[] rxdata)
{
String line = "RX: " + rxframecounter.ToString().PadLeft(6, ' ') + " ";
missBlocks += (frmnum - rxframecounter);
if (missBlocks < 0) missBlocks = 0;
String line = "RX: " + frmnum.ToString().PadLeft(6, ' ') + " "; // + rxframecounter + " " + missBlocks + " ";
rxframecounter = frmnum;
// print payload (must be printable chars)
line += Encoding.UTF8.GetString(rxdata).Substring(0, 50) + " ...";
@@ -1060,28 +754,72 @@ namespace oscardata
line += " " + bits.ToString() + " " + sbit + " " + bytes.ToString() + " " + sbyt;
line += " BER: " + string.Format("{0:#.##E+0}", ber); // ber.ToString("E3");
line += "\r\n";
printText(rtb,line);
int fl = framelost;
if (fl <= 1) fl = 0;
String s = "Speed: " + speed.ToString() + " bit/s, Lost Frames: " + fl.ToString();
toolStripStatusLabel.Text = s;
}
private void ShowStatus(int rxbytecounter, int totalseconds)
int[] blockres = new int[2];
private void ShowStatus(int rxtype, int minfo)
{
int fl = framelost;
if (fl <= 1) fl = 0;
String s = "Speed: " + speed.ToString() + " bit/s, Lost Frames: " + fl.ToString();
toolStripStatusLabel.Text = s;
if (minfo == statics.FirstFrame)
rxbytecounter = 0;
int rspeed = 0;
if (totalseconds >= 1)
rspeed = rxbytecounter * 8 / totalseconds;
RXstatus.Text = "received " + rxbytecounter + " byte " + totalseconds + " s, " + rspeed + " bit/s";
// calculate speed
int fsz = (int)recfile.filesize;
if (fsz == 0) fsz = ArraySend.FileSize; // during reception we do not have the final size, use the transmitted size
// fsz = real or zipped file size, whatever available
// transmitted size in % of zipped file
int txsize = 0;
if (ArraySend.FileSize > 0)
txsize = (recfile.rxbytes * 100) / ArraySend.FileSize;
// transmitted size of real filesize
int txreal = (fsz * txsize) / 100;
// speed
int speed_bps = 0;
if(recfile.runtime.TotalSeconds > 0)
speed_bps = (int)(((double)txreal * 8.0) / recfile.runtime.TotalSeconds);
// show RX status on top of the RX windows
String s = "RX: ";
recfile.blockstat(blockres);
int missingBlocks = blockres[0] - blockres[1];
if (ArraySend.rxFilename != null && ArraySend.rxFilename.Length > 0)
{
s += ArraySend.rxFilename + " ";
s += recfile.rxbytes / 1000 + " of " + ArraySend.FileSize / 1000 + " kB ";
s += Math.Truncate(recfile.runtime.TotalSeconds) + " s, ";
s += blockres[1] + " of " + blockres[0] + " blocks OK";
}
else
s += "wait for RX";
if (rxtype == statics.Image)
label_rximage.Text = s;
if (rxtype == statics.AsciiFile || rxtype == statics.HTMLFile || rxtype == statics.BinaryFile)
label_rxfile.Text = s;
// show speed in status line at the left side
toolStripStatusLabel.Text = "Line Speed: " + speed.ToString() + " bps";
if (missBlocks < 0) missBlocks = 0;
if (missingBlocks < 0) missingBlocks = 0;
// show RX status in the status line
if (rxtype == statics.BERtest)
RXstatus.Text = "RXed: " + rxbytecounter + " Byte. Missing blocks: " + missBlocks;
else
{
if(fsz > 0)
RXstatus.Text = "RXed: " + fsz + " Byte. Missing blocks: " + missingBlocks;
else
RXstatus.Text = "RXed: " + rxbytecounter + " Byte. Missing blocks: " + missingBlocks;
}
if(speed_bps > 0)
RXstatus.Text += " Net Speed:" + speed_bps + " bps";
}
private void button_cancelimg_Click(object sender, EventArgs e)
@@ -1139,7 +877,10 @@ namespace oscardata
label_txfile.Location = new Point(rtb_TXfile.Location.X, ly);
label_rxfile.Location = new Point(rtb_RXfile.Location.X, ly);
label_speed.Location = new Point(panel_txspectrum.Location.X + panel_txspectrum.Size.Width + 20,panel_txspectrum.Location.Y+10);
trackBar_maxlevel.Location = new Point(panel_txspectrum.Location.X + panel_txspectrum.Size.Width + 5, panel_txspectrum.Location.Y);
trackBar_maxlevel.Size = new Size(20, panel_txspectrum.Size.Height);
label_speed.Location = new Point(trackBar_maxlevel.Location.X + trackBar_maxlevel.Size.Width + 15,panel_txspectrum.Location.Y+10);
cb_speed.Location = new Point(label_speed.Location.X + label_speed.Size.Width + 10, label_speed.Location.Y-5);
label_fifo.Location = new Point(label_speed.Location.X, label_speed.Location.Y + 35);
@@ -1207,26 +948,6 @@ namespace oscardata
statics.ModemIP = "1.2.3.4";
}
private void bt_file_ascii_Click(object sender, EventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "Text Files(*.txt*; *.*)|*.txt; *.*";
if (open.ShowDialog() == DialogResult.OK)
{
TXfilename = open.FileName;
TXRealFilename = open.SafeFileName;
String text = File.ReadAllText(TXfilename);
rtb_TXfile.Text = text;
txcommand = statics.AsciiFile;
// compress file
ZipStorer zs = new ZipStorer();
zs.zipFile(statics.zip_TXtempfilename,open.SafeFileName,open.FileName);
TXRealFileSize = statics.GetFileSize(statics.zip_TXtempfilename);
ShowTXstatus();
}
}
private void bt_file_send_Click(object sender, EventArgs e)
{
rtb_RXfile.Text = "";
@@ -1236,36 +957,35 @@ namespace oscardata
ArraySend.Send(textarr, (Byte)txcommand, TXfilename, TXRealFilename);
}
private void bt_file_ascii_Click(object sender, EventArgs e)
{
bt_sendFile("Text Files(*.txt*; *.*)|*.txt; *.*", statics.AsciiFile);
}
private void button2_Click(object sender, EventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "HTML Files(*.html; *.htm; *.*)|*.html; *.htm; *.*";
if (open.ShowDialog() == DialogResult.OK)
{
TXfilename = open.FileName;
TXRealFilename = open.SafeFileName;
String text = File.ReadAllText(TXfilename);
rtb_TXfile.Text = text;
txcommand = statics.HTMLFile;
// compress file
ZipStorer zs = new ZipStorer();
zs.zipFile(statics.zip_TXtempfilename, open.SafeFileName, open.FileName);
TXRealFileSize = statics.GetFileSize(statics.zip_TXtempfilename);
ShowTXstatus();
}
bt_sendFile("HTML Files(*.html; *.htm; *.*)|*.html; *.htm; *.*", statics.HTMLFile);
}
private void bt_sendBinaryFile_Click(object sender, EventArgs e)
{
bt_sendFile("All Files(*.*)|*.*", statics.BinaryFile);
}
private void bt_sendFile(String filter, int cmd)
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "All Files(*.*)|*.*";
open.Filter = filter;
if (open.ShowDialog() == DialogResult.OK)
{
txcommand = cmd;
TXfilename = open.FileName;
TXRealFilename = open.SafeFileName;
rtb_TXfile.Text = "Binary file " + TXfilename + " loaded";
txcommand = statics.BinaryFile;
if (txcommand == statics.BinaryFile)
rtb_TXfile.Text = "Binary file " + TXfilename + " loaded";
else
rtb_TXfile.Text = File.ReadAllText(TXfilename);
// compress file
ZipStorer zs = new ZipStorer();
zs.zipFile(statics.zip_TXtempfilename, open.SafeFileName, open.FileName);
@@ -1277,26 +997,17 @@ namespace oscardata
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
int idx = cb_speed.SelectedIndex;
int real_rate=4000;
switch (idx)
{
case 0: real_rate = 3000; break;
case 1: real_rate = 3150; break;
case 2: real_rate = 3675; break;
case 3: real_rate = 4000; break;
case 4: real_rate = 4410; break;
case 5: real_rate = 4800; break;
case 6: real_rate = 5525; break;
case 7: real_rate = 6000; break;
case 8: real_rate = 6615; break;
case 9: real_rate = 7200; break;
}
statics.setDatarate(real_rate);
if (cb_speed.Text.Contains("3000")) statics.real_datarate = 3000;
if (cb_speed.Text.Contains("4000")) statics.real_datarate = 4000;
if (cb_speed.Text.Contains("4410")) statics.real_datarate = 4410;
if (cb_speed.Text.Contains("4800")) statics.real_datarate = 4800;
if (cb_speed.Text.Contains("5500")) statics.real_datarate = 5500;
if (cb_speed.Text.Contains("6000")) statics.real_datarate = 6000;
if (cb_speed.Text.Contains("6600")) statics.real_datarate = 6600;
if (cb_speed.Text.Contains("7200")) statics.real_datarate = 7200;
Byte[] txdata = new byte[statics.PayloadLen + 2];
int idx = cb_speed.SelectedIndex;
txdata[0] = (Byte)statics.ResamplingRate; // BER Test Marker
txdata[1] = (Byte)idx;
@@ -1307,7 +1018,6 @@ namespace oscardata
// stop any ongoing transmission
button_cancelimg_Click(null, null);
}
private void timer_searchmodem_Tick(object sender, EventArgs e)
{
@@ -1415,6 +1125,9 @@ namespace oscardata
s = ReadString(sr);
cb_autostart.Checked = (s == "1");
try { cb_announcement.Text = ReadString(sr); } catch { }
s = ReadString(sr);
try { cb_stampinfo.Checked = (s == "1"); } catch { }
try { tb_info.Text = ReadString(sr); } catch { }
}
}
catch
@@ -1443,7 +1156,8 @@ namespace oscardata
sw.WriteLine(tb_CAPvol.Value.ToString());
sw.WriteLine(cb_autostart.Checked ? "1" : "0");
sw.WriteLine(cb_announcement.Text);
sw.WriteLine(cb_stampinfo.Checked ? "1" : "0");
sw.WriteLine(tb_info.Text);
}
}
catch { }
Binary file not shown.
-11
View File
@@ -54,7 +54,6 @@ namespace oscardata
public static int UdpBlocklen = 258; // length of a data block (UDP)
public static int PayloadLen = UdpBlocklen - FecLen - 3 - 2 - 2;
public static int real_datarate = 6000; // speed in bit/s
static int datarate = (real_datarate * 100) / 99; // little bit more to avoid underruns
public static String jpg_tempfilename = "rxdata.jpg";
public static String zip_TXtempfilename = "TXtemp.zip";
public static String zip_RXtempfilename = "RXtemp.zip";
@@ -67,16 +66,6 @@ namespace oscardata
public static String[] AudioCAPdevs;
public static int PBfifousage = 0;
public static void setDatarate(int rate)
{
real_datarate = rate;
datarate = (rate * 100) / 99;
}
public static int getDatarate()
{
return datarate;
}
public static String[] getOwnIPs()
{
+14 -1
View File
@@ -57,7 +57,7 @@ namespace oscardata
return 5;
}
public Bitmap ResizeImage(Image image, int width, int height, String callsign)
public Bitmap ResizeImage(Image image, int width, int height, String callsign, String info)
{
// get original size of img
int x = image.Width;
@@ -90,6 +90,19 @@ namespace oscardata
g.DrawString(callsign, fnt, Brushes.Blue, 5, 5);
}
}
if (info != "")
{
using (var fnt = new Font("Verdana", 11.0f))
{
int ypos = nh - 30;
var size = g.MeasureString(info, fnt);
var rect = new RectangleF(5, ypos, size.Width, size.Height);
SolidBrush opaqueBrush = new SolidBrush(Color.FromArgb(128, 255, 255, 255));
g.FillRectangle(opaqueBrush, rect);
g.DrawString(info, fnt, Brushes.Blue, 5, ypos);
}
}
}
return destImage;
+1
View File
@@ -67,6 +67,7 @@
<Compile Include="imagehandler.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="receivefile.cs" />
<Compile Include="udp.cs" />
<Compile Include="zip.cs" />
<EmbeddedResource Include="Form1.resx">
+533
View File
@@ -0,0 +1,533 @@
/*
* High Speed modem to transfer data in a 2,7kHz SSB channel
* =========================================================
* Author: DJ0ABR
*
* (c) DJ0ABR
* www.dj0abr.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* File restauration process
* =========================
* 1) file header is received, get filename and file ID (which is the CRC16 over the complete file contents)
* 2) is this file already existing ? yes-> 3)
* 3) this file does not exist -> 4)
*
* 3) file with this name and ID exists is already, cancel reception, show file
*
* 4) file dows not exist, receive the blocks
* 5) a block is missing -> find a previous block-file with this name+ID. If exists, take the block from this file
* 6) reception complete, the files is OK -> save the file, delete a block file
* 7) reception complete, the files is incomplete -> save the block file for late use
*
* Filenames:
* ----------
* transmitter:
* the sender takes any filename, but the ID is the C&C16 over the file contents (to identify different files with the same name)
*
* receiver:
* use the filename as transmitted for the good original file
* the blockfile's filename is the ID in Ascii-Hex representation, i.e.: ID= 0x45 0xfe ... filename is: 45FE.blk
*/
using System;
using System.Drawing;
using System.IO;
namespace oscardata
{
class receivefile
{
int rxtype;
int rxfrmnum;
int minfo;
int rxstat;
int speed;
int maxlevel;
int dummy4;
int dummy5;
Byte[] rxdata = new byte[statics.PayloadLen];
// file buffer, we have max 2^10=1024 blocks with 219 bytes each = 224.256kB
Byte[,] blockbuf = new byte[1024, statics.PayloadLen];
bool[] blockvalid = new bool[1024];
int blockidx;
Byte[] firstblock;
bool receiving = false;
public String filename = null;
public String StatusText = "";
public long filesize = 0;
public Bitmap pbmp = null;
DateTime starttime;
public TimeSpan runtime;
public int rxbytes = 0;
bool autoRXnum = false;
String blockFilename = "";
public bool receive(Byte []rxdp)
{
// read frame header
if(!getFrameHeader(rxdp))
{
// invalid situation
blockidx = 0;
receiving = false;
return false;
}
// receive first frame of a transmission
if (minfo == statics.FirstFrame || minfo == statics.SingleFrame)
{
starttime = DateTime.UtcNow;
rxbytes = 0;
filesize = 0;
filename = "";
if (!StartFileRX()) return false; // invalid file
// check if file already exists
if (fileExists())
{
// exists already, no need to receive
filename = makeRXfilename();
if (rxtype == statics.Image)
{
try
{
// show existing image
Image img = Image.FromFile(filename);
pbmp = new Bitmap(img);
}
catch { pbmp = null; }
}
receiving = false;
return true;
}
}
if (minfo != statics.FirstFrame)
runtime = DateTime.UtcNow - starttime;
// receive continous frames of a transmission
if (minfo == statics.NextFrame)
{
// there are more frames for this file
if(!FileRX())
{
// invalid situation
blockidx = 0;
receiving = false;
return false;
}
}
rxbytes += statics.PayloadLen;
// receive last file of a transmission
if (minfo == statics.LastFrame || minfo == statics.SingleFrame)
{
if (!FileRX())
{
// invalid situation
blockidx = 0;
receiving = false;
return false;
}
// the last block was received ok
// save file if all blocks valid
SaveFile();
blockidx = 0;
receiving = false;
if (rxtype == statics.AsciiFile || rxtype == statics.HTMLFile || rxtype == statics.BinaryFile)
{
// these file type must be unzipped
handleZIPfiles();
receiving = false;
return true;
}
}
if (rxtype == statics.Image)
{
// build bitmap from received data
pbmp = buildBitmap();
return true;
}
return false;
}
bool getFrameHeader(Byte[] rxd)
{
rxtype = rxd[0];
rxfrmnum = rxd[1];
rxfrmnum <<= 8;
rxfrmnum += rxd[2];
minfo = rxd[3];
rxstat = rxd[4];
speed = rxd[5];
speed <<= 8;
speed += rxd[6];
maxlevel = rxd[7];
dummy4 = rxd[8];
dummy5 = rxd[9];
if (rxfrmnum >= 1024) return false;
if (!autoRXnum)
blockidx = rxfrmnum;
Array.Copy(rxd, 10, rxdata, 0, rxd.Length - 10);
return true;
}
bool StartFileRX()
{
if (receiving) return true; // already open
//Console.WriteLine("first block");
// store first block
filename = null;
if (rxfrmnum != 0)
{
Console.WriteLine("blockidx auto increment");
autoRXnum = true; // for old compatibility, increment blockidx by ourself
}
blockidx = 0;
if (rxdata.Length > statics.PayloadLen)
{
Console.WriteLine("wrong payload size: " + rxdata.Length + " expected:" + statics.PayloadLen);
return false; // wrong size
}
// read file header
ArraySend.rxFilename = "";
firstblock = ArraySend.GetAndRemoveHeader(rxdata);
if (firstblock == null)
{
Console.WriteLine("invalid File header");
return false; // cannot read header, file is corrupted, ignore
}
// get block filename for this file
blockFilename = idToFilename(ArraySend.FileID);
// init valid blocks table
for(int i=0; i<blockvalid.Length; i++)
blockvalid[i] = false;
// insert previously received blocks
readBlocks();
// insert first block
for (int i = 0; i < rxdata.Length; i++)
blockbuf[blockidx, i] = rxdata[i]; // contains file info header and file data
// mark first block as valid
blockvalid[blockidx] = true;
receiving = true;
return true;
}
String idToFilename(int id)
{
char hexToChar(Byte h)
{
if (h >= 0 && h <= 9) return (char)(0x30 + h);
return (char)(0x41 + h - 10);
}
Byte b0 = (Byte)((id >> 12) & 0x0f);
Byte b1 = (Byte)((id >> 8) & 0x0f);
Byte b2 = (Byte)((id >> 4) & 0x0f);
Byte b3 = (Byte)(id & 0x0f);
String s = "";
s += hexToChar(b0);
s += hexToChar(b1);
s += hexToChar(b2);
s += hexToChar(b3);
s += ".blk";
return statics.getHomePath("blocks", s);
}
public bool blockstat(int[] result)
{
if (blockidx == 0) return false;
int ok = 0;
for (int i = 0; i <= blockidx; i++)
{
if (blockvalid[i]) ok++;
}
result[0] = blockidx+1; // +1 because we start with block 0
result[1] = ok;
return true;
}
void saveBlocks()
{
try
{
using (BinaryWriter writer = new BinaryWriter(File.Open(blockFilename, FileMode.Create)))
{
for (int i = 0; i <= blockidx; i++)
{
// first byte of a block: valid/invalid block
Byte[] blk = new byte[statics.PayloadLen + 1];
for (int j = 0; j < statics.PayloadLen; j++)
blk[j + 1] = blockbuf[i, j];
blk[0] = blockvalid[i] ? (Byte)1 : (Byte)0;
writer.Write(blk);
}
writer.Close();
}
}
catch { }
}
void readBlocks()
{
Byte[] blk = new byte[statics.PayloadLen + 1];
int idx = 0;
try
{
using (BinaryReader reader = new BinaryReader(File.Open(blockFilename, FileMode.Open)))
{
while (true)
{
int ret = reader.Read(blk, 0, statics.PayloadLen + 1);
if (ret != statics.PayloadLen + 1) break;
for (int j = 0; j < statics.PayloadLen; j++)
{
if (blk[0] == 1)
{
blockbuf[idx, j] = blk[j + 1];
blockvalid[idx] = true;
}
}
idx++;
}
reader.Close();
}
}
catch { }
}
bool FileRX()
{
if (!receiving)
{
Console.WriteLine("next/last block: not receiving, first block missing?");
return false;
}
//Console.WriteLine("next/last block");
// store next block
if (rxdata.Length != statics.PayloadLen)
{
Console.WriteLine("wrong payload size: " + rxdata.Length + " expected:" + statics.PayloadLen);
return false; // wrong size
}
if (autoRXnum)
{
blockidx++;
Console.WriteLine("blockidx: do auto increment " + blockidx);
}
for (int i = 0; i < rxdata.Length; i++)
blockbuf[blockidx, i] = rxdata[i];
blockvalid[blockidx] = true;
return true;
}
// build full path+filename from received filename
String makeRXfilename()
{
String fn = "";
// remove possible path from filename
String fname = ArraySend.rxFilename;
int idx = fname.IndexOfAny(new char[] { '\\', '/' });
if (idx != -1)
{
try
{
fname = fname.Substring(idx + 1);
}
catch { }
}
if (rxtype == statics.Image)
fn = statics.getHomePath(statics.RXimageStorage, fname);
else
fn = statics.getHomePath("", fname);
return fn;
}
bool fileExists()
{
String fn = makeRXfilename();
if (!File.Exists(fn)) return false;
// File exists, but is the ID the same ?
Byte[] ba = File.ReadAllBytes(fn);
if (ba == null) return false;
Crc c = new Crc();
int fncrc = c.crc16_messagecalc(ba, ba.Length);
if (ArraySend.FileID != fncrc) return false;
return true;
}
bool SaveFile()
{
Console.WriteLine("save file");
// check if all blocks ok
for (int i = 0; i <= blockidx; i++)
{
if (blockvalid[i] == false)
{
Console.WriteLine("save file: not all blocks ok");
// save block file
saveBlocks();
return false;
}
}
// reception was ok, blockfile no more needed, delete it
// file is OK, blockfile no more needed, delete it
try { File.Delete(blockFilename); } catch { }
// make filename
filename = makeRXfilename();
Console.WriteLine("save at " + filename);
using (BinaryWriter writer = new BinaryWriter(File.Open(filename, FileMode.Create)))
{
for (int i = 0; i <= blockidx; i++)
{
if (i == 0)
writer.Write(firstblock);
else
{
Byte[] blk = new byte[statics.PayloadLen];
for (int j = 0; j < statics.PayloadLen; j++)
blk[j] = blockbuf[i, j];
writer.Write(blk);
}
}
writer.Close();
}
return true;
}
Bitmap buildBitmap()
{
Bitmap bmp = null;
using (MemoryStream memStream = new MemoryStream())
{
for (int i = 0; i <= blockidx; i++)
{
if (i == 0)
memStream.Write(firstblock, 0, firstblock.Length);
else
{
Byte[] blk = new byte[statics.PayloadLen];
for (int j = 0; j < statics.PayloadLen; j++)
blk[j] = blockbuf[i, j];
memStream.Write(blk, 0, blk.Length);
}
}
try
{
// first assign it to an "Image", this checks if the image is valid
Image img = Image.FromStream(memStream);
bmp = new Bitmap(img);
}
catch
{
return null;
}
}
return bmp;
}
void handleZIPfiles()
{
if (filename == null)
{
Console.WriteLine("handleZIPfile: no filename");
return;
}
// filename has the received data, but maybe too long (multiple of payload length)
// reduce for the real file length
Byte[] fc = File.ReadAllBytes(filename);
Byte[] fdst = new byte[ArraySend.FileSize];
if (fc.Length < ArraySend.FileSize)
{
Console.WriteLine("file not complete: got len=" + fc.Length + " expected len=" + ArraySend.FileSize);
return;
}
Array.Copy(fc, 0, fdst, 0, ArraySend.FileSize);
File.WriteAllBytes(statics.zip_RXtempfilename, fdst); // the received file (still zipped) is here
// unzip received data and store result in file: unzipped_RXtempfilename
ZipStorer zs = new ZipStorer();
String fl = zs.unzipFile(statics.zip_RXtempfilename);
if (fl != null)
{
// save file
// fl is the filename of the file inside the zip file, so the originally zipped file
// remove path to get just the filename
int idx = fl.LastIndexOf('/');
if (idx == -1) idx = fl.LastIndexOf('\\');
String fdest = fl.Substring(idx + 1);
fdest = statics.getHomePath("", fdest);
// fdest is the file in the oscardata's user home directoty
// remove old file with same name
try { File.Delete(fdest); } catch { }
// move the unzipped file to the final location
File.Move(fl, fdest);
filesize = statics.GetFileSize(fdest);
StatusText = "unzip OK";
}
else
StatusText = "unzip failed";
File.Delete(statics.zip_RXtempfilename);
}
}
}