📄 obexwebrequest.cs
字号:
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using bluetoothX;
namespace bluetoothX
{
public class ObexWebRequest : WebRequest
{
private System.IO.MemoryStream requestStream = new System.IO.MemoryStream();
private WebHeaderCollection headers = new WebHeaderCollection();
private bool connected = false;
private Socket s;
private NetworkStream ns;
private ObexMethod method = ObexMethod.Put;
private short remoteMaxPacket = 0x400;
private int connectionId = 0;
#region Constructor
static ObexWebRequest()
{
//register the obex schemes with the WebRequest base method
ObexWebRequestCreate owrc = new ObexWebRequestCreate();
WebRequest.RegisterPrefix("obex",owrc);
WebRequest.RegisterPrefix("obex-push",owrc);
WebRequest.RegisterPrefix("obex-ftp",owrc);
WebRequest.RegisterPrefix("obex-sync",owrc);
}
public ObexWebRequest(Uri requestUri)
{
if(!requestUri.Scheme.StartsWith("obex"))
{
throw new UriFormatException("Scheme type not supported by ObexWebRequest");
}
uri = requestUri;
}
#endregion
#region Headers
public override WebHeaderCollection Headers
{
get
{
return headers;
}
set
{
headers = value;
}
}
#endregion
#region Method
public override string Method
{
get
{
switch(method)
{
case ObexMethod.Put:
return "PUT";
case ObexMethod.Get:
return "GET";
default:
return "";
}
}
set
{
switch(value.ToUpper())
{
case "PUT":
method = ObexMethod.Put;
break;
case "GET":
method = ObexMethod.Get;
break;
default:
throw new InvalidOperationException("Method not supported");
}
}
}
#endregion
#region Connect
private ObexStatusCode Connect()
{
if (!connected)
{
if(ns == null)
{
try
{
BluetoothAddress ba;
if(BluetoothAddress.TryParse(uri.Host,out ba))
{
s = new Socket(AddressFamily32.Bluetooth, SocketType.Stream, BluetoothProtocolType.RFComm);
Guid serviceGuid;
switch (uri.Scheme)
{
case "obex-ftp":
serviceGuid = BluetoothService.ObexFileTransfer;
break;
case "obex-sync":
serviceGuid = BluetoothService.IrMCSyncCommand;
break;
default:
serviceGuid = BluetoothService.ObexObjectPush;
break;
}
BluetoothEndPoint bep = new BluetoothEndPoint(ba, serviceGuid);
s.Connect(bep);
}
else
{
//assume a tcp host
s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipa;
try
{
ipa = IPAddress.Parse(uri.Host);
}
catch
{
ipa = System.Net.Dns.Resolve(uri.Host).AddressList[0];
}
IPEndPoint ipep = new IPEndPoint(ipa, 650);
s.Connect(ipep);
}
ns = new NetworkStream(s, true);
ns.ReadTimeout = timeout;
ns.WriteTimeout = timeout;
//do obex negotiation
byte[] connectPacket;
if (uri.Scheme == "obex-ftp")
{
connectPacket = new byte[] { 0x80, 0x00, 26, 0x10, 0x00, 0x20, 0x00, 0x46, 0x00, 19, 0xF9, 0xEC, 0x7B, 0xC4, 0x95, 0x3C, 0x11, 0xD2, 0x98, 0x4E, 0x52, 0x54, 0x00, 0xDC, 0x9E, 0x09 };
}
else
{
connectPacket = new byte[7] { 0x80, 0x00, 0x07, 0x10, 0x00, 0x20, 0x00 };
}
ns.Write(connectPacket, 0, connectPacket.Length);
byte[] receivePacket = new byte[3];
ns.Read(receivePacket, 0, 3);
if (receivePacket[0] == (byte)(ObexStatusCode.OK | ObexStatusCode.Final))
{
//get length
short len = (short)(IPAddress.NetworkToHostOrder(BitConverter.ToInt16(receivePacket, 1)) - 3);
byte[] receivePacket2 = new byte[len];
ns.Read(receivePacket2, 0, len);
ParseHeaders(receivePacket2, ref remoteMaxPacket, null, headers);
}
return (ObexStatusCode)receivePacket[0];
}
finally
{
if (s != null && !s.Connected)
{
s = null;
}
}
}
}
return (ObexStatusCode)0;
}
#endregion
#region Content Type
public override string ContentType
{
get
{
return headers["TYPE"];
}
set
{
headers["TYPE"] = value;
}
}
#endregion
#region Content Length
public override long ContentLength
{
get
{
string len = headers["LENGTH"];
if(len == null || len == string.Empty)
{
return 0;
}
return long.Parse(len);
}
set
{
headers["LENGTH"] = value.ToString();
}
}
#endregion
#region Proxy
public override IWebProxy Proxy
{
get
{
throw new NotSupportedException();
}
set
{
throw new NotSupportedException();
}
}
#endregion
#region Timeout
private int timeout = 50000;
public override int Timeout
{
get
{
return timeout;
}
set
{
if (value < -1)
{
throw new ArgumentOutOfRangeException("value");
}
if (value == -1)
{
timeout = 0;
}
else
{
timeout = value;
}
}
}
#endregion
#region Uri
private Uri uri;
public override Uri RequestUri
{
get
{
return uri;
}
}
#endregion
#region DoPut
private ObexStatusCode DoPut()
{
ObexStatusCode status = 0;
byte[] buffer = new byte[remoteMaxPacket];
string filename = uri.PathAndQuery.TrimStart(new char[]{'/'});
int filenameLength = (filename.Length + 1) * 2;
int packetLength = 6 + filenameLength;
buffer[0] = (byte)ObexMethod.Put;
buffer[3] = (byte)ObexHeader.Name;
BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)(filenameLength+3))).CopyTo(buffer, 4);
System.Text.Encoding.BigEndianUnicode.GetBytes(filename).CopyTo(buffer, 6);
string contentType = headers["TYPE"];
if(contentType!=null && contentType!="")
{
int contentTypeLength = (contentType.Length + 1);// *2;
buffer[packetLength] = (byte)ObexHeader.Type;
BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)(contentTypeLength+3))).CopyTo(buffer, packetLength+1);
System.Text.Encoding.ASCII.GetBytes(contentType).CopyTo(buffer, packetLength+3);
packetLength += (3+contentTypeLength);
}
if(this.ContentLength!=0)
{
buffer[packetLength] = (byte)ObexHeader.Length;
BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Convert.ToInt32(this.ContentLength))).CopyTo(buffer, packetLength+1);
packetLength += 5;
}
//write the final packet size
BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)packetLength)).CopyTo(buffer, 1);
//send packet with name header
ns.Write(buffer, 0, packetLength);
if (CheckResponse(ref status))
{
int totalBytes = 0;
int thisRequest = 0;
byte[] requestBuffer = requestStream.GetBuffer();
//we really want the content length, but if not available send the whole buffer
if(this.ContentLength > 0)
{
totalBytes = (int)this.ContentLength;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -