コード例 #1
0
ファイル: ServiceRecordHelper.cs プロジェクト: mcmap4/32feet
        internal static int GetRfcommChannelNumber(ServiceElement channelElement)
        {
            Debug.Assert(channelElement != null, "channelElement != null");
            System.Diagnostics.Debug.Assert(channelElement.ElementType == ElementType.UInt8);
            byte value = (byte)channelElement.Value;

            return(value);
        }
コード例 #2
0
ファイル: ServiceRecordCreator.cs プロジェクト: mcmap4/32feet
        /// <exclude/>
        protected virtual int CreateAttrId(ServiceAttributeId attrId, byte[] buf, int offset)
        {
            ServiceElement dummyElement
                = new ServiceElement(
                      ElementType.UInt16, unchecked ((UInt16)attrId));

            return(CreateElement(dummyElement, buf, offset));
        }
コード例 #3
0
ファイル: ServiceElement.cs プロジェクト: mcmap4/32feet
        public ServiceElement[] GetValueAsElementArray()
        {
            IList <ServiceElement> list = GetValueAsElementList();

            ServiceElement[] arr = new ServiceElement[list.Count];
            GetValueAsElementList().CopyTo(arr, 0);
            return(arr);
        }
コード例 #4
0
ファイル: ServiceRecordHelper.cs プロジェクト: mcmap4/32feet
        internal static int GetL2CapChannelNumber(ServiceElement channelElement)
        {
            Debug.Assert(channelElement != null, "channelElement != null");
            System.Diagnostics.Debug.Assert(channelElement.ElementType == ElementType.UInt16);
            var value = (UInt16)channelElement.Value;

            return(value);
        }
コード例 #5
0
ファイル: ServiceRecordCreator.cs プロジェクト: mcmap4/32feet
        private void WriteInt64(ServiceElement element, Int64 value, byte[] buf, ref int offset, out int totalLength)
        {
            Int64 host64 = value;
            Int64 net64  = IPAddress.HostToNetworkOrder(host64);

            byte[] valueBytes = BitConverter.GetBytes(net64);
            WriteFixedLength(element, valueBytes, buf, ref offset, out totalLength);
        }
コード例 #6
0
ファイル: ServiceRecordCreator.cs プロジェクト: mcmap4/32feet
        protected virtual void WriteFixedLength(ServiceElement element, byte[] valueBytes, byte[] buf, ref int offset, out int totalLength)
        {
            int headerLen = WriteHeaderFixedLength(element.ElementTypeDescriptor, valueBytes.Length, buf, offset, out totalLength);

            offset += headerLen;
            VerifyWriteSpaceRemaining(valueBytes.Length, buf, offset);
            valueBytes.CopyTo(buf, offset);
            System.Diagnostics.Debug.Assert(totalLength == headerLen + valueBytes.Length);
        }
コード例 #7
0
ファイル: ServiceRecordHelper.cs プロジェクト: mcmap4/32feet
        /// <summary>
        /// Reads the L2CAP Channel Number value from the service record,
        /// or returns -1 if the element is not present.
        /// </summary>
        /// -
        /// <param name="record">The <see cref="T:InTheHand.Net.Bluetooth.ServiceRecord"/>
        /// to search for the element.
        /// </param>
        /// -
        /// <returns>The PSM number as an uint16 cast to an Int32,
        /// or -1 if at the <see cref="F:InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.ProtocolDescriptorList"/>
        /// attribute is missing or contains invalid elements.
        /// </returns>
        public static int GetL2CapChannelNumber(ServiceRecord record)
        {
            ServiceElement channelElement = GetL2CapChannelElement(record);

            if (channelElement == null)
            {
                return(-1);
            }
            return(GetL2CapChannelNumber(channelElement));
        }
コード例 #8
0
ファイル: ServiceRecordHelper.cs プロジェクト: mcmap4/32feet
        /// <summary>
        /// Sets the RFCOMM Channel Number value in the service record.
        /// </summary>
        /// -
        /// <param name="record">The <see cref="T:InTheHand.Net.Bluetooth.ServiceRecord"/>
        /// in which to set the RFCOMM Channel number.
        /// </param>
        /// <param name="channelNumber">The Channel number to set in the record.
        /// </param>
        /// -
        /// <exception cref="T:System.InvalidOperationException">The
        /// <see cref="F:InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.ProtocolDescriptorList"/>
        /// attribute is missing or contains invalid elements.
        /// </exception>
        public static void SetRfcommChannelNumber(ServiceRecord record, byte channelNumber)
        {
            ServiceElement channelElement = GetRfcommChannelElement(record);

            if (channelElement == null)
            {
                throw new InvalidOperationException("ProtocolDescriptorList element does not exist or is not in the RFCOMM format.");
            }
            System.Diagnostics.Debug.Assert(channelElement.ElementType == ElementType.UInt8);
            channelElement.SetValue(channelNumber);
        }
コード例 #9
0
ファイル: ServiceRecordCreator.cs プロジェクト: mcmap4/32feet
        protected virtual void WriteVariableLength(ServiceElement element, byte[] valueBytes, byte[] buf, ref int offset, out int totalLength)
        {
            HeaderWriteState headerState;
            int curLen;

            curLen  = MakeVariableLengthHeader(buf, offset, element.ElementTypeDescriptor, out headerState);
            offset += curLen;
            VerifyWriteSpaceRemaining(valueBytes.Length, buf, offset);
            valueBytes.CopyTo(buf, offset);//write
            offset += valueBytes.Length;
            CompleteHeaderWrite(headerState, buf, offset, out totalLength);
        }
コード例 #10
0
ファイル: ServiceRecord.cs プロジェクト: ulebule/32feet
        public String GetMultiLanguageStringAttributeById(ServiceAttributeId id, LanguageBaseItem language)
        {
            if (language == null)
            {
                throw new ArgumentNullException("language");
            }
            ServiceAttributeId actualId = CreateLanguageBasedAttributeId(id, language.AttributeIdBase);
            ServiceAttribute   attr     = GetAttributeById(actualId);
            ServiceElement     element  = attr.Value;
            // (No need to check that element is of type TextString, that's handled inside the following).
            String str = element.GetValueAsString(language);

            return(str);
        }
コード例 #11
0
        /// <summary>
        /// Get the enum-like class containing the Service Attribute Id definitions
        /// for the type of the Service Class contained in the given
        /// <see cref="F:InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.ServiceClassIdList"/>
        /// (type <see cref="F:InTheHand.Net.Bluetooth.ElementTypeDescriptor.Uuid"/>) data element.
        /// </summary>
        /// -
        /// <param name="idElement">A <see cref="T:InTheHand.Net.Bluetooth.ServiceElement"/>
        /// of 'UUID' type containing the Service Class to search for.
        /// </param>
        /// -
        /// <returns>
        /// A <see cref="T:System.Type"/> object representing the enum-like class
        /// holding the Attribute Id definitions, or null if the Service Class is
        /// unknown or the element is not of <see cref="F:InTheHand.Net.Bluetooth.ElementTypeDescriptor.Uuid"/>
        /// type.
        /// </returns>
        /// -
        /// <exception cref="T:System.ArgumentNullException">
        /// <paramref name="idElement"/> is null.
        /// </exception>
        protected virtual Type GetAttributeIdEnumType(ServiceElement idElement)
        {
            if (idElement == null)
            {
                throw new ArgumentNullException("idElement");
            }
            //
            if (idElement.ElementTypeDescriptor != ElementTypeDescriptor.Uuid)
            {
                return(null);
            }
            Guid uuid = idElement.GetValueAsUuid();

            //
            return(GetAttributeIdEnumType(uuid));
        }
コード例 #12
0
        /// <summary>
        /// Add a custom attribute of simple type.
        /// </summary>
        /// -
        /// <remarks>
        /// <para>If the <paramref name="elementType"/> is a numerical type
        /// then this is equivalent to using
        /// <see cref="M:InTheHand.Net.Bluetooth.ServiceElement.CreateNumericalServiceElement(InTheHand.Net.Bluetooth.ElementType,System.Object)"/>
        /// otherwise the value is used directly in creating the
        /// <see cref="T:InTheHand.Net.Bluetooth.ServiceElement"/>.
        /// </para>
        /// </remarks>
        /// -
        /// <param name="id">The Attribute Id as a <see cref="T:InTheHand.Net.Bluetooth.ServiceAttributeId"/>.</param>
        /// <param name="elementType">The type of the element as an <see cref="T:InTheHand.Net.Bluetooth.ElementType"/>.</param>
        /// <param name="value">The value for the new element.</param>
        public void AddCustomAttribute(ServiceAttributeId id, ElementType elementType, object value)
        {
            ServiceElement        e;
            ElementTypeDescriptor etd = ServiceRecordParser.GetEtdForType(elementType);

            if ((etd == ElementTypeDescriptor.UnsignedInteger ||
                 etd == ElementTypeDescriptor.TwosComplementInteger))
            {
                e = ServiceElement.CreateNumericalServiceElement(elementType, value);
            }
            else
            {
                e = new ServiceElement(elementType, value);
            }
            this.AddCustomAttribute(new ServiceAttribute(id, e));
        }
コード例 #13
0
ファイル: ServiceRecordHelper.cs プロジェクト: mcmap4/32feet
        private static ServiceElement CreatePdlLayer(UInt16 uuid, params ServiceElement[] data)
        {
            IList <ServiceElement> curSeqChildren;
            ServiceElement         curValueElmt, curSeqElmt;

            //
            curSeqChildren = new List <ServiceElement>();
            curValueElmt   = new ServiceElement(ElementType.Uuid16, uuid);
            curSeqChildren.Add(curValueElmt);
            foreach (ServiceElement element in data)
            {
                curSeqChildren.Add(element);
            }
            curSeqElmt = new ServiceElement(ElementType.ElementSequence, curSeqChildren);
            return(curSeqElmt);
        }
コード例 #14
0
        private static ServiceElement ServiceElementFromUuid(object classRaw)
        {
            ServiceElement tmp = null;

            UInt32 classU32 = 99;
            bool   writeIntegral;

            // First check raw type, and also if u16/u32 inside Guid.
            // If Guid write it, otherwise handle all integral value.
            if (classRaw is Guid)
            {
                Guid uuid128 = (Guid)classRaw;
                if (ServiceRecordUtilities.IsUuid32Value(uuid128))
                {
                    classU32      = ServiceRecordUtilities.GetAsUuid32Value(uuid128);
                    writeIntegral = true;
                }
                else
                {
                    tmp           = new ServiceElement(ElementType.Uuid128, uuid128);
                    writeIntegral = false;
                }
            }
            else
            {
                System.Diagnostics.Debug.Assert(classRaw != null,
                                                "Unexpected ServiceClassId value: null");
                System.Diagnostics.Debug.Assert(classRaw is Int32,
                                                "Unexpected ServiceClassId type: " + classRaw.GetType().Name);
                Int32 i32 = (Int32)classRaw;
                classU32      = unchecked ((UInt32)i32);
                writeIntegral = true;
            }
            if (writeIntegral)
            {
                try {
                    UInt16 u16 = Convert.ToUInt16(classU32);
                    Debug.Assert(classU32 <= UInt16.MaxValue, "NOT replace the throw, LTE");
                    tmp = new ServiceElement(ElementType.Uuid16, u16);
                } catch (OverflowException) {
                    Debug.Assert(classU32 > UInt16.MaxValue, "NOT replace the throw, GT");
                    tmp = new ServiceElement(ElementType.Uuid32, classU32);
                }
            }

            return(tmp);
        }
コード例 #15
0
ファイル: ServiceRecordHelper.cs プロジェクト: mcmap4/32feet
        /// <summary>
        /// Creates the data element for the
        /// <see cref="F:InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.ProtocolDescriptorList"/>
        /// attribute in an L2CAP service,
        /// with upper layer entries.
        /// </summary>
        /// -
        /// <returns>The new <see cref="T:InTheHand.Net.Bluetooth.ServiceElement"/>.</returns>
        /// -
        /// <remarks>Thus is the following structure at the first layer:
        /// <code lang="none">
        /// ElementSequence
        ///    ElementSequence
        ///       Uuid16 = L2CAP
        ///       UInt16 = 0      -- The L2CAP PSM Number.
        /// </code>
        /// One can add layers above that; remember that all layers are formed
        /// of an ElementSequence.  See the example below.
        /// </remarks>
        /// -
        /// <example>
        /// <code>
        /// var netProtoList = new ServiceElement(ElementType.ElementSequence,
        ///     ServiceElement.CreateNumericalServiceElement(ElementType.UInt16, 0x0800),
        ///     ServiceElement.CreateNumericalServiceElement(ElementType.UInt16, 0x0806)
        ///     );
        /// var layer1 = new ServiceElement(ElementType.ElementSequence,
        ///     new ServiceElement(ElementType.Uuid16, Uuid16_BnepProto),
        ///     ServiceElement.CreateNumericalServiceElement(ElementType.UInt16, 0x0100), //v1.0
        ///     netProtoList
        ///     );
        /// ServiceElement element = ServiceRecordHelper.CreateL2CapProtocolDescriptorListWithUpperLayers(
        ///     layer1);
        /// </code>
        /// </example>
        /// -
        /// <param name="upperLayers">The list of upper layer elements, one per layer.
        /// As an array.
        /// </param>
        public static ServiceElement CreateL2CapProtocolDescriptorListWithUpperLayers(params ServiceElement[] upperLayers)
        {
            IList <ServiceElement> baseChildren = new List <ServiceElement>();

            baseChildren.Add(CreatePdlLayer((UInt16)ServiceRecordUtilities.HackProtocolId.L2Cap,
                                            new ServiceElement(ElementType.UInt16, (UInt16)0)));
            foreach (ServiceElement nextLayer in upperLayers)
            {
                if (nextLayer.ElementType != ElementType.ElementSequence)
                {
                    throw new ArgumentException("Each layer in a ProtocolDescriptorList must be an ElementSequence.");
                }
                baseChildren.Add(nextLayer);
            }//for
            ServiceElement baseElement = new ServiceElement(ElementType.ElementSequence, baseChildren);

            return(baseElement);
        }
コード例 #16
0
 private static void DumpProtocolDescriptorList(TextWriter writer, int depth, ServiceElement element)
 {
     Debug.Assert(element.ElementType == ElementType.ElementAlternative ||
                  element.ElementType == ElementType.ElementSequence);
     //
     // If passes a list of alternatives, each a protocol descriptor list,
     // then call ourselves on each list.
     if (element.ElementType == ElementType.ElementAlternative)
     {
         foreach (ServiceElement curStack in element.GetValueAsElementList())
         {
             DumpProtocolDescriptorListList(writer, depth + 1, curStack);
         }//foreach
         return;
     }
     //else
     DumpProtocolDescriptorListList(writer, depth, element);
 }
コード例 #17
0
 private static void DumpRawElement(TextWriter writer, int depth, ServiceElement elem)
 {
     WritePrefix(writer, depth);
     if (elem.ElementType == ElementType.ElementSequence ||
         elem.ElementType == ElementType.ElementAlternative)
     {
         writer.WriteLine("{0}", elem.ElementType);
         foreach (ServiceElement element in elem.GetValueAsElementList())
         {
             DumpRawElement(writer, depth + 1, element);
         }
     }
     else if (elem.ElementType == ElementType.Nil)
     {
         writer.WriteLine("Nil:");
     }
     else if (elem.ElementType == ElementType.TextString ||
              elem.ElementType == ElementType.Boolean ||
              elem.ElementType == ElementType.Url)
     {
         // Non-numeric types
         writer.WriteLine("{0}: {1}", elem.ElementType, elem.Value);
     }
     else if (elem.ElementType == ElementType.Uuid128)
     {
         writer.WriteLine("{0}: {1}", elem.ElementType, elem.Value);
     }
     else if (elem.ElementType == ElementType.UInt128 ||
              elem.ElementType == ElementType.Int128)
     {
         string valueText = BitConverter.ToString((byte[])elem.Value);
         writer.WriteLine("{0}: {1}", elem.ElementType, valueText);
     }
     else
     {
         writer.WriteLine("{0}: 0x{1:X}", elem.ElementType, elem.Value);
         //{catch(?FOrmatExptn){
         //   writer.WriteLine("{0}: 0x{1}", elem.Type, elem.Value);
         //}
     }
 }
コード例 #18
0
ファイル: ServiceRecordHelper.cs プロジェクト: mcmap4/32feet
        /// <summary>
        /// Sets the RFCOMM Channel Number value in the service record.
        /// </summary>
        /// -
        /// <remarks>
        /// <para>Note: We use an <see cref="T:System.Int32"/> for the
        /// <paramref name="psm"/> parameter as its natural type <see cref="T:System.UInt16"/>
        /// in not usable in CLS Compliant interfaces.
        /// </para>
        /// </remarks>
        /// -
        /// <param name="record">The <see cref="T:InTheHand.Net.Bluetooth.ServiceRecord"/>
        /// in which to set the L2CAP PSM value.
        /// </param>
        /// <param name="psm">The PSM value to set in the record.
        /// Note that although the parameter is of type <see cref="T:System.Int32"/>
        /// the value must actually be in the range of a <see cref="T:System.UInt16"/>,
        /// see the remarks for more information.
        /// </param>
        /// -
        /// <exception cref="T:System.InvalidOperationException">The
        /// <see cref="F:InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.ProtocolDescriptorList"/>
        /// attribute is missing or contains invalid elements.
        /// </exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException">
        /// The PSM must fit in a 16-bit unsigned integer.
        /// </exception>
        public static void SetL2CapPsmNumber(ServiceRecord record, int psm)
        {
            if (psm < 0 || psm > UInt16.MaxValue)
            {
                throw new ArgumentOutOfRangeException("psm", "A PSM is a UInt16 value.");
            }
            var            psm16         = checked ((UInt16)psm);
            ServiceElement rfcommElement = GetRfcommChannelElement(record);

            if (rfcommElement != null)
            {
                Debug.WriteLine("Setting L2CAP PSM for a PDL that includes RFCOMM.");
            }
            ServiceElement channelElement = GetChannelElement(record, BluetoothProtocolDescriptorType.L2Cap);

            if (channelElement == null ||
                channelElement.ElementType != ElementType.UInt16)
            {
                throw new InvalidOperationException("ProtocolDescriptorList element does not exist, is not in the L2CAP format, or it the L2CAP layer has no PSM element.");
            }
            channelElement.SetValue(psm16);
        }
コード例 #19
0
        /// <summary>
        /// Get a list of enum-like classes containing Service Attribute Id definitions
        /// for the type of the Service Class contained in the given Service Record.
        /// </summary>
        /// -
        /// <param name="record">A <see cref="T:InTheHand.Net.Bluetooth.ServiceRecord"/>
        /// whose <see cref="F:InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.ServiceClassIdList"/>
        /// element will be retrieved, and its Service Class Id will used
        /// for the lookup.
        /// </param>
        /// -
        /// <returns>
        /// An array of <see cref="T:System.Type"/> each of which is a enum-like class
        /// which defines the set of Service Attribute IDs used by a particular
        /// Service Class e.g. ObjectPushProfile.
        /// An empty array will be returned if none of the Service Classes
        /// are known, or the record contains no
        /// <see cref="F:InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.ServiceClassIdList"/>
        /// attribute, or it is invalid.
        /// <note>Currently only the first Service Class Id is looked-up.</note>
        /// </returns>
        /// -
        /// <exception cref="T:System.ArgumentNullException">
        /// <paramref name="record"/> is null.
        /// </exception>
        public Type[] GetAttributeIdEnumTypes(ServiceRecord record)
        {
            if (record == null)
            {
                throw new ArgumentNullException("record");
            }
            //
            ServiceAttribute attr;

            try {
                attr = record.GetAttributeById(UniversalAttributeId.ServiceClassIdList);
            } catch (System.Collections.Generic.KeyNotFoundException ex) {
                System.Diagnostics.Debug.Assert(ex.Message == ServiceRecord.ErrorMsgNoAttributeWithId);
                goto InvalidRecord;
            }
            ServiceElement element = attr.Value;

            if (element.ElementType != ElementType.ElementSequence)
            {
                goto InvalidRecord;
            }
            ServiceElement[] idElements = element.GetValueAsElementArray();
            //TODO ((GetServiceClassSpecificAttributeIdEnumDefiningType--foreach (ServiceElement curIdElem in idElements) {))
            if (idElements.Length != 0)
            {
                ServiceElement curIdElem = idElements[0];
                Type           enumType  = GetAttributeIdEnumType(curIdElem);
                if (enumType != null)
                {
                    return(new Type[] { enumType });
                }
            }//else fall through...
            // None-matched, or invalid attribute format etc.
InvalidRecord:
            return(new Type[0]);
        }
コード例 #20
0
ファイル: ServiceRecordCreator.cs プロジェクト: mcmap4/32feet
 private void WriteByte(ServiceElement element, Byte value, byte[] buf, ref int offset, out int totalLength)
 {
     byte[] valueBytes = new byte[1];
     valueBytes[0] = value;
     WriteFixedLength(element, valueBytes, buf, ref offset, out totalLength);
 }
コード例 #21
0
        private static void DumpProtocolDescriptorListList(TextWriter writer, int depth, ServiceElement element)
        {
            // The list.
            Debug.Assert(element.ElementType == ElementType.ElementSequence);
            WritePrefix(writer, depth);
            writer.Write("( ");
            bool firstLayer = true;

            foreach (ServiceElement layer in element.GetValueAsElementList())
            {
                ServiceElement[] items = layer.GetValueAsElementArray();
                int used = 0;
                Debug.Assert(items[used].ElementTypeDescriptor == ElementTypeDescriptor.Uuid);
                Guid           protoGuid = items[used].GetValueAsUuid();
                string         protoStr;
                HackProtocolId proto = GuidToHackProtocolId(protoGuid, out protoStr);
                //
                used++;
                writer.Write("{0}( {1}", (firstLayer ? string.Empty : ", "), protoStr);
                if (proto == HackProtocolId.L2Cap)
                {
                    if (used < items.Length)
                    {
                        Debug.Assert(items[used].ElementType == ElementType.UInt16);
                        var u16 = (ushort)items[used].Value;
                        HackProtocolServiceMultiplexer psm = unchecked ((HackProtocolServiceMultiplexer)u16);
                        used++;
                        writer.Write(", PSM={0}", Enum_ToStringNameOrHex(psm));
                    }
                }
                else if (proto == HackProtocolId.Rfcomm)
                {
                    if (used < items.Length)
                    {
                        Debug.Assert(items[used].ElementType == ElementType.UInt8);
                        byte channelNumber = (byte)items[used].Value;
                        used++;
                        writer.Write(", ChannelNumber={0}", channelNumber);
                    }
                }
                // Others include BNEP for instance, which isn't defined in the base SDP spec.
                if (used < items.Length)
                {
                    writer.Write(", ...");
                }
                writer.Write(" )");
                firstLayer = false;
            }//foreach layer
            writer.WriteLine(" )");
        }
コード例 #22
0
ファイル: ServiceRecordHelper.cs プロジェクト: mcmap4/32feet
        // TODO GetRfcommChannelElement(ServiceAttribute attr) Could be public -> Tests!
        internal static ServiceElement GetChannelElement(ServiceAttribute attr,
                                                         BluetoothProtocolDescriptorType proto,
                                                         out bool?isSimpleRfcomm)
        {
            if (proto != BluetoothProtocolDescriptorType.L2Cap &&
                proto != BluetoothProtocolDescriptorType.Rfcomm)
            {
                throw new ArgumentException("Can only fetch RFCOMM or L2CAP element.");
            }

            //
            isSimpleRfcomm = true;
            Debug.Assert(attr != null, "attr != null");
            ServiceElement e0 = attr.Value;

            if (e0.ElementType == ElementType.ElementAlternative)
            {
                Trace.WriteLine("Don't support ElementAlternative ProtocolDescriptorList values.");

                goto NotFound;
            }
            else if (e0.ElementType != ElementType.ElementSequence)
            {
                Trace.WriteLine("Bad ProtocolDescriptorList base element.");

                goto NotFound;
            }
            IList <ServiceElement>       protoStack = e0.GetValueAsElementList();
            IEnumerator <ServiceElement> etor       = protoStack.GetEnumerator();
            ServiceElement         layer;
            IList <ServiceElement> layerContent;
            ServiceElement         channelElement;

            // -- L2CAP Layer --
            if (!etor.MoveNext())
            {
                Trace.WriteLine(string.Format(CultureInfo.InvariantCulture,
                                              "Protocol stack truncated before {0}.", "L2CAP"));

                goto NotFound;
            }
            layer        = etor.Current; //cast here are for non-Generic version.
            layerContent = layer.GetValueAsElementList();
            if (layerContent[0].GetValueAsUuid() != BluetoothProtocol.L2CapProtocol)
            {
                Trace.WriteLine(String.Format(CultureInfo.InvariantCulture,
                                              "Bad protocol stack, layer {0} is not {1}.", 1, "L2CAP"));
                goto NotFound;
            }
            bool hasPsmEtc = layerContent.Count != 1;

            // Cast for FX1.1 object
            isSimpleRfcomm = (bool)isSimpleRfcomm && !hasPsmEtc;
            if (proto == BluetoothProtocolDescriptorType.L2Cap)
            {
                if (layerContent.Count < 2)
                {
                    Trace.WriteLine("L2CAP PSM element was requested but the L2CAP layer in this case hasn't a second element.");

                    goto NotFound;
                }
                channelElement = (ServiceElement)layerContent[1];
                goto Success;
            }
            //
            // -- RFCOMM Layer --
            if (!etor.MoveNext())
            {
                Trace.WriteLine(string.Format(CultureInfo.InvariantCulture,
                                              "Protocol stack truncated before {0}.", "RFCOMM"));

                goto NotFound;
            }
            layer        = etor.Current;
            layerContent = layer.GetValueAsElementList();
            if (layerContent[0].GetValueAsUuid() != BluetoothProtocol.RFCommProtocol)
            {
                Trace.WriteLine(String.Format(CultureInfo.InvariantCulture,
                                              "Bad protocol stack, layer {0} is not {1}.", 2, "RFCOMM"));

                goto NotFound;
            }
            //
            if (layerContent.Count < 2)
            {
                Trace.WriteLine(String.Format(CultureInfo.InvariantCulture,
                                              "Bad protocol stack, layer {0} hasn't a second element.", 2));

                goto NotFound;
            }
            channelElement = (ServiceElement)layerContent[1];
            if (channelElement.ElementType != ElementType.UInt8)
            {
                Trace.WriteLine(String.Format(CultureInfo.InvariantCulture,
                                              "Bad protocol stack, layer {0} is not UInt8.", 2));

                goto NotFound;
            }
            // Success
            //
            // -- Any remaining layer(s) --
            bool extraLayers = etor.MoveNext();

            isSimpleRfcomm = (bool)isSimpleRfcomm && !extraLayers;
Success:
            //
            return(channelElement);

NotFound:
            isSimpleRfcomm = null;
            return(null);
        }
コード例 #23
0
 private static void DumpElement(TextWriter writer, int depth, ServiceElement elem)
 {
     WritePrefix(writer, depth);
     if (elem.ElementType == ElementType.ElementSequence || elem.ElementType == ElementType.ElementAlternative)
     {
         writer.WriteLine("{0}", elem.ElementType);
         foreach (ServiceElement element in elem.GetValueAsElementList())
         {
             DumpElement(writer, depth + 1, element);
         }//for
     }
     else if (elem.ElementType == ElementType.Nil)
     {
         writer.WriteLine("Nil:");
     }
     else if (elem.ElementType == ElementType.TextString)
     {
         DumpString(writer, depth, elem, null);
     }
     else if (elem.ElementType == ElementType.Boolean ||
              elem.ElementType == ElementType.Url)
     {
         // Non-numeric types
         writer.WriteLine("{0}: {1}", elem.ElementType, elem.Value);
     }
     else
     {
         string name      = null;
         string valueText = null;
         if (elem.ElementTypeDescriptor == ElementTypeDescriptor.Uuid)
         {
             if (elem.ElementType == ElementType.Uuid16)
             {
                 name = BluetoothService.GetName((ushort)elem.Value);
             }
             else if (elem.ElementType == ElementType.Uuid32)
             {
                 name = BluetoothService.GetName((uint)elem.Value);
             }
             else
             {
                 Debug.Assert(elem.ElementType == ElementType.Uuid128);
                 name      = BluetoothService.GetName((Guid)elem.Value);
                 valueText = ((Guid)elem.Value).ToString();
             }
         }//if UUID
         if (valueText == null)
         {
             if (elem.ElementTypeDescriptor == ElementTypeDescriptor.Unknown)
             {
                 valueText = "unknown";
             }
             else if (elem.ElementType == ElementType.UInt128 ||
                      elem.ElementType == ElementType.Int128)
             {
                 valueText = BitConverter.ToString((byte[])elem.Value);
             }
             else
             {
                 valueText = string.Format(System.Globalization.CultureInfo.InvariantCulture, "0x{0:X}", elem.Value);
             }
         }
         if (name == null)
         {
             writer.WriteLine("{0}: {1}", elem.ElementType, valueText);
         }
         else
         {
             writer.WriteLine("{0}: {1} -- {2}", elem.ElementType, valueText, name);
         }
     }//else
 }
コード例 #24
0
        //--------------------------------------------------------------

        /// <summary>
        /// Initializes a new instance of the <see cref="T:InTheHand.Net.Bluetooth.ServiceAttribute"/> class.
        /// </summary>
        /// -
        /// <param name="id">The Attribute Id as a <see cref="T:InTheHand.Net.Bluetooth.ServiceAttributeId"/>.</param>
        /// <param name="value">The value as a <see cref="T:InTheHand.Net.Bluetooth.ServiceElement"/>.</param>
        public ServiceAttribute(ServiceAttributeId id, ServiceElement value)
        {
            m_id      = id;
            m_element = value;
        }
コード例 #25
0
 [CLSCompliant(false)] // instead use .ctor(ServiceAttributeId,AttributeValue).
 public ServiceAttribute(ushort id, ServiceElement value)
     : this(unchecked ((ServiceAttributeId)(Int16)id), value)
 {
 }
コード例 #26
0
ファイル: ServiceRecordCreator.cs プロジェクト: mcmap4/32feet
        /// <summary>
        /// Create the element in the buffer starting at offset, and return its totalLength.
        /// </summary>
        /// <param name="element">The element to create.
        /// </param>
        /// <param name="buf">The byte array to write the encoded element to.
        /// </param>
        /// <param name="offset">The place to start writing in <paramref name="buf"/>.
        /// </param>
        ///
        /// <returns>The total length of the encoded element written to the buffer
        /// </returns>
        protected virtual int CreateElement(ServiceElement element, byte[] buf, int offset)
        {
            int totalLength;

            //
            if (element.ElementTypeDescriptor == ElementTypeDescriptor.ElementSequence ||
                element.ElementTypeDescriptor == ElementTypeDescriptor.ElementAlternative)
            {
                HeaderWriteState headerState;
                int curLen;
                curLen  = MakeVariableLengthHeader(buf, offset, element.ElementTypeDescriptor, out headerState);
                offset += curLen;
                foreach (ServiceElement childElement in element.GetValueAsElementList())
                {
                    curLen  = CreateElement(childElement, buf, offset);
                    offset += curLen;
                }//for
                CompleteHeaderWrite(headerState, buf, offset, out totalLength);
                //----------------
            }
            else if (element.ElementTypeDescriptor == ElementTypeDescriptor.UnsignedInteger ||
                     element.ElementTypeDescriptor == ElementTypeDescriptor.TwosComplementInteger)
            {
                switch (element.ElementType)
                {
                case ElementType.UInt8:
                    WriteByte(element, (Byte)element.Value, buf, ref offset, out totalLength);
                    break;

                case ElementType.Int8:
                    WriteSByte(element, (SByte)element.Value, buf, ref offset, out totalLength);
                    break;

                case ElementType.UInt16:
                    WriteUInt16(element, (UInt16)element.Value, buf, ref offset, out totalLength);
                    break;

                case ElementType.Int16:
                    WriteInt16(element, (Int16)element.Value, buf, ref offset, out totalLength);
                    break;

                case ElementType.UInt32:
                    WriteUInt32(element, (UInt32)element.Value, buf, ref offset, out totalLength);
                    break;

                case ElementType.Int32:
                    WriteInt32(element, (Int32)element.Value, buf, ref offset, out totalLength);
                    break;

                case ElementType.UInt64:
                    WriteUInt64(element, (UInt64)element.Value, buf, ref offset, out totalLength);
                    break;

                case ElementType.Int64:
                    WriteInt64(element, (Int64)element.Value, buf, ref offset, out totalLength);
                    break;

                default:
                    System.Diagnostics.Debug.Fail(String.Format(System.Globalization.CultureInfo.InvariantCulture,
                                                                "Unexpected integral type '{0}'.", element.ElementType));
                    totalLength = 0;
                    break;
                }//switch
                 //----------------
            }
            else if (element.ElementTypeDescriptor == ElementTypeDescriptor.Uuid)
            {
                if (element.ElementType == ElementType.Uuid16)
                {
                    WriteUInt16(element, (UInt16)element.Value, buf, ref offset, out totalLength);
                }
                else if (element.ElementType == ElementType.Uuid32)
                {
                    WriteUInt32(element, (UInt32)element.Value, buf, ref offset, out totalLength);
                }
                else
                {
                    //TODO If the 'Guid' holds a 'Bluetooth-based' UUID, then should we write the short form?
                    byte[] bytes;
                    System.Diagnostics.Debug.Assert(element.ElementType == ElementType.Uuid128);
                    Guid hostGuid = (Guid)element.Value;
                    Guid netGuid  = BluetoothAddress.HostToNetworkOrder(hostGuid);
                    bytes = netGuid.ToByteArray();
                    WriteFixedLength(element, bytes, buf, ref offset, out totalLength);
                }
                //----------------
            }
            else if (element.ElementTypeDescriptor == ElementTypeDescriptor.Url)
            {
                Uri    uri        = element.GetValueAsUri();
                String uriString  = uri.ToString();
                byte[] valueBytes = System.Text.Encoding.ASCII.GetBytes(uriString);
                WriteVariableLength(element, valueBytes, buf, ref offset, out totalLength);
                //----------------
            }
            else if (element.ElementTypeDescriptor == ElementTypeDescriptor.TextString)
            {
                byte[] valueBytes;
                String valueString = element.Value as String;
                if (valueString != null)
                {
                    valueBytes = System.Text.Encoding.UTF8.GetBytes(valueString);
                }
                else
                {
                    System.Diagnostics.Debug.Assert(element.Value is byte[]);
                    valueBytes = (byte[])element.Value;
                }
                WriteVariableLength(element, valueBytes, buf, ref offset, out totalLength);
                //----------------
            }
            else if (element.ElementTypeDescriptor == ElementTypeDescriptor.Nil)
            {
                WriteFixedLength(element, new byte[0], buf, ref offset, out totalLength);
                //----------------
            }
            else if (element.ElementTypeDescriptor == ElementTypeDescriptor.Boolean)
            {
                bool   value      = (bool)element.Value;
                byte[] valueBytes = new byte[1];
                valueBytes[0] = value ? (byte)1 : (byte)0;
                WriteFixedLength(element, valueBytes, buf, ref offset, out totalLength);
                //----------------
            }
            else
            {
                totalLength = 0;
            }
            //
            if (totalLength == 0)
            {
                throw new NotSupportedException(String.Format(System.Globalization.CultureInfo.InvariantCulture,
                                                              "Creation of element type '{0}' not implemented.", element.ElementType));
            }
            return(totalLength);
        }
コード例 #27
0
 //--------
 private static void DumpAdditionalProtocolDescriptorLists(TextWriter writer, int depth, ServiceElement element)
 {
     Debug.Assert(element.ElementType == ElementType.ElementSequence);
     //
     // Is a list of PDLs
     foreach (ServiceElement curList in element.GetValueAsElementList())
     {
         DumpProtocolDescriptorList(writer, depth + 1, curList);
     }//foreach
 }
コード例 #28
0
        private static XElement GetAttributeValue(ServiceElement value)
        {
            // There isn't much formal documentation on the BlueZ SDP XML format.
            // The actual serialization is implemented in the convert_raw_data_to_xml
            // function at https://github.com/bluez/bluez/blob/9be85f867856195e16c9b94b605f65f6389eda33/src/sdp-xml.c#L637
            switch (value.ElementType)
            {
            case ElementType.Nil:
                return(new XElement("nil"));

            case ElementType.Boolean:
                var boolean = new XElement("boolean");
                boolean.SetAttributeValue("value", (bool)value.Value ? "true" : "false");
                return(boolean);

            case ElementType.UInt8:
                var uint8 = new XElement("uint8");
                uint8.SetAttributeValue("value", $"0x{value.Value:x2}");
                return(uint8);

            case ElementType.UInt16:
                var uint16 = new XElement("uint16");
                uint16.SetAttributeValue("value", $"0x{value.Value:x4}");
                return(uint16);

            case ElementType.UInt32:
                var uint32 = new XElement("uint32");
                uint32.SetAttributeValue("value", $"0x{value.Value:x8}");
                return(uint32);

            case ElementType.UInt64:
                var uint64 = new XElement("uint64");
                uint64.SetAttributeValue("value", $"0x{value.Value:x16}");
                return(uint64);

            case ElementType.Int8:
                var int8 = new XElement("int8");
                int8.SetAttributeValue("value", $"{value.Value:d}");
                return(int8);

            case ElementType.Int16:
                var int16 = new XElement("int16");
                int16.SetAttributeValue("value", $"{value.Value:d}");
                return(int16);

            case ElementType.Int32:
                var int32 = new XElement("int32");
                int32.SetAttributeValue("value", $"{value.Value:d}");
                return(int32);

            case ElementType.Int64:
                var int64 = new XElement("int64");
                int64.SetAttributeValue("value", $"{value.Value:d}");
                return(int64);

            case ElementType.Uuid16:
                var uuid16 = new XElement("uuid");
                uuid16.SetAttributeValue("value", $"0x{value.Value:x4}");
                return(uuid16);

            case ElementType.Uuid32:
                var uuid32 = new XElement("uuid");
                uuid32.SetAttributeValue("value", $"0x{value.Value:x8}");
                return(uuid32);

            case ElementType.Uuid128:
                var uuid128 = new XElement("uuid");
                uuid128.SetAttributeValue("value", $"0x{value.Value:D}");
                return(uuid128);

            case ElementType.TextString:
                var textString = new XElement("text");

                if (value.Value is byte[])
                {
                    textString.SetAttributeValue("encoding", "hex");
                    textString.SetAttributeValue("value", GetHexString((byte[])value.Value));
                }
                else
                {
                    textString.SetAttributeValue("value", (string)value.Value);
                }

                return(textString);

            case ElementType.Url:
                var url = new XElement("url");
                url.SetAttributeValue("value", value.Value);
                return(url);

            case ElementType.ElementSequence:
                var sequence = new XElement("sequence");

                foreach (var child in value.GetValueAsElementList())
                {
                    sequence.Add(GetAttributeValue(child));
                }

                return(sequence);

            case ElementType.ElementAlternative:
                var alternate = new XElement("alternate");

                foreach (var child in value.GetValueAsElementList())
                {
                    alternate.Add(GetAttributeValue(child));
                }

                return(alternate);

            default:
                throw new ArgumentOutOfRangeException(nameof(value));
            }
        }
コード例 #29
0
ファイル: ServiceRecordCreator.cs プロジェクト: mcmap4/32feet
        private void WriteSByte(ServiceElement element, SByte value, byte[] buf, ref int offset, out int totalLength)
        {
            Byte valueU = unchecked ((Byte)value);

            WriteByte(element, valueU, buf, ref offset, out totalLength);
        }
コード例 #30
0
ファイル: ServiceRecordCreator.cs プロジェクト: mcmap4/32feet
        private void WriteUInt64(ServiceElement element, UInt64 value, byte[] buf, ref int offset, out int totalLength)
        {
            Int64 valueS = unchecked ((Int64)value);

            WriteInt64(element, valueS, buf, ref offset, out totalLength);
        }