/// <exclude/> protected virtual int CreateAttrId(ushort attrId, byte[] buf, int offset) { ServiceElement dummyElement = new ServiceElement( ElementType.UInt16, unchecked (attrId)); return(CreateElement(dummyElement, buf, offset)); }
private void WriteInt32(ServiceElement element, int value, byte[] buf, ref int offset, out int totalLength) { int host32 = value; int net32 = IPAddress.HostToNetworkOrder(host32); byte[] valueBytes = BitConverter.GetBytes(net32); WriteFixedLength(element, valueBytes, buf, ref offset, out totalLength); }
private void WriteInt64(ServiceElement element, long value, byte[] buf, ref int offset, out int totalLength) { long host64 = value; long net64 = IPAddress.HostToNetworkOrder(host64); byte[] valueBytes = BitConverter.GetBytes(net64); WriteFixedLength(element, valueBytes, buf, ref offset, out totalLength); }
private void WriteInt16(ServiceElement element, short value, byte[] buf, ref int offset, out int totalLength) { short host16 = value; short net16 = IPAddress.HostToNetworkOrder(host16); byte[] valueBytes = BitConverter.GetBytes(net16); WriteFixedLength(element, valueBytes, buf, ref offset, out totalLength); }
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); }
/// <summary> /// Reads the RFCOMM Channel Number value from the service record, /// or returns -1 if the element is not present. /// </summary> /// - /// <param name="record">The <see cref="ServiceRecord"/> /// to search for the element. /// </param> /// - /// <returns>The Channel Number as an unsigned byte 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 GetRfcommChannelNumber(ServiceRecord record) { ServiceElement channelElement = GetRfcommChannelElement(record); if (channelElement == null) { return(-1); } return(GetRfcommChannelNumber(channelElement)); }
protected virtual void WriteVariableLength(ServiceElement element, byte[] valueBytes, byte[] buf, ref int offset, out int totalLength) { int curLen; curLen = MakeVariableLengthHeader(buf, offset, element.ElementTypeDescriptor, out HeaderWriteState headerState); offset += curLen; VerifyWriteSpaceRemaining(valueBytes.Length, buf, offset); valueBytes.CopyTo(buf, offset);//write offset += valueBytes.Length; CompleteHeaderWrite(headerState, buf, offset, out totalLength); }
/// <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); }
public string GetMultiLanguageStringAttributeById(ushort id, LanguageBaseItem language) { if (language == null) { throw new ArgumentNullException("language"); } ushort 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); }
private static ServiceElement ServiceElementFromUuid(object classRaw) { ServiceElement tmp = null; uint 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 uuid128) { 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 int, "Unexpected ServiceClassId type: " + classRaw.GetType().Name); int i32 = (int)classRaw; classU32 = unchecked ((uint)i32); writeIntegral = true; } if (writeIntegral) { try { ushort u16 = Convert.ToUInt16(classU32); Debug.Assert(classU32 <= ushort.MaxValue, "NOT replace the throw, LTE"); tmp = new ServiceElement(ElementType.Uuid16, u16); } catch (OverflowException) { Debug.Assert(classU32 > ushort.MaxValue, "NOT replace the throw, GT"); tmp = new ServiceElement(ElementType.Uuid32, classU32); } } return(tmp); }
/// <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(ushort 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); } AddCustomAttribute(new ServiceAttribute(id, e)); }
//-------------------- // /// <summary> /// Gets the list of <see cref="T:InTheHand.Net.Bluetooth.LanguageBaseItem"/> /// items in the service record. /// </summary> /// - /// <param name="elementSequence"> /// A <see cref="T:InTheHand.Net.Bluetooth.ServiceElement"/> holding the /// data from the /// <see cref="F:InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.LanguageBaseAttributeIdList"/> /// attribute. /// </param> /// - /// <returns> /// An array of <see cref="T:InTheHand.Net.Bluetooth.LanguageBaseItem"/>. /// An array length zero is returned if the service record contains no such attribute. /// </returns> /// - /// <exception cref="T:System.ArgumentException"> /// <paramref name="elementSequence"/> is not of type /// <see cref="F:InTheHand.Net.Bluetooth.ElementType.ElementSequence"/>. /// </exception> /// <exception cref="T:System.Net.ProtocolViolationException"> /// The element sequence contains incorrectly formatted or invalid content, /// for example it contains the wrong element data types, or doesn't contain /// the elements in groups of three as required. /// </exception> public static LanguageBaseItem[] ParseListFromElementSequence(ServiceElement elementSequence) { if (elementSequence.ElementType != ElementType.ElementSequence) { throw new ArgumentException(ErrorMsgLangBaseListParseNotSequence); } #if V1 IList elementList = elementSequence.GetValueAsElementList(); #else IList <ServiceElement> elementList = elementSequence.GetValueAsElementList(); #endif int numElements = elementList.Count; const int ElementsPerItem = 3; if (numElements == 0 || (numElements % ElementsPerItem) != 0) { throw new System.Net.ProtocolViolationException(ErrorMsgLangBaseListParseNotInThrees); } int numItems = numElements / ElementsPerItem; LanguageBaseItem[] items = new LanguageBaseItem[numItems]; for (int i = 0; i < numItems; ++i) { // Casts are for the non-Generic version. ServiceElement e1Lang = elementList[i * ElementsPerItem]; ServiceElement e2EncId = elementList[i * ElementsPerItem + 1]; ServiceElement e3BaseId = elementList[i * ElementsPerItem + 2]; if (e1Lang.ElementType != ElementType.UInt16 || e2EncId.ElementType != ElementType.UInt16 || e3BaseId.ElementType != ElementType.UInt16) { throw new System.Net.ProtocolViolationException(ErrorMsgLangBaseListParseNotU16); } if ((ushort)e3BaseId.Value == 0) { throw new System.Net.ProtocolViolationException(ErrorMsgLangBaseListParseBaseInvalid); } LanguageBaseItem item = new LanguageBaseItem( (ushort)e1Lang.Value, (ushort)e2EncId.Value, (ushort)e3BaseId.Value); items[i] = item; } return(items); }
private void WriteUInt64(ServiceElement element, ulong value, byte[] buf, ref int offset, out int totalLength) { long valueS = unchecked ((long)value); WriteInt64(element, valueS, buf, ref offset, out totalLength); }
private void WriteUInt32(ServiceElement element, uint value, byte[] buf, ref int offset, out int totalLength) { int valueS = unchecked ((int)value); WriteInt32(element, valueS, buf, ref offset, out totalLength); }
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); }
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); }
//-------------------------------------------- private void WriteUInt16(ServiceElement element, ushort value, byte[] buf, ref int offset, out int totalLength) { short valueS = unchecked ((short)value); WriteInt16(element, valueS, buf, ref offset, out totalLength); }
/// <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) { int curLen; curLen = MakeVariableLengthHeader(buf, offset, element.ElementTypeDescriptor, out HeaderWriteState 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, (ushort)element.Value, buf, ref offset, out totalLength); break; case ElementType.Int16: WriteInt16(element, (short)element.Value, buf, ref offset, out totalLength); break; case ElementType.UInt32: WriteUInt32(element, (uint)element.Value, buf, ref offset, out totalLength); break; case ElementType.Int32: WriteInt32(element, (int)element.Value, buf, ref offset, out totalLength); break; case ElementType.UInt64: WriteUInt64(element, (ulong)element.Value, buf, ref offset, out totalLength); break; case ElementType.Int64: WriteInt64(element, (long)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, (ushort)element.Value, buf, ref offset, out totalLength); } else if (element.ElementType == ElementType.Uuid32) { WriteUInt32(element, (uint)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 = Sockets.BluetoothListener.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; if (element.Value is string valueString) { 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); }