コード例 #1
0
        internal ObexListenerContext(SocketAdapter s)
        {
            buffer = new byte[0x2000];

            this.localEndPoint  = s.LocalEndPoint;
            this.remoteEndPoint = s.RemoteEndPoint;

            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);
                        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 (SocketException 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 = s.Receive(this.buffer, iPos + 3, wanted, SocketFlags.None);
                            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)
                        {
                            s.Send(responsePacket);
                        }
                    } catch (Exception se) {
                        //Console.WriteLine(se.Message);
                        HandleConnectionError(se);
                    }
                }
                else
                {
                    moretoreceive = false;
                }
            }//while

            Debug.WriteLine(s.GetHashCode().ToString("X8") + ": Completed", "ObexListener");
            s.Close();
            s = null;

            if (!putCompleted)
            {
                // Should not return the request.
                throw new ProtocolViolationException("No PutFinal received.");
            }
            request = new ObexListenerRequest(bodyStream.ToArray(), headers, localEndPoint, remoteEndPoint);
        }
コード例 #2
0
ファイル: ObexParser.cs プロジェクト: seuzht/32feet
        internal static void ParseHeaders(byte[] packet, bool isConnectPacket, ref ushort remoteMaxPacket, Stream bodyStream, WebHeaderCollection headers)
        {
            ObexMethod method       = (ObexMethod)packet[0];
            int        packetLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(packet, 1));

            int pos     = 3;
            int lastPos = int.MinValue;

            while (pos < packetLength)
            {
                if (pos == lastPos)
                {
                    Debug.Fail("Infinite Loop!");
                    throw new InvalidOperationException("Infinite Loop!");
                }
                lastPos = pos;

                ObexHeader header = (ObexHeader)packet[pos];
                switch (header)
                {
                case ObexHeader.None:
                    return;

                case (ObexHeader)0x10:
                    Debug.Assert(isConnectPacket, "NOT isConnectPacket");
                    Debug.Assert(pos == 3, "NOT before any headers!");
                    remoteMaxPacket = unchecked ((ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(packet, pos + 2)));
                    pos            += 4;
                    break;

                case ObexHeader.ConnectionID:
                case ObexHeader.Count:
                case ObexHeader.Length:
                case ObexHeader.CreatorID:
                case ObexHeader.Time4Byte:
                    int intValue = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(packet, pos + 1));
                    pos += 5;
                    string key   = header.ToString().ToUpper();
                    string value = intValue.ToString();
                    // Duplicate headers causes comma-separated HTTP list!!
                    if (-1 != Array.IndexOf <string>(headers.AllKeys, key))
                    {
                        string existing = headers.Get(key);
                        if (value == existing)
                        {
                            // Just discard it then.
                            break;
                        }
                        else
                        {
                            Debug.Assert(-1 == Array.IndexOf <string>(headers.AllKeys, header.ToString().ToUpper()),
                                         "Duplicate headers causes comma-separated HTTP list!!: " + header.ToString().ToUpper());
                        }
                    }
                    headers.Add(header.ToString().ToUpper(), intValue.ToString());
                    break;

                case ObexHeader.Who:
                    short  whoSize  = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(packet, pos + 1));
                    byte[] whoBytes = new byte[16];
                    Buffer.BlockCopy(packet, pos + 3, whoBytes, 0, whoSize - 3);
                    Guid service = new Guid(whoBytes);
                    headers.Add(header.ToString().ToUpper(), service.ToString());
                    pos += whoSize;
                    break;

                case ObexHeader.Body:
                case ObexHeader.EndOfBody:
                    short bodySize = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(packet, pos + 1));
                    bodyStream.Write(packet, pos + 3, bodySize - 3);
                    pos += bodySize;
                    break;

                case ObexHeader.Type:
                    int typeSize = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(packet, pos + 1));
                    if (typeSize > 3)
                    {
                        string typeString = System.Text.Encoding.ASCII.GetString(packet, pos + 3, typeSize - 4);
                        if (typeString != null)
                        {
                            int nullindex = typeString.IndexOf('\0');
                            if (nullindex > -1)
                            {
                                typeString = typeString.Substring(0, nullindex);
                            }

                            if (typeString != string.Empty)
                            {
                                headers.Add(header.ToString().ToUpper(), typeString);
                            }
                        }
                    }
                    pos += typeSize;
                    break;

                default:
                    int headerSize = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(packet, pos + 1));

                    if (headerSize > 3)
                    {
                        string headerString = System.Text.Encoding.BigEndianUnicode.GetString(packet, pos + 3, headerSize - 5);
                        if (headerString != null)
                        {
                            int nullindex = headerString.IndexOf('\0');
                            if (nullindex > -1)
                            {
                                headerString = headerString.Substring(0, nullindex);
                            }

                            if (headerString != string.Empty)
                            {
                                headers.Add(header.ToString().ToUpper(), Uri.EscapeDataString(headerString));
                            }
                        }
                    }

                    pos += headerSize;
                    break;
                }
            }
        }
コード例 #3
0
        private byte[] HandleAndMakeResponse(ref bool moretoreceive, ref bool putCompleted, ObexMethod method)
        {
            byte[] responsePacket;
            switch (method)
            {
            case ObexMethod.Connect:
                ObexParser.ParseHeaders(buffer, true, ref remoteMaxPacket, bodyStream, headers);
                responsePacket = new byte[7] {
                    0xA0, 0x00, 0x07, 0x10, 0x00, 0x20, 0x00
                };
                break;

            case ObexMethod.Put:
                if (putCompleted)       // Don't allow another PUT to append to the previous content!
                {
                    goto case ObexMethod.PutFinal;
                }
                ObexParser.ParseHeaders(buffer, false, ref remoteMaxPacket, bodyStream, headers);
                responsePacket = new byte[3] {
                    (byte)(ObexStatusCode.Continue | ObexStatusCode.Final), 0x00, 0x03
                };
                break;

            case ObexMethod.PutFinal:
                if (putCompleted)                                   // Don't allow another PUT to append to the previous content!
                {
                    ObexStatusCode code = ObexStatusCode.Forbidden; // Any better one?
                    responsePacket = new byte[3] {
                        (byte)(code | ObexStatusCode.Final), 0x00, 0x03
                    };
                    moretoreceive = false;
                    break;
                }
                ObexParser.ParseHeaders(buffer, false, ref remoteMaxPacket, bodyStream, headers);
                responsePacket = new byte[3] {
                    (byte)(ObexStatusCode.OK | ObexStatusCode.Final), 0x00, 0x03
                };
                // Shouldn't return an object if the sender didn't send it all.
                putCompleted = true;     // (Need to just assume that it does contains EndOfBody)
                break;

            case ObexMethod.Disconnect:
                ObexParser.ParseHeaders(buffer, false, ref remoteMaxPacket, bodyStream, headers);
                responsePacket = new byte[3] {
                    (byte)(ObexStatusCode.OK | ObexStatusCode.Final), 0x00, 0x03
                };
                moretoreceive = false;
                break;

            default:
                //Console.WriteLine(method.ToString() + " " + received.ToString());
                responsePacket = new byte[3] {
                    (byte)ObexStatusCode.NotImplemented, 0x00, 0x03
                };
                break;
            }
            return(responsePacket);
        }