diff --git a/InTheHand.Net.Obex/ObexHeader.cs b/InTheHand.Net.Obex/ObexHeader.cs
index 619ff1c..a2e304f 100644
--- a/InTheHand.Net.Obex/ObexHeader.cs
+++ b/InTheHand.Net.Obex/ObexHeader.cs
@@ -2,7 +2,7 @@
//
// InTheHand.Net.ObexHeader
//
-// Copyright (c) 2003-2023 In The Hand Ltd, All rights reserved.
+// Copyright (c) 2003-2024 In The Hand Ltd, All rights reserved.
// This source code is licensed under the MIT License
using System;
@@ -36,7 +36,7 @@ public enum ObexHeader : byte
Type = 0x42,
///
- /// Date/time stamp – ISO 8601 version - preferred
+ /// Date/time stamp – ISO 8601 version - preferred
///
/// Byte sequence. ASCII encoded ISO 8601 DateTime string.
Time = 0x44,
@@ -132,7 +132,7 @@ public enum ObexHeader : byte
Length = 0xC3,
///
- /// Date/time stamp – 4-byte version.
+ /// Date/time stamp – 4-byte version.
///
/// 4-byte unsigned integer.
[Obsolete("Use ObexHeader.Time instead", false)]
diff --git a/InTheHand.Net.Obex/ObexListenerContext.cs b/InTheHand.Net.Obex/ObexListenerContext.cs
index efbb86e..e045678 100644
--- a/InTheHand.Net.Obex/ObexListenerContext.cs
+++ b/InTheHand.Net.Obex/ObexListenerContext.cs
@@ -28,6 +28,7 @@ public class ObexListenerContext
private MemoryStream bodyStream = new MemoryStream();
private EndPoint localEndPoint;
private EndPoint remoteEndPoint;
+ private string _path;
ushort remoteMaxPacket = 0;
internal ObexListenerContext(Socket s)
@@ -133,7 +134,138 @@ internal ObexListenerContext(Socket s)
request = new ObexListenerRequest(bodyStream.ToArray(), headers, localEndPoint, remoteEndPoint);
}
+ #region David Rodgers added
+ // David Rodgers - Added
+ // Uses stream communication rather than socket for compatability with Android
+ // public allows bypassing ObexListener and using BluetoothListener directly for using custom service id for app to app transfer
+ // TODO - extend ObexListener to handle custom service id's
+ public ObexListenerContext(Stream rs)
+ {
+
+ buffer = new byte[0x2000];
+ bool moretoreceive = true;
+ bool putCompleted = false;
+
+ while (moretoreceive)
+ {
+ //receive the request and store the data for the request object
+ int received = 0;
+ try
+ {
+
+ while (received < 3)
+ {
+ //int readLen = s.Receive(buffer, received, 3 - received, SocketFlags.None);
+ int readLen = rs.Read(buffer, received, 3 - received);
+ if (readLen == 0)
+ {
+ moretoreceive = false;
+ if (received == 0)
+ {
+ break; // Waiting for first byte of packet -- OK to close then.
+ }
+ else
+ {
+ throw new EndOfStreamException("Connection lost.");
+ }
+ }
+ received += readLen;
+ }
+ //Debug.WriteLine(s.GetHashCode().ToString("X8") + ": RecvH", "ObexListener");
+ }
+ catch (Exception se)
+ {
+ //Console.Write(se.Message);
+ HandleConnectionError(se);
+ }
+
+ if (received == 3)
+ {
+
+ ObexMethod method = (ObexMethod)buffer[0];
+ //get length (excluding the 3 byte header)
+
+ short len = (short)(IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buffer, 1)) - 3);
+ if (len > 0)
+ {
+ int iPos = 0;
+
+ while (iPos < len)
+ {
+ int wanted = len - iPos;
+ Debug.Assert(wanted > 0, "NOT wanted > 0, is: " + wanted);
+ int receivedBytes = rs.Read(buffer, iPos + 3, wanted);
+ if (receivedBytes == 0)
+ {
+ moretoreceive = false;
+ throw new EndOfStreamException("Connection lost.");
+ }
+ iPos += receivedBytes;
+ }
+ }
+
+ byte[] responsePacket; // Don't init, then the compiler will check that it's set below.
+ //Debug.WriteLine(s.GetHashCode().ToString("X8") + ": Method: " + method, "ObexListener");
+ responsePacket = HandleAndMakeResponse(ref moretoreceive, ref putCompleted, method);
+
+ try
+ {
+ System.Diagnostics.Debug.Assert(responsePacket != null, "Must always respond to the peer.");
+ if (responsePacket != null)
+ {
+ rs.Write(responsePacket, 0, responsePacket.Length);
+ rs.Flush();
+
+ }
+
+ }
+ catch (Exception se)
+ {
+ //Console.WriteLine(se.Message);
+ HandleConnectionError(se);
+ }
+ }
+ else
+ {
+ moretoreceive = false;
+ }
+
+ }//while
+
+ Debug.WriteLine(rs.GetHashCode().ToString("X8") + ": Completed", "ObexListener");
+ rs.Close();
+ rs = null;
+
+ if (!putCompleted)
+ {
+ // Should not return the request.
+ throw new ProtocolViolationException("No PutFinal received.");
+ }
+ request = new ObexListenerRequest(bodyStream.ToArray(), headers, localEndPoint, remoteEndPoint);
+ _path = headers["NAME"];
+ }
+
+ // David Rodgers added
+ // retrieve the Md5 checksum generated by the sender from the headers
+ public string getSentMD5()
+ {
+ return headers["ContentMd5"];
+ }
+
+ ///
+ /// Gets the filename of the received file from header
+ ///
+ // David Rodgers added
+ //
+ public string getPath
+ {
+ get
+ {
+ return _path;
+ }
+ }
+ #endregion
private byte[] HandleAndMakeResponse(ref bool moretoreceive, ref bool putCompleted, ObexMethod method)
{
byte[] responsePacket;
diff --git a/InTheHand.Net.Obex/ObexWebRequest.cs b/InTheHand.Net.Obex/ObexWebRequest.cs
index a49515f..138d61b 100644
--- a/InTheHand.Net.Obex/ObexWebRequest.cs
+++ b/InTheHand.Net.Obex/ObexWebRequest.cs
@@ -2,7 +2,7 @@
//
// InTheHand.Net.ObexWebRequest
//
-// Copyright (c) 2003-2023 In The Hand Ltd, All rights reserved.
+// Copyright (c) 2003-2024 In The Hand Ltd, All rights reserved.
// This source code is licensed under the MIT License
using System;
@@ -1056,8 +1056,16 @@ public override WebResponse GetResponse()
ObexStatusCode status;
MemoryStream ms = new MemoryStream();
WebHeaderCollection responseHeaders = new WebHeaderCollection();
+ // Added David Rodgers to facilitate sending an Md5 checksum in the header
+ // could be expanded to loop through Headers and add any headers that are set by the user
+ if (Headers["ContentMd5"] != null)
+ {
+ responseHeaders.Add("ContentMd5", Headers["ContentMd5"]);
+ }
+ // end Added David Rodgers
// try connecting if not already
- try {
+ try
+ {
status = Connect();
Debug.Assert(status == ObexStatus_OK, "connect was: " + status);
} catch (Exception se) {